十月 15, 2009
» List all of installed packages (easy_install eggs)

List all of installed packages (easy_install eggs)
example::

>>>import pkg_resources
>>>pkg = pkg_resources.AvailableDistributions()
>>>for i in pkg:
>>>    for j in pkg[i]:
>>>        print j

see also::
Package Discovery and Resource Access using pkg_resources

二月 25, 2009
» Plone Hosting:One-Click Install scripts (Tests)

在先前一篇 Plone Hosting:One-Click Install with Buildout (Tests) 所展示的方法是利用 buildout 方式來自動建立多個 Plone Site,但這會產生 port 數量的問題。

因此這次的改寫,是將它改成在一個 Zope Instance 之下,自動建立許多個 Plone Site,並且處理好各別 Plone Site 的 Admin 權限問題。換句話說,每一個自動建立的 Plone Site 能有自己獨立的 Admin 權限,而這權限不會擴展到上層的 Zope ZMI 之中。

mkplone.py
Need Three arguments:<sitename><admin><password>
$ bin/instance run ./mkplone.py  Project1  Yenjinc  12345

#!/usr/bin/env python
import sys
import os

from AccessControl.SecurityManagement import \
newSecurityManager, noSecurityManager

from Products.CMFCore.utils import getToolByName
from zope.app.component.hooks import setSite
from Testing.makerequest import makerequest

import transaction

# site:admin:pwd
arguments = sys.argv[1:]
pname = arguments[0]
myname = arguments[1]
rpwd = arguments[2]

# ZMI Admin log in
app = makerequest(app)
acl_users = app.acl_users
admin_username='admin'
user = acl_users.getUser(admin_username)
user = user.__of__(acl_users)
newSecurityManager(None, user)

# Add New Plone-site
pid = pname
factory = app.manage_addProduct['CMFPlone']
factory.addPloneSite(pid, title='Portal')

# Add Manager
site_id = pid
portal = getattr(app,site_id)
setSite(portal)
mtool = getToolByName(portal, 'portal_membership')
regtool = getToolByName(portal, 'portal_registration')
regtool.addMember(myname, rpwd, ['Manager'])

# Log out and commit
transaction.commit()
noSecurityManager()
app._p_jar.sync()

print "Finished adding Plone site"

最後利用 Plone+Apache+mod_rewrite 的方式,僅針對各別目錄 rewrite 即可,就能完成一個初階的 Plone Hosting 構想。

完成這隻程式主要參考:

二月 23, 2009
» Plone Hosting:One-Click Install with Buildout (Tests)

在安裝好 Plone Unified Installer 之後,可以利用 paster 工具來建立 plone buildout 目錄,在這 buildout 目錄底下,除了視作為一個 Plone 開發環境之外,也可將這個 buildout 當作上線的 Plone-Site 使用。

Unified Installer 的安裝介紹可參考:Installing Plone 3 with the Unified Installer。下載完檔案後,打開 README.txt 了解如何安裝:

To install Plone 3.2.1 in a stand-alone (single Zope instance) configuration:
* cd to the installer directory and issue the following command:
>> sudo ./install.sh standalone

To install Plone 3.2.1 in a ZEO Cluster (ZEO server, 2 clients) configuration:
* cd to the installer directory and issue the following command:
>> sudo ./install.sh zeo

安裝完成後,即可使用 buildout 來建置 Plone 系統,事前可參考 Working with buildout 這份文件。更完整的教學可以參考 Managing projects with Buildout

以下簡略將安裝步驟整理:

安裝 unified-installer
$ sudo ./install.sh standalone

設定 PATH
$ export PATH="/opt/Plone-3.1/Python-2.4/bin:$PATH"
$ vi .profile; which python ; python -v

更新 ZopeSkel
$ sudo easy_install -U ZopeSkel
$ sudo paster create --list-templates

設定專案目錄
$ paster create -t plone3_buildout MyBuildout

設定起始環境
$ cd MyBuildout ; python bootstrap.py

下載與安裝
$ bin/buildout

啟動 Plone
$ cd ~/MyBuildout
$ bin/instance start | fg

修改與更新
$ bin/buildout -No

以上是利用 buildout 建立 Plone-Site 的範例。

接下來要展示 Plone One-Click Install with Buildout 的測試範例,用來模擬 Plone Hosting 可能的概況。使用者可透過一個互動介面來輸入 Project Name,接著系統將自動產生一個 Plone-Site 提供給這個 Project 使用。

使用 shell scripts 將 buildout 過程自動化,並額外執行 install.py 來修改 buildout.cfg 的內容,主要目的是產生 random password 以及 port number。最後再執行 siteAutoInstall.py 自動產生 Plone-Site。

Shell Scripts 長像這樣:

#!/bin/bash
read -p "Please Insert Project Name:" pname

paster create -t plone3_buildout --no-interactive $pname
cd $pname && python bootstrap.py
cp buildout.cfg buildout.cfg.ori
cp buildout.cfg buildout.cfg.tmp

