2009/12/22

Plone 4 Preview

Plone 4 於十二月進入 alpha 2 階段,這個版本搭配 Python 2.6 和 Zope 2.12 執行,因此要留意 Python 執行版本的細節。

$ python -V
Python 2.6.1

$ svn co http://svn.plone.org/svn/plone/buildouts/plone-coredev/branches/4.0 Plone-4-svn
A Plone-4-svn/tests.cfg
A Plone-4-svn/sources.cfg
A Plone-4-svn/pil.cfg
A Plone-4-svn/bootstrap.py
A Plone-4-svn/buildout.cfg
A Plone-4-svn/versions.cfg
... ...
A Plone-4-svn/experimental/i18n.cfg
U Plone-4-svn
Checked out revision 32308.

$ cd Plone-4-svn
$ python bootstrap.py
Downloading http://pypi.python.org/packages/source/d/distribute/distribute-0.6.8.tar.gz
... ...
Generated script '/home/marr/Download/Plone-4-svn/bin/buildout'.

$ bin/buildout
Getting distribution for 'mr.developer==1.7'.
Got mr.developer 1.7.

$ bin/buildout -c pil.cfg
mr.developer: Updating 'Plone' with subversion.
mr.developer: Updating 'Products.ATContentTypes' with subversion.
mr.developer: Updating 'Products.PasswordResetTool' with subversion.
mr.developer: Updating 'plone.app.upgrade' with subversion.
mr.developer: Updating 'plone.app.users' with subversion.
mr.developer: Updating 'plonetheme.sunburst' with subversion.
Develop: '/home/marr/Download/Plone-4-svn/src/plonetheme.sunburst'
Develop: '/home/marr/Download/Plone-4-svn/src/plone.app.upgrade'
Develop: '/home/marr/Download/Plone-4-svn/src/Products.PasswordResetTool'
Develop: '/home/marr/Download/Plone-4-svn/src/Products.ATContentTypes'
Develop: '/home/marr/Download/Plone-4-svn/src/plone.app.users'
Develop: '/home/marr/Download/Plone-4-svn/src/Plone'
Uninstalling alltests.
Uninstalling test.
Uninstalling instance.
Uninstalling zopepy.
Uninstalling _mr.developer.
Installing _mr.developer.
Generated script '/home/marr/Download/Plone-4-svn/bin/develop'.
Installing zopepy.
Getting distribution for 'PIL==1.1.6'.

Plone 4 有了新的 Plone Site 新增按鈕,透過 http://localhost:8080/@@plone-addsite 之類的網址來呼叫建立功能,預設的網站畫面也不同於 Plone 3.x 版本。





2009/12/14

FancyZoomView

collective.fancyzoomviewjQuery 為基礎,提供 Plone 放大顯示圖片的功能。

以 News Item 為例,它會去修改 page template 內容,先加上一段:

<metal:javascript fill-slot="javascript_head_slot">
<script type="text/javascript"
tal:attributes="src
string:${context/++resource++collective.fancyzoomview.javascript/fancyzoom.js};">
</script>
<script type="text/javascript" charset="utf-8">
jq(document).ready(function() {
jq('div.newsImageContainer a').fancyZoom({closeOnClick: true})
});
</script>
</metal:javascript>

把 tal:attributes="href string:$here_url/image/image_view_fullscreen" 改成 tal:attributes="href string:#news_item_image;"

再加上

<div id="" tal:attributes="id string:news_item_image">
<img tal:replace="structure python: here.tag(scale='large', css_class='newsImage')" src="" alt="" />
</div>

2009/12/09

Adding Portal Actions

Plone 的 content type 預設會顯示 Send this 和 Print this 的 document action 項目,如果想要新增一個 Google this 項目,該怎樣做呢?



在 ZMI 裡 portal_actions/document_actions 新增 CMF Action 項目,先要填寫識別碼。



以 google 為例,再點選進入填寫更多細節,範例如下:

Title: Google this
I18n Domain: plone
URL (Expression): string:javascript:(function(){open('http://www.google.com.tw/search?q=' +encodeURIComponent(document.title)+'&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a','google','toolbar=no,width= 700,height=250')})()
Permissions: View
Visible?: true



按 Save Changes 鈕後就會直接生效。

有些細節值得留意。即使沒做翻譯的動作,像是 I18n Domain 最好要填,預設是 plone。在 URL (Expresion) 欄位裡常用的變數有:

$portal_url - 例 string:${portal_url}/news
$object_url - 例 string:${object_url}/addtoFavorites
$globals_view - 例 string:${globals_view/navigationRootUrl}

2009/11/26

Plone Maintenance Branch

Development process 的討論串裡,談到 Plone 3.x 有許多 package maintenance branch 可從 coredev buildout 的 source.cfg 內容來查詢,如果 package 維護 maintenance branch 的話,就可以在 branch 裡改好再 merge 回 trunk 裡。

2009/11/13

Collection By Example

特定主題的各式內容可能分屬系統裡的不同目錄,例如活動照片被統一放在照片區,心得文件要到部落格區裡找,顯然,單純利用目錄分類的方式,無法有效滿足上述的需求。

