2011/01/29

EEA Vocabulary Setup

了解 vocabulary 的運作原理後,可以參考 Products.EEAContentTypes 的設定範例,在 Products/EEAContentTypes/setup/vocabularies.py 檔案裡看得到變數設定值:
vocabs = {}
vocabs['themes'] = (
('default', 'Default'),
...
('various', 'Various other issues'),
('waste', 'Waste'),
('water', 'Water'),
)
在 Products/EEAContentTypes/setup/ConfigurationMethods.py 裡看得到設定方法:
def setupATVocabularies(self, portal):
""" Installs all AT-based Vocabularies """

from Products.ATVocabularyManager.config import TOOL_NAME \
as ATVOCABULARYTOOL
from vocabularies import vocabs

vkeys = vocabs.keys()
atvm = getToolByName(portal, ATVOCABULARYTOOL, None)
if atvm is None:
return

for vkey in vkeys:

if hasattr(atvm, vkey):
continue

print "adding vocabulary %s" % vkey

atvm.invokeFactory('SimpleVocabulary', vkey)
vocab = atvm[vkey]
for (ikey, value) in vocabs[vkey]:
vocab.invokeFactory('SimpleVocabularyTerm', ikey)
vocab[ikey].setTitle(value)
不過,ConfigurationMethods.py 裡用的 SetupWidget 是舊式方法,新版已改用 GenericSetup 方式安裝。另外,collective.realestatebroker 使用 unicode_vocabulary 來取代 SimpleVocabularycollective-docs 裡說明 vocabulary 的新式建立方式也和 Archetypes 不同,目前使用 dexterity 來搭配測試。

2011/01/21

Drop Down Menu

目前試過三種 Plone 的 dropdown menu 模組,最早用的是 webcouturier.dropdownmenu,最近再裝了 quintagroup.dropdownmenuProducts.qPloneDropDownMenu,初步看來 quintagroup.dropdownmenu 可以配合 Plone 4 環境,Products.qPloneDropDownMenu 則有兩個版本分支,分別配合 Plone 3 和 Plone 4 環境。
安裝 quintagroup.dropdownmenu 的方式之一,是到 src 目錄下載原始碼:
$ cd src
$ svn co \
http://svn.quintagroup.com/products/quintagroup.dropdownmenu/trunk \
quintagroup.dropdownmenu
再編輯 buildout.cfg 內容,在 eggs, zcml, devel 變數加上 quintagroup.dropdownmenu 設定值,最後執行 buildout 讓設定值生效,我用的是指定 develop.cfg 來當執行參數:
$ bin/buildout -c develop.cfg
過程遇到版本衝突的訊息:
While:
Installing instance.
Error: There is a version conflict.
We already have: zope.schema 3.5.4
but z3c.form 2.4.1 requires 'zope.schema>=3.6.0'.
再次編輯 buildout.cfg 裡的 versions 設定區段,加上 z3c.form = 2.2.0 後,重新執行上述指令就行。


安裝後的設定方式,是到 ZMI portal_actions 裡的 portal_tabs 新增 CMF Action 和 CMF Action Category,由於它用了 RAM Cache,想要馬上看到更改後的效果,從 http://localhost:8080/mysite/@@ramcache-controlpanel 之類的網址,清除 cache 記錄即可。

2011/01/16

Study on Vocabulary

Dynamic Vocabularies in Plone Archetypes 文件裡,介紹幾種常見的 vocabulary 範例。最簡單的設定方式,是在 config.py 檔案列出清單:
HOUR = DisplayList((
('1', '1'),
('2', '2'),
etc...
))
再於 content type 的定義檔案裡,指定 vocabulary 變數值:
StringField(
'hour',
vocabulary=HOUR,
widget=SelectionWidget(
label='Hour',
),
required=1,
),
這個例子的清單,還可以用程式碼來產生:
class Event(ATContent):
def getHours(self):
dl = DisplayList()
for x in range(1, 13):
dl.add(str(x))
dl.add(str(x))
return dl
這樣就可以改用 method 存取:
StringField(
'hour',
vocabulary="getHours",
widget=SelectionWidget(
label='Hour',
),
required=1,
),
進一步來看,想要動態存取目錄裡的物件,可以借助 Acquisition 的服務:
from Acquisition import aq_parent
程式碼範例如下:
def getLinks(self):
dl = DisplayList()
linklist = aq_parent(self).contentValues(
filter={'portal_type': 'Link'}
)
for link in linklist:
dl.add(link['id'], link['title'])

return dl
接著,還可以參考 eea.faceted.vocabularies 的範例:
eea/faceted/vocabularies
|-- README.txt
|-- __init__.py
|-- catalog.py
|-- configure.zcml
|-- faceted.py
|-- portal.py
|-- position.py
|-- section.py
|-- simple.py
|-- tests.py
|-- types.py
|-- utils.py
`-- version.txt
以 faceted.py 為例,裡面的 FacetedPortalTypesVocabulary 會回傳 portal_types 和 portal_facedted 裡定義的項目,而 portal_facedted 是由 eea.faceted.tool 提供,如果要調整項目的排序方式,可以查詢 items.sort(key=operator.itemgetter(1), cmp=compare) 程式碼片段。

測試過程遇到 ValueError: Supplied vocabulary values resulted in duplicate term tokens 錯誤訊息,狀況是混用 Products.ATVocabularyManager 和 vocabularies.zcml 兩種方式,把 vocabulary name 都設成一樣,結果在進入 facetednavigation 的 configlet 畫面,它要把所有 vocabulary 清單列出時,發生這樣的錯誤。

更底層的細節,則可參考 zope.schema.vocabulary 和 zope.app.schema.vocabulary 的內容:
SimpleVocabulary : implements(IVocabularyTokenized)
SimpleTerm : implements(ITokenizedTerm)
FacetedPortalTypesVocabulary : implements(IVocabularyFactory)