python ../install.py
bin/buildout
bin/instance run ../siteAutoInstall.py $pname admin
bin/instance start

port=`cat port.txt`
pwd=`cat pwd.txt`
echo -e "已完成安裝!"
echo -e "Plone-Site: http://localhost:$port/$pname"
echo -e "Password: $pwd (登入後請立即更改密碼)"

install.py 用途是修改 buildout.cfg 的 admin pwd 跟 port,主要使用的 function 如 Python random passwordPython search-and-replace string in files,整個 scripts 會長得像這樣:

>>>from random import Random
>>>import string
>>>from glob import *
>>>import re
>>>
>>>PWD = ''.join( Random().sample(string.letters+string.digits, 12) )
>>>f=open('pwd.txt', 'w')
>>>f.write(PWD)
>>>f.close
>>>
>>>f=open('../port-num.txt', 'r')
>>>old_num=f.read()
>>>f.close()
>>>tmp_num=int(old_num)
>>>tmp_num2=tmp_num+1
>>>new_num=str(tmp_num2)
>>>f=open('../port-num.txt', 'w')
>>>f.write(new_num)
>>>f.close
>>>
>>>f=open('port.txt', 'w')
>>>f.write(new_num)
>>>f.close
>>>
>>>fileList = glob('buildout.cfg.ori')
>>>pattern = re.compile('admin:', re.IGNORECASE)
>>>replace = "admin:"+PWD
>>>cfg = open('buildout.cfg.tmp', 'wU')
>>>for filename in fileList:
>>>        for line in file(filename):
>>>                print >>cfg,pattern.sub(replace, line),
>>>cfg.close()
>>>
>>>fileList2 = glob('buildout.cfg.tmp')
>>>pattern2 = re.compile('8080', re.IGNORECASE)
>>>replace2 = new_num
>>>cfg2 = open('buildout.cfg', 'wU')
>>>for filename in fileList2:
>>>        for line in file(filename):
>>>                print >>cfg2,pattern2.sub(replace2, line),
>>>cfg2.close()

最後一個執行的 Scripts 是 siteAutoInstall.py,這個檔案用途是自動化建立一個 Plone-Site(with NuPlone Skin)。如果僅是純粹產生 Default Plone-Site 的話,可以執行:

>>>from sys import exit
>>>import transaction
>>>from AccessControl.SecurityManagement import \
>>>    newSecurityManager, noSecurityManager
>>>from Testing.makerequest import makerequest
>>>
>>>app = makerequest(app)
>>>admin_username='admin'
>>>
>>>oids = app.objectIds()
>>>pid = 'Plone'
>>>if pid in oids:
>>>    print "A Plone site already exists"
>>>    exit(1)
>>>
>>>acl_users = app.acl_users
>>>user = acl_users.getUser(admin_username)
>>>if user:
>>>    user = user.__of__(acl_users)
>>>    newSecurityManager(None, user)
>>>    #print "Retrieved the admin user"
>>>else:
>>>    print "Retrieving admin user failed"
>>>    exit(1)
>>>
>>>factory = app.manage_addProduct['CMFPlone']
>>>factory.addPloneSite(pid, title='Portal')
>>>print "Added Plone"
>>>
>>>transaction.commit()
>>>noSecurityManager()
>>>
>>>print "Finished adding Plone site"

最後參照 Running Plone and Zope behind an Apache 2 web server 來設定 mod_rewrite,把新建立的 buildout Plone 位址對應到 ex: http://localhost/CMS or http://localhost/project ..etc。

目前這些測試,是在 Shell 底下執行,另外必須研究如何將這互動介面產生到 Web Page 或者是 Plone 頁面上,並且在最後執行成功時,自動 Email 給註冊者相關網址及帳號資訊等 (搭配 mail server)。

以上是直覺化的使用 buildout 建立多個 Plone-Site,每個專案網站擁有一個自己的 buildout 目錄。但這種方式在處理 port 數量以及 Plone+mod_rewrite 時會有問題 (因為要對應許多 port),相對的這些 port 也會造成更多的安全疑慮問題。

因此另一種較好的方法是,研究 siteAutoInstall.py 程式的運作原理,另外撰寫自動化 scripts,並處理好各別 Plone-Site 的 Admin 權限問題後,利用 mod_rewrite 的方式,僅針對各別目錄 rewrite 即可,就能完成一個初階的 Plone Hosting 構想。

Google 上也有類似的 Plone Hosting 構想 (Easier Plone Hosting: Some Ideas),但未見其實作的內容。若 Plone Hosting 的考量需像 http://objectis.org/ 這樣的完整時,需考量及面臨的技術問題就更具規模了。

二月 17, 2009
» Plone-Site Auto Install scripts

用 bin/buildout 建立環境之後,接著需要進入到 ZMI 來建立 Plone-Site。這個動作可以將它自動化。下面這個 Scripts 從 marr’s weblog 來的,就是用來處理這樣的事情。另外也在 Google 上找到類似這樣的 example:plone-scripts/siteAutoInstall.py。Python 在 Plone/Zope 層面的技術及用法,很值得在深入研究。

