Tornador UI module modifies JS embedding position

Source: Internet
Author: User
Tags cdata extend

Because the vue.js is used, and then the UI module defines some vue.js directives, the directives must be defined before the body.

However, Tornado UI Module defaults to append JS to </body> before it's too late.

How to do it!

In order not to modify the Tornador code, only inherited and overloaded.

JS processing is in the web.py render method inside to do, is a very large method, here and did not do the split. All I have is copy.

This is the final implementation version

Class Basehandler (RequestHandler):

'''
Create by Bigzhu at 15/01/29 22:53:07 Customize some basic methods
Set PG
Set Current_User as Cookie user_id
Modify by Bigzhu at 15/01/30 09:59:46 return directly User_info
Modify by Bigzhu at 15/01/30 10:32:37 the default return user_info to remove
Modify by Bigzhu at 15/02/21 00:41:23 modifies js_embed location to '''

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 to change the position of 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 No (Path.startswith (x) for x in ["/", "http:", "https:"])
If Js_files:
# Maintain order of the 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 ' 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 ' 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 ' html = Html[:hloc] + css + b ' \ n ' + Html[hloc:]
If Html_heads:
Hloc = Html.index (b ' 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 in order to set the _getframe, you have to overload this method. Otherwise, the template path will be called by 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)

The process is very tangled and complex, slowly speaking.

Background

Because my basehandler did not put together with the specific items, but to take out as a common method to join the Pythonpath inside to use the

Overload Render

When I put the render overload in, and simply change the inside </body> to

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 ' html = Html[:sloc] + js + b ' \ n ' + Html[sloc:]

And then the error is not due to this modification error, but can not find the template error:

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, 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 '
Because of the overload, the result is not as template/sites.html as before to find the template based on different projects, but to navigate to the path of the common method I defined.

It's just. Puzzled by the solution.

Troubleshoot template problems

Read it carefully. Templates are assembled in render_string.

Other than the discovery setting can set the Template_path parameter, vainly set to solve the problem. The module template is not available.

After careful consideration, the following functions need to be implemented

For the method that inherits the Basehandler implementation, use the path under this project
For module, you have to use an absolute path
The discovery uses strange sys._getframe to take the relative path, when the project uses, takes is ", empty, then is normal."

The original is to use the level of stack to solve this problem, I took out the overload, the level is wrong, leading to the wrong path

Continue to Overload render_string, Sys._getframe (0) to Sys._getframe (1), done, all normal!

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.