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/19

Programming Languages and Airlines

如果作業系統是航空公司,聽過這個笑話的話,也找得到程式語言的版本。提到程式語言,我最感興趣的是 Scripting 之間的差異,或是人們對 Forth、Haskell 這類非主流語言的評論。程式語言比較像江湖門派,有些武功是隱世不露的。前兩天,Forth 推廣年會在中研院人文館舉辦,讓我也想記錄這個程式語言世界裡的傳奇。

"C 讓你認為 C 是世界上最好的語言,Forth 則讓你認為自己是世界上最好的程式員。"

"有了Forth,中國人不需要原子彈。"

"在某些狂熱者的眼中,FORTH 不只是一種電腦語言,有時它更像是一種宗教,受到支持者的崇拜與信仰。在眾多的宗教中,FORTH 與禪的境界最接近。"

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)