>>>from sys import exit
>>>import transaction

>>>from AccessControl.SecurityManagement import \
>>>    newSecurityManager, noSecurityManager

>>>from Testing.makerequest import makerequest

>>>app = makerequest(app)
>>>admin_username='admin'

>>>oids = app.objectIds()
>>>pid = 'Plone'
>>>if pid in oids:
>>>    print "A Plone site already exists"
>>>    exit(1)

>>>acl_users = app.acl_users
>>>user = acl_users.getUser(admin_username)
>>>if user:
>>>    user = user.__of__(acl_users)
>>>    newSecurityManager(None, user)
>>>    #print "Retrieved the admin user"
>>>else:
>>>    print "Retrieving admin user failed"
>>>    exit(1)

>>>factory = app.manage_addProduct['CMFPlone']
>>>factory.addPloneSite(pid, title='Portal')
>>>print "Added Plone"

>>>transaction.commit()
>>>noSecurityManager()

>>>print "Finished adding Plone site"

» Python search-and-replace string in files

近日在寫一個 scripts,想以 Python 來做到 Shell scripts 或 Sed 下,常用來搜尋檔案內特定文字並取代的功能。透過好用的 Google,還是有找到一些實用的 example。

這是一個修改過的範例:

>>>from glob import *
>>>import re

>>>fileList = glob('buildout.cfg.tmp')
>>>pattern = re.compile('admin:', re.IGNORECASE)
>>>replace = "admin:NewPWD"
>>>cfg = open('buildout.cfg', 'wU')
>>>for filename in fileList:
>>>    for line in file(filename):
>>>        print >>cfg,pattern.sub(replace, line),
>>>cfg.close()

改寫這個 example 的用途是,將 buildout.cfg.tmp 裡的 admin: 字串改成 admin:NewPWD,最後的取代結果存入到 buildout.cfg 內。

» Python random password

那隻厲害的咕狗,我只有餵它吃 這隻骨頭,它就幫我帶來了這個東東:

