在前篇文章裡,提到安裝Plone系統的方法,並練習基本的內容管理操作,這是從把Plone當作產品的角度來說明。接著,將依序從前台、檔案系統、後台,深入管理介面,認識更多技術名詞和系統管理的細節,作為拆解和組合系統模組的準備。
Python以egg檔案作為軟體元件的管理單位,Plone則以「擴充模組」作為擴充功能時的管理單位,一個擴充模組可能包含一個或數個egg檔案。
本篇文章裡,將以地圖功能為範例,介紹擴充內容管理功能的方法,並且進一步認識buildout的操作細節。
前台管理擴充模組
先從Site Setup管理前台開始,這裡的Add-ons列出了「擴充模組」的清單,並分成「可用的擴充模組」(Available Add-ons)以及「啟用的擴充模組」(Activated Add-ons)兩類。
也就是說,剛安裝好的擴充模組,會被系統先放在可用模組的清單裡,由管理員勾選啟用後,才會真正生效。
|
▲擴充模組的清單畫面。 |
Add-on有時候被稱為Third Party Product,或直接稱為Product,原則上就是提供特定功能服務的一組軟體。
舉例來說,想要為Plone網站新增OpenID服務支援,只要勾選「OpenID Authentication Support」項目,點擊〔Activate〕按鈕即可。
若想要停用OpenID服務,同樣是勾選後點擊〔Deactivate〕按鈕,此功能相當直覺。
那麼,該去哪尋找更多的擴充模組呢?
擴充模組集散地
Plone官網的Downloads頁面,分門別類地整理了許多擴充模組,是專屬的集散地,欲找尋擴充模組時,應優先到這裡查詢。
|
▲Plone官網的下載頁面。 |
除了閱讀擴充模組的摘要說明之外,使用者通常最關心它的支援版本,例如是否能夠支援Plone 4版本。
|
▲擴充模組版本相容資訊。 |
如果在「http://plone.org/products」網頁內沒有找到想要的擴充模組,請再到「http://pypi.python.org/」中查詢,這裡被稱為Python Package Index,縮寫是PyPI,有時直接用Cheese Shop當暱稱,是Python軟體的集散地。
|
▲Python Package Index網站。 |
使用關鍵字在PyPI找各式軟體元件,它會依照分數(Score)排序,列出所有相關的元件。元件的網頁內容主要包括版本號碼、摘要資訊、下載網址、詮釋資料等等。
一般的Python軟體元件,如果單純只是一個egg檔案,通常是使用setuptools裡的easy_install工具來安裝。以軟體元件docutils為例,可以仿照下圖中的執行指令,將docutils安裝至系統裡。
|
▲使用easy_install安裝docutils。 |
安裝擴充模組
透過egg來安裝軟體元件,雖然很方便,但是setuptools預設只會找元件的最新版本,有時反而會造成困擾。因為管理一個專案時,可能不需要用到元件的最新版本;另一方面,安裝元件只是專案開發的環節之一,通常還需要進行軟體設定,結合自製的元件,反覆測試,最後才能選出相容性最高且最穩定的元件版本。這時候,如果搭配合適的專案管理工具,開發專案的負擔就有機會減輕。
buildout就是這樣的工具。只要管理buildout.cfg之類的設定檔,就可以自動下載egg檔案,安裝並設定想要的Plone系統,有效處理軟體相依或版本混亂的問題,也可以同時管理多種開發環境。
下列以Collective Geo為例子,示範安裝擴充模組的步驟。這個模組能新增地圖欄位,讓內容項目加入地理資訊。請到「http://plone.org/products/collective.geo」閱讀它的詳細描述,包括安裝說明。
buildout搭配的設定檔,以.cfg為副檔名,最重要的是buildout.cfg這個檔案,要修改它的內容,加入擴充模組Collective Geo的資訊。
|
▲buildout搭配的設定檔。 |
首先,可以用「eggs =」當關鍵字,搜尋eggs的參數設定,預設會看到Plone與PIL的設定值,前面有四個空白字元。
|
▲編輯eggs參數設定。 |
這是Python設定檔的標準格式。由於想要新增安裝Collective Geo,設定方式是在新的一行輸入四個空白,再把collective.geo.bundle加上去。
由於collective.geo在安裝過程中有許多軟體相依關係須要維護,其中相依的plone.app.z3cform,還要額外指定對應的軟體版本清單。
這類的對應清單,平常由Plone開發人員維護,稱為Known Good Versions或Known Good Sets,有時也簡稱為KGS,此網站(http://good-py.appspot.com/)是維護KGS的集散地。
指定KGS的方式,是用「extends =」作為關鍵字,搜尋extends的參數設定,把「http://good-py.appspot.com/release/plone.app.z3cform/0.5.3-1」網址加入。
|
▲編輯extends參數設定。 |
編輯buildout.cfg後完成存檔,執行「bin/buildout」讓設定值生效。
執行「bin/plonectl」啟動系統後,再到Site Setup裡的Add-ons啟用擴充模組,勾選「Plone Maps (collective.geo)」並按下〔Activate〕按鈕。它會自動啟用其他相依的模組項目。
|
▲啟用Plone Maps擴充模組。 |
設定擴充模組
以Collective Geo為例,真正開始使用之前,還要到Add-on Configuration設定軟體預設值,請點擊〔Collective Geo〕,進入它的設定畫面。
|
▲Add-on Configuration設定畫面。 |
|
▲Base Geo Settings設定畫面。 |
首先,要決定地圖的預設經緯度和放大的級數,預設的地圖是OpenStreetMap的畫面。
接著,必須決定哪些內容類型搭配這一項地圖功能,具備地圖功能的類型稱為「Georeferenceable Content Type」,把想要的項目從左邊方框移到右邊方框,點擊〔Apply〕按鈕完成設定。
|
▲「Advanced Geo Settings」設定畫面。 |
使用地圖功能
地圖功能生效後,原本〔View〕活頁標籤的右方,會出現新增的〔Coordinates〕活頁標籤。點選後可以看到Base Layer的地圖畫面,利用方向和放大縮小按鈕就可以決定可視區域的畫面。
接著,依照想要標示的形狀種類例如「點座標」、「線座標」、「面座標」等,從地圖右上方分別點選〔筆按鈕〕、〔線按鈕〕、〔面按鈕〕。
決定點座標,只需要在地圖上按一下。線和面座標是由數個點所構成,要在地圖上將最後一點按兩下,才能做確認。
此外,地圖下方會顯示選定的座標值,使用WKT(Well Known Text)格式來記錄。
|
▲地圖功能編輯畫面。 |
想要切換Base Layer的話,可以點擊地圖右上方的藍底〔+〕符號,預設是在OpenStreetMap和Google Maps之間進行初換。如果有其他「Overlay」選項的話,也可以進行勾選。
|
▲切換Base Layer和Overlay。 |
完成地圖編輯後,顯示內容項目即包含地圖畫面,且同樣可以執行地圖的顯示操作,包括切換Base Layer與Overlay等。
|
▲內容項目與地圖搭配呈現。 |
以上內容看起來似乎不錯,那麼,背後的運作原理是什麼呢?
內容型別框架
Plone 4.0預設使用Archetypes作為內容型別框架。什麼是內容型別呢?之前提過的Page、News Item等,稱為「內容項目」,它們就是「內容型別」的具體呈現。拿Python的物件體系來做比擬,可以想像內容型別是class,內容項目就是instance。
|
▲內容項目與內容型別的對應範例。 |
可以在檔案系統裡,找到Archetypes相對應的程式碼內容,請到「Plone/buildout-cache/eggs/Products.Archetypes-1.6.4-py2.6.egg」目錄,查看它的檔案細節。關於內容型別,最基本的技術細節在於Field、Widget和Schema。
所謂的Schema姑且可以譯為「基模」。它是一個Container物件,定義了項目物件的結構,特別是內容項目的屬性值,例如欄位、編輯方式、儲存方式、顯示方式等。
每個欄位的屬性值,是由Field Class來定義,同時,每個欄位又搭配一個Widget,它負責具體呈現Field的工作。
詳細的Field和Widget說明,可以參考「http://plone.org/documentation/manual/developer-manual/archetypes/fields」內容。
一個Schema還可以有數個Schemata,目的是將欄位進行分組,例如編輯內容項目時,分成Default、Categorization、Settings等編輯標籤。
|
▲Schema Field Widget的關係示意圖。 |
預設型別定義
Archetypes框架提供三個基本的Schema定義值:
● BaseSchema
● BaseFolderSchema
● BaseBTreeFolderSchema
根據這些Schema,也預設提供四個基本內容類別:
● BaseContent
● BaseFolder
● OrderedBaseFolder
● BaseBTreeFolder
Folder屬於Container物件,可以包含其他內容型別。另外,Ordered物件可以指定排序,但存取效能較差,只適於項目數量不多的目錄。
相反地,BTree物件在系統內部的存取效能較好,但不能指定排序。開發者可視需要選擇合適的預設型別,才是聰明的作法。
由於Archetypes是Plone的預設型別框架,預設的內容項目模組,稱為ATContentTypes,其中的AT就是Archetypes的縮寫。ATContentTypes的實作沿用了上述的基本內容類別,並提供開發者擴充內容型別的基礎。
範例程式碼
在此擷取「Plone/buildout-cache/eggs/Products.ATContentTypes-2.0.6-py2.6.egg/Products/ATContentTypes/content/newsitem.py」當作範例,並簡化程式碼內容片斷,藉此可以一窺Archetypes的實作方式,如下所示:
透過ATContentTypeSchema.copy(),這裡複製了基本Schema的定義值。像Title或Summary欄位就直接繼承沿用,不必從頭造輪子,只要再加上需要的擴充定義。範中的'text'和'image'分別是TextField和ImageField,它們搭配RichWidget和ImageWidget來呈現,比對下圖中的畫面,可以看到呈現效果。
|
▲RichWidget和ImageWidget呈現效果。 |
從後台管理介面觀察
Plone系統的後台稱為Zope Management Interface,簡稱為ZMI,透過「http://localhost:8080/manage」之類的網址,可以進入ZMI後台管理介面。
|
▲ZMI管理介面。 |
上述程式碼,除了存放在檔案系統外,它們的定義值也可以從ZMI觀察,甚至進行修改,修改的結果會記錄在ZODB裡。
進入ZMI的portal_types裡,可以看到預設內容型別的屬性定義值。
|
▲portal_types畫面。 |
|
▲News Item的屬性值。 |
以News Item為例,它的操作行為包括代表圖示、新增時呼叫的函式、顯示時呼叫的函式等,都能藉由網頁方式來觀察或修改。
結語
從Plone 4開始,另一個稱為Dexterity的框架正在積極發展,它結合新版CMF、Zope 3的技術與功能,希望有一天能正式取代Archetypes。而Dexterity具備下列幾項改良之處:
1. Dexterity具備更高的模組化程度,更容易整合SQL資料庫。
2. Archetypes使用accessor與mutator來處理設定值,Dexterity則使用attribute notation方式來處理,因此Archetypes的寫法類似context.getFirstName(),而Dexterity是context.first_name這樣的寫法。
3. Archetypes自有的field和widget要配合內容物件的脈絡來運作,並不容易被應用在獨立表單上,Dexterity則使用z3c.form函式庫,這是表單運作的標準工具。
4. Dexterity透過z3c.form來支援表單新增的功能,這代表它不需要用到portal_factory,執行效率能夠改善。
不過,Archetypes是一個成熟的內容型別框架,支援許多Widget類型,並且被廣為應用,一般的開發場合,使用Archetypes仍是最穩健的方案。預計在Plone 5問世的時候,Dexterity就會成為預設的內容型別框架。
(完整內容詳見http://www.openfoundry.org/en/foss-programs/8294--plone-2-)