本站首页    管理页面    写新日志    退出


«September 2025»
123456
78910111213
14151617181920
21222324252627
282930


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7603868
建立时间:2006年5月29日




[Python]web.py templating system (codename: templetor)
软件技术

lhwork 发表于 2007/2/6 16:33:50

There are almost as many Python templating systems as there are web frameworks (and, indeed, it seems like many templating systems are adopting web framework-like features), so it is with some trepidation that I work on a new one. Sadly, again I find that my requirements are met by nothing else: The templating system has to look decent. No <%#foo#%> crud. Reuse Python terms and semantics as much as possible. Expressive enough to do real computation. Usable for any text language, not just HTML and XML. And requirements for the implementation as well: Sandboxable so that you can let untrusted users write templates. Simple and fast implementation. So here's my entry. Variable substitutionLook, a $string. Hark, an ${arbitrary + expression}. Gawk, a $dictionary[key].function('argument'). Cool, a $(limit)ing. Stop, \$money isn't evaluated. We use basically the same semantics as (rejected) PEP 215. Variables can go anywhere in a document. Newline suppressionIf you put a backslash \ at the end of a line \ (like these) \ then there will be no newline. renders as all one line. ExpressionsHere are some expressions: $for var in iterator: I like $var! $if times > max: Stop! In the name of love. $else: Keep on, you can do it. $try: $get(input) $except: Couldn't find it. That's all, folks. All your old Python friends are here: if, while, for, try, except, else. break, continue, and pass also act as you'd expect. (Obviously, you can't have variables named any of these.) The Python code starts at the $ and ends at the :. The $ has to be at the beginning of the line, but that's not such a burden because of newline suppression (above). Also, we're very careful about spacing -- all the lines will render with no spaces at the beginning. (Open question: what if you want spaces at the beginning?) There are a couple changes from Python: for and while now take an else clause that gets called if the loop is never evaluated. (Possible feature to add: Django-style for loop variables.) Comments$# Here's where we hoodwink the folks at home: Please enter in your deets: CC: [ ] $#this is the important one SSN: $#Social Security Number#$ [ ] Comments start with $# and go to #$ or the end of the line, whichever is first. CodeSometimes you just need to break out the Python. $ mapping = { $ 'cool': ['nice', 'sweet', 'hot'], $ 'suck': ['bad', 'evil', 'awful'] $ } Isn't that $mapping[thought]? That's$ del mapping $ fine with me. $ complicatedfunc() $ for x in bugs: $ if bug.level == 'severe': Ooh, this one is bad. $ continue And there's $x... Body of loops have to be indented with exactly 4 spaces. Code begins with a $ and a space and goes until the next $ or the end of the line, whichever comes first. Nothing ever gets output if the first character after the $ is a space (so complicatedfunc above doesn't write anything to the screen like it might without the space). Python integration A template begins with a line like this:$def with (name, title, company='BigCo') which declares that the template takes those arguments. (The with keyword is special, like def or if.) Don't forget to put spaces in the definition The following will not work:$def with (name,title,company='BigCo') Inside Python, the template looks like a function that takes these arguments. It returns a storage object with the special property that evaluating it as a string returns the value of the body of the template. The elements in the storage object are the results of the defs and the sets. Perhaps an example will make this clearer. Here's a template, "entry":$def with (post) $var title: $post.title <p>$markdown(post.body)</p> <p class="byline">by $post.author</p> Here's another; "base":$def with (self) <html><head> <title>$self.title</title> </head><body> <h1>$self.title</h1> $self </body></html> Now let's say we compile both from within Python, the first as entry, the second as base. Here's how we might use them:print base( entry( post ) ) entry takes the argument post and returns an object whose string value is a bit of HTML showing the post with its title in the property title. base takes this object and places the title in the appropriate place and displays the page itself in the body of the page. The Python code prints out the result. Where did markdown come from? It wasn't passed as an argument. You can pass a list of functions and variables to the template compiler to be made globally available to templates. Here's an example:import template render = template.render('templates/') template.Template.globals['len'] = len print render.base(render.message('Hello, world!')) The first line imports templetor. The second says that our templates are in the directory templates/. The third give all our templates access to the len function. The fourth grabs the template message.html, passes it the argument 'Hello, world!', passes the result of rendering it to the template base.html and prints the result. (If your templates don't end in .html or .xml, templetor will still find them, but it won't do its automatic HTML-encoding.) Turning Off Filter By default template.render will use web.websafe filter to do HTML-encoding. To turn it off, put a : after the $ as in:$:form.render() Output from form.render() will be displayed as is.


阅读全文(4224) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.332 second(s), page refreshed 144786790 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号