在 Plone 裡,更好的方式之一,是利用群集 (Collection) 來分類,它可以從不同位置的多個目錄裡,依據篩選條件來收集內容,可以想像它是一個能夠呈現搜尋結果的網頁。



跟目錄一樣,群集也有多種顯示方式可選擇,包括 Standard view 或 Tabular view 等,預設是 Collection 方式。



在 Edit 頁籤裡,可以看到 Limit Search Results 選項,勾選的話,就可以限定搜尋結果的顯示數量,例如每頁最多顯示前五筆內容。把 Numbers of Items 設為 0 的話,是指一次顯示所有搜尋結果。







每個群集都可以產生 RSS 供外界使用。



最後,或許有比「群集」來得更好的中譯,歡迎朋友提供給我。

2009/11/08

Content Type Migration

由於 Plone 2.5 和 Plone 3.x 的 package 管理方式不同,想要把 2.5 時代的 custom archetype-based content type 改成 3.x 新版格式,可參考 changing product name/structure 的討論,特別留意可能要處理 archetype migration 的動作,也就是改用新版 content type 的情形。
想看 Plone 核心系統如何處理這樣的問題,可以到 Products/CMFPlone/migrations 找看看程式碼,如果是用 archetype 額外寫的小型應用程式,很可能要參考 ATContentTypes 附的 migration 機制。在 Products/Archetypes/Extensions 和 Products/ATContentTypes/migration 可能有細部線索。
如果想再跟上 Plone 4.x 的發展方向,就要考量適合的時機,從 archetype 轉到 dexterity 的開發方式。

2009/11/07

TypeError: iteration over non-sequence

這是將 Data.fs 昇級至 Plone 3.3.1 後,同時使用 Plone 2.x 舊式模組時,遇到的問題,症狀是無法將目錄更名,而這個目錄內含 custom content type 的資料。

第一個線索來自 Plone Error Reference 的說明,表示要留意 log 裡 "Could not import class" 的訊息。不過,我沒在 log 裡看到這類的訊息。

第二個線索來自 Archetype Fields Supporting Multiple Selection 的範例,表示要留意 custom content type 裡的欄位屬性,使用 multiValued = 1 時,要配合 LinesField 的欄位。檢查後,看來也都正常。

第三個線索是 ZMI 裡 custom content type 的 Size 欄位空白,而且 log 裡有下列的訊息:
  Module Products.CMFPlone.CatalogTool, line 272, in getObjSize
Module Products.Archetypes.BaseObject, line 590, in get_size
Module Products.Archetypes.Field, line 1501, in get_size
Module Products.Archetypes.Field, line 1486, in get

綜合以上的線索,我懷疑是 custom content type 曾經改版,但資料早在改版前已鍵入,造成版本不一致。

之前 custom content type 也發生過 AttributeError: __getitem__ 的錯誤,此刻的結論,就是再仔細檢查 custom content type 的內容,而且優先清查 LinesField 欄位。

2009/11/05

Custom Plone Home Page

記錄幾個客製 Plone 首頁畫面的技巧。

以 blog style 的首頁為例,新增一個 collection 把 blog 搜尋出來,再於首頁指定顯示這個 collection 即可。想要同時顯示多個 collection 的話,方法之一是尋求擴充模組的支援,像 ContentWellPortlets 就是一個例子。試用 PortletPage 後,覺得是較合用的選項,它可以把 portlet 新增在上下左右共四個區位。

如果想要修改首頁的顯示方式,可以參考 Create a different look and feel for different sections of your web site 這篇文件,利用 sectional CSS 方式來完成。下面的例子,就是把首頁的 heading 和 byline 都取消顯示。

在 portal_skins/custom 裡新增一個 DTML Method 將 Id 設為 sections.css 後,使用下列範例程式碼:

/* <dtml-with base_properties> (do not remove this :) */
/* <dtml-call "REQUEST.set('portal_url', portal_url())"> (not this either :) */

.section-front-page
.documentFirstHeading {
display: none;
}
.documentByLine {
display: none;
}

/* </dtml-with> */

到 portal_css 裡新增一個 stylesheet 填寫 ID 為 sections.css 其他都使用預設值。必要的話,可以設定 Plone 在 debug mode 執行,並勾選 portal_css 的 Debug/development mode 讓修改結果馬上生效。

還有許多修改技巧,可以在 Plone 3 Theming 這本書裡看到。

另外,使用 Plone 3.3.1 的朋友,可能會發現 collection 設定 criteria 時的錯誤,請參考 Impossible to add a criteria in a collection in 3.3.1 的修訂方法,先處理掉這個問題。

2009/10/19

Content Type Workflow Configuration



workflow 是一種 state machine,在 Plone 系統的脈絡裡,就是指 content type 生命週期裡的可能狀態。Plone 預設提供完整的 (role-based) workflowcontent rule 功能,是開放源碼 CMS 裡少數具備這項特色的產品,藉由 workflow 和 content rule 的支援,我們可以針對 content type 或目錄各別指定工作流程或自動化程序。


進入 ZMI 的 portal_workflow 可以從 Contents 頁籤查看既有的工作流程項目,除了預設啟用的 simple_publication_workflow 之外,還有 one_state_workflow 和 intranet_workflow 等。


