CMFの仕組みをお勉強をした時のメモ
2004/09/16 更新
Zope Developer Camp 2004
では、CMF 1.5β のソースをベースに、その仕組みを勉強しました。以下は、キャンプに備えて、私が個人的に予習したときのメモに加筆(=復習)したものです。
あくまでも、メモですのであまり見ない方が良いです。よりも Zope Developer Camp 2004
で、他の人がより良い資料を作ってくれたのでそれを見た方が良いです
より良い資料
アーカイブの内容から考えてみる
CMF 1.5 のアーカイブには以下のようなディレクトリがあります。
- CMFDefault (CMF Site)
- CMFCore (狭義の CMF。)
- CMFActionIcons (action とアイコンイメージを関連づけるもの。)
- CMFCalendar (カレンダー機能。CMFDefaultでは使わなくても良い。)
- CMFSetup (CMFSiteの設定を XML形式で保存できるもの。初期状態では Addされていないので、使いたい場合は、ZMIから
portal_setup を Add する。)
- CMFTopic (Add Contentで1番下に出る Topic のこと。どうやって使うか知らない。)
- CMFUid (ユニークなIDを作るツール。詳細は不明。)
- DWorkflow (定義可能なワークフローツール。)
CMFとは、CMSを作るフレームワークなわけですが、これらのうち狭義のフレームワークとは CMFCore のことです。
そして、CMF Productをインストール(Productディレクトリにコピー)すると、ZMIから Addできる 「CMF Site」 は、上記のうち、CMFDefaultで定義されています。CMFDefault は、CMFCoreの他に 3.~8.の Product の機能を使っています。
つまり、
- CMFDefault = アプリケーション
- その他 = アプリケーションを構築するためのライブラリ
と考えると判り易いと思います。(以下では CMFを基盤にして作成した Product を CMFアプリケーションと呼びます)
同様に Plone のソースアーカイブを解くとたくさんのディレクトリがありますが、このうち、CMFPlone ディレクトリ(Product)が狭義の Plone teamが開発したもので、他は、使用している Pruduct を同梱しているにすぎません。
CMF Site に作られるオブジェクトから考えてみる
CMF Site を ZMI から Add すると、CMF Siteの中にたくさんのオブジェクトが
追加されますが、それらは、大きく分けて
- ツール(portal_tool)
- コンテンツ (Content Type オブジェクト)
- その他オブジェクト
に分けられます。(以下では、その他オブジェクトの説明は省略)
1.ツール(portal_tool)
ZMI 上にスパナのアイコンで表されるツールは、Java でいうインターフェースの実装
だけを持つクラスのようなものだと考えると判り易いでしょう。
(ツール内にプロパティを持ちますが、サイト運用時にころころ変わるものではなく、
いわば定数のようなものです。)
ツールは、まとまりのある機能のメソッドを集めたもので、アイコンは同じですが、ツール間に機能上の関連性はありません。(CMF
アプリケーションでは、必要なツールのみを使うことができますし、自分で特別なツールを書くこともできます。)
以下、処理内容はよく判りませんが、ツールとその定義してある場所を書いておきます。
- portal_actions (ActionsTool.py)
- portal_catalog (CatalogTool.py)
- portal_memberdata (MemberDataTool.py)
- portal_skins (SkinsTool.py)
- portal_types (TypesTool.py)
- portal_undo (UndoTool.py)
- portal_url (URLTool.py)
- portal_workflow (WorkflowTool.py)
- portal_discussion (DiscussionTool.py)
- portal_membership (MembershipTool.py)
- portal_registration (RegistrationTool.py)
- portal_properties (CMFDefault/PropertiesTool.py)
- portal_metadata (CMFDefault/MetadataTool.py)
- portal_syndication (CMFDefault/SyndicationTool.py)
- portal_uidannotation (CMFUid/UniqueIdAnnotationTool.py)
- portal_uidgenerator (CMFUid/UniqueIdHandlerTool.py)
- portal_uidhandler (CMFUid/UniqueIdHandlerTool.py)
それぞれのツールの ZMI 画面に Actions というタブがある場合は、これは、
- 「ID」と「式(Action)や有効になる条件、表示・非表示の状態等」を結びつけるもの
で、その使い方は同じです。
言葉では(私もよく判ってないので)説明しにくいですが、例えば、
portal_registration の id 「join」の「visible?」のチェックを外して Saveすると、
CMF Site の Joinのリンクが消えます。
この機能をうまく使うと、skinを変更しなくても
- 機能の追加、削除ができる
- ユーザー権限などの条件により表示するページを変える
などというようなこともできるわけです。
CMFアプリケーション作成者は、
some_tool = getToolByName(self, 'portal_some_function')
result = some_tool.one_of_method() |
のように、名前でツールを検索してメソッドを呼び出せるので、使うのが簡単です。
2.コンテンツ (Content Type オブジェクト)
文章、ファイル、イメージ等が電子化されているもので、ワークフローで管理
されているものがコンテンツです。
Webコンテンツマネジメントシステム入門
という書籍では、「デジタル・アセット」という用語を作っていましたが、
アセット(資産)という考え方をすると判り易いかも知れません
(つまり、サイトの見た目やロジックはアセットではない)。
例えば、サイトトップにあるロゴイメージは、ワークフローで管理されるものでは、
ないので(=skin で定義されている)画像であってもコンテンツではありません。
PortalContent (CMFCore/PortalConent.py)から派生しているもの
- Document (CMFDefault/Document.py)
- Image (CMFDefault/Image.py)
- File (CMFDefault/Image.py)
- Link (CMFDefault/Link.py)
- NewsItem (CMFDefault/NewsItem.py) Documentから派生
- Favorite (CMFDefault/Favorite.py) Link から派生
- Event (CMFCalendar/Event.py)
- DiscussionItem(CMFDefault/DiscussionItem.py) Documentから派生
PortalFolder(CMFCore/PortalFolder) から派生しているもの
- Folder (CMFDefault/SkinnedFolder.py)
- Topic (CMFTopic/CMFTopic.py)
すでに存在する Content Typeでは、必要な機能が備わっていない場合があります。
例えば、CMFDefaultでは、Documentが Public になると、検索可能になりますが、
PDFファイルを、File(これに入れるしかない)に保存しても検索できません。
PDFファイルで検索できるようにするには、PDFファイルのテキスト文字列を抽出して、portal_catalog で検索文字列として登録するような新たな Content Type
を定義すれば良いわけです。
http://www005.upp.so-net.ne.jp/nakagami/tips/CMFPdfDocument.html
新たな Content Typeを定義するというのは、結局のところ、
どんなプロパティを持っているか(値チェックを含む)や、特定のステータス
の時の挙動が異なるだけで、ほとんどの場合同じような手順の開発になります。
そこで新たな Content Type を作成する時の場合のフレームワークとしてArchetypes http://plone.org/documentation/archetypes/ が開発され、
たとえば、Ploneの配布物には同梱されています。
CMF でアプリケーションを作るとは
CMFを使わずに Productを作成する場合は、アプリケーションのためのクラスを定義し、その中に
- 表示するメソッド
- データを修正するメソッド
- 検索のための索引作成処理メソッド
- その他、機能として必要なメソッドとプロパティ
・・・と、アプリケーションに必要な機能を、クラスのメソッドとして定義していくことになると思います。
一方 CMFアプリケーションを作成する場合は、大雑把にいって、
- アプリケーション固有のロジックをツールとして作成
- skinに ZPT や PythonScriptを書く(プレゼンテーション)
- 必要な コンテンツ(Content Type) のクラスを定義・・・つまり、PortalFolder/PortalContentの派生クラスを書く
- portal_type で、コンテンツが、どのクラス、どの入力フォーム、どのアイコン・・・と結びついているか定義
- skin と、コンテンツを結びつけるように Actionを定義
- CMFDefault/Portal.py をまねっこして、Siteクラスの作成
というような感じで作成することになると思います。
skin の中に置く ZPT や PythonScript から適宜、必要なツールの機能(メソッド)を呼び出すことになりますが、たとえば
workflowの機能や joinの機能は必要ないような場合は、それらを使う必要はありません(portal_membership や portal_workflowを
サイト内に Addする必要もありません)。
ある意味、周りくどいやり方ではありますが、これによりツールやコンテンツの実装はそのままに、skin や
Action を書き換えるだけで、当初とは異なる画面推移に、変更したり、別のアプリケーションにコンテンツやツールを使い回したりすることができます。
つまるところ、CMFは分割統治の道具だと思います。
参考文献
ある nakagami のメモ