2011/10/20

Creating Windows Buildout Project

試著在 Windows 建立 Plone 4.1.2 的 Buildout 專案環境,事先要安裝 Python 2.6.7、PyWin32PIL 1.1.6easy_installSubversionGit。再下載安裝 zopeskel:

C:\> easy_install zopeskel

接著,可以用 zopeskel 來建立 Buildout 專案,範例指令如下:

C:\> mkdir Plone
C:\> cd Plone
C:\Plone> zopeskel basic_buildout

basic_buildout: A basic buildout skeleton
This creates a basic skeleton for a buildout.
Enter project name: myproj

If at any point, you need additional help for a question, you can enter
'?' and press RETURN.

Expert Mode? (What question mode would you like? (easy/expert/all)?) ['easy']:

如果遇到下列訊息,可以予以略過不理會:

UserWarning:
You don't have the C version of NameMapper installed!
I'm disabling Cheetah's useStackFrames option as it is painfully slow
with the Python version of NameMapper.
You should get a copy of Cheetah with the compiled C version of NameMapper.
You don't have the C version of NameMapper installed!

剛建立的 myproj 專案目錄裡,只有 bootstrap.py 和 buildout.cfg 兩個檔案,執行 python bootstrap.py 之後,會建立必要的目錄架構,特別是 bin 目錄裡會建立 buildout 工具程式,額外的撇步是指定 zc.buildout 版本是 1.4.4,不然預設裝的 1.5.2 版本會造成衝突,範例訊息如下:

C:\Plone\myproj> python bootstrap.py -v 1.4.4
Downloading http://pypi.python.org/packages/2.6/s/setuptools/setup
tools-0.6c11-py2.6.egg
Creating directory 'C:\\Plone\\myproj\\bin'.
Creating directory 'C:\\Plone\\myproj\\parts'.
Creating directory 'C:\\Plone\\myproj\\eggs'.
Creating directory 'C:\\Plone\\myproj\\develop-eggs'.
Getting distribution for 'setuptools'.
Got setuptools 0.6c12dev-r88846.
Generated script 'C:\\Plone\\myproj\\bin\\buildout'.

預設的 buildout.cfg 檔案內容如下:

[buildout]
parts =
    templer

[templer]
recipe = zc.recipe.egg
eggs =
    PasteScript
    templer.core

不過,我並沒使用這個 buildout.cfg 內容,而是直接複製 Linux 環境上安裝的 *.cfg 檔案,修改 base.cfg 和 lxml_static.cfg 的 eggs-directory 和 download-cache 配合 Windows 環境的目錄,再執行 buildout:

C:\Plone\myproj> bin\buildout -c develop.cfg
mr.developer: Creating missing sources dir C:\Plone\myproj\src.
Getting distribution for 'zc.recipe.egg==1.2.2'.
Got zc.recipe.egg 1.2.2.
Getting distribution for 'plone.recipe.zope2instance==4.1.9'.
Got plone.recipe.zope2instance 4.1.9.
Getting distribution for 'Zope2==2.13.10'.
Installing Zope2 2.13.10
Caused installation of a distribution:
zope2 2.13.10
with a different project name.
Got zope2 2.13.10.
Getting distribution for 'mailinglogger==3.3.3'.
Got mailinglogger 3.3.3.
Getting distribution for 'nt-svcutils==2.13.0'.
Got nt-svcutils 2.13.0.
Getting distribution for 'Products.StandardCacheManagers==2.13.0'.
Installing Products.StandardCacheManagers 2.13.0
Caused installation of a distribution:
products.standardcachemanagers 2.13.0
with a different project name.
Got products.standardcachemanagers 2.13.0.
Getting distribution for 'Products.PythonScripts==2.13.0'.
...

安裝 Pillow 時,需要安裝 Visual Studio 2008 Express,據說 2008 之外的版本並不行:

error: Setup script exited with error: Unable to find vcvarsall.bat
An error occured when trying to install Pillow 1.7.2. Look above this message fo
r any errors that were output by easy_install.
While:
  Installing instance.
  Getting distribution for 'Pillow==1.7.2'.
