代码改变世界

Uliweb模板分析

2009-09-22 12:56  ubunoon  阅读(580)  评论(1编辑  收藏  举报

limodou的文档介绍,uliweb的模板是基于webpy框架的模板,是一种非常简洁的模板表示方式,语法很简单,除了标准的html语言外,还可以包含下面介绍的语法代码,需要注意的是,这些语法代码中的名称都是由view函数通过字典返回的key值来表示的。

 

所有与Python相关的模板代码均需要放置在{{}}之中!

 

{{ = result }} 用来输出标记,result可以为一个变量或者一个函数调用,系统会自动对输出的内容进行转义处理,需要注意的是 = reuslt之间有一个空格,或者=左右均无空格,这原本是一个bug,在发了一份邮件给limodou后,马上就修正了。

 

如果result是一个函数func{{ = func }} 将得到funcrepr显示,如果需要调用函数,则需要将代码编写成 {{ = func() }},这是一个非常有用的方法,可以在html中调用各类合适的方面的内部函数,其实这是一个任何一个合法的Python语句都可以的函数,如果我们故意将这个函数写错,在http://localhost:8000/主页面上将显示出错误消息,在最后一行,可以看到是采用out.write(func())方式写出html代码的,因此只要是合法的代码(能够返回一个string对象)的值,都可以作为out.write()的参数,既然我们知道了{{=}}中的内容是作为out.write参数,而且为string对象,那么我们也可以直接使用{{="your"}}来输出一个字符串,尽管"your"并不是我们从view中获取得到的一个变量,但是它确实可以使用!!

 

从上面的分析我们也可以知道,模板的代码最终都将会转换成python中的代码,那么任何内嵌的函数都是可以使用的,由此我们可以构建一个复杂的函数来输出我们当前文件的内容

 

 

{{ }} 语句块中包含的是Python的代码语句,此Python语句需要pass语句块来进行结束。如果在模板中编写如下代码:

{{ for local in dic: }}

{{=local }}

{{ pass}}

uliweb后台,将执行下面的代码:

out.write('\n\n', escape=False)

for local in dic:

   out.write('\n', escape=False)

  

   out.write(local)

 

   out.write('\n', escape=False)

   pass

out.write('\n\n', escape=False)

因此我们很容易在{{}中编写Python语句,在{{=}}中使用Python的变量,或者函数等内容!

 

 

 

{{ extend template }} 将扩展有template指定的模板,template可以为字符串,表示从父模板中继承,在最新的版本中,在原先的教程中,说是需要在父模板中定义一个{{include }},这样在{{extend}}之后的所有内容都将插入到这个位置,但是如果在{{extend}}之前还有内容将插入到父模板的最前面去。通过这种方式就可以在子模板中定义变量,但是在父模板中使用。就是将变量的定义放在{{extend}}之前就行了!

 

也可以通过include方式载入模板,常用的一个模板是menu,一般在extend模板之后include的。

menu模板的定义如下:

{{

menus = [

    ('settings', 'Settings', '/admin'),

    ('appsinfo', 'Apps Info', '/admin/appsinfo'),

    ('urls', 'Urls', '/admin/urls'),

    #('application',"Application", '/admin/app'),

    #("variable","Variable","/admin/var"),

    ('request', "Request", "/admin/request"),

]

def menu(current='settings'):

    for id, caption, link in menus:

        if id == current:

            out.write('<li id="current"><strong>%s</strong></li>' % caption, escape=False)

        else:

            out.write('<li><a href="%s">%s</a></li>' % (link, caption), escape=False)

        pass

    pass

pass

}}

 

通过include menu模板之后,之后就可以调用menu函数进行输出处理。

 

不建议那么使用,而且在最新的版本中,include template方法有些无奈![ubunoon] 可以在父template中定义某个块 {{ block main }} 方式,然后在子模板用 {{ block mian }} {{end}} 语句块来取代父模板中的内容。这个与django的模板方式有些类似!

 

 

我们已经分析得知,模板是运行在Python环境下,那么template中实际具有那些特殊的环境呢?

Uliweb首先为我们内置了一些常用函数(方法):

 

xml(text)  用来输出不转移的字符,可以用来输出HTML代码,如果有一段文本,里面包含了<>等具有特殊意义的HTML字符,可以通过xml来实现正确输出。

 

out对象,用来输出信息,从上面分析我们已经看到,所有的{{=}}都是通过out对象的write方法来进行输出,该方法也可以直接作为python语句在模板中进行应用。{{= result}}{{ out.write(result) }} 是等同的。

out对象一般不需要直接在模板中使用,具有两个特殊的方法:

   write(text, escape = True) 输出文本,escape表示是否要进行转义

   noescape(text) 输出不需要进行转义的文本

由此我们可以得到,xml(text)其实就是使用write(text,False)方式进行处理,只是使用xml方便一些。我们可以在模板中通过调用{{=xml}}{{=out.write}}来查看输出的是否为同一个对象的同一个地址,我的测试结果如下:

<bound method Out.noescape of <uliweb.core.template.Out object at 0x02EAB490>>

<bound method Out.write of <uliweb.core.template.Out object at 0x02EAB490>>

很明显,xmlout.write使用同一个方法,只是xml调用的Out.noescape方法。

 

在最新的版本中,增加了一个{{ << }} 功能,和{{xml()}}具有相同的功能,也就是{{ <<val }} {{ xml(var) }}具有相同的功能,由于<<只是一个符号,因此无法通过测试其调用地址!!查看源代码就可以知道,{{<<}}{{xm()}}只是在解析时不同,最后仍是通过Out.write对象来调用的。

 

同时,模板还支持一个url_for的反转方法,url_for方法可以将调用获取的url地址进行反转获取。

 

 

如果要给自己的增加自己定义的函数,则需要在app目录下面修改__init__.py文件,在里面添加代码:

 

from uliweb.core.plugin import plugin

 

##################################################

# insert rst2html function to template environment

##################################################

 

@plugin('prepare_template_env')

def prepare_template_env(sender, env):

    from uliweb.utils.rst import to_html

    from uliweb.core.SimpleFrame import errorpage

    def rst2html(filename):

        f = env.get_file(filename)

        if f:

            return to_html(file(f).read())

        else:

            errorpage("Can't find the file %s" % filename)

    env['rst2html'] = rst2html

 

系统会自动调用prepare_template_env函数,从而将模板功能rst2html添加到环境中去。在prepare_template_env函数下面定义内嵌函数,所有相关的内嵌函数通过env[]字典方式,都可以添加到模板方法中去。

 

模板采用utf-8进行编码,因此最好将所有的字符均用utf-8进行处理,所有的文档也保存为utf-8格式。在父模板中设置的charset=gb2312并不会起作用!

 

Uliweb的模板技术是在不断的更新与变化之中的,因此需要不断关注uliweb,了解其技术发展。


这个分析的uliweb模板,也不是最新版本的。



已经不存在该方法了!