Personal tools
You are here: Home Zope Zope宝典 Zope脚本进阶
Document Actions

Zope脚本进阶

by 潘俊勇 last modified 2005-12-14 00:27
英文原稿
Advanced Zope Scripting
来源
zope.slat.org
翻译
由 marr 先行完成部份內容中譯 (目前由 Hsieh Wei-dong 認領接續進行)
整理
潘俊勇 转换为简体

本章出现之重要译词单字

script 命令稿

scripting language 描述式语言

presentation method 物件方法

context single out 挑选

注意事项:

单数与复数

context 指的是

第八章 Zope 命令稿进阶功能

Zope 透过物件来处理你的介面,逻辑,和资料。截至目前为止,你已经学会在 Zope 里如何利用 DTML 来管理介面呈现,并使用 File 和 Image 两种物件来管理资料储存。本章要告诉你如何新增 Script 物件,透过你的浏览器来撰写 Python 和 Perl 的命令稿。

什么是逻辑? 而它和介面呈现有何不同呢? 逻辑提供了物件修改、讯息传送、条件判断和事件反应的功能服务,而介面呈现在于将资料与执行结果进行格式化与画面显示。原则上,我们会使用 DTML 来掌控介面,而使用 Python 和 Perl 的命令稿来掌控逻辑。

Zope 命令稿

Zope 环境下的 Script 物件,里头包含了一些以程式语言所撰写的程式片断。目前,Zope 提供 Python 基底的 Script 物件,以及 Perl 基底的 Script 物件,前者以 Python 语法来撰写,后者以 Perl 语法来撰写。Script 是 Zope 2.3 版本后所引进的新物件,而且是目前 Zope 环境下建议使用的程式逻辑处理方式。

本书行文至此,你已经大量运用 DTML Method 或 DTML Document 在 Zope 环境里建置简单的网站应用程式。DTML 可以让你完成简单的命令稿操作,例如字串处理,但大体来说,DTML Method 的用途,应该还是以介面呈现的服务为主。DTML Method 的相关解说,出现在第四章「Dynamic Content with DTML」与第七章「Advanced DTML」。

以下是 Zope 命令稿的总览:

Python 基底的命令稿

Python 是一个通用型的描述式程式语言,你可以使用 Python 来控制 Zope 的物件或执行其他工作。这些 Python Script 物件在 Zope 环境下提供了一套通用式的程式开发服务。

Perl 基底的命令稿

Perl 是一个功能强大的文字处理程式语言,你可以使用 Perl 来写作 Zope 程式物件,或是存取 Perl 函式库服务。这些 Perl Script 物件所提供的功能和 Python Script 相似,但对于那些只熟悉 Perl 而不认识 Python,或是想要存取 Perl 函式库服务的程式人员来说,这样的物件功能显得较有吸引力。

新增命令稿物件到 Zope 应用程式的方式,和其他物件的操作方法一样。

命令稿的呼叫方式

Zope 的命令稿可以经由网页,或是别的命令稿及物件来呼叫,几乎各种类型的命令稿都可以被其他类型的物件所呼叫,比方说,你可以由 DTML Method 来呼叫一个 Perl-based Script,或是由 Perl-based Script 呼叫内建的物件方法。事实上,命令稿可以呼叫别的命令稿,别的命令稿也可以再呼叫命令稿,如此反覆运用。正如第四章所提过的,你可以用另一个程式语言,重写一个命令稿功能,将其取代后而不会产生任何副作用。举例说,如果你正使用 Perl 来执行某项工作,但后来发现使用 Python 会更好,那么可以用一个相同物件编号的 Python-based Script 将它取代掉。

当你呼叫一个命令稿时,不同的呼叫方式,可能会带给命令稿不同的执行环境。命令稿的执行环境非常重要,举例来说,当你呼叫一个命令稿时,通常你会想要挑出一些物件,作为命令稿工作执行时的核心项目,你会希望命令稿在执行工作时,它所处的执行环境和特定的物件能够相互配合。简单地说,就是你在这物件上呼叫命令稿来执行。

经由网页来呼叫命令稿

你可以直接经由造访网址的方式来呼叫命令稿。你可以透过不同网址的指定方式,在不同的物件上呼叫同一个的命令稿,由于指定的网址并不同,所以命令稿执行时所处的环境也不同,命令稿会依照所处的环境来执行程式的内容。这样的运作方式功能强大,因为,不必实际在 document 或 folder 里编写程式码,你就能在这些物件里应用程式逻辑。