Python 2.4.5 (#1, Nov  6 2008, 18:04:30)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from random import Random
>>> import string
>>> PWD = ''.join( Random().sample(string.letters+string.digits, 12) )
>>> PWD
'35lV71NJ6BxL'
>>> f=open('/tmp/r_pwd.txt', 'w')
>>> f.write(PWD)
>>> f.close
<built-in method close of file object at 0x1999f8>

二月 16, 2009
» Translation Service broken (Data.fs moving troubles)

昨日將 Linux 主機上的 Data.fs 搬移到 Windows 上還原,在 Data.fs 移轉之後,Windows 這端出現了 Translation Service broken 的問題,也就是說幾乎所有的 PO Path 路徑名稱都吃到原本 Data.fs 的路徑。在 Error Log 中,大致上會這樣描述:

.... (略)
------
2009-02-15T22:48:14 WARNING PlacelessTranslationService Message Catalog has errors
PloneTranslations.i18n-plonelanguagetool-zh-tw.po
------
2009-02-15T22:48:14 WARNING PlacelessTranslationService Message Catalog has errors
PloneTranslations.i18n-plonelanguagetool-zh-tw.po
------
... (略)

因為 PO檔的 Path 跑掉了 (吃到原本的 Data.fs 上的路徑),所以 translation 是壞掉的。如果這個時候就放棄了,那就損失大了。因為 Google 之後才發現,這個問題是『正常』的...

使用這樣的關鍵字:”Placeless Translation Service Data.fs” 搜尋到這篇 Re: Moving troubles,底下的描述正說明了這個問題的解法:

You need to copy both the Data.fs and all your custom products.

Normally the paths are not a problem., But for some reason the placeless translation service stores the path to the translation files. So on the first reboot it cannot find them, and translation is broken.

Just restart the server once more. That will make the translationservice load them from the correct location.

也就是說,第一次會痛是正常了,接著重新啟動 Zope/Plone 之後,就會順暢了。

二月 13, 2009
» Products.Maps i18n:translate example

Products.Maps 2.0. A simple, easy to use Plone integration with Google Maps by Jarn AS. 修改 buildout.cfg 檔案,表述將安裝 Products.Maps eggs:

eggs =
Products.Maps

接著執行 bin/build (第一次建立) 或 bin/buildout -No (更新)。安裝完成後,就可以在 Plone 裡新增一個 GoogleMap Location 的 Content Type。

這裡要示範將 Products.Maps 新增的 Content Type 名稱 (Location) 做額外的 i18n:translate 的設定。因預設它的 Location 將生硬的翻為 “位置”,若我們需要將 Products.Maps 應用在服務客戶的需求上時,這個名稱是必須經過客製修改。

第一步驟,是找到 eggs/Products.Maps-2.0-py2.4.egg/Products/Maps/profiles/default/types/GeoLocation.xml。在 title: Location 的描述裡新增 i18n:translate:

$ vi eggs/Products.Maps-2.0-py2.4.egg/Products/Maps/profiles/default/types/GeoLocation.xml
<property name="title" i18n:translate="">Location</property>

接著將 GeoLocation.xml 複製(或 Link) 到 parts/plone/CMFPlone/profiles/default/types/ 裡:

$ ln eggs/Products.Maps-2.0-py2.4.egg/Products/Maps/profiles/default/types/GeoLocation.xml parts/plone/CMFPlone/profiles/default/types/GeoLocation.xml

再來修改 plone-zh-tw.po 檔 (./parts/plone/PloneTranslations/i18n/plone-zh-tw.po) 加入 msgid 及 msgstr 的描述:

$ vi parts/plone/PloneTranslations/i18n/plone-zh-tw.po
#. Default: "Location"
#: CMFPlone/profiles/default/types/GeoLocation.xml:5
msgid "Location"
msgstr "公司店家資訊"

最後在 Plone 的 “網站設定” 裡將 Products.Maps reinstall,這樣我們客製修改過的 i18n:translate 就會立即生效。Location 的 Content Type 名稱也會改成我們所定義的內容,例如:

p-maps

二月 12, 2009
» Registration Form Customize

預設 Plone 的 Registration Form 會長像這個樣子:

reg-2

如果有修改的需求,則需找到 /Plone/portal_skins/plone_login/join_form 來修改裡面的樣式。

這一個示範例子,是將預設的 “寄送密碼 Checkbox” 拿掉,取而代之的是我們想自己提供的簡單文字敘述。於是打開 join_form 檔案來修改,找到下面這一塊敘述:

<div class="field"
tal:condition="not: allowEnterPassword"
tal:define="mail_me request/mail_me|nothing">
.
.
</div>

將預設的 Password Checkbox:

<input type="checkbox"
class="noborder"
name="mail_me"
size="30"
id="cb_mailme"
tal:attributes="checked python:test(mail_me, 'checked', None);"
/>
<label for="cb_mailme" i18n:translate="label_mail_password">Send a mail with the password</label>

改為我們想要的內容:

<label for="cb_mailme">若是廠商會員身份,請額外寄信通知管理員,信件內含您的全名和名稱。</label>

儲存之後,新的註冊頁面就會長得像這個樣子:

reg-1

» Documents_actions (Link) open in new window

在 Plone 的 Documents view 底下預設會有兩個 documents_actions Link,分別是 Sendto 及 Print 等。

在 CMF Action at /Plone/portal_actions/document_actions/sendto 的 URL (Expression) 可以透過 string:$object_url/sendto_form 來改連結的位址。但如果要讓新連結開啟於新的視窗,就必須找到 document_actions.pt 這個檔案來修改,並加入 HTML 中 target=_blank 的語法即可。

可以利用 grep -r “document_actions” 的指令來找到 Plone Buildout 目錄裡所有包含相關字串的檔案。

在 ./eggs/plone.app.layout-1.1.5-py2.4.egg/plone/app/layout/viewlets/document_actions.pt 這個檔案可以找到定義 documents_actions Link 的方式。

修改如下:

<a href=""
tal:attributes="href daction/url;
title daction/description"
tal:content="daction/title"
target="_blank">
</a>

這樣就完成了。

二月 4, 2009
» Portlets CSS customized (Firebug)

Firebug 是一個好用的工具,如果在這之前沒接觸過的話,可參考 Google 找到的介紹 來認識這個 Firefox Add-ons。我在這裡使用 Firebug 來找 Plone 網頁畫面中,某些特定區域所定義的 CSS 檔案位置及行數。這對於 CSS 的調整有很大的幫助。

安裝 Firebug 之後,點選 Firefox 瀏覽器最右下方的 “小蟲” 後,就可以開始觀察 “滑鼠點選區域中” 的 HTML 內容以及 CSS 樣式。執行的畫面會像是下圖這樣:

firebug

利用這個工具,可以找到 Plone 目錄選單的 CSS 樣式定義檔案,修改內容以達成客製化樣式。例如:目錄選單的樣式定義在 public.css 這個檔案。因此進入到 /portal_skins/plone_styles/public.css 來修改檔案。下面的例子是將目錄字體設定為 “標楷體”,大小設為 12pt。

pic1

pic2

以下是兩個修改的例子:

若要修改左邊 Portlet 選單的標題,則需要修改 portlets.css,因此進入到 /portal_skins/plone_styles/portlets.css 來改檔案。將字體設為標楷體,大小設為 12pt。

pic3

pic4

若要修改 Document 的標題 (Header),則需要修改 base.css,因此進入到 /portal_skins/plone_styles/base.css 來改檔案。將 H1 字體設為標楷體,大小設為 200%(預設是 160%)。

pic5

pic6

除了上面的例子之外,這邊也還有一份文件可以參考:
http://plone.org/documentation/tutorial/creating-plone-themes/toolchain

十二月 22, 2008
» Creating static text portlets in Plone3

延續先前 How to manage portlets in Plone 3 的內容,這次繼續把 Creating static text portlets in Plone 3.0 的部份完成。

這篇文章 Creating static text portlets in Plone 3.0 介紹如何建立一個 “讓我們自行填寫內容” 的 portlets。這次採用 buildout 的方式很快就完成了,而且沒遇到之前發生的 Error。

.
首先第一步驟:修改 buildout.cfg

.
在 zcml 的區塊中加入 plone.portlet.static

.
接著在終端機執行:
$ sudo ./bin/buildout
$ sudo ./bin/instance start

.
來到 Manage portlets 畫面,Add Static text portlet。

.
填入版面所要顯示的內容:

.
儲存離開後,剛才新增的版面就會出現囉!

一月 29, 2008
» Plone HTTP Cache Manager + Apache mod_cache

使用 Plone 內建的 HTTP Cache Manager 配合 Apache mod_cache,
可以讓 Plone-Site 的頁面存取速度增快,網站整體的效能也會跟著提昇。

在開始之前,可先閱讀 使用 Cache Manager,認識 Zope 底下
Cache Manager 的運作模式。若想直接快速獲得 Benchmark 的數據,
可參考 Plone 效能測試綜合報告

底下將說明如何實做 Plone 的 HTTP Cache Manager 並搭配
Apache mod_cache 提昇 Plone 網站的存取效能。

首先載入 Apache mod_cache:

$ sudo a2emod cache
$ sudo a2emod mem_cache
$ sudo a2emod disk_cache

編輯 httpd.conf 加入 Cache Configuration:

<IfModule mod_cache.c>
<IfModule mod_mem_cache.c>
CacheEnable mem /
MCacheSize 65536
MCacheMaxObjectCount 2000
MCacheMinObjectSize 1
MCacheMaxObjectSize 10240
</IfModule>
</IfModule>

$ sudo /etc/init.d/apache2 restart (或 force-reload)

Cache Configuration 的設定值可參考 Apache Module mod_cache

接下來要設定 Apache 做為前端伺服器,並且啟動 mod_rewrite、
mod_proxy,設定步驟可參考:Running Plone and Zope behind
an Apache 2 web server

最後搭配 mod_cache 作為前端快取機制,並設定 Plone HTTP Cache
Manager。

底下是 Plone/manage 的 HTTP Cache Manager 設定畫面:

cache-1.jpg

點選 Associate,找出所有可被 cache 的物件,勾選所需要 Cache 的物件,
選擇完畢後按下 Save Changes:

cache-2.jpg

cache-3.jpg
cache-4.jpg

勾選完成之後,即完成了所有的設定。

此時 Plone 會將需要 Cache 的內容轉交給
Apache mod_cache 來處理,以增進網站存取效能。

.
最後我們使用 ab 來 benchmarking 網站的效能:

1. 完全沒做任何 Cache 的 Plone-Site:
$ ab -n 500 -c 20 -d -k http://localhost:8080/Plone

測出的數據
Requests per second 7.24 #/sec
Time per request 2761.690 ms

2. HTTP Cache Manager + Apache mod_cache 的 Plone-Site:
$ ab -n 500 -c 20 -d -k http://localhost/Plone

測出的數據
Requests per second 2787.50 #/sec
Time per request 7.175 ms

3. 將 Cache interval seconds 設成 5 秒的情況下:

測出的數據
Requests per second 710.95 #/sec
Time per request 28.22 ms

.
由 ab benchmarking 後的數據可以發現:

1. HTTP Cache Manager + Apache mod_cache 的 Plone-Site
相較於沒做任何 Cache 設定的網站,網站存取效能提昇將近 400 倍。

2. 將 interval seconds 由 3600 秒縮減為 5 秒後,
所造成的網站存取效能耗減,將近有 4 倍之多。

.

一月 14, 2008
» Running Plone and Zope behind an Apache 2 web server

測試了 Apache mod_rewrite 以及 Zope 的 Virtual Host Monster 物件,
藉由 Rewrite Module 的方式,把瀏覽 Plone 網站的 Request 重導給 Zope,
除此之外,原本在 /var/www/* 裡的 Apache 網頁目錄也能直接在網站上運作。

實際執行的方法很容易,首先要載入 Apache 相關模組:
$ sudo a2enmod rewrite
$ sudo a2enmod proxy
$ sudo a2enmod proxy_http

接著在 Apache ServerRoot 下做轉址的設定,
這裡我是採用修改 .htaccess 的方式:
$ sudo vi /var/www/.htaccess

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^phpform - [L]
RewriteRule ^(.*) http://localhost:8080/VirtualHostBase/http/localhost:80/VirtualHostRoot/Plone/$1 [P]
</IfModule>

PS: RewriteRule ^(.*) 那行為同一行,這裡因為排版關係它自動跳行。

填寫完成之後 restart Apache。

未來在存取 http://localhost/ 時,就會導向到 http://localhost:8080/Plone,
Plone 底下所有的 URL 都會從原本的 :8080/Plone/*
重新導向到 http://localhost/Plone/*,
除此之外,原本在 /var/www/phpform 這個目錄,
會原封不動的交給 Apache 來處理。

底下有更詳盡的參考資源:
1. Running Plone and Zope behind an Apache 2 web server
2. Mixing Local Apache and Proxyed Content
3. 使用 Apache 作為 Zope 的前端
4. ZopePowerUser 進階講師研習班
5. Zope 虛擬主機的實例教學

一月 6, 2008
» Plone & Python Workshop @ IIS

這是 1/7 日在資訊所與法鼓山朋友一同參與的聚會,
由我與 Marr 介紹 Plone & Python 相關的主題,
並且讓大家一同參與實做。

講題的內容:

* Denny
0. Plone 基礎介紹、架構特色與應用
1. windows/Linux 安裝 Plone-site
2. Plone3.0 操作手冊內容介紹
3. 在 Plone 上安裝 Product (ex: Wiki、Blog...)
4. 介紹 PHParser + MySQL/PostgreSQL
5. 介紹 SQLPASPlugin + MySQL/PostgreSQL

* Marr
1. Baby Steps for Python
2. Lessons Learned from a Python-based Project

.
我準備的內容是 Plone 的入門介紹與實做,
以下是參用的資料,有興趣的朋友歡迎參考。

0. Plone 基礎介紹、架構特色與應用
http://yenjinc.info//?p=268

1. windows/Linux 安裝 Plone-site
http://yenjinc.info/?p=27 (Windows)
http://yenjinc.info/?p=29 (Mac OSX)
http://yenjinc.info/?p=166 (Linux)

2. Plone3.0 操作手冊內容介紹
http://plone.org/documentation/manual/plone-3-user-manual
http://plone.org/documentation/manual/plone-2.5-user-manual

3. 在 Plone 上安裝 Product (LinguaPlone、ZWiki、Blog...)
http://plone.org/products
http://yenjinc.info/?p=273
http://zwiki.org/releases/ZWiki-0.60.0.tgz
http://yenjinc.info/?p=282

4. 介紹 PHParser + MySQL/PostgreSQL
http://marrtw.blogspot.com/2007/12/phparser-with-plone.html
http://yenjinc.info/?p=284
http://yenjinc.info/?p=285

5. 介紹 SQLPASPlugin + MySQL/PostgreSQL
http://yenjinc.info/?p=286
http://yenjinc.info/?p=297

6. 其他參考資源

.Zope / Plone 的相關介紹
http://www.song.idv.tw/docs/ZopeIntro/
http://www.song.idv.tw/docs/ZopeIntro/PloneDoc

.Definitive Guide to Plone (Plone 電子書)
http://plone.org/documentation/manual/definitive-guide

.非開發者角度的文件:
http://learnplone.org/

.客製化網站外觀可參考:
http://plone.org/documentation/tutorial/creating-custom-style

一月 4, 2008
» 好吧,那我們再來裝一次 Zope 與 Plone

看過 Better Web App Development 後,也許你也開始想不開要試試Plone?又或,在 Zope 2.9.5 released! Plone 2.5.1 released! 的情況下,也許是時候來清理一下門戶上陳年的Warming、Error訊息了?那就來吧。在這裡我們把 Python、Zope 與 Plone 一口氣裝到 Ubuntu 或 Debian Linux 上。

(也許這次我們要認真點?)首先建置測試環境,為了不破壞系統上原來的環境,我們使用apt上的Python(當然,也不使用root的身份),相對地,我們要抓Python回來自行編譯,夠認真了吧?別害怕,通常沒什麼問題,大不了出現少了什麼套件(如g++)無法編譯的狀況,這時便是 aptitude (好吧,或著apt-get)上場的時候。

參考 Michael Thornhill 的這個繁雜而有點過時的.sh檔,我寫一個比較簡化的版本來先。(暫時不含ZEO、MySkin、IPython等有的沒的的玩意兒,以後還有機會慢慢玩)下載來用(或參考)吧!

簡單地說呢,這個script首先設定環境變數,它預設了你先建了一個空白的資料夾然後在它下面執行這個script,所以拜託別忘記這麼做(或是你之後或著轉職為搬運工,或著轉為debug工程師)。然後開始下載原始檔,編譯、安裝分三部分:Python、Zope、Plone(於 Zope Instance 的 Products 資料夾下的東東)。

Python的部份,首先裝 Python-2.4.3 (不必擔心,Zope-2.9.5不支援也跑不動Python-2.5),然後裝 setuptools-0.6c3 ,並藉此來裝 PIL 1.1.5 (Plone-2.5.1 要求PIL,順便看看它的Release Notes?)。

然後裝 Zope 2.9.5 ,利用它的 mkzopeinstance.py 指令來生成一個 instance 後,把 Plone 裝上去,再順便裝一個聽說很不錯的Doc。便大功告成可喜可賀了?不過,若配置於 subversion 環境下,不妨先 initial check in 吧!(即使也許我們之後還需要MySite的幫忙)

那麼?裝好了?……好吧,裝好大半了;接下來就用滑鼠點一點了事吧。
先把zope instance跑起來:(執行,但別問我說你是不是要先移動到哪個資料夾) ./ins/zoper/bin/runzope
呃?即使我們如此認真,還是得到兩個warming(也許你得到更多?)(這要怪它 "Although practicality beats purity. Errors should never pass silently." 嗎?呵);不過暫時別管它,因為我們以前看過更多的warming。現在我們可以用心愛的瀏覽器連上 http://localhost:8080/manage ,用你放在 setupit.sh 裡所設的使用者 (ZOPE_USER) 與密碼 (USER_PASSWORD) 登入管理介面(沒錯,還是那個ZMI)。

來到這裡,等不及地把點下圖的選單找到 Plone Site 後,再點下旁邊的 Add 。(呃,blog上的圖片可能要點入才看得到,網頁模版的問題,so sorry)

addplone

再來就是例行的討厭的麻煩的填資料的鎖事(但千萬別亂填,看看我,填得多麼認真?)
addplone2

注意第一欄 Id ,將會成為你(或不可思義地,別人)之後要連上的位址。像我填 plone,那我之後要連的位址便是 http://localhost:8080/plone 。填完後按下方的Add Plone Site按鈕,接著便是 Zope 與 Plone 結合的一刻。
addplone3

恭喜。結束了。

參考資料:
Setting up Plone and Zope from source — plone.org
Michael Thornhill: Team Development with Plone/ Zope/ ZEO/ Subversion/ ipython
更多在我的連結筆記: Plone Quest



然後?去渡個中秋小假。回來後,或許先試著匯入舊的資料試試吧。
可以試著玩玩 ArcheTypes ,用來自製內容型態似乎滿方便的。(第一步你可以由它的tracsvn co出ArchExample資料夾,或從它那下載原始檔解開得到那個資料夾,然後複製到zope instance的Products資料夾,重新啟重zope instance後便能利用plone的 portal_quickinstaller 安裝這個範例,然後探索一下發生了什麼變化吧!)

plonesitesetup

plonesetup

plonequickinstall

一月 2, 2008
» PostgreSQL + ZPsycopgDA + SQLPASPlugin

在上一篇:SQLPASPlugin for SQL based authentication in Plone
介紹 MySQL+SQLPASPlugin 實做過程。

接著我又參考這篇:
How To Setup SQLPASPlugin to Authenticate Against A PostgreSQL Database 實做了 PostgreSQL+SQLPASPlugin。

結果發現事情並不如 文件中 寫的那麼簡單,
這裡面存有一些 小問題需修正 才行!

.
底下是在 Ubuntu7.10 實做的過程紀錄:

.
1. 首先安裝這些軟體 (apt-get install XXX)

apache2
libapache2-mod-php5
libapache2-mod-auth-pgsql
php5
php5-cgi
php5-pgsql
phppgadmin
postgresql-8.2
postgresql-plpython-8.2
postgresql-pltcl-8.2
python-pygresql
python-psycopg2
python-psycopg2da
zope-psycopgda2
plone-site

.
2. 參考這份文件:Debian Linux 架設 PostgreSQL+PhpPgAdmin

2-1. 切換成 postgres 的身份執行
# sudo -u postgres psql template1

2-2. 修改 postgres 的密碼
# template1=# alter user postgres with password ‘PASSWORD’;

2-3. 建立 zope 使用者 (作為 Plone-site 讀取 PostgreSQL 的角色)
# template1=# create user zope with password ‘PASSWORD’ createdb createuser;

這裡的使用者務必建立為 zope/plone 服務啟動角色,
否則在執行 ZPsycopgDA 時會有錯誤訊息:
例如://psql: 嚴重錯誤: Ident 驗證使用者 “某某某” 失敗//

2-4. 離開 PostgreSQL
# template1=# \q

2-5. 參考 上面那篇文件 繼續完成 phppgadmin 的設定。

.
3. 使用 zope 使用者登入 phpPgAdmin 建立資料庫與表格
3-1. 建立使用者認證資料庫 zope_sqlpas
3-2. 建立角色資料表 roles,欄位設定為 username, rolename
3-3. 建立認證資料表 users,欄位設定為 username, password, email

zpsycopgda-1.jpg

.
4. 安裝設定 ZPsycopgDA

cd /var/lib/zope2.9/instance/plone-site/Products/
sudo cp -rf /usr/share/zope/Products/ZPsycopgDA\:2/ .
sudo mv ZPsycopgDA\:2/ ZPsycopgDA
sudo chown zope:zope -Rf ZPsycopgDA

sudo vi ZPsycopgDA/DA.py

找到 99 行:self.encoding = encoding
改成:self.encoding = “utf8″

(如果沒修改,在執行 ZPsycopgDA 存取 PostgreSQL 時
會出現 encoding 錯誤訊息)

.
5. 在 Plone 根目錄建立 Z Psycopg2 Database Connection。

在 Connection string 填入正確的 PostgreSQL 連結資訊
//例如: dbname=zope_sqlpas user=zope password=xxxxx//

zpsycopgda-2.jpg

.
6. 安裝 SQLPASPlugin

.
7. 到 Plone Control Panel 設定 SQL Authentication。

zpsycopgda-3.jpg

zpsycopgda-4.jpg

.
8. 設定 /Plone/acl_users/source_properties。

.
大功告成啦!
此時 Plone 的使用者管理以及認證資訊皆已在 PostgreSQL 進行。

十二月 29, 2007
» SQLPASPlugin for SQL based authentication in Plone

Plone 是一個可供多人註冊使用的 content management system (CMS)
註冊的 user record 會儲存在 ZODB 裡,經由 ZMI /Plone/acl_users,
可以對其 Authentication 的規則窺知一二。

在 Plone 上預設已安裝 PlonePAS Product,它可讓我們安裝
PluggableAuthService(PAS) plugins,作用是讓其他系統上既有存在
的使用者資料作為 Plone 的 user/group sources,並且支援其帳號密碼認證。

SQLPASPlugin Product 是一個 PAS plugins,
藉由 SQLPASPlugin+PlonePAS,可以把 Plone 的 使用者管理/認證
交由另一台 SQL database 來處理,也就是讓 Plone 網站可以存取
另外一個網站 SQL 裡的帳號密碼。

.
底下簡略紀錄
Plone3+MySQL+SQLPASPlugin 的整合測試。

1. 首先安裝 MySQL for Python & ZMySQLDA

2. 在 Plone 根目錄建立 Z MySQL_Database_Connection。

sqlpas-1.jpg

.
3. 安裝 SQLPASPlugin

sqlpas-2.jpg

.
4. 到 Plone Control Panel 設定 SQL Authentication。

sqlpas-3.jpg

sqlpas-4.jpg

.
5. 設定 /Plone/acl_users/source_properties。

sqlpas-5.jpg

sqlpas-6.jpg

.
6. 到 Plone Control Panel 安全設置,打開使用者相關功能。

sqlpas-7.jpg

.
7. 此時 Plone 的使用者管理以及認證資訊皆已在 MySQL Database 進行。

.
關於 PluggableAuthService(PAS) 資源,可參考 PAS reference manual,
PlonePAS Presentation 的介紹。

以上整合測試是在 MySQL Database,若搭配 PostgreSQL Database,
可參照 How To Setup SQLPASPlugin to Authenticate Against A PostgreSQL Database

十二月 26, 2007
» PHParser + PostgreSQL

接續上一篇的內容:
Plone and PHP+MySQL (Quick-Note)

這次搭配的 database 改成了 PostgreSQL
安裝流程與方法幾乎跟 上篇 一樣,
差別只在於安裝的是 psycopgZPsycopgDA

經過測試後發現,若純粹搭配 PHParser 來與資料庫互動的話,
其實可以不用安裝 ZMySQLDA / ZPsycopgDA

十二月 25, 2007
» Plone and PHP+MySQL (Quick-Note)

以下將條列式的說明:
如何讓 Plone 能支援 PHP Code 以及 PHP+MySQL 的連結。

.
安裝與設定相關環境

1. 佈置好 PHP+MySQL 環境 (MS: Appserv, Linux: apt-get install)
2. 佈置好 Plone3 環境 (MS: Plone3 download, Linux: apt-get install)

3. 安裝 MySQL for Python & ZMySQLDA
3-1. 用 Plone 的 easy_install 工具安裝 MySQL_python
3-2. 將下載完成的 ZMySQLDA 安裝到 Plone Product 裡

4. 安裝 PHParser (參考 PHParser with Plone)
4-1. 在 CMFPlone/configure.zcml 裡加上 five:traversable 的相關設定
4-2. 更改 Products/PHParser/PHParser.py 檔案裡的 PHPath

5. 在 ZMI 新增 Z MySQL Database Connection (填入 MySQL 連結資訊)
6. 在 ZMI 新增 Z SQL Method (填入 MySQL 連結資訊)

.
寫 PHP Code (or PHP+MySQL 連結)

7. 在 ZMI 裡新增 PHParser,在此檔案裡寫自己的 PHP Code (包含 PHP+MySQL 的程式)。
7-1. 參考 Integrating PHP applications in Plone
7-2. 新增 Page template 並結合 PHParser 的內容

在 Plone 呈現 MySQL 資料,還有第二種方法:參考 Plone and MySQL

8. 新增 Z MySQL database connection 連結資料
8-1. 新增 Z SQL Methods 連結資料
8-2. 新增 Page template 並結合 Z MySQL / Z SQL 的內容

.
MySQL 資料在 Plone 上的編碼問題

9. 在 PHP+MySQL 程式中使用 mysql_query(”SET NAMES ‘utf8′”);

10. 改 lib/python/ZPublisher 的 HTTPResponse.py
10-1. 設定 default_encoding = ‘utf8′

完成!

biggo.com.tw

A Django site.