自定义模板语言整合

Posted 财经知识狂魔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义模板语言整合相关的知识,希望对你有一定的参考价值。

  这篇文章主要对比一下两大框架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---支持

 

以上是关于自定义模板语言整合的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段1——vue主模板

VSCode自定义代码片段(vue主模板)

VSCode自定义代码片段2——.vue文件的模板

如何在片段着色器中进行自定义模板测试

pycharm自定义代码模板

VSCode 如何操作用户自定义代码片段(快捷键)