想要透过网页来呼叫命令稿,只要造访这物件的网址,后面跟随着命令稿的名称。如此一来,命令稿执行时的工作环境就会由这个物件提供。举例来说,假设你有一群物件及命令稿,其架构如同图 8-1 所示: Figure 8-1 http://www.zope.org/Members/michel/ZB/Figures/8-1.png

图 8-1 一群物件及命令稿

想要在 hippo 物件上呼叫 feed 命令稿,你可以造访 Zoo/LargeAnimals?/hippo/feed 这个网址,想要在 kangarooMouse 物件上呼叫 feed 命令稿,你可以造访 Zoo/SmallAnimals?/kangarooMouse/feed 这个网址。这些不同的网址方式,会分别让物件 hippokangarooMouse 成为命令稿 feed 的执行环境。

如同地图一般,Zope 透过网址 来寻找你想要呼叫的物件和命令稿。

Zope 将网址拆开,并和物件阶层树进行比对,由前向后,直到找到符合者,这个过程叫作 URL traversal。举例来说,当你给 Zope 一个 Zoo/LargeAnimals?/hippo/feed 网址,它会从根目录开始来寻找名称为 Zoo 的物件,然后它会移到 Zoo 目录里寻找名称为 LargeAnimals? 的物件,然后它会移到 LargeAnimals? 目录里寻找名称为 hippo 的物件,然后它会移到 hippo 物件里寻找名称为 feed 的物件。这个叫作 feed 的命令稿无法在物件 hippo 里找到,而是在 Zoo 目录里,透过一个称为 acquisition 的运作方式来找到。

acquisition 会做两件事,首先它会试着在目前的 物件容器 里来寻找这个物件,如果没有发现,它会沿着网址路径回溯到上一层,再次进行尝试。在这个例子中,Zope 首先在 hippo 物件里寻找 feed 物件,然后它再移到第一个容器 LargeAnimals?,然后是移到下一个容器 Zoo,最后终于找到 feed

现在 Zope 已经完成整个网址的比对,它便呼叫所找到的最后一个物件,也就是 feedfeed 命令稿会以找到的倒数第二个物件,也就是 hippo,当做工作环境来执行。这就是如何在 hippo 物件上呼叫 feed 命令稿的方法。

同样的,你也可以透过造访 Zoo/LargeAnimals?/hippo/wash 网址的方式,在 hippo 上呼叫 wash 物件方法,在这个例子里,Zope 从 LargeAnimals? 目录中取得 wash 物件方法。

我们还可以有更复杂的指定方式。假设你想要在 hippo 物件上呼叫 vaccinate 命令稿,你能够使用怎样的网址呢?如果你使用 Zoo/LargeAnimals?/hippo/vaccinate 网址,那么 Zope 无法找到 vaccinate 命令稿,因为它并未存在于 hippo 物件的任何容器里。

解决的方法,是在网址内加入命令稿的所在目录路径。如此一来,当 Zope 透过 acquisition 方式来寻找命令稿时,它会在回溯网址的过程中找到正确的命令稿。要在 hippo 上呼叫 vaccinate 的网址格式是 Zoo/Vet/LargeAnimals?/hippo/vaccinate。同理,如果你想要在 kargarooMouse 物件上呼叫 vaccinate 命令稿,你应该使用网址 Zoo/Vet/SmallAnimals?/kargarooMouse/vaccinate。

让我们跟随 Zope 的运作模式,将 Zoo/Vet/LargeAnimals?/hippo/vaccinate 这个网址的路径架构走一趟。Zope 从根目录开始来寻找名称为 Zoo 的物件,然后它会移到 Zoo 目录里来寻找名称为 Vet 的物件,然后它会移到 Vet 目录里来寻找名称为 LargeAnimals? 的物件。Vet 目录里并没有包含这个物件,但是可以在它的容器 Zoo 目录中取得 LargeAnimals? 目录,所以它移到 LargeAnimals? 目录里寻找名称为 hippo 的物件,然后它移到 hippo 物件上寻找名称为 vaccinate 的物件。由于 hippo 物件及它的容器都没有包含 vaccinate 物件,所以 Zope 沿着网址回溯,尝试找寻 vaccinate 物件。首先,它回到了 LargeAnimals? 目录,还是没有寻获 vaccinate,然后再回到 Vet 目录,发现 vaccinate 命令稿就在 Vet 目录里。由于 Zope 已经完成整个网址的比对,于是它以 hippo 物件为工作环境来执行 vaccinate 命令稿。

当 Zope 透过网址比对的方式来寻找一个子物件,它会先在目前的物件中寻找,如果没有发现子物件,它会到目前物件的容器里寻找,如果还是没有发现,它会沿着网址回溯并再次地搜寻。这个步骤会一直持续到发现这个物件,或是因为没有找到而产生错误才停止。