Error: Couldn't install: Pillow 1.7.2

編譯 lxml 如果遇到錯誤,要補足需要的檔案,以 Plone 4.1.3 為例,要下載 lxml 2.3.2 的原始碼。如果沒成功的話,還可以試試直接安裝較低的 lxml 版本

2011/10/17

Search Events and News via Calendar Portlet

Plone 的月曆方框預設是搭配 Event 來顯示,如果某一天是在 Event 發生的期間,就可以在月曆上點選來顯示,它會先利用類似 search?review_state=published&start.query:record:list:date... 網址格式來搜尋,如果想要增加其他內容型別到月曆方框,例如新聞的話,就要到 ZMI 的 portal_calendar 新增型別,並為型別新增 start 和 end 屬性值。

2011/10/15

RelStorage Installation

RelStorage 是 ZODB 的後端儲存工具,能夠將 pickle 資料存到關聯式資料庫,也就是說,經由 RelStorage 和 ZODB 的合作,Plone 裡的內容可以直接轉存到 MySQL、PostgreSQL 之類的資料庫裡,讓資料庫的類型選擇和轉換更具彈性。

經過原作者 Shane Hathaway 不斷的改進,安裝 RelStorage 變得很簡單,以 Ubuntu 和 PostgreSQL 為搭配範例,先要建立適當的帳號和資料庫:

$ sudo su - postgres
$ createuser --pwprompt zodbuser
$ createdb -O zodbuser zodb

編輯 /etc/postgresql/8.4/main/pg_hba.conf 存取控制規則,範例如下:

local  zodb  zodbuser  md5

接著可以修改 develop.cfg 的 eggs 設定區段:

eggs +=
    psycopg2
    RelStorage

修改 base.cfg 的 instance 設定區段,其中 blob-dir 參數指定一個目錄名稱,就是用來儲存 ZODB 的 BLOB 檔案:

rel-storage =
    type postgresql
    dbname zodb
    host localhost
    user zodbuser
    password mypass
    blob-dir var/blobs

執行 buildout 生效並啟動系統後,可以查看到資料庫的表單內容:

public | blob_chunk        | table    | zodbuser
public | commit_lock       | table    | zodbuser
public | current_object    | table    | zodbuser
public | object_ref        | table    | zodbuser
public | object_refs_added | table    | zodbuser
public | object_state      | table    | zodbuser
public | pack_object       | table    | zodbuser
public | pack_state        | table    | zodbuser
public | pack_state_tid    | table    | zodbuser
public | transaction       | table    | zodbuser
public | zoid_seq          | sequence | zodbuser

object_state 表單用來記錄 Page、Folder 等的內容,它的欄位包括:

zoid, tid, prev_tid, md5, state_size, state
其中 state 欄位記錄的就是內容項目的資料值。

2011/10/14

EEA Faceted Navigation Installation

EEA Faceted Navigation 已經正式支援 Plone 4.x 版本,測試成功的安裝方式是,先到 zinstance/src 目錄下載程式碼:

$ cd ~/Plone/zinstance/src
$ svn co http://svn.plone.org/svn/collective/eea.facetednavigation/trunk eea.facetednavigation
$ svn co http://svn.plone.org/svn/collective/eea.jquery/trunk eea.jquery
$ svn co http://svn.plone.org/svn/collective/eea.faceted.vocabularies/trunk eea.faceted.vocabularies

編輯 develop.cfg 內容,下列是範例:

[sources]
    eea.facetednavigation = fs eea.facetednavigation
    eea.jquery = fs eea.jquery
    eea.faceted.vocabularies = fs eea.faceted.vocabularies

[buildout]
eggs +=
    eea.facetednavigation

zcml +=
    eea.facetednavigation-meta
    eea.facetednavigation-overrides
    eea.facetednavigation

執行 buildout 生效:

$ cd ~/Plone/zinstance
$ bin/buildout -c develop.cfg

啟用模組後,在目錄的 Action 下拉選單,可以看到 Enable faceted navigation 選項,生效後可以再到 Faceted settings 和 Faceted criteria 設定細項。

2011/10/11

RichDocument SimpleAttachment Title

RichDocument 是個 content type 模組,它跟 Page 功能很像,但編輯介面提供特定欄位來上傳圖檔和檔案,這些特定欄位又搭配 SimpleAttachment 模組,讓上傳檔案的工作變得更容易擴充維護,SimpleAttachment 也是 Ploneboard 的相依模組

以前 Plone 3.x 時代,就試用過 RichDocument 和 SimpleAttachment,當時覺得成熟度不足,現在新版支援 Plone 4.x 的 blob 功能,再次試用,仍然遇到無法處理附檔中文標題的問題。

不過,它的設計概念和實作方式,是學習開發技巧時的參考,下列是幾個程式碼片段和錯誤訊息的記錄:

BooleanField('displayImages',
    default=False,
    languageIndependent=0,
    widget=ImagesManagerWidget(
        label="Display images download box"
    ),
),

BooleanField('displayAttachments',
    default=True,
    languageIndependent=0,
    widget=AttachmentsManagerWidget(
        label="Display attachments download box"
    ),
),
<tal:main-macro metal:define-macro="main"
 tal:define="text context/getText;
             images python:context.getFolderContents(
                        contentFilter = {'portal_type' : ['ImageAttachment']});
             firstImage python:images and images[0] or None;
             is_editable context/@@plone_context_state/is_editable;">
<div metal:use-macro="python:context.widget('displayImages')"/>
<div metal:use-macro="python:context.widget('displayAttachments')"/>
ERROR Zope.SiteErrorLog 1317974487.770.594350019308
 http://localhost:8080/mysite/Members/marr/my-page/richdocument_view_float
Traceback (innermost last):
  Module ZPublisher.Publish, line 126, in publish
  Module ZPublisher.mapply, line 77, in mapply
  Module ZPublisher.Publish, line 46, in call_object
  Module Shared.DC.Scripts.Bindings, line 322, in __call__
  Module Shared.DC.Scripts.Bindings, line 359, in _bindAndExec
  Module Products.CMFCore.FSPageTemplate, line 240, in _exec
  Module Products.CMFCore.FSPageTemplate, line 180, in pt_render
  Module Products.PageTemplates.PageTemplate, line 79, in pt_render
  Module zope.pagetemplate.pagetemplate, line 113, in pt_render
  Module zope.tal.talinterpreter, line 271, in __call__
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 888, in do_useMacro
...
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 531, in do_optTag_tal
  Module zope.tal.talinterpreter, line 513, in no_tag
  Module zope.tal.talinterpreter, line 343, in interpret
  Module zope.tal.talinterpreter, line 742, in do_insertStructure_tal
  Module Products.PageTemplates.Expressions, line 219, in evaluateStructure
  Module Products.PageTemplates.Expressions, line 264, in _handleText
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 94:
 ordinal not in range(128)

2011/10/05

Link Integrity Checks

Plone Site Setup 裡的 Editing 設定介面,勾選 Enable link integrity checks 後,可以啟動連結檢查功能,也就是說,某個項目被刪除或搬移時,如果發現有其他項目連結到它,系統會提醒無法刪除或搬移,並在 var/log/instance.log 裡,記錄 TypeError: ('Could not adapt', None, <InterfaceCalss plone.uuid.interfaces.IUUID>) 的錯誤訊息。只要停用連結檢查功能,完成動作後再恢復即可。

另一種處理方式,是在 ZMI 裡,檢查項目的 Interfaces 內容,確認 IUUID 被選用,應該就可以在 ZMI 裡把它刪除。

UID (Unique identifier) 是系統唯一的識別碼,即使內容項目被改名或搬移,它的 UID 仍然維持一致。像 Archetypes、ReferenceField、Kupu 都有用到 UID 服務,不過,Dexterity 使用 integer id 來管理關連,並未使用 UID。

2011/10/04

PIL vs Pillow

安裝 Plone 4.x 的時候,通常會看到 Pillow 的身影,它是 PIL (Python Image Library) 的分支,因為 Plone 社群需要一份相容 setuptools 的版本,於是開始維護這個分支,考量點在於簡化安裝流程。