• 自定义模板语言整合


      这篇文章主要对比一下两大框架Tornado和Django自定义模块语言,以及对Tornado的自定义模块语言进行一个分离整合

      首先我们先看一下在Tornado里,我怎么实现的自定义模板语言

    • 第一步,创建UIMethods.py文件,写入自定义方法(第一参数一定为self),创建UIModules.py文件,定义类(必须继承Tornado一个导入类UIModule,通过重写render方法实现)
    • 第二步,注册到settings里
    • 第三步,在模板语言里调用  {{ 函数方法 }}  {% module 类名(参数) %}
    def tab(self):
        return 'UIMethod'
    UIMethods
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from tornado.web import UIModule
    from tornado import escape
     
    class custom(UIModule):
     
        def render(self, *args, **kwargs):
            return escape.xhtml_escape('<h1>wupeiqi</h1>')
            #return escape.xhtml_escape('<h1>wupeiqi</h1>')
    UIModules
    #! /usr/bin/env python
    # -*- coding:utf-8 -*-
    __author__ = "laoliu"
    
    import tornado.ioloop
    import tornado.web
    from UIMethods import Method1 as mt1
    from UIMethods import UIMethod2 as mt2
    
    
    class MainHandler(tornado.web.RequestHandler):
        def get(self):
            self.render("hello.html")
    
    settings = {
        'template_path': 'views',        # html文件
        'static_path': 'statics',        # 静态文件(css,js,img)
        'static_url_prefix': '/statics/',# 静态文件前缀
        'ui_methods': [mt1,mt2],              # 自定义UIMethod函数
        # 'ui_modules': md,              # 自定义UIModule类
    }
    
    application = tornado.web.Application([
        (r"/index", MainHandler),  #localhost:9999/index
    ],**settings)
    
    
    
    if __name__ == "__main__":
        application.listen(9999)
        tornado.ioloop.IOLoop.instance().start()
    
    <body>
        <h1>hello</h1>
        {% module custom(123) %}
        {{ tab() }}
    </body>
    前端

      上述过程已经实现了在Tornado中的自定义模板语言,但是上述配置都还写在启动文件里,没有做到有效的分离,而且上面就光注册到settings里这一步,就要操作两次,一个导入模块,一个就是在settings里写入模块名,能更简洁一点呢?答案是有的

      我们是不是可以在配置文件里为UIMethods和UIModules定义两个组,组元素为要导入的文件路径,然后在启动程序文件里只需要循环这两个组,__import__导入就可以了

    • 在公共组件创建两个文件夹,分别存放UIMethod模块和UIModule模块

    •  在配置文件中,定义两个元组,分别存放要导入的模块
    ui_method = (
        'Infrastructure.UIMethods.Null',
    )
    
    ui_module = (
        'Infrastructure.UIModules.Null',
    )
    
    settings = {
        'template_path': 'Views',
        'static_path': 'Statics',
        'static_url_prefix': '/Statics/',
    }
    
    •  在程序启动文件,写入加载自定义方法
    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    import tornado.ioloop
    import tornado.web
    import Config
    
    
    def load_ui_module(settings):
        module_list = []
        for path in Config.ui_method:
            m = __import__(path, fromlist=True)
            module_list.append(m)
        settings['ui_modules'] = module_list
    
    
    def load_ui_method(settings):
        method_list = []
        for path in Config.ui_method:
            m = __import__(path, fromlist=True)
            method_list.append(m)
        settings['ui_methods'] = method_list
    
    
    def load_routes(app):
        for route in Config.routes:
            host_pattern = route['host_pattern']
            route_path = route['route_path']
            route_name = route['route_name']
    
            m = __import__(route_path, fromlist=True)
            pattern_list = getattr(m, route_name)
    
            app.add_handlers(host_pattern, pattern_list)
    
    
    # def load_hook():
    #     pass
    
    
    def start():
    
        settings = {}
    
        load_ui_method(settings)
        load_ui_module(settings)
    
        settings.update(Config.settings)
    
        application = tornado.web.Application([
            #(r"/index", home.IndexHandler),
        ], **settings)
    
        load_routes(application)
    
        # load_hook()
        # print('http://127.0.0.1:8888')
    
        application.listen(8888)
        tornado.ioloop.IOLoop.instance().start()
    
    if __name__ == "__main__":
        start()
    

       上面就达到我刚才说的那两个目的了,只要写好自定义方法,在配置文件里配置一下路径即可

      说了Tornado,那我们看下Django,对于这个大而全的框架,自定义模板语言在操作上限定非常死,必须按照它们的规则取创建使用

      注:操作前,必须确保你注册了app

    • 第一步,在app中创建templatetags文件夹,并创建xx.py文件放在templatetags文件夹下,在xx.py文件定义HTML调用的方法
    #xx.py
    from django import template from django.utils.safestring import mark_safe from django.template.base import resolve_variable,Node,TemplateSyntaxError register = template.Library() @register.simple_tag def my_simple_time(v1,v2,v3): return v1+v2+v3 @register.simple_tag def my_input(id,arg): result = "<input type='text' id='%s' class='%s'/>"%(id,arg,) return mark_safe(result)
    •  在需要进行渲染模板里调用,首选要在模板文件头部加载自定义方法文件{% load xx %},然后再调用函数 {% 函数名 参数 %}
    {% load xx %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            .hide{
                display:none;
            }
        </style>
    </head>
    <body>
        <h1>simple_tag</h1>
        {% my_input 123 'hide' %}
        <input type="button" onclick="show();"/>
        {% my_simple_time 1 2 3 %}
    <script>
        function show(){
            var inp = document.getElementById('123');
            inp.classList.remove('hide');
        }
    </script>
    </body>
    </html>
    

       除了自定义simple_tag之外,还可以自定义filter

    #xx.py
    from django import template
    from django.utils.safestring import mark_safe
    from django.template.base import resolve_variable,Node,TemplateSyntaxError
     
     
    register = template.Library()
     
    @register.filter
    def detail(value,arg):
        allcount,remainder = arg.split(',')
        allcount = int(allcount)
        remainder = int(remainder)
        if value % allcount == remainder:
            return True
        return False
     
    @register.filter
    def func(val1,val2):
        if val1 + val2 == 2:
            return True
        return False
    
    {% load xx %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>filter</h1>
        <div>
    {#        {% if 1|func:1 %}#}
    {#            <h1>bingo</h1>#}
    {#        {% endif %}#}
     
            {% for item in detail_list %}
                {% if forloop.counter|detail:"4,0" %}
                    <div>
                        <p>{{ item.name }}</p>
                    </div>
                {% endif %}
            {% endfor %}
        </div>
    <script>
     
    </script>
    </body>
    </html>
    

       我们发现他们在定义时,装饰器是不同的,另外还有以下几点不同:

    两种自定义方式对比

    • 参数:sample_tag---任意参数,filter---只能两个
    • 执行方式:sample_tag---{% 函数名:参数1 参数2 ... %},filter---{{ 参数一|函数名:参数二 }}
    • 支持条件if:sample_tag---不支持,filter---支持
  • 相关阅读:
    JUC回顾之-可重入的互斥锁ReentrantLock
    java基础知识回顾之java Thread类学习(十二)-- 线程中断
    mknod命令
    一个公益水塘引发的纠纷
    对cgic的理解——name选项
    linux的fwrite()使用方法,当前时间写入文本的程序
    /etc/resolv.conf文件详解
    关于函数strtok和strtok_r的使用要点和实现原理
    shell视频
    进程一些命令pstree,ps,pstack,top
  • 原文地址:https://www.cnblogs.com/xinsiwei18/p/7868740.html
Copyright © 2020-2023  润新知