自定義模板語言整合
阿新 • • 發佈:2017-11-21
routes bing ret custom mod url mar == hand
這篇文章主要對比一下兩大框架Tornado和Django自定義模塊語言,以及對Tornado的自定義模塊語言進行一個分離整合
首先我們先看一下在Tornado裏,我怎麽實現的自定義模板語言
- 第一步,創建UIMethods.py文件,寫入自定義方法(第一參數一定為self),創建UIModules.py文件,定義類(必須繼承Tornado一個導入類UIModule,通過重寫render方法實現)
- 第二步,註冊到settings裏
- 第三步,在模板語言裏調用 {{ 函數方法 }} {% module 類名(參數) %}
def tab(self): return ‘UIMethodUIMethods‘
#!/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---支持
自定義模板語言整合