zoukankan      html  css  js  c++  java
  • tornado学习笔记(三)

    3 Extending Templates

    1 blocks and substitutions

    模板可以继承于基类模板,这样可以重复使用很多模块减少代码量

    如在index.html中继承main.html,在index.html的开头加上:{% extends "main.html" %}

    block:划定一些扩展模板的时候可能需要修改的代码块,在子类中直接通过block name就可以重写这一块

    如在main.html中:

    <header>
        {% block  header %}{% end %}
    </header>
    

    在子模板index.html中:

    {% extend main.html %}
    
    {% block header %}
        <h1>hello world</h1>
    {% end %}
    

    2 autoescaping

    escape的意思就是转义,将一些原本是script中的符号换一些编码表示,如<变为&lt;, 在浏览器显示的时候才显示出原来的字符,这样是为了安全起见,比如别人在文章评论中可能上传一些<script>alert('dangerous...')</script>的文本来进行攻击,会导致我们打开网页弹出警告框.

    默认情况下tornado会自动escape模板中的内容,但有些时候自动转义会导致一些变量无法正常使用,如在模板中有

    {% set mailLink = "<a href="mailto:contact@burtsbooks.com">Contact Us</a>" %}
    {{ mailLink }}
    

    本来是设置一个邮件地址作为变量,但是由于转义变成类似&lt;a href=&quot;mailto:contact@burtsbooks.... 为了处理这种情况,我们可以自己设置关闭自动转义,加上{% autoescape None %}

    关闭自动转义虽然可以处理但是又少了保护机制,所以还有一种解决方法是加上raw block: {% raw mailLink %}

    3 UI modules

    Modules是继承于tornado的UIModule类的一个python类,当遇到{% module Foo(...) %}这种标签,会调用模块的render函数,返回一个string替换module标签。

    UI模块可以嵌入js,css文件

    basic module usage

    要在模板中使用module,首先需要在应用中声明,ui_modules参数接受一个dict将模块名字映射到渲染它们的类

    hello.py

    import os.path
    import tornado.httpserver
    import tornado.ioloop
    import tornado.options
    import tornado.web
    
    from tornado.options import define, options
    define("port", default=8000, help="run on the given port", type=int)
    
    
    class HelloHandler(tornado.web.RequestHandler):
        def get(self):
            self.render('hello.html')
    
    class HelloModule(tornado.web.UIModule):
        def render(self):
            return '<h1>hello world!</h1>'
    
    
    if __name__ == '__main__':
        tornado.options.parse_command_line()
        app = tornado.web.Application(
            handlers=[(r'/', HelloHandler)],
            template_path = os.path.join(os.path.dirname(__file__), 'templates'),
            ui_modules={'Hello': HelloModule}
        )
        server = tornado.httpserver.HTTPServer(app)
        server.listen(options.port)
        tornado.ioloop.IOLoop.instance().start()
    

    hello.html

    <html>
        <head><title>UI module example</title></head>
        <body>
            {% module Hello() %}
        </body
    </html>
    

    例子中ui_modules={'Hello': HelloModule}定义Hello模块是用HelloModule类来进行处理,所以html中间中的模块标签会被替换为HelloModule类中返回的内容

    modules in depth

    在看Burt's books的例子,现在建立一个页面用来推荐一些书,每一本书都是用同样的模板进行渲染,创建modules/book.html文件:

    <div class="book">
        <h3 class="book_title">{{ book["title"] }}</h3>
        {% if book["subtitle"] != "" %}
            <h4 class="book_subtitle">{{ book["subtitle"] }}</h4>
        {% end %}
        <img src="{{ book["image"] }}" class="book_image"/>
        <div class="book_details">
            <div class="book_date_released">released: {{ book["date_released"] }}</div>
            <div class="book_date_added">added: {{ locale.format_date(book["date_added"], relative=False) }}</div>
            <h5>description:</h5>
            <div class="book_body">{% raw book["description"] %}</div>
    </div>
    </div>
    

    这个模板接受名为book的字典,然后定义展示一本书的形式,函数locale.format_date()是tornado中提供时间功能的函数,参数为时间,relative=False说明是绝对时间

    在recommended.html中,对每一本书调用Book模块来进行渲染:

    {% extends "main.html" %}
    
    {% block body %}
    <h2>recommended reading</h2>
        {% for book in books %}
            {% module Book(book) %}
        {% end %}
    {% end %}
    

    在py文件中,建立RecommendedHandler类和BookModule类

    class RecommendedHandler(tornado.web.RequestHandler):
        def get(self):
            self.render(
                "recommended.html",
                page_title="burt's books | recommended reading",
                header_text="recommended reading",
                books=[
                    {
                        "title": "Programming Collective Intelligence",
                        "subtitle": "Building Smart Web 2.0 Applications",
                        "image": "/static/images/collective_intelligence.gif",
                        "author": "Toby Segaran",
                        "date_added": 1310248056,
                        "date_released": "August 2007",
                        "isbn": "978-0-596-52932-1",
                        "description": "<p>This fascinating book demonstrates how you " +
                                       "can build web applications to mine the enormous " +
                                       "amount of data created by people... </p>"
                    },
                ]
            )
    
    class BookModule(tornado.web.UIModule):
        def render(self, book):
            return self.render_string('modules/book.html', book=book)
    
    if __name__ == "__main__":
        ...
        ui_modules = {
            "Book": BookModule,
        }
        ...
    

    render_string是将模板渲染后以string的形式返回,这里的逻辑是请求首先通过RecommendedHandler类来处理,这个类使用模板recommended.html来渲染,然后在这个模板中对于每一本书的渲染将调用BookModule类来处理

    embedding javascript and css

    一些用来在模板中嵌入jss,cs,html等的函数:

    • embedded_css()
    • embedded_javascript()
    • html_body()
    • css_files()
    • javascript_files()

    1.embedded_javascript

    class BookModule(tornado.web.UIModule):
        def render(self, book):
            return ...
        def embedded_javascript(self):
            return "document.write("hi!")"
    

    2.函数中插入的内容在html中将会内置在<script>标签中,放在</body>标签的前面

    <script type="text/javascript">
        document.write("hi")
    </script>
    

    3.embedded_css用法类似,插入的内容内置在<style>标签中,eg

    def embedded_css(self):
        return ".book {background-color:#F5F5F5}"
    

    4.html_body()函数可以在</body>前加入html语句

    def html_body(self):
        reutrn "<script>document.write(...)</script>"
    

    5.css_files(), javascript_files()可以引用css,js文件

    def css_files(self):
        return "static/css/style.css"
    
    def javascript(self):
        return "https://ajax.googleapis.com/ajax/.../jquery-ui.min.js"
    
  • 相关阅读:
    2020软件工程作业05
    一、uart&tty驱动
    柔性数组使用备忘
    指针和数组备忘
    计算信息帧的校验和(备忘)
    Linux系统vim几个常见配置
    C语言实现过滤ASCII在0~127范围内的字符,并去除重复的字符
    extern "C"的用法
    strtol详解
    将一个十进制整数转换为二进制并输出
  • 原文地址:https://www.cnblogs.com/jolin123/p/4505792.html
Copyright © 2011-2022 走看看