舉例來說,想讓新建的文件馬上對外公開,可採用 one_state_workflow 設定值,因為它只有 public 一種狀態。

在 Workflows 頁籤可看到預設 (Default) 的指定值,和 type 與 workflow 的指定列表。


舉例來說,想要把 News Item 設定成 one_state_workflow 工作流程,就把 (Default) 改為 one_state_workflow 按 Change 鈕,再按 Update security settings 確認更新的動作。

2009/10/14

Embed Gmap HTML Code in Plone

想在 Plone 預設的 kupu editor 裡嵌入 Gmap HTML 內容,先到 Site Setup 裡 HTML Filter 項目。

設定內容的下方 Custom tags 新增 iframe 並儲存。
從 Google Map 找到的地圖,左上方選項 Link 裡的 Paste HTML to embed in website 複製內容,嵌入到自己想要的內容位置。
另外像 flickr, youtube 的內容嵌入原理類似。

2009/10/07

Plone Navigation Tree Tips

Plone 的 portlet 包括 navigation (稱為導覽) 的項目,預設會指示正在閱讀的文件位置,如果想要控制位置顯示的細節,文件 How to hide an item from the navigation tree even it is the current item 介紹 Plone 2.5 環境的技巧,想在 Plone 3.x 環境完成類似的效果,方法很多種,文件 How to really exclude from navigation 裡有介紹範例。

2009/10/03

Plone Developer Manual

之前要讀 Plone 技術文件,會從 Plone Core Developer ReferenceArchetypes Developer 找起,現在多了一篇 Plone Developer Manual。這份新手冊的目標,就是要統整並取代舊有散落各處的文件
目前還是草稿階段,最早是由 Mikko Ohtamaa 帶頭發起,並讓社群協力維護
我最關心 Sessions and cookies 的章節,它應該可以處理 PlonePAS 整合 PHP 應用軟體的議題,而且還得繼續學習 HTTP 資料傳輸的底層原理。

2009/09/24

Changing Tabs in Plone

在 Plone Site 根目錄 (root folder) 所建立的項目,例如 (id = about, title = 認識協會) 目錄,它會自動以 tab 型式出現,就像下圖裡的 1。 http://www.contentmanagementsoftware.info/plone-book/navigation/plone-site.png
讀取各別文章時,會有 You are here: 的提示,如圖裡的 2。左方可以有 navigation portlet 導覽視框,如圖裡的 3。

我們也可以讓新增的項目,不要"自動"出現在 tab 位置,方法是從 Site Setup 點選 Navigation Setting 導覽設定,取消"自動產生"的設定值

完成上述的設定調整後,除了"首頁"之外,其他 tab 都不會自動出現。

接著,想再把"認識協會"加回 tab 位置,先進入 ZMI 到 portal_actions/portal_tabs 畫面,從右上方選 CMF Action 來新增

ID 欄位填 about。

http://lh4.ggpht.com/_BESgcgeL9eA/SsB-EugJnJI/AAAAAAAABJ4/DRt3vUUZauI/s800/cmf-action.png

再點選 about 進去填其他詳細資料,注意到 Permissions 欄位選擇 View,而且 Visual? 要勾選生效。

http://lh3.ggpht.com/_BESgcgeL9eA/SsB-E6br48I/AAAAAAAABJ8/YE0V5bccI9w/s800/portal_tabs-config.png

至此,我們在 portal_tabs 裡有兩個 CMF Action,分別是 index_html 和 about,還可以用 Up / Down 或 Top / Bottom 來控制順序。

http://lh5.ggpht.com/_BESgcgeL9eA/SsCB4hAu_jI/AAAAAAAABKA/xKQ8He2MfBc/s800/cmf-action-position.png

想要讓某個 tab 未登入前看不見,登入後才看得到,要在 Condition 欄位裡填 python: member,想要讓某個 tab 只有管理員才看得到,要在 Condition 欄位裡填 python:portal.portal_membership.getAuthenticatedMember().has_role('Manager')


以上說明參考自 http://plone.org/documentation/how-to/changing-tabs

2009/09/11

CMS Showdown for NPO

CMS Showdown for NPO 是個網站改造的觀摩賽,構想仿自「全能住宅改造王」,由 charlesc 開頭籌辦,招募 NPO 團體報名,訪談 NPO 的需求,最後由 Joomla, Drupal, Plone 組隊實作,並在 ICOS 2009 裡舉行。

其中的 Plone 隊伍來自日本 CMS Communications Inc. 成員,隊員介紹如下:


* 寺田學 (Manabu Terada)
o CMS Communications Inc. 總經理,過往十年工作領域在電子工程及系統工程,五年的 Zope/Plone 開發經驗,是日本 Zope/Plone 社群主要成員。現居千葉縣。
o Twitter: http://twitter.com/Terapyon
o Plone site show case (2009): http://www.osaka-u.ac.jp/ http://www.asean.or.jp/


* 永井孝 (Takashi Nagai)
o CMS Communications Inc. 首席工程師,開發 Zope/Plone 及 Google App Engine 應用程式,亦研究遠距學習系統。
o Website: http://ngi644.net/blog/


