- TurboGears 教程
- TurboGears - 主页
- TurboGears - 概述
- TurboGears - 环境
- TurboGears - 第一个程序
- TurboGears - 依赖关系
- TurboGears - 服务模板
- TurboGears - HTTP 方法
- Genshi模板语言
- TurboGears - 包括
- TurboGears - JSON 渲染
- TurboGears - URL 层次结构
- TurboGears - Toscawidgets 表格
- TurboGears - 验证
- TurboGears - 闪讯
- TurboGears - Cookie 和会话
- TurboGears - 缓存
- TurboGears - Sqlalchemy
- TurboGears - 创建模型
- TurboGears - 原油操作
- TurboGears - 数据网格
- TurboGears - 分页
- TurboGears - 管理员访问
- 授权与认证
- TurboGears - 使用 MongoDB
- TurboGears - 脚手架
- TurboGears - 挂钩
- TurboGears - 编写扩展
- TurboGears - 可插拔应用
- TurboGears - 安静的应用程序
- TurboGears - 部署
- TurboGears 有用资源
- TurboGears - 快速指南
- TurboGears - 有用的资源
- TurboGears - 讨论
TurboGears - Genshi 模板语言
Genshi 是一种基于 XML 的模板语言。它类似于Kid,它曾经是 TurboGears 早期版本的模板引擎。Genshi 和 Kid 的灵感来自其他著名的模板语言,如HSLT、TAL和PHP。
Genshi 模板由处理指令组成。这些指令是模板中的元素和属性。Genshi 指令在命名空间http://genshi.edgewall.org/中定义。因此,这个命名空间需要在模板的根元素中声明。
<html xmlns = "http://www.w3.org/1999/xhtml" xmlns:py = "http://genshi.edgewall.org/" lang = "en"> ... </html>
上面的声明意味着默认命名空间设置为 XHTML,并且 Genshi 指令具有“py”前缀。
原氏指令
Genshi 中定义了许多指令。以下列表列举了 Genshi 指令 -
- py:如果
- py:选择
- py:对于
- py:定义
- py:匹配
- py:与
- py:替换
- py:内容
- py:属性
- py:条带
条件部分
Genshi 提供了两个用于条件渲染内容的指令 - py:if 和 py:choose。
py:如果
仅当if 子句中的表达式计算结果为 true 时,才会呈现该指令元素的内容。假设模板上下文中的数据是{'foo':True, 'bar':'Hello'},以下指令 -
<div> <b py:if = "foo">${bar}</b> </div>
将导致
Hello
但是,如果'foo' 设置为 False ,则不会呈现此输出。
该指令也可以用作元素。在这种情况下<py:if>必须由相应的</py:if>关闭
<div> <py:if test = "foo"> <b>${bar}</b> </py:if> </div>
py:选择
通过将py:choose与py:when和py:otherwise指令结合使用,可以实现高级条件处理。这个特性类似于C/C++中的switch-case构造。
使用py:choose指令中的不同值来检查表达式:何时将呈现替代项和相应的内容。可以以py:otherwise指令的形式提供默认替代方案。
<div py:choose = "foo”> <span py:when = "0">0</span> <span py:when = "1">1</span> <span py:otherwise = "">2</span> </div>
以下示例说明了py:choose和py:when指令的使用。HTML 表单将数据发布到 /marks URL。marks ()函数将标记和结果以字典对象的形式重定向到total.html模板。结果通过/失败的条件显示是通过使用py:choose和py:when指令实现的。
输入标记的 HTML 脚本 ( marks.html ) 如下 -
<html> <body> <form action = "http://localhost:8080/marks" method = "post"> <p>Marks in Physics:</p> <p><input type = "text" name = "phy" /></p> <p>Marks in Maths:</p> <p><input type = "text" name = "maths" /></p> <p><input type = "submit" value = "submit" /></p> </form> </body> </html>
root.py的完整代码如下。marks ()控制器将标记和结果发送到total.html模板 -
from hello.lib.base import BaseController from tg import expose, request class RootController(BaseController): @expose("hello.templates.marks") def marksform(self): return {} @expose("hello.templates.total") def marks(self, **kw): phy = kw['phy'] maths = kw['maths'] ttl = int(phy)+int(maths) avg = ttl/2 if avg ≥ 50: mydata = {'phy':phy, 'maths':maths, 'total':ttl, 'result':2} else: mydata = {'phy':phy, 'maths':maths, 'total':ttl,'result':1} return mydata
templates 文件夹中的total.html接收字典数据并有条件地在html 输出中解析它,如下所示 -
<html xmlns = "http://www.w3.org/1999/xhtml" xmlns:py = "http://genshi.edgewall.org/" lang = "en"> <head> <title>TurboGears Templating Example</title> </head> <body> <h2>Hello, Welcome to TurboGears!.</h2> <h3>Marks in Physics: ${phy}.</h3> <h3>Marks in Maths: ${maths}.</h3> <h3>Total Marks: ${total}</h3> <div py:choose = "result"> <span py:when = "1"><h2>Result: Fail</h2></span> <span py:when = "2"><h2>Result: Pass</h2></span> </div> </body> </html>
启动服务器(如果尚未运行)
Gearbox server –reload –debug
在浏览器中输入http://localhost::8080/marksform -
Total.html将呈现以下输出-
py:对于
py:for 指令中的元素对于可迭代对象(通常是 Python List 对象)中的每个项目重复。如果items = [1,2,3]存在于模板上下文中,则可以通过以下 py:for 指令对其进行迭代 -
<ul> <li py:for = "item in items">${item}</li> </ul>
将呈现以下输出 -
1 2 3
以下示例显示使用 py:for 指令在 Total.html 模板中呈现的 HTML 表单数据,也可以按如下方式使用 -
<py:for each = "item in items"> <li>${item}</li> </py:for>
HTML 表单脚本
<html> <body> <form action = "http://localhost:8080/loop" method="post"> <p>Marks in Physics:</p> <p><input type = "text" name = "phy" /></p> <p>Marks in Chemistry:</p> <p><input type = "text" name = "che" /></p> <p>Marks in Maths:</p> <p><input type = "text" name = "maths" /></p> <p><input type = "submit" value = "submit" /></p> </form> </body> </html>
Loop ()控制器读取表单数据并将其以列表对象的形式发送到total.template。
from hello.lib.base import BaseController from tg import expose, request class RootController(BaseController): @expose("hello.templates.marks") def marksform(self): return {} @expose("hello.templates.temp") def loop(self, **kw): phy = kw['phy'] maths = kw['maths'] che = kw['che'] l1 = [] l1.append(phy) l1.append(che) l1.append(maths) return ({'subjects':['physics', 'Chemistry', 'Mathematics'], 'marks':l1})
temp.html 模板使用 py:for 循环以表格的形式呈现 dict 对象的内容。
<html xmlns = "http://www.w3.org/1999/xhtml" xmlns:py = "http://genshi.edgewall.org/" lang = "en"> <body> <b>Marks Statement</b> <table border = '1'> <thead> <py:for each = "key in subjects"><th>${key}</th></py:for> </thead> <tr> <py:for each = "key in marks"><td>${key}</td></py:for> </tr> </table> </body> </html>
启动服务器(如果尚未运行)
gearbox server –reload –debug
在浏览器中输入http://localhost::8080/marksform 。
提交上述表单后,浏览器中将显示以下输出。
py:定义
该指令用于创建宏。宏是模板代码的可重用片段。与 Python 函数非常相似,它有一个名称,并且可以选择包含参数。该宏的输出可以插入到模板中的任何位置。
py:def 指令遵循以下语法 -
<p py:def = "greeting(name)"> Hello, ${name}! </p>
该宏可以使用“name”参数的变量值来呈现。
${greeting('world')} ${greeting('everybody)}
该指令还可以与另一个版本的语法一起使用,如下所示 -
<py:def function = "greeting(name)"> <p>Hello, ${name}! </p> </py:def>
在下面的示例中,root.py中的Macro()控制器将具有两个键 name1 和 name2 的dict对象发送到 Macro.html 模板。
from hello.lib.base import BaseController from tg import expose, request class RootController(BaseController): @expose('hello.templates.macro') def macro(self): return {'name1':'TutorialPoint', 'name2':'TurboGears'}
此 Macro.html 模板包含名为greeting 的宏的定义。它用于为从控制器接收的数据生成问候消息。
<html xmlns = "http://www.w3.org/1999/xhtml" xmlns:py = "http://genshi.edgewall.org/" lang = "en"> <body> <h2>py:def example</h2> <div> <div py:def = "greeting(name)"> Hello, Welcome to ${name}! </div> <b> ${greeting(name1)} ${greeting(name2)} </b> </div> </body> </html>
使用变速箱启动服务器
gearbox serve –reload –debug
通过在浏览器中输入以下 URL 来调用 Macro() 控制器 -
http://localhost:8080/宏
以下输出将在浏览器中呈现 -
py:与
该指令允许您将表达式分配给局部变量。这些局部变量使内部的表达式更简洁、更高效。
假设在模板的上下文数据中给出 x = 50,以下将是 py:with 指令 -
<div> <span py:with = "y = 50; z = x+y">$x $y $z</span> </div>
它将产生以下输出 -
50 50 100
py:with 指令的替代版本也可用 -
<div> <py:with = "y = 50; z = x+y">$x $y $z</py:with> </div>
在下面的示例中,macro() 控制器返回一个带有 name、phy 和 maths 键的 dict 对象。
from hello.lib.base import BaseController from tg import expose, request class RootController(BaseController): @expose('hello.templates.macro') def macro(self): return {'name':'XYZ', 'phy':60, 'maths':70}
模板 Macro.html 使用 py:with 指令添加 phy 和 maths 键的值。
<html xmlns = "http://www.w3.org/1999/xhtml" xmlns:py = "http://genshi.edgewall.org/" lang = "en"> <body> <h2>py:with example</h2> <h3>Marks Statement for : ${name}!</h3> <b>Phy: $phy Maths: $maths <span py:with = "ttl = phy+maths">Total: $ttl</span> </b> </body> </html>
浏览器将呈现以下输出以响应 URL http://localhost:8080/macro
结构操作指令
py :attrs指令添加、修改或删除元素的属性。
<ul> <li py:attrs = "foo">Bar</li> </ul>
如果foo = {'class':'collapse'}存在于模板上下文中,上面的代码片段将呈现该上下文。
<ul> <li class = "collapse">Bar</li> </ul>
py :content指令用计算表达式的结果替换任何嵌套内容 -
<ul> <li py:content = "bar">Hello</li> </ul>
给定上下文数据中的 bar = 'Bye',这将产生
<ul> <li>Bye</li> </ul>
py :replace指令用表达式求值的结果替换元素本身 -
<div> <span py:replace = "bar">Hello</span> </div>
给定上下文数据中的 bar = 'Bye',它将产生
<div> Bye </div>