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)

1 comment:

marr said...

Vocabulary / Term / Token Translation http://plone.293351.n2.nabble.com/schema-Choice-i18n-patch-for-Plone-4-0-tp6419283p6434957.html