* 足立健誌 (Takeshi Adachi)
o Scient UX Inc. 設計師及網站顧問,大學畢業後到美國洛杉磯學習平面設計,2002年回到日本大阪任職網站設計工作,五年的網站設計經驗,專長是使用者操作經驗的改善。興趣是吉他、貓、電影。
o Blog: http://www.thinkcreative.jp/blog/
o Google Profile: http://www.google.com/profiles/takeshi.adachi


* 宮本加奈子 (Kanako Miyamoto)
o 自由工作者,專長是 (X)HTML/CSS 程式設計。興趣是吹奏薩克斯風。
o Website: http://balanced.jp/
o Twitter: http://twitter.com/ayaxx


* 渡邊あや (Aya Watanabe)
o 自由工作者,日本網站設計社群 WebSig24/7 主要成員,專長是視覺設計,HTML 及 FLASH 程式設計。
o Website: http://balanced.jp/
o Twitter: http://twitter.com/ayaxx

2009/08/28

Display Portlets Where You Want

在 Plone 裡 portlet 通常只顯示在網頁畫面的兩側,如果想要任意調整 portlet 的顯示位置,利用 ContentWellPortlets 模組是個方式。
測試這模組的最簡易方式,是先下載 Plone 最新版 Windows Installer,假設安裝在 C:\Plone 目錄,它會提供一個 Plone Controller 來管理系統的啟動和關閉。

可以先不急著啟動它,到 C:\Plone 目錄裡利用文字編輯器打開 buildout.cfg 設定檔,如果你完全不清楚文字編輯器的用途,那麼就用 WordPad 打開這個設定檔。

找到設定檔裡的 [instance] 區段,它會包含一個 egg = 的設定項目,在 = 等號之後,就是要指定 Products.ContentWellPortlets 的設定值,完成後的內容類似下列所示:
[instance]
...
# If you want Zope to know about any additional eggs, list them here.
# e.g. eggs = ${buildout:eggs} my.package
eggs =
${buildout:eggs}
Products.ContentWellPortlets

儲存上述設定檔案,再打開 CMD.exe 到 C:\Plone 目錄,執行 bin\buildout 指令。

順利讓 buildout.cfg 的設定值生效後,系統已自動完成 ContentWellPortlets 的第一步安裝。
再啟動 Plone 系統,到 Site Setup 裡的 Add-on Products 把 ContentWellPortlets 啟用。

ContentWellPortlets 生效作用後,從網站首頁畫面看得到 Add, edit or remove a portlet above the content 字樣,點選進入後,會出現 portlet 的設定畫面。

例如在 Column A 的 Add portlet... 裡新增一個 RSS Portlet,設定 Title 為 BBC News,填入 URL of RSS feed。

同樣地,也可以從 Add, edit or remove a portlet below the content 進入設定。

2009/08/14

Aceh and Taiwan

Aceh 亞齊是印尼北部地區,之前海嘯災難,台灣曾參與救援,部份單位選擇長期駐點,新竹的社區大學就是一例。台灣和亞齊建立的合作之一,是安排兩位學生到中研院實習,既然由我照料,學習 Python Plone 就成為學生的功課之一。這星期完成學習心得簡報,我也鼓勵他們回國後建立 Python Plone 社群。
華人的飲食文化有融入印尼當地,例如 mi 就是麵 daofu 就是豆腐,我還學會 mi golian 是炒麵 beibei 是鴨子。另外,當地多數人只有名沒有姓,通常貴族才有家族姓氏,也是相當特別。
剛好,客家電視「客家新聞雜誌」日前在亞齊採訪,專題報導在八月15日晚上九點播出,首播和重播時間如下:
客家電視--17頻道
(六) 21:00(首播)
(日) 16:00
(二) 15:00 / 01:00
公共電視--13頻道
(六) 09:00
(日) 04:00
另外,【重返亞齊DAILY系列報導】於八月24日至八月27日晚間七點在暗夜新聞播出,當天最夜新聞22:00、隔天過晝新聞12:30也會重播。
一邊是海嘯,一邊是風災,除了努力重建外,也期盼我們都能夠有更大的智慧來和大自然相處。

Recurring Event

近期有個在 Plone 裡實作農曆 recurring event 的需求,剛好 Plone 開發者正在討論這功能,先把相關資訊記下來
當然,農曆功能主要得靠"我們自己"了
其他 calendar 相關的小軟體列表如下,有空再了解它們:

2009/07/25

plonectl debug

以 standalone 方式安裝 Plone3 installer 後,可用 zinstance 目錄裡 bin/plonectl 程式來啟動 Zope/Plone,bin/plonectl 功能和之前的 bin/instance 一樣。例如執行 bin/plonectl fg 後,除了啟動 Zope/Plone 外,還可以在 shell 即時顯示系統訊息。使用 fg 或 start 參數啟動 Zope/Plone 後,它會鎖住 Data.fs 檔案,代表這種啟動方式只允許一個 client 存取 ZODB。想要多個 client 同時存取 ZODB,必須改用 zeo 安裝方式。

