Zope 简介
无论您使用何种语言和操作系统,Web 开发通常意味着要使用 HTML 文件、图形文件、独立程序、混合 HTML/代码模板以及与关系数据库的连接。经验丰富的开发人员可以轻松地从 Perl 过渡到 PHP 再到 ASP,因为这些概念在一种语言到另一种语言之间转换时只有细微的变化。这种范例的趋同对开发人员来说很方便,但代价是 Web 开发社区的自满和懒惰。
幸运的是,开源的 Zope 应用程序服务器的出现,将我们从自满中唤醒,并让我们看到开发 Web 应用程序的新方法。Zope 由 Zope 公司(前身为 Digital Creations)编写和支持,它改变了您对 Web 开发的所有认知。您仍然可以创建动态生成的内容并使用关系数据库,但 Zope 的实现方式与市场上任何其他应用程序服务器都截然不同。
本月,我们将开始探索 Zope 作为一个 Web 开发平台。在此过程中,我希望大家能够清楚地认识到,虽然 Zope 与其他环境不同,但它的优雅和强大使其成为开源爱好者的有力竞争者。
理解 Zope 的部分困难在于它实际上是多种事物的结合体。简而言之,Zope 为您提供了创建 Web 应用程序所需的一切。安装 Zope 后,您将获得一个简单的 HTTP、FTP 和 Web-DAV 服务器(称为 ZServer)、一个对象数据库(称为 ZODB)以及一个用于创建服务器端 Web 应用程序的框架。
Zope 的大部分是用 Python 编写的,这意味着它可以轻松地跨平台移植。虽然用 Perl、Python 或 Java 编写的程序可以在 Linux 和 Windows 上同样轻松地运行是有道理的,但一个著名的开源系统能在 Windows 上运行仍然是不寻常的。
一个典型的网站混合了静态 HTML 文件、模板和图形文件。当 HTTP 服务器收到请求时,服务器会确定请求的文件类型(通过查看文件的扩展名、位置和 MIME 类型),执行文件内任何必要的代码,并返回 HTTP 响应。
在 Zope 中,任何内容都不会存储在文件系统中。相反,所有站点内容和程序都存储在 ZODB 对象数据库中。(数据库本身通常存储为一个大型磁盘文件,可以备份或复制到备份 Zope 服务器。)
要创建一个简单的 HTML 文件,您需要在 ZODB 中创建一个“文件”对象。要在网站上显示图像,您需要在 ZODB 中创建一个图像对象。要在调用特定 URL 时执行一段代码,您必须将代码存储在 ZODB 中。
幸运的是,在 ZODB 中存储和检索项目非常容易。Zope 为您处理了大部分工作,允许您在安装时设置高级参数。此外,Zope 的设计使其可以通过一个 Web 浏览器完全控制。您可以使用 Zope 的 Web 工具之一,这使得仅使用 Web 浏览器即可创建、编辑和管理网站成为可能。因此,您可以使用浏览器创建、修改或删除网站上的任何内容(HTML、图像或目录)。
如果您更喜欢在 Emacs 而不是 Web 文本区域中编辑文本(和代码),则 ZServer 支持 FTP,将 ZODB 中的对象显示为文件系统层次结构。如果您(以及您培训的非技术人员)以前使用 FTP 将文件传输到 Web 服务器和从 Web 服务器传输文件,则 ZServer 的 FTP 实现将使您可以几乎无缝地继续沿着这条道路前进。
尽管 Zope 很复杂,但安装起来却出奇地容易。您需要从 www.zope.org(请参阅“资源”)下载最新版本。在您选择要下载的版本后,切换到您的 Zope 目录(通常是 /usr/local/zope/,但任何目录都可以),然后解压缩 Zope 文件
mkdir /usr/local/zope cd /usr/local/zope tar zxvvf /downloads/Zope-2.4.3-linux2-x86.tgz
打开 Zope 归档文件会显示许多目录,包括
bin,Zope 启动和关闭脚本所在的位置。
doc,完整的 Zope 文档保存在这里。
lib,Python 和所有各种 Zope 应用程序(称为产品)都保存在这里。
ZServer,其中包含 ZServer 所需的类。
utilities,其中包含几个与 Zope 相关的实用程序。
在您第一次启动 Zope 之前,您必须使用安装脚本安装它。仅在您将 Zope 文件放置在其最终位置后才运行此脚本,因为 install 使用当前目录名称来设置几个全局配置值。
完成 Zope 的安装后,您可以通过运行主 Zope 目录中的 start 脚本来启动它。默认情况下,此脚本在端口 8080 上启动 Zope 的 HTTP 服务器(FTP 服务器在另一个端口上运行)。您可以使用命令行开关更改这些值;通过键入 start -help 可以获得完整列表。
虽然 Zope 主要用 Python 编写,但您的系统上不需要安装 Python。Zope 自带 Python 副本,它使用自己的 Python 副本,而不是操作系统上的任何 Python。这减少了版本问题和错误的可能性。截至撰写本文时,Zope 使用 Python 2.1(最新的稳定版本),但 Python 2.2 应该在不久的将来发布。看看 Zope 何时采用它将很有趣。
安装脚本不仅设置了初始 Zope 配置,还为系统的“admin”用户创建了一个难以猜测的密码。我们将在几分钟后需要此密码,因此请务必将其写下来。
现在我们已经启动了 Zope,我们如何使用它呢?嗯,第一步也是最重要的一步是启动我们的 Web 浏览器,并将其指向我们的计算机,给出 URL http://localhost:8080/。这将显示一些初始 Zope 信息,包括指向文档和网站的指针。
让我们离开这个介绍屏幕,转而访问 http://localhost:8080/manage 的主 Zope 管理界面。系统将提示您输入站点管理器的用户名和密码;使用 admin 用户和安装脚本在您首次安装 Zope 时打印出的密码。
输入正确的密码后,您的浏览器窗口将被分成两个垂直框架:左侧显示 Zope 服务器的层次结构,而右侧显示您当前正在查看的对象的详细信息。
很容易理解当您向 Apache 服务器请求文档 /foo/bar 时会发生什么。Apache 在其文档根目录下的 foo 目录中查找名为 bar 的文件。如果存在这样的文件,则 Apache 从磁盘读取它并在 HTTP 响应中返回其内容。如果该文件是 CGI 程序,则它执行该程序并在 HTTP 响应中返回其输出。如果该文件不存在,则 Apache 向用户的浏览器返回错误消息。
Zope 对 URL 的解释方式截然不同;URL /foo/bar 被解释为请求 Zope 在 foo 对象内部的 bar 对象上调用显示方法。如果 foo 或 bar 都不存在,则 Zope 将返回一条错误消息,指示在 ZODB 中找不到该对象。
如果我们总是需要担心创建对象和编写显示方法,那么 Zope 对程序员来说将是一个功能强大的玩具。对我们来说幸运的是,Zope 几乎可以让我们假装 ZODB 是一个分层文件系统,我们在其中放置 HTML 文件和图形。
例如,我们可以仅使用 Web 浏览器创建一个简单的 HTML 文件。在 Zope 的根文件夹内(您始终可以通过单击浏览器左侧框架的左上角返回到该文件夹),通过从右上角的“选择要添加的类型...”选择列表中选择 DTML 文档来创建新文档。(正如我们很快将看到的,DTML—文档模板标记语言—是 Zope 的 HTML 超集;Zope 几乎总是指 DTML 文档而不是 HTML 文档。)
您的 Web 浏览器现在应该显示一个简短的 HTML 表单,其中包含三个元素
id 文本字段。Zope 中的每个对象都有一个 ID,并且 ID 在文件夹内必须是唯一的。ID 类似于磁盘上的文件名,它们用于标识 URL 中的对象。在 URL /foo/bar 中,foo 是文件夹对象的 ID,而 bar 是该文件夹内对象的 ID。Zope 文档传统上没有后缀(例如,.html 和 .gif);因为系统知道每个 ID 关联的对象类型,所以这样的后缀是多余的。
标题文本字段。对象的 ID 出现在 URL 中,但对象的标题出现在所有内部 Zope 管理屏幕中。(对象的标题与 HTML <title> 标签无关,您仍然需要创建该标签。)
文件元素允许您使用 HTTP 上传从本地计算机上传文件。这意味着您可以在本地计算机上创建一个 DTML 文件,并在您准备好测试时将其上传到 Zope。
对于本示例的目的,我们将输入 ID testdoc 和标题“Test document”。虽然我们可以简单地将此文档添加到 ZODB,但这会使其为空。因此,我们将单击“添加并编辑”按钮,这将为我们提供一个文本区域,其中包含一些默认内容
<dtml-var standard_html_header> <h2><dtml-var title_or_id></h2> <p> This is the <dtml-var id> Document. </p> <dtml-var standard_html_footer>
您可以在此文本区域中随意编辑内容。完成后,单击屏幕底部的“保存更改”按钮。此按钮会将您带回编辑窗口,但会添加一个提醒,指示文档上次修改的时间。
我们的 DTML 文档看起来很像 HTML,除了它包含几个以 <dtml-var> 开头的标签。DTML 实际上是一种编程语言,可让您执行各种操作,但可能最容易(也是最好)将其视为一种非常强大的服务器端包含机制。正如本示例文档中所示,<dtml-var> 可让您将动态值插入到当前文档中。因此,<dtml-var standard_html_header> 插入 ID 为 standard_html_header 的对象的内容,而 <dtml-var id> 插入当前文档的 ID。您可以想象,<dtml-var title_or_id> 会显示标题或 ID,具体取决于是否已定义标题。
当 Zope 遇到表达式 <dtml-var standard_html_header> 时,它会在当前文件夹中查找 ID 为 standard_html_header 的对象。如果存在这样的对象,则 <dtml-var> 标记将被替换为对象的可查看内容。如果不存在这样的对象,则 Zope 会在其封闭文件夹中重复搜索。通过这种方式,Zope 会一直向上遍历整个层次结构,直到到达根文件夹。
这意味着自动插入的页眉和页脚不仅取决于我们的 <dtml-var> 标记,还取决于我们的 DTML 文档的位置。对象在对象层次结构中的位置影响其输出的概念在 Zope 世界中被称为获取 (acquisition),它既重要又有用。使用获取,您可以为每个文件夹设置不同的页眉和页脚。将文档从一个文件夹移动到另一个文件夹会更改 Zope 在查找页眉、页脚和其他对象时使用的搜索路径。因此,Zope 中对象的行为不仅取决于其定义,还取决于其在对象层次结构中的位置。因此,获取有时被解释为类似于生物学中的“先天与后天”的争论:对象的定义可以被视为“先天”,而其在对象层次结构中的位置可以被视为“后天”。
要查看文档的当前内容,请单击框架顶部的“查看”选项卡。您将看到用户希望看到的文档内容。要再次编辑文档,我发现最简单的方法是单击左上角的“根文件夹”链接,选择 testdoc 对象,然后再次使用文本区域编辑内容。
如果您在编辑 DTML 文档时犯了错误,您会很高兴知道 Zope 提供了无限撤消。单击 DTML 编辑屏幕右上角的“撤消”选项卡,然后选择您要返回的版本。无限撤消是我在 Zope 中最喜欢的功能之一,不仅因为它允许我撤消我的错误,还因为它对非程序员来说非常容易访问,并且它适用于系统上的任何类型的对象。
有许多 DTML 标签,每个标签都以 dtml- 开头。大多数 DTML 标签都带有一个或多个参数,每个参数都允许它以稍微不同的方式工作。例如,我们可以修改我们的测试文档以包含 <dtml-var expr> 的简单用法
<p><dtml-var expr="5+10"></p>
上面代码中 expr 的值是一个简单的 Python 表达式。Zope 计算表达式并将 dtml-var 标签替换为该计算的结果。我们也可以尝试比简单加法更有趣的东西。例如,我们可以通过在 expr 属性中命名 string 模块(自动导入到 Zope 中)中的 capitalize 方法
<p><dtml-var expr="_.string.capitalize('abc')"></p>请注意,我们不能调用 string.capitalize(),而必须调用 _.string.capitalize()。
虽然 DTML 允许您以这种方式使用 string 模块,但您可能永远不必直接调用它,因为许多有用的字符串函数都内置在 DTML 中。
DTML 的创建是为了让设计师和其他非程序员能够创建自己的动态内容,而不会受限于服务器端包含的糟糕语法和文档。DTML 对非程序员来说并不像我们某些人可能认为的那么容易学习,但它远比教他们一门成熟的编程语言容易得多。并且 Zope 在保存 DTML 文档时执行一些错误检查这一事实有助于避免与运行时语言相关的一些问题。
本月,我们对 Zope 的几个功能进行了旋风式巡览,包括通过 Web 编辑、管理界面、获取和简单的 DTML 文档。下个月,我们将研究 Zope 产品——如何下载和安装它们,以及如何编写我们自己的产品。
Reuven M. Lerner 拥有一家小型咨询公司,专门从事 Web 和互联网技术。他与妻子 Shira 和女儿 Atara Margalit 一起住在以色列的 Modi'in。您可以通过 reuven@lerner.co.il 或 ATF 主页 www.lerner.co.il/atf 与他联系。