2011/11/30

Workteam with oDesk

感謝 pofeng 的安排,有機會到 CloudTW 聚會分享 oDesk 的使用經驗。

簡報檔: http://www.slideshare.net/marr/workteam-with-odesk

討論過程中,有人回應「這是個讓 developer 找 developer 的服務」,沒錯,所以適合在技術人員聚會裡介紹 oDesk 服務,用它來累積專案管理的經驗,oDesk 試著促成一個良性循環,讓雇主和工程師都願意重視評價結果,彼此長期建立良好名聲。

自己的使用經驗,只以 employer 身份發包 Plone web development,值得找機會以 developer 角色登入,了解專業技能認證的流程。

2011/11/29

Joyent Cloud Computing

CloudTW 有段 SmartOS 的討論,於是查了相關資訊。Joyent 成立於 2004 年,業務內容與日俱進,目前已發展為 cloud computing software stack 提供者,據說公司接收了 OpenSolarisIllumos 的開發人員,併購 LayerBoom 的案例,也能跟台灣教改挫敗扯上關係,總之,這些都算是藉由 cloud computing 時代造英雄的例子。

網路上找到的既有資料,都顯示 Joyent 是家強調技術本位的公司,看了 Community Manager 也就是技術公關,心想,台灣何時會有這種角色?

2011/11/26

POSKeyError: 'No blob file'

執行 Plone migration 時,遇到 POSKeyError 錯誤,發現某個目錄裡的 File 內容出了問題,刪除這些 File 之後,就可以順利從 Plone 4.0.5 昇級到 4.1.2。

2011/11/23

Content Not Existing?

遇到 Plone instance 透過 http://mysite.com/news-events 之類的網址,出現「網頁並不存在」的訊息,透過 http://mysite.com/news-events/folder_contents 網址是可以看到內容,最後發現用 http://mysite.com/news-events/selectViewTemplate?templateId=folder_listing 之類的方式,就能解決問題。發生原因是之前選用了 lead image 擴充模組的顯示方式,當這個顯示方式不存在時,就會造成網頁無法正常顯示的問題。

2011/11/19

Content Type Extension

SchemaExtender 可以動態調整 Archetypes 型別定義值,下列是一個 extender.py 範例:
from zope.component import adapts
from zope.interface import implements

from archetypes.schemaextender.interfaces import ISchemaExtender
from archetypes.schemaextender.field import ExtensionField
from plone.app.blob.field import BlobField

from Products.Archetypes import atapi

from example.blobattype.interfaces import IExampleATType
from example.blobattype import blobattypeMessageFactory as _


class ExtensionBlobField(ExtensionField, BlobField):
    """ derivative of blobfield for extending schemas """


class ExampleATTypeExtender(object):
    adapts(IExampleATType)
    implements(ISchemaExtender)

    fields = [
        ExtensionBlobField('afile',
            widget=atapi.FileWidget(
                label=_(u"A file"),
                description=_(u"Some file"),
            ),
            required=True,
            validators=('isNonEmptyFile'),
        ),

        ExtensionBlobField('secondfile',
            widget=atapi.FileWidget(
                label=_(u"Some other file"),
                description=_(u"Some other file"),
            ),
            required=True,
            validators=('isNonEmptyFile'),
        ),
    ]

    def __init__(self, context):
        self.context = context

    def getFields(self):
        return self.fields

2011/11/17

ATBTreeFolder vs ATFolder

最近把一個 Plone 網站從 3.3.5 昇級到 4.0.7,在 ZMI 裡看得到 ATBTreeFolder 和 ATFolder 兩種目錄型別,ATBTreeFolder 就是所謂的 Large Folder,在 Plone 3 之前的時代,用它來儲存大量的內容項目,到 Plone 4 之後,目錄型別被統合了

ATBTreeFolder 在 ZMI 裡提供 Security 設定頁籤,可以指定 Local Roles,不過 Plone 4 裡的 ATFolder 並沒有這樣的設定介面,必須搭配 plone.app.workflow 編輯 sharing.xml 來擴充權限設定介面

2011/11/08

CMF Action Condition

使用 Products.Carousel 時,會新增一個 Carousel tab,如果想在特定的目錄裡才出現它,可以在 ZMI portal_actions/object/carousel 的 Condition (Expression) 欄位輸入下列表示式:

python: (context.id in ['carousel']) and plone_context_state.is_folderish()

2011/11/06

Localization with i18ndude

以 develop.cfg 為例,先在 parts 裡加一行 i18ndude,再加一整段的 [i18ndude] 內容:

parts =
    ...
    i18ndude

[i18ndude]
recipe = zc.recipe.egg
eggs = i18ndude

執行 bin/buildout -c develop.cfg 會在 bin 目錄裡建立 i18ndude 工具程式。

以 my.example 模組專案為例,處理 .po 檔案的步驟如下:

$ cd src/my.example/my/example
$ vi configure.zcml
<configure
  xmlns:i18n="http://namespaces.zope.org/i18n"

  <i18n:registerTranslations directory="locales" />

$ mkdir -p locales/zh_TW/LC_MESSAGES
$ i18ndude rebuild-pot --pot locales/my.example.pot --create my.example .
$ touch locales/zh_TW/LC_MESSAGES/my.example.po
$ i18ndude sync --pot locales/my.example.pot locales/zh_TW/LC_MESSAGES/my.example.po
$ vi locales/zh_TW/LC_MESSAGES/myexample.po # do the translation work
$ msgfmt -o locales/zh_TW/LC_MESSAGES/my.example.mo locales/zh_TW/LC_MESSAGES/my.example.po

如果有手動增加的 po 內容,通常是寫在 manual.pot 裡,再用下列指令併進 pot 檔案裡。

$ i18ndude rebuild-pot --pot locales/my.example.pot --create my.example --merge manual.pot .