在 Data.fs 沒被鎖住的情況下,可以執行 bin/plonectl debug 手動存取 ZODB 內容。

$ bin/plonectl debug
instance: Starting debugger (the name "app" is bound to the top-level Zope object)
>>> dir()
['Zope2', '__builtins__', '__doc__', '__name__', 'app', 'configure']
>>> app.Plone['front-page'].getRawTitle()
'Welcome to Plone'
>>> app.Plone['front-page'].setTitle("New Title for Plone Site")
>>> import transaction
>>> transaction.commit()

>>> myitem = app.mysite['my-folder']['001']
>>> myitem.meta_type
'MyType'

以上是最簡單的範例。下列是其他範例,記得改過內容的話,都要使用 transaction.commit() 來確認寫進 ZODB。

>>> for k, v in app.Plone.Members.marr.objectItems():
...     print k, v.getRawText()
...
>>> for obj in app.Plone.Members.marr.objectValues():
...     obj.setText('<h2>My Test</h2>')
...

另外還可以把指令寫成 script 檔案,例如 updateTitle.py 的內容:

app.Plone['front-page'].setTitle("New Title Updated by Script")
import transaction
transaction.commit()

再用 bin/plonectl run updateTitle.py 執行結果。如果需要 admin 權限的話,要事先加上權限宣告:

import os
import transaction

from AccessControl.User import UnrestrictedUser
from AccessControl.SecurityManagement import newSecurityManager

admin = UnrestrictedUser('admin', '', ['Manager'], '')
newSecurityManager(None, admin)

app['mysite'].mytype['my-item'].setStartDate('1918/01/01')
transaction.commit()

2009/07/18

EMP: Collision of Styles

NGC 介紹了 Frank Gehry 著名的建築計畫,不規則曲線的建築結構是 Gehry 的特性,他並大量引用電腦系統來設計並交換資料。西班牙 Bilbao Guggenheim Museum 是他較早期的作品,九年後他在 Paul Allen 的委託下,在西雅圖完成了 Experience Music Project。因為 Paul Allen 和 Jimi Hendrix 都出身於西雅圖,促使這項搖滾樂體驗館的誕生,當然,還要靠 Frank Gehry 才能讓這項酷斃的建築物,充份包含並展現搖滾文化的多樣性。

2009/07/10

Deliverance Installation

Deliverance 是管理 web theme 的工具,常見的用法是,即時結合 site A 的應用程式和內容,和 site B 的佈景主題外觀,透過 WSGI 技巧將整合過的網頁呈現給使用者。有圖有真相,請參考 screencast 介紹。

QuickStart 頁面裡,提及 virtualenv, buildout 的不同安裝方法,我是用 Plone 3.2.2 UnifiedInstaller 的 buildout 安裝成功,在 buildout.cfg 裡加上 parts = deliverance 並新增:

[deliverance]
recipe = plone.recipe.deliverance
libxml2-url = ftp://xmlsoft.org/libxml2/libxml2-2.7.3.tar.gz
libxslt-url = ftp://xmlsoft.org/libxml2/libxslt-1.1.24.tar.gz

產生 deliverance 目錄和 bin/deliverance 執行檔後,再編輯 deliverance/deliverance-proxy.ini 內容,主要是修改 serializer 使用 deliverance.serializers:HTML4,並設定 host 和 wrap_href 後,就可以執行 bin/deliverance 看結果。想要精緻地完成整合工作,還需要設定 rules.xml 內容

2009/07/08

Quote of the Day

可能,最好的,已經在你的身邊,只是,你還沒有學會珍惜。人們總是盯著得不到的東西,而忽視了那些已經得到的東西。
社會上一夜暴富的新聞很多,這些消息,總會在我們的心裏面掀起很多漣漪,漣漪多了就變成驚濤駭浪,心裏的驚濤駭浪除了打翻承載你目標的小船,並不會使得你也一夜暴富。“只見賊吃肉,不見賊挨揍。”我們這些普通人既沒有當賊的勇氣,又缺乏當賊的狠辣絕決,雖然羡慕吃肉,卻更害怕挨揍,偶爾看到幾個沒挨揍的賊就按奈不住,或者心思活動,或者大感不公,真要叫去做賊,卻也不敢。
好吧,世道不夠好,可是,你有推翻世道的勇氣麼?如果沒有,你有更好的解決辦法麼?有很多時候,人需要一點耐心,一點信心。每個人總會輪到幾次不公平的事情,而通常,安心等待是最好的辦法。
人總是會遇到挫折的,人總是會有低潮的,人總是會有不被人理解的時候的,人總是有要低聲下氣的時候,這些時候恰恰是人生最關鍵的時候,因為大家都會碰到挫折,而大多數人過不了這個門檻,你能過,你就成功了。
逆境,是上帝幫你淘汰競爭者的地方。要知道,你不好受,別人也不好受,你堅持不下去了,別人也一樣,千萬不要告訴別人你堅持不住了,那只能讓別人獲得堅持的信心,讓競爭者看著你微笑的面孔,失去信心,退出比賽。勝利屬於那些有耐心的人。
其實選什麼行業真的不重要,關鍵是怎麼做。事情都是人做出來的,關鍵是人。
每天,每一刻我們都在做這樣那樣的決定,我們可以漫不經心,也可以多花些心思,成千上萬的小選擇累計起來,就決定了最終我們是個什麼樣的人。
你可以選擇把這輩子最大的困難放在最有體力最有精力的時候,也可以走一步看一步,等到了40歲再說,只是到了40多歲,那正是一輩子最脆弱的時候,上有老下有小,如果在那個時候碰上了職業危機,實在是一件很苦惱的事情。
人生最需要的不是規劃,而是在適當的時機掌握機會,採取行動。
與改變世界相比,改變自己更困難。
人生有三個階段,一個階段是為現實找一份工作,一個階段是為現實,但可以選擇一份自己願意投入的工作,一個階段是為理想去做一些事情。