这是一个非常好用的机制,它允许你透过网址的格式组合,表达相当多样的意义。你提供给 Zope 寻找一个物件的路径格式,将影响它是如何透过 acquisition 来找寻这个物件的命令稿。

由其他物件来呼叫命令稿

你可以由其他的物件来呼叫命令稿。举例来说,我们可以经常看到透过 DTML Method 来呼叫命令稿。

如同在第七章 "Advanced DTML" 所学到的,你可以利用 DTML 的 call 标签来呼叫 Zope 命令稿。例如:

   <dtml-call updateInfo>

DTML 会呼叫这个 updateInfo 命令稿,而你不需要指明这个命令稿究竟是用 Perl、Python 或是其他任何语言所撰写(你一样可以用这种方式来呼叫其他 DTML 物件与 SQL Method)。

如果这个 updateInfo 命令稿需要配合参数,你有二种选择,一是选定一个名称,做为 DTML 名称空间变数连结之用 (参阅「变数连结」说明),如此一来,参数资讯会在此一名称空间当中寻找,另一则是在叙述式里指定参数值,就像这样:

   <dtml-call expr="updateInfo(color='brown', pattern='spotted')">

透过 Python 或 Perl 来呼叫命令稿,其运作方式与上述完全相同,差别只在于,当你透过 Python 或 Perl 来呼叫一个命令稿时,一定要指定命令稿的参数。举例来说,当你透过 Python 来呼叫 updateInfo 命令稿时,应该会像这样:

   context.updateInfo(color='brown', pattern='spotted')

你可以透过 Perl 以标准的 Perl 语法来呼叫命令稿,完成同样的工作:

   $self->updateInfo(color => 'brown', pattern => 'spotted');

每一种描述式语言使用不同的方式来呼叫命令稿,但是你不需要知道所呼叫的命令稿是用什么语言写成的。实际场合上,Zope 物件可以由几种不同语言的命令稿所实作出来。当你要呼叫命令稿时,不需要知道它是如何实作的,只需要传递适当的参数给它。

Zope 透过 acquisition 来寻找你所呼叫的命令稿,其运作方式与经由网页呼叫命令稿的情况相同。回到我们上一节喂食 hippo 的范例,让我们看看如何透过 Python 和 Perl 来给 hippo 接种疫苗。图 8-2 的内容是一个稍微修改过的物件架构图,里头包含了两个命令稿,即 vaccinateHippo.pyvaccinateHippo.pl

A collection of objects and scripts

图 8-2 一群物件和命令稿

假设 vaccinateHippo.py 是个 Python 命令稿,若是你透过 Python 来呼叫 hippo 物件上的 vaccinate 命令稿,应该会像这样:

   context.Vet.LarheAnimals<a class="new" href="http://members.czug.org/zope/zopebook/Zope_e8_84_9a_e6_9c_ac_e8_bf_9b_e9_98_b6/createform?page=LarheAnimals" title="create this page">?</a>.hippo.vaccinate()

换言之,你可以使用与网页呼叫时一样的路径搜寻模式,来找到所需物件,同理,在 Perl 里你可以这样呼叫:

   $self->Vet->LargeAnimals<a class="new" href="http://members.czug.org/zope/zopebook/Zope_e8_84_9a_e6_9c_ac_e8_bf_9b_e9_98_b6/createform?page=LargeAnimals" title="create this page">?</a>->hippo->vaccinate();

透过其他命令稿来叫用命令稿,与透过网页来呼叫命令稿的方式非常相似,其语法上稍有不同,但运用相同的 acquisition 规则。稍后在本章的内容里,你会看到更多关于 Python 和 Perl 命令稿如何运作的范例。

传递参数给命令稿

你可以传递参数给所有的命令稿。参数让命令稿获得更多有关工作执行的资讯。当你透过网页呼叫一个命令稿, Zope 会试着在网页要求的环境里寻找命令稿的参数,并且把它们传给命令稿。举例来说,你有一个命令稿搭配了两个参数 dolphinREQUEST,Zope 会在网页要求里寻找 dolphin 变数,并且将要求本身以 REQUEST 为参数名称传递给命令稿。就实务情况来看,这代表你可以很容易地透过命令稿来进行表单处理。例如下列是个表单:

   <form action="actionScript">

   Name <input type="text" name="name">
   Age <input type="text" name="age:int">
   <input type="submit">
   </form>

你可以轻松透过一个叫做 actionScript 的命令稿来处理


Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: