自定义模板语言整合
Posted 财经知识狂魔
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义模板语言整合相关的知识,希望对你有一定的参考价值。
这篇文章主要对比一下两大框架Tornado和Django自定义模块语言,以及对Tornado的自定义模块语言进行一个分离整合
首先我们先看一下在Tornado里,我怎么实现的自定义模板语言
- 第一步,创建UIMethods.py文件,写入自定义方法(第一参数一定为self),创建UIModules.py文件,定义类(必须继承Tornado一个导入类UIModule,通过重写render方法实现)
- 第二步,注册到settings里
- 第三步,在模板语言里调用 {{ 函数方法 }} {% module 类名(参数) %}
def tab(self): return \'UIMethod\'
#!/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>\')
#! /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---支持
以上是关于自定义模板语言整合的主要内容,如果未能解决你的问题,请参考以下文章