2009/06/25

Eggs and Plone3

egg 是 Python 世界裡散佈模組軟體的包裝機制,在 egg 環境裡,會記錄軟體專案的相依資訊,還會提供 plugin 給其他模組。實際打包成壓縮檔的方式有許多種,最常見的方式,是使用 '.egg' 檔名的 ZIP 檔案。

Python 世界的 egg 當然不只用於 Zope 或 Plone 專案裡,但是 Zope 在 2008 年才廣泛使用 egg 機制,對 Zope 2 的開發者而言,可能仍是新的議題。傳統的 Zope 2 應用程式,以 Zope product 方式來開發和散佈,只要把程式專案放進 $INSTANCE_HOME/Products 目錄,Zope 就會在啟動時掃瞄這個目錄,並處理應用程式的安裝與註冊工作,相當容易管理。

但是,上述特定目錄裡的程式碼,搭配 Products.* 命名空間的黑魔法,只能被 Zope 認得,很難再應用於其他場合,另一方面,也造成命名空間的侷限,開發者不容易建立精簡而重用性高的模組。

新版的 Zope (Zope 3) 在設計哲學上,主動走進 Python 社群成為一份子,讓專案模組能夠盡量精簡,並致力於提高模組的重用性。只要把相依關係設定好,任何模組應該都能在各式環境裡執行,例如 zope.interface 模組被 Twisted 專案所採用,但 Twisted 和 Zope 兩個專案平常是各自獨立發展的。這樣的架構方式,也讓 Zope 3 的新模組,容易被 Zope 2 或 Plone 重複使用。

從 Plone 3 開始,開發者也努力將模組精簡,像 plone.memoize 與 plone.portlets 是高獨立性的模組,其他相依於 Plone 的模組,則使用 plone.app 命名空間,例如 plone.app.layout 或 plone.app.portlets 之類的名稱,而 plone.app.portlets 就以 plone.portlets 為基礎,再針對 Plone 專案設計專屬的程式碼。

2009/06/01

Package Releases

open source developer 通常只優先抓自己的癢,一個有規模的 project 會嘗試事先宣告未來新版的改進內容,並開放一段時間,收集合適的使用者需求清單。以 Plone 為例,如果你有改版需求想要優先列入,可以與原作者溝通。

Plone 在第2版與第3版之間,擴充模組的處理方式有些不同。首先,稱呼上有所不同,擴充模組在 Plone 2 稱為 Product,在 Plone 3 則開始改稱 Package。命名的方式,Plone 2 常見的範例類似 PloneSurvey 或 WebServerAuth 這樣,但 Plone 3 常見的範例類似 Products.Maps 或 plonetheme.stylized 或 collective.indexing 這樣。

散佈時的檔案格式,Plone 2 以 tar.gz 為主,Plone 3 則以 egg 為主。安裝的目錄位置,Plone 2 是在 Products 裡,Plone 3 egg 則使用 eggs 或 develop-eggs 之類的目錄,舊式的 package 也可以放在 products 或 productdistros 目錄裡,而開發中的 package 則位於 src 目錄裡。

2009/05/26

Moblin Linux Preview

Quote from "Moblin netbook Linux preview"
"[Moblin] is a Linux desktop that's built on top of a Fedora Linux framework; uses GNOME for its desktop and applications, and will rely on Novell/SUSE to get customized versions of the desktop pre-installed on the Taiwanese OEM (original equipment manufacturers) netbooks."

2009/05/21

NASA Science Case Study

kcunning wrote 3 blogs on how their team building the NASA Science website. Here is the Japanese version. And some of my favorite quotes from the blogs:
Well, when you use Google rather than your own native search, you know you have a problem.

Developers, of course, love CMS's, but the only way we could sell it was to show the customer what they would gain... and respect what they would lose.

One of the funny things about taking on a large project is you either have a group with no ideas at all, or way too many.

One measure of a Plone developer's skill is their ability to evaluate what others have done. -- Alexandar Limi

2009/05/20

ZODB or SQL ?

Plone 的潛在用戶在評估採用時,最大的猶豫之一,來自對 Zope Object Databse (ZODB) 的不熟悉,希望既有的 SQL Database 能夠繼續主導全局,如果初期評估 Plone 跟後期動手整合的人員是兩批不同人馬,這項疑慮與不安尤其明顯。終究,新的東西會帶來變動和風險,留在熟悉的範圍裡是多數人的自然反應。

文件 Zope/ZODB FAQ for IT Administrators 試圖提供說明和方法,讓上述的疑慮和不安能夠降到最低。

RDBMS 適合處理大量同質資料的場合,例如總帳系統使用關連式資料庫就很有效,但在表單格式變動大的情況下就受到限制。

ZODB 能讓開發者專注在資料模型的設計上,物件導向資料庫能在背景自動處理物件儲存的動作。在 class 的 method 改變時,並不會造成物件資料庫的困擾,當 attribute 修改時,等同於 relational schema 的修改,此時就要撰寫 migration 程式。

常見的需求之一,是把舊有的 SQL 資料交由 Plone 整合顯示,這並不難,利用 ZSQL Method 就能搞定最主要的工作。另外還可以試看看 RelStorage 能否處理未盡事宜。

ZODB 本身的執行效能,僅管不是最頂尖,應付一般場合卻已足夠。好吧,實驗數據看起來還不錯,但,很多人的實務經驗,還是覺得使用 ZODB 的 Plone 跑得很慢,該怎麼辦?

由於 Plone 以低階的企業級應用為場景,預設已納入群組權限、工作流程、版本控制等管理機制,多數的耗時運算,來自於安全權限的檢查,為了滿足 Plone 既有的胃口,最好先提供 1G 或 2G 的記憶體。

2009/05/18

Love Will Tear Us Apart

在一九九○年的中學日子裡,翻著水晶的新音樂百科全書,到唱片行查側標,就像是課後作業一樣。Joy Division 是課後作業裡,生澀晦暗的一篇,Ian Curtis 總是把人拉進一個不安的世界。水晶把團名譯成「喜悅分割」,搭著「莫名快感 (Unknown Pleasure)」,喜歡幻想的人剛好就有了想像空間。

2009/05/09

zh-tw PO for Plone

四月17日取得 Plone Collective 存取權後,今天第一次上傳更新內容,主要是把「產品(product)」改譯為「擴充模組」。期待也有其他朋友加入 PO 翻譯的行列,意者可聯絡我。
Plone 3 的 i18n + l10n 方式就跟一般 Python 應用程式的處理機制一樣,想用 subversion check out 的話,指令是 svn co https://svn.plone.org/svn/collective/PloneTranslations/trunk PloneTranslations 或是參考 Vincent Fretin 的說明。另外,加入貢獻行列的說明,或在 Plone-i18n list 偶有社群翻譯工作的討論,也值得參考。

2009/05/04

Ploneboard Migration

在 Plone 2.5 昇級到 Plone 3.1 過程中,同時需要將 Ploneboard 從 1.0 昇級到 2.0,在安裝啟用階段遇到下列錯誤訊息:

ERROR Zope.SiteErrorLog http://localhost:8080/Plone/
portal_quickinstaller/installProducts
... ...
KupuError: Resource type: linkable, invalid type: FileInnerContentProxy

解法之一是到 Plone Configuration 的 Kupu visual editor 項目,在 resource type 頁籤裡的 map resource types 點選 save 按鈕,不需要更改任何設定值。接著再到 Add-on products 裡啟用 Ploneboard 即可。
資料方面是先在 Plone 2.5 做 export 再從 Plone 3.1 做 import,目前看來還沒發現問題。

2009/04/21

BigramSplitter

World Plone Day 2009 台北場在四月22日,於國泰醫院本館第三會議室舉行。值得一提的是,日本朋友 堀田直孝 Naotaka Hotta 到場介紹 BigramSplitter 並尋求試用回報。我用剛裝好的 Plone 3.2.1 來測試,簡單新增一個 Page 並上傳 Word PDF 檔案各一,在 Linux 環境先把 wvware 與 xpdf 裝好,就可以自動對 Word PDF 進行索引。

2009/04/13

Plone3 Books

Plone 3.x 在 2007 年八月首次問世,如今 Plone3 的書籍也算是完整出版,由淺到深,它們分別是 A User's Guide to PlonePractical Plone 3: A Beginner's GuidePlone 3 ThemingProfessional Plone Development。像 Content Rulebuildout 的設定技巧,就分別在 Practical Plone 3 和 Professional Plone Development 裡詳細介紹。
雖然 Plone3 著重「更方便的開發環境」,本質上還是 Zope 2 的機制,但離令人期待的 Plone4 或 Zope 3 又近了一步。

2009/04/09

Plone 2.5 to 3.0 Migration

想要昇級 Plone 2.5.x 網站到 3.x 的話,Upgrading Plone 2.5 to 3.0Plone.org Migration Steps 是兩篇值得參考的資料。以往直接昇級 Data.fs 的經驗是,如果 portal_migration 能成功,大抵就搞定,但現在額外發現 plone_kss 沒成功加入 portal_skins 的 layer 設定值,而且 Plone 2.5 裡 portal_skins 沒用到的 layer 要事先刪除,不然昇級完的 Plone 3 網站首頁顯示會有問題。

2009/03/30

Flash-style Banner

在 Plone 上直接於表頭區擺 flash 檔,是個不小的系統負擔,比較輕量的方法是利用 KSS 或 jQuery,或是借力於 Carousel
http://fjelleiligheter.no/ 可看到範例。
至於 zope.conf 裡 TimeZone 的設定方法能否成功,我得看到「錯誤訊息」,才能判斷可能的下一步。

2009/03/20

Make Plone3 Forms the easy way

plone.app.z3cform 能讓 Plone3 應用 z3c.form 來建立表單。在 Plone2 初期開始引用 Archetypes 工具建立表單,此方案過於複雜,不適合建立獨立而簡單的表單場合。另一個 zope.formlib 工具,也有人覺得 adaptability 與 widget 不足。

在架構上,最底層是 z3c.form,而 plone.z3cform 是 z3c.form 的介面,最後再由 plone.app.z3cform 提供 widget 與 utility 給表單開發者。使用 plone.app.z3cform 所建立的表單,原則上就等同於利用 z3c.form 在 Zope 3 環境裡所建立的表單,開發過程也可直接參考 z3c.form 的文件

更多範例可參考 http://plone.org/documentation/how-to/easy-forms-with-plone3 和 http://kayeva.wordpress.com/2008/07/16/using-z3cform-for-our-forms-in-plone

也可以 svn co https://svn.plone.org/svn/collective/collective.dancing/trunk/collective/dancing 查看 Singing & Dancing 的程式碼範例。

2009/03/07

Catalog to Speed Up Plone

在 Plone 資料夾裡呼叫所有的內容項目,會讓系統效能大受影響,非必得已,應降低這類的動作。早期 Plone 的導引清單因為設計還不成熟,成為效能殺手的主因之一,但隨著 Plone 2.1 和 ExtendedPathIndex 的問世,情況已大幅改善。

查詢目錄內容項目清單的方法有好幾種,但 objectValues() 和 contentValues() 則是最耗資源的兩種,應優先考慮改用 catalog 工具,範例如下:
 catalog = getToolByName(self, 'portal_catalog')
results = catalog.searchResults(
path = {'query' : '/'.join(self.getPhysicalPath()),
'depth' : 1 },
sort_on = 'getObjPositionInParent',
)
更多資訊可參考 http://plone.org/documentation/tutorial/richdocument/folder-listings

2009/02/04

UnicodeEncodeError in Plone

記錄一個 Plone 除錯訊息,發生在會員帳號管理介面。

ERROR Zope.SiteErrorLog http://mysite.com:8080/MySite/prefs_users_overview
Traceback (innermost last):
Module ZPublisher.Publish, line 119, in publish
...
Module zope.tales.tales, line 696, in evaluate
- URL: file:/home/marr/Plone317/zinstance/parts/ \
plone/CMFPlone/skins/plone_templates/batch_macros.pt
- Line 43, Column 8
- Expression:
- Names:
...
'request': ,
'root': ,
'template': ,
'traverse_subpath': [],
'user': }
Module Products.PageTemplates.ZRPythonExpr, line 49, in __call__
- __traceback_info__: '%s?%s' % (url , mq( request.form, {batch.b_start_str:n.first} ))
Module PythonExpr, line 1, in
Module ZTUtils.Zope, line 181, in make_query

UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: \
ordinal not in range(128)

第一次遇到它,是在仿照 http://tomster.org/geek/plonezope/importPASfromCSV.py/view 批次建立會員帳號後發生,後來讀到 http://dev.plone.org/collective/changeset/67165 似乎開啟曙光,在 CMFPlone/patches 裡 unicodehacks.py 和 unicodeFallbackPatch.py 也有線索,希望能即早解決這問題。

2009/01/13

Plone Content Item Rating

想在 Plone Site 裡為 content item 評分,有很多種方法。我試了 EasyRating 還算符合自己的需求,雖然它仍處於 beta 階段。

安裝文件裡建議使用 buildout 方式,但我是把主程式解開放到 $INSTANCE/lib/python 目錄,並把 iqpp.plone.rating-configure.zcml 放到 $INSTANCE/etc/package-includes 目錄,這是方便開發者測試的安裝方式。

安裝後到 Site Setup 裡啟用。img1

在 Add-on Product Configuration 裡設定想要的選項。img2

在想要的目錄裡透過 Portlet Manager 新增 Rating Portlet 後,瀏覽 content item 時就會看到評分方框。img3

Rating Portlet 搭配 AJAX 效果。img4

2009/01/06

Plone Installer Updates

全面採用 buildout 機制,是 Plone 發展過程的一大分水嶺,宣告所有應用程式都該使用 egg 包裝方式,開發完成的 egg 應該放到 PyPI 昭告天下。

Plone 3.2 的改進目標之一是將 installer 變得更友善,主要調整項目包括,各平台均採用 buildout 機制,新的 bin/plonectl 命令稿,附加註解的 buildout.cfg 範本檔案,paster 和 ZopeSkel 由 buildout 來管理,預設安裝目錄改到 /usr/local/Plone。

這些變化從 Plone 3.1.4 開始出現,更多資訊可參考 http://plone.org/documentation/manual/plone-community-developer-documentation/tutorials/buildout