TurboGears(一)此刻,你可能已经看了“教程”或“关于 TurboGears”。就算没看也没关系。这份指南也是个很好的开始。 本指南介于教程和参考文档之间。就是说既不过多的纠缠于细节也不指望成为一份教程。 这里不介绍如何安装 TurboGears,具体的安装指令官方网站的“下载”上介绍的有。这里同样也不介绍 Python 的相关知识,了解它有很多其它的渠道。 1、tg-admin tg-admin 是 TurboGears 的一个命令行工具,它有几个子命令,它同它的子命令一起可以让你快速的创建一个新项目、交互式的以面向对象有方式维护你的数据库等等。 如果你在命令行上运行 tg-admin,会得到一个它的子命令的列表以及简单的功能介绍:
xxx@x[~]$ tg-admin
这里我们只是简单的使用“quickstart”开启一个项目:
tg-admin quickstart
它会提示你输入项目名称等,输入你喜欢的名字,回车就可以了:
Enter project name: gs Enter package name [gs]: Do you need Identity (usernames/passwords) in this project? [no] Selected and implied templates: TurboGears#tgbase tg base template TurboGears#turbogears web framework
运行完后,当前目录下会出现一个以你输入的项目名称命名的目录,cd 进去,会发现 TurboGears 已经为你自动生成了一些代码,使用 TurboGears 开发的过程其实就是对这些代码修修补补、加上你自己代码的过程了。 2、开启服务器 一旦运行完“quickstart”,你就可以发动 CherryPy 的内置服务器了:
xxx@x[pythonExc]$ cd gs/ xxx@x[gs]$ ls dev.cfg gs.egg-info sample-prod.cfg setup.pyc gs README.txt setup.py start-gs.py xxx@x[gs]$ python start-gs.py 2006-06-01 17:44:10,606 cherrypy.msg INFO CONFIG: Server parameters: ......
在浏览器中打开http://localhost:8080,你就会看到一个简单的欢迎页面。要停止服务器的话,可以按 Ctrl-C 组合键。 3、配置 “quickstart”会为你创建一些配置文件,这些配置文件以”.cfg“结尾。
xxx@x[gs]$ ls *.cfg dev.cfg sample-prod.cfg xxx@x[gs]$ ls gs/config/*.cfg gs/config/app.cfg gs/config/log.cfg xxx@x[gs]$
从它们的名字可以猜出: dev.cfg 是为开发过程准备的一套配置,sample-prod.cfg 则是正式发布你的程序时用的配置文件 prod.cfg 的一个样例。dev.cfg 和 prod.cfg 同时要用到的配置则应该写进 gs/config/app.cfg。gs/config/log.cfg 通常开发过程中才用到,但一些特殊的处理以及格式定义可以写在这儿。 启动服务器时,start-xxx.py 脚本会先看当前目录下有没有 setup.py 文件,如果有的话就使用 dev.cfg 中的配置,否则的话,使用 prod.cfg 中的配置。 你也可以从命令行指定使用哪个配置文件:
xxx@x[gs]$ python start-gs.py sample-prod.cfg
打开 http://localhost: 8080,会看到服务器正常工作了。(注:我现在还不能确信是不是这样从命令行指定配置文件,但上面的命令在我这里可以工作。究竟该怎么做,我们后来再求证。) 4、TurboGears 工作原理示意图 很多盒子和箭头!它展示了一个 TurboGears 应用程序的所有组成部分。大部分都是 TurboGears 自带的,你只需要关心浅紫色盒子表示的部分就行了。
你只要修改这三部分代码就可以了。这也就是 TurboGears 被称为 MVC 框架的由来。 除此之外,你还会看到一些其它颜色的盒子。其中,CherryPy 是一种非常 pythonic 的、面向对象 web 开发框架,我的这个网站就是基于它写的。作为 TurboGears 最主要的部件之一,它主要负责提供 web 服务,即完成 controller 的功能。SQLObject 定义 model,Kid 用来编写模板,MochiKit是一套 AJAX 库,和 Kid 一起完成 view 功能。
TurboGears(三)5、CherryPy发布 请参考这里,或 CherryPy 官方文档。 6、自动单元测试 TurboGears 使用 Nose 完成此项功能。 单元测试这个概念,此前我从未接触过,一时之间难以弄明白,所以暂时隔过去,不然的话对 TurboGears 的学习又会就此停顿。 以下是 Google 到的一些资料,留到后来仔细阅读。
7、参数有效性验证及类型转换 TurboGears 提供了一个简便的工具 FormEncode,来验证传入的方法参数是否有效以及将这些参数从字符串转换为其它合适的 Python 类型。这里是一个简单的例子:
import turbogears from turbogears import validators, expose, validate
传递给 turbogears.expose 的 validators 字典意思是说,使用 Int 校验器来验证参数值是否有效。如果无效,就会得到一个 tg_errors,否则的话,tg_errors 的值为 None,你就可以确认参数值是 Int 类型了。 如果验证失败,tg_errors 将会是一个字典类型的值,查看 tg_errors[ ‘value‘ ]的话,你会得到一个 ‘Invalid‘ 异常对象。Invalid 异常对象提供了一个用户友好的错误信息。 TurboGears 有一个非常强大和灵活的的错误处理机制,允许你传递错误给不同的方法,以便你的 controller 方法可以始终接收到良好的输入。 所有的验证器都被导入了 turbogears.validators 模块。你可以查阅这个模块或者 FormEncode 验证器模块来看一下都有哪些具体的验证器可用。 还有些比较高级的内容,需要的时候可以查阅 FormEncode 的官方网站。
TurboGears(四)8、如何选择 View 模板 单独用 CherryPy 的话,你可以返回一个字符串给浏览器。这很好,但更多时候你想返回的是一个完整的页面。在 TurboGears 中,你则可以将一个字典型的变量返回给 Kid 模板,用这些变量的值填充模板中相应的变量。 在使用 quickstart 创建的项目中,你的模板文件位于 packagename.templates 中。它们以 .kid 结尾,但具体指定时,你可以省略这个扩展名。所以如果你想使用一个叫 welcome 的模板,你可以这样指定:
template = ‘packagename.templates.welcome‘
在我的例子中,如果我打开 ‘gs/controllers.py‘,会看到这么几行:
class Root(controllers.RootController): @expose(template="gs.templates.welcome") def index( self, value = ‘0‘ ):
这可以看作一个更加具体的如何指定所要使用的模板文件的例子。 返回的字典中应该包括你模板中所有要访问的值。比如如果你返回 dict( newvalue = 5 ),那么模板中的 ${newvalue} 变量的值就会是 5。 某些时候,在处理某个请求时你可能会发现,你需要一个不同的模板,而不是此前在 @expose 中指定的那个。你可以为返回的字典指定一个 ‘tg_template‘ 键,然后以合适的模板名称作为它的值,例如:
dict( tg_template = ‘packagename.templates.lancelot‘ )
这样 TurboGears 就会将返回值填充到上述指定的 lancelot 模板文件中,而不是 expose 中指定的那个模板。 9、返回 XML 而不是 HTML Kid 首先就是一个 XML 模板语言。使用 HTML 转换器,它可以产生优良的 HTML 文件。同时,如果使用其它的转换器,你还可以用它生产 XHTML 或其它 XML 格式的文档。 expose 函数允许你指定格式(可是以“json”或 Kid 的某种转换器)和内容类型。假设你想产生 RSS 文件,你可以把你的 expose 设置成这样:
@expose( template = ‘project.templates.rss‘, format = ‘xml‘, content_type = ‘text/xml+rss‘ )
expose 函数的模式输出格式是 HTML,但通过上述方式,你可以很容易的得到所需要的格式。
TurboGears(六)11、设计友好 因为写的模板是标准的 XHTML,所以我们可以直接用浏览器打开 Kid 模板文件。这很重要而且很有用,可以保证你的模板在浏览器中看起来美观。 你可以从中观查你的样式表、JavaScript脚本、以及应该出现动态内容的部分,是不是同你设想的一样。 有时候,当你直接浏览模板文件或执行后的模板文件时,它们可能不能正确的链接到它们的样式表文件。要避免这个,你可以使用 href 标识要浏览的模板、使用 py:attrs 处理执行后的页面。例如:
<link rel=‘stylesheet‘ type=‘text/css‘ href=‘/path/to/file.css‘ py:attrs=‘href="/path/on/website"‘ />
这样再在浏览器中查看模板的话,浏览器只会去查找 href 属性,样式表就会正确的被载入了。 12、共用页眉和页脚 Kid 提供了几中方式来共用页眉和页脚,我们来集中看其中的一种。 Kid 有一个非常有用的命令 py:match,它可以用来创建一个匹配模式,然后在模板的其它位置引用它。 假设我们想将页眉页脚应用于这样一个模板:
<html xmlns:py="http:///kid/ns#" py:extends="‘master.kid‘"> <body> <h2>You‘re running TurboGears!</h2> </body> </html>
上述模板文件中,对获得页眉和页脚来说最重要的部分应该是 html 标签中的 py:extends 了。py:extends 可以从其它多个模块或模板文件中继承它们定义的 py:def 和 py:match。对于上面这个例子来说,py:extends 会把 master.kid 模板文件中定义的 py:def、py:match 导入到当前模板文件的名称空间中,然后这些定义就会直接在当前模板文件中有效,就像这些定义就在当前模板文件中一样。 master.kid 看起来可能会是这样:
<html xmlns:py="http:///kid/ns#"> <body py:match="item.tag==‘body‘"> <h1>会发生变化吗?</h1> </body> </html>
为了叙述方便,我们假设第一个例子那个文件保存为 test.kid,而这个例子当然是 master.kid。我们来看 master.kid 中 body 标签中的 py:match。它的意思是在文件中寻找接下来的 <body> 标签,如果找到的话,把它里面的内容替换为当前定义的内容。 现在,我们在 test.kid 继承了这个 py:match,那 test.kid 中的 body 部分会不会被 master.kid 中的 body 部分来代替呢?来验证一下:
xxx@x[~]$ kid test.kid <?xml version="1.0" encoding="utf-8"?> <html> <body> <h1>会发生变化吗?</h1> </body>
结果很明显,body 部分的内容被替换掉了。 但是,如果我还想保留 test.kid 中的部分该怎么办呢?可以对 master.kid 稍作修改:
<html xmlns:py="http:///kid/ns#"> <body py:match="item.tag==‘body‘"> <h1>会发生变化吗?</h1> <div py:replace=‘item[:]‘ /> </body> </html>
这时,再来看一下结果:
xxx@x[~]$ kid test.kid <?xml version="1.0" encoding="utf-8"?> <html> <body> <h1>会发生变化吗?</h1> <h2>You‘re running TurboGears!</h2> </body>
test.kid 中的内容被保留了。利用这个原理,我们就可以在 master.kid 中写共用的页眉和页脚了。但是
<div py:replace=‘item[:]‘ />
是什么意思呢?我们再来做个测试好了,先对 test.kid 稍加修改:
<html xmlns:py="http:///kid/ns#" py:extends="‘master.kid‘"> <body> <h2>You‘re running TurboGears!</h2> <h2>这次该显示了吧!</h2> </body> </html>
master.kid 也做一丁点儿的变动,把 item[:] 改为 item[1:],再来看一下结果:
xxx@x[~]$ kid test.kid <?xml version="1.0" encoding="utf-8"?> <html> <body> <h1>会发生变化吗?</h1> <h2>这次该显示了吧!</h2> </body>
item[:] 是什么意思,也就不言自明了吧。 TurboGears(五)10、Kid 模板语言简介 Kid 模板可以是任何形式的 XML 文档,只要在名称空间中告诉它如何处理这个模板就行了。在实际使用时,则通常是 XHTML 文档,经过处理转换为切实可用的 HTML 文档。 这是摘自 Kid 官方文档的一个例子,Kid 模板基本上就是这个样子:
<?python title = ‘A Kid Test Document‘ fruits = [ ‘apple‘, ‘orange‘, ‘kiwi‘, ‘M&M‘ ] from platform import system ?> <html xmlns:py=‘http:///kid/ns#‘> <head> <title py:content=‘title‘>This is replaced.</title> </head> <body> <p>These are some of my favorite fruits:</p> <ul> <li py:for=‘fruit in fruits‘> I like ${fruit}s </li> </ul> <p py:if=‘system() == ‘Linux‘> Good for you! </p> </body> </html>
使用 Kid 模板需要重点注意的是:
有关 Kid 的最美妙事是,你所知道的一切 Python 的用法基本上都可以用到这里。举个例子,py:for=‘fruit in fruits‘ 同 Python 中的 for fruit in fruits: 是一样的意思。 在真正使用 TurboGears 开发应用程序时,如下的代码
<?python title = ‘A Kid Test Document‘ fruits = [ ‘apple‘, ‘orange‘, ‘kiwi‘, ‘M&M‘ ] from platform import system ?>
并不会直接写在模板文件里,而是定义成一个字典。它其中的所有变量你都可以当成模板中的变量来用。 变量传入模板时,Kid 会自动对它们转义。例如,你基本上不用考虑变量值如果包含 < 会不会出现错误,Kid 会自动将它转换成 <。但如果你就是要传入一段 XHTML 代码,不想让它们被自动转义,你可以使用 XML() 函数。举个例子来说,假如有个变量 X,它的值为
<title>Title</title>
默认情况下,Kid 会将它转换为
<title>Title</title>
如果你希望转换后的结果仍旧为 HTML 代码的话,你需要这样使用 X 变量:
${XML( X )}
我们来测试一下,假如 test.kid 内容如下:
<?python title = ‘‘ ?> <html xmlns:py="http:///kid/ns#"> <head> ${title} </head> <body> ${XML(title)} </body> </html>
当然,真实的文件中不会这样写,我们这里只是为了测试。现在打开终端:
xxx@x[~]$ kid test.kid <?xml version="1.0" encoding="utf-8"?> <html> <head> <title>Title</title> </head> <body> <title>Title</title> </body>
结果跟我们上面所说的一样。关于 Kid 还有很多东西要学,我随后会单独作 Kid 的学习笔记。你也可以查看 Kid 语言指南来了解更多的东西。
|
|
来自: 昵称11338 > 《TurboGears》