Skip to content. | Skip to navigation

Personal tools

Navigation

You are here: Home / Tips / Zope Component Architecture

Zope Component Architecture

通常簡稱為 ZCA,是 Zope 3 的架構基礎,Plone 3 開始採用。

adapter 有兩種,一般的只需要讀取一個參數,另一種則以 tuple 讀取多個參數。

dieter@handshake.de on 2013/11/14: Adapters are characterized by 3 pieces of information (called the "adapter discriminant"): the interface it provides, the interface[s] it adapts and its name.

三步驟: 1) Define an Interface 2) Register Adapters 3) Request Adaption Adapter is 3 times faster than Helper Browser View

Global Adapters vs Local Adapters

Global Adapter 通常在啟動時完成註冊,Local Adapter (persistent) 能被所有 Zope Instance 存取。

adapt fake and real parent: contentratings

refactoring: Adapter Factory Products.EasyNewsletter

Component 可以透過 zope.component 來註冊,也可以透過設定檔 ZCML 語法來註冊。在 zope.component 4.0 後,可以針對 browser:view 或 browser:page 指定 Layer。

ZCML Directives

ZCML (Zope Configuration Markup Language) 是 XML 語法的設定格式,每個設定段落被稱為 Directive,常見的段落像是 <adapter /> <subscriber /> <utility /> <interface /> 等。

動態新增 Interface 的 Attribute 設定值

Adapter

zope.interface Dorator, example: plone.formwidget.recurrence implementsOnly vs implementer_only

-from zope.interface import implements
+from zope.interface import implementer

+@implementer(IEventAccessor)
 class EventAccessor(object):

-    implements(IEventAccessor)

Subscriber

會員資料更新時的 Subscriber 範例

Utility

提供 site-wide 工具功能,又分成 global 和 local 兩類,前者在 Zope start-up 階段註冊,後者在 add-on installer 階段註冊。

ZCML 註冊範例:

<utility
  provides="gomobile.convergence.interfaces.IConvergenceMediaFilter"
  factory=".filter.ConvergedMediaFilter" />

Python 程式範例:

def registerOnsitePaymentProcessor(procrssor_class):
    processor = processor_class()
    gsm = component.getGlobalSiteManager()
    gsm.registerUtility(processor, interfaces.IOnsitePaymentProcessor, processor.name)

Utility Class 又稱為 Factory,最簡化的形式是實作介面:

class ConvergedMediaFilter(object):
    """ Helper class to deal with media state of content objects.
    """
    zope.interface.implements(IConvergenceMediaFilter)
    def foobar(x):
        """ An exmaple method """
        return x+2

按照 addons/components/utilities.html 文件讀取 ICover 的 utilities,本身是個 generator,讀取內容的方式?

查詢 Adapter 或 View 的註冊狀況

利用 queryMultiAdapter 取代 getMultiAdapter 來避免 ComponentLookupError 錯誤。

利用 wildcard.fixpersistentutilities 來移除 Utility 通常處理 Plone4 昇級 Plone5 的 AttributeError .. has no attribute '__iro__' 錯誤。

實務範例 collective.searchandreplace 要求實作 ISearchReplaceable 的物件才能生效,雖然 ZCML 指定後能讓 Content Type 設定生效,但既有的物件要執行 object_provides 重新索引才行。