2012/02/24

Version Conflict While Running Buildout

安裝的模組如果使用 z3c.form,在 Plone 4.1 以下的環境,很容易遇到 版本衝突的訊息

While:
  Installing instance.
Error: There is a version conflict.
We already have: zope.schema 3.5.4
but z3c.form 2.6.1 requires 'zope.schema>=3.6.0'.

詳細的處理方式是,如果找得到 versions.cfg 檔案,就在裡面加上 z3c.form = 2.2.0 的設定,如果沒有 versions.cfg 檔案,就是寫在 buildout.cfg 檔案裡,再把之前被裝進系統的 z3c.form 刪除,例如 buildout-cache/eggs/z3c.form-2.6.1-py2.6.egg。在 z3c.form 2.3.0 用到 zope.schema 3.6.0,造成相容性的大調整。

2012/02/22

Embed Tile

以前在 Plone 要嵌入 Gmap 的步驟並不直覺,現在有機會變得簡單了。toutpt 正在開發的 collective.oembedtile 讓你直接編輯 Gmap 或 Youtube 的嵌入碼。

2012/02/15

Display Only For Logged In Users

除了讓未登入的訪客看得到會員清單之外,常見的需求,就是限制特定欄位,僅允許登入的使用者才看得到。下列是程式碼範例:

<tal:block define="isAnon context/@@plone_portal_state/anonymous">
<span tal:condition="python: not isAnon"
      tal:replace="context/content_to_show" />
</tal:block>

控制 navigation tab 的顯示,是另一個常見的需求,這要在 portal_actions/portal_tabs 裡設定 Condition (Expression),常見的例子是 python:(member is not None),控制登入的使用者才看得到 tab。

更多常見的權限定義,像是 'Manage portal' 或 'View',被稱為 CMF Core Permission,可以先到 Products/CMFCore/permissions.py 檔案裡找。

2012/02/04

Products.AutocompleteWidget Sample

Products.AutocompleWidget 有支援 Plone 4.x,範例程式碼並不多,因此特別記錄找到的:

測試結果,使用 multiValued=True 後,編輯介面才看得到變化。

"""Definition of the Wiki Doc content type
"""

from zope.interface import implements, directlyProvides

from Products.Archetypes import atapi
from Products.Archetypes.public import LinesField
from Products.Archetypes.public import DisplayList
from Products.ATContentTypes.content import base
from Products.ATContentTypes.content import schemata
from Products.AutocompleteWidget.AutocompleteWidget import AutocompleteWidget
from Products.CMFCore.utils import getToolByName


from tlc.kbase import kbaseMessageFactory as _
from tlc.kbase.interfaces import IWikiDoc
from tlc.kbase.config import PROJECTNAME

WikiDocSchema = schemata.ATContentTypeSchema.copy() + atapi.Schema((

          
     LinesField('tags',
                searchable=1,
                required=0,
                mutator='setTagSubject',
                accessor='getTagSubject',
                edit_accessor='getTagSubject',
                vocabulary='getSubjectVocab',
                widget=AutocompleteWidget(label='Tags'),
                enforceVocabulary=0,
     ),

))

# Set storage on fields copied from ATContentTypeSchema, making sure
# they work well with the python bridge properties.

WikiDocSchema['title'].storage = atapi.AnnotationStorage()
WikiDocSchema['description'].storage = atapi.AnnotationStorage()

schemata.finalizeATCTSchema(WikiDocSchema, moveDiscussion=False)

class WikiDoc(base.ATCTContent):
    """Description of the Example Type"""
    implements(IWikiDoc)

    meta_type = "Wiki Doc"
    schema = WikiDocSchema

    title = atapi.ATFieldProperty('title')
    description = atapi.ATFieldProperty('description')
    
    def setTagSubject(self, value):
        """Set tag widget contents to subject of object"""
        self.getField('subject').set(self, value)
 
    def getTagSubject(self):
        """Set tag widget contents to subject of object"""
        return self.Subject()
 
    def getSubjectVocab(self):
        """Get subject (keywords) vocabulary"""
        catalog = getToolByName(self, 'portal_catalog')
        return catalog.uniqueValuesFor('Subject')

atapi.registerType(WikiDoc, PROJECTNAME)