tornador UI module 修改 js 嵌入位置

因为用到 vue.js, 然后 UI module 里面定义了一些 vue.js 的 Directives, 必须要在 body 以前将 Directives 定义出来.

但是 tornado 的 UI Module 默认是将 js append 到</body> 前的, 这时候为时已晚了.

怎么办呢!

为了不修改 tornador 的代码,只有继承并重载了.

js 的处理是在web.py的render方法里面来做的, 是个非常大的方法, 这里并没有做拆分.我只有全部 copy 过来了

这是最终的实现版本

class BaseHandler(RequestHandler):

    '''
    create by bigzhu at 15/01/29 22:53:07 自定义一些基础的方法
        设置 pg
        设定 current_user 为 cookie user_id
    modify by bigzhu at 15/01/30 09:59:46 直接返回 user_info
    modify by bigzhu at 15/01/30 10:32:37 默认返回 user_info 的拆离出去
    modify by bigzhu at 15/02/21 00:41:23 修改 js_embed 的位置到 </head> 前
    '''

    def initialize(self):
        self.pg = self.settings['pg']

    def get_current_user(self):
        return self.get_secure_cookie("user_id")

    def render(self, template_name, **kwargs):
        """Renders the template with the given arguments as the response.
        create by bigzhu at 15/02/21 01:50:52 就是为了把embedded_javascript 的位置换一下
        """

        html = self.render_string(template_name, **kwargs)

        # Insert the additional JS and CSS added by the modules on the page
        js_embed = []
        js_files = []
        css_embed = []
        css_files = []
        html_heads = []
        html_bodies = []
        for module in getattr(self, "_active_modules", {}).values():
            embed_part = module.embedded_javascript()
            if embed_part:
                js_embed.append(utf8(embed_part))
            file_part = module.javascript_files()
            if file_part:
                if isinstance(file_part, (unicode_type, bytes_type)):
                    js_files.append(file_part)
                else:
                    js_files.extend(file_part)
            embed_part = module.embedded_css()
            if embed_part:
                css_embed.append(utf8(embed_part))
            file_part = module.css_files()
            if file_part:
                if isinstance(file_part, (unicode_type, bytes_type)):
                    css_files.append(file_part)
                else:
                    css_files.extend(file_part)
            head_part = module.html_head()
            if head_part:
                html_heads.append(utf8(head_part))
            body_part = module.html_body()
            if body_part:
                html_bodies.append(utf8(body_part))

        def is_absolute(path):
            return any(path.startswith(x) for x in ["/", "http:", "https:"])
        if js_files:
            # Maintain order of JavaScript files given by modules
            paths = []
            unique_paths = set()
            for path in js_files:
                if not is_absolute(path):
                    path = self.static_url(path)
                if path not in unique_paths:
                    paths.append(path)
                    unique_paths.add(path)
            js = ''.join('<script src="' + escape.xhtml_escape(p) +
                         '" type="text/javascript"></script>'
                         for p in paths)
            sloc = html.rindex(b'</body>')
            html = html[:sloc] + utf8(js) + b'\n' + html[sloc:]
        if js_embed:
            js = b'<script type="text/javascript">\n//<![CDATA[\n' + \
                b'\n'.join(js_embed) + b'\n//]]>\n</script>'
            sloc = html.rindex(b'</head>')
            html = html[:sloc] + js + b'\n' + html[sloc:]
        if css_files:
            paths = []
            unique_paths = set()
            for path in css_files:
                if not is_absolute(path):
                    path = self.static_url(path)
                if path not in unique_paths:
                    paths.append(path)
                    unique_paths.add(path)
            css = ''.join('<link href="' + escape.xhtml_escape(p) + '" '
                          'type="text/css" rel="stylesheet"/>'
                          for p in paths)
            hloc = html.index(b'</head>')
            html = html[:hloc] + utf8(css) + b'\n' + html[hloc:]
        if css_embed:
            css = b'<style type="text/css">\n' + b'\n'.join(css_embed) + \
                b'\n</style>'
            hloc = html.index(b'</head>')
            html = html[:hloc] + css + b'\n' + html[hloc:]
        if html_heads:
            hloc = html.index(b'</head>')
            html = html[:hloc] + b''.join(html_heads) + b'\n' + html[hloc:]
        if html_bodies:
            hloc = html.index(b'</body>')
            html = html[:hloc] + b''.join(html_bodies) + b'\n' + html[hloc:]
        self.finish(html)

    def render_string(self, template_name, **kwargs):
        """Generate the given template with the given arguments.

        We return the generated byte string (in utf8). To generate and
        write a template as a response, use render() above.

        create by bigzhu at 15/02/21 01:49:51 为了设定 _getframe,也得把这个方法重载一遍.否则 template 路径会按 bz 的来找

        """
        # If no template_path is specified, use the path of the calling file
        template_path = self.get_template_path()
        if not template_path:
            frame = sys._getframe(1)
            web_file = frame.f_code.co_filename
            while frame.f_code.co_filename == web_file:
                frame = frame.f_back
            template_path = os.path.dirname(frame.f_code.co_filename)
        with RequestHandler._template_loader_lock:
            if template_path not in RequestHandler._template_loaders:
                loader = self.create_template_loader(template_path)
                RequestHandler._template_loaders[template_path] = loader
            else:
                loader = RequestHandler._template_loaders[template_path]
        t = loader.load(template_name)
        namespace = self.get_template_namespace()
        namespace.update(kwargs)
        return t.generate(**namespace)

过程很纠结和复杂,慢慢来讲吧.

背景

因为我的BaseHandler并没有和具体项目放在一起,而是抽离出来作为公用的方法,加入到PYTHONPATH里面来使用了

重载 render

当我将render重载进来,并且简单的将里面的</body>修改为</head>

        if js_embed:
            js = b'<script type="text/javascript">\n//<![CDATA[\n' + \
                b'\n'.join(js_embed) + b'\n//]]>\n</script>'
            sloc = html.rindex(b'</head>')
            html = html[:sloc] + js + b'\n' + html[sloc:]

然后报错了!并不是因为这个修改报错,而是找不到模板报错:

Traceback (most recent call last):
  File "/Library/Python/2.7/site-packages/tornado/web.py", line 1332, in _execute
    result = method(*self.path_args, **self.path_kwargs)
  File "yemai.py", line 287, in get
    self.render(tornado_bz.getTName(self, 'sites'), sites=sites)
  File "/Users/bigzhu/Dropbox/lib/python_lib_bz/tornado_bz.py", line 44, in render
    html = self.render_string(template_name, **kwargs)
  File "/Library/Python/2.7/site-packages/tornado/web.py", line 769, in render_string
    t = loader.load(template_name)
  File "/Library/Python/2.7/site-packages/tornado/template.py", line 343, in load
    self.templates[name] = self._create_template(name)
  File "/Library/Python/2.7/site-packages/tornado/template.py", line 370, in _create_template
    with open(path, "rb") as f:
IOError: [Errno 2] No such file or directory: '/Users/bigzhu/Dropbox/lib/python_lib_bz/template/sites.html'
因为重载了,导致并没有像以前一样得到的是template/sites.html从而根据不同项目能找到模板,反而定位到了我定义的公用的方法的路径里面.

简直??百思不得其解.

解决模板问题

仔细研读.模板是在render_string里面来组合的.

以外的发现setting可以设置template_path参数,妄图设置了来解决这个问题.于是 Module 的模板找不到了.

仔细思索了一下,需要实现以下功能

对于继承BaseHandler实现的方法,用这个项目下的路径
对于 module, 又得用绝对路径
发现使用奇怪的sys._getframe来取相对路径的,项目用的时候,取到的是'',空的,于是正常了.

原来是用栈的级别来解决这个问题的, 我拿出来重载了,层级不对,导致路径不对了

继续重载render_string,把sys._getframe(0)改为sys._getframe(1),搞定,一切正常!

时间: 2024-12-24 17:41:44

tornador UI module 修改 js 嵌入位置的相关文章

修改Jquery Dialog 位置的实现方法_jquery

今天在做一个功能的时候使用到了Jquery UI中的dialog组件,因为是一个很简单的组件,有很多功能都没有提供,比如说直接获取到dialog的位置,直接修改dialog的位置都是不行的,并且但可拖动的位置看不见的时候,这个时候就是坑了,关闭不了,也拖动不了,这个时候只能刷新页面来重新初始化界面了. 我今天解决的就是这个问题:解决这种问题有两种方式(个人认为) 1.修改属性让可拖动局域可见,进行拖动 2.不让出现可拖动区域不可见的情况. 针对第一种情况,我没有想到合适的办法.下面给出第二种情况

TCPMP播放器UI的修改方法

 TCPMP播放器UI的修改方法     前段时间对TCPMP程序进行了研究,花了点时间把TCPMP程序的UI修改成了自已想要的样子,现对UI的修改方法简单介绍下:     网上有文章对于TCPMP程序在ARMV4下的编译方法和程序的结构介绍比较详细,但对于inteface方面的修改方法讲得并不多.     修改TCPMP界面基本上有两种方法: 1)     建立自已的工程,把TCPMP下的lib移植到这个工程里,这样界面的修改比较灵活,但是工作量比较大; 2)     直接在TCPMP工程里修

win7系统怎么修改当前所在位置?

  win7系统怎么修改当前所在位置? 1.首先,咱们单击开始菜单,然后在菜单中点击进入到控制面板的界面中,在控制面板中,咱们单击其中的"时钟.语言和区域"选项. 2.在接下来弹出的界面中,咱们就可以看到如下图中所示的界面了,咱们直接在区域和语言下方单击进入到更改位置. 3.之后弹出区域和语言的设置窗口,咱们将界面切换到位置这一栏,然后下面的当前位置就可以供我们操作更改了,大家想设置到哪个位置就直接在这里选择就是了.设置好之后记得点击下方的确定按钮保存哦.

photoshop修改临时文件存放位置的两种方法

我们在使用ps的时候,电脑会自己的的生成一些临时文件,当你关掉了ps后,这些临时文件就会关闭了.可当你存放的位置的空间不够大的时候,那要怎么版呢?下面网管之家为大家介绍photoshop修改临时文件存放位置的两种方法,希望能对大家有所帮助! 方法一:编辑--受选项--性能 方法二:快捷键,"ctrl"+"K".选择属性暂存盘.选择好点击确定 以上就是网管之家为大家介绍photoshop修改临时文件存放位置的两种方法介绍,希望能对大家有所帮助! 分类: PS入门教程

xp纯净版系统修改命令提示符默认位置的方法

xp纯净版系统修改命令提示符默认位置的方法   具体如下: 1.在Windows XP中,单击"开始→所有程序→附件→命令提示符",即可打开命令提示符窗口,默认情况下系统会定位到"X:Documents and Settings当前用户名>"下,其中X为操作系统所在盘符.但一般来说,我们用到命令提示符时需要在特定的目录下工作,因此有必要使用"计算机管理"功能来更改命令提示符的默认位置. 2.单击"开始→控制面板→性能和维护→管理工

win7下载后如何修改目前的位置

  有时候用户需要把自己的电脑拿到其他的地方去,这个这个时候位置就会发生变化.其实在win7系统操作系统的时候,我们能够对当前所在位置进行修改的,这样一些软件或者系统功能就会给我们提供一些所在地的天气或信息等.那么win7 64位旗舰版下载后如何修改目前的位置呢?下面小编就给大家详细的介绍一下具体的修改方法. 1.第一步需要做的就是单击win7系统里面的开始菜单,然后打开控制面板,选择"时钟.语言和区域"; 2.这时候就会弹出来界面汇总,直接点击区域和语言下的"更改位置&qu

javascript-chrome调试修改js怎么保存?

问题描述 chrome调试修改js怎么保存? 参照下图: 改css可以实时预览,改js怎么保存,实时预览呢 解决方案 在Console 里面执行 解决方案二: 去控制台,就是Console那个选项卡输入js代码执行 解决方案三: chrome调试动态加载的JSchrome调试jschrome中调试js

jeasyui-找前端UI高手修改ACE-admin 框架为iframe模式

问题描述 找前端UI高手修改ACE-admin 框架为iframe模式 本公司在使用ACE-Admin 作为软件后台界面框架,但原框架是每次刷新页面的不很好适应我们需求. 现想参考JeasyUI框架的模式,把ACE-admin改一下,使其支持iframe方式 . 有这方面的高手可以认真查看附件中的要求,然后联系我们, 费用不是问题,只要能达到要求.http://test1.swkj.it/ace/ui_ace_admin42208006.rar QQ42208006

android开发-最近在做个android应用市场的项目,想实现修改应用安装位置这个功能

问题描述 最近在做个android应用市场的项目,想实现修改应用安装位置这个功能 在应用市场 的设置选项中,实现一个功能,让用户选择应用的安装位置,共三个选项,1,应用的默认安装位置;2,优先安装在SD卡;3,优先安装在手机内存中.有DEMO非常感谢.邮箱yvhdcwxf@126.com