前 [第七章:Ploneスタイルガイド] | 目次 | Next [第九章:Ploneの最適化]
この章ではディフォルトインストールを超えてPloneを拡張する方法を説明します。これは大きなトピックであり、もし全部を含めようとすると何冊かの本になってしまいます。ここではいくつかの一般的なPloneの拡張方法について説明したいと思います。
PloneとCMFにはいろいろなアイテムタイプが含まれます。とはいえ、初めから含まれているタイプがあなたを満足させなくなる時がやがてやってくるでしょう。この章は自分の拡張をPloneインスタンスに追加するにはどうするのかを説明します。
独自のタイプを追加するにはPythonの知識が少し必要になるでしょう。Ploneを拡張するにはいくつかの方法があります。
注意:いくつかはZClassを用いても実現できます。ですが私たちはZClassを使うことはお勧めしませんし、ここでも説明はしません。ZClassを使ってコンテンツを作るための素晴らしい本としてXXXがあります。
コンテンツタイプは特定のタスクと機能のために設計されています。Ploneはいくつかの一般的なコンテンツタイプを提供しますが、それらはあなたのニーズを満たすかもしれませんしそうでないかもしれません。再目的化は既存のコンテンツタイプ、例えばニュースアイテムを元にしてより良い形でニーズに適合するように変更することを意味する用語です。
これは例をあげて説明するのが簡単でしょう。大部分の会社は新しい製品や取引といった会社のニュースの発表としてプレスリリースを発行します。このためには、多くの場合ニュースアイテムは満足できるものですが、このプレスリリースでは少し違うことをやりたいと私たちが思っていると考えてください。
これを完了させるまでの各ステップを見ていきます。
ZMIからportal_typesへアクセスします。portal_types ツールはサイトに登録されているコンテンツタイプをすべてリストします。すべての標準的なもの、ドキュメント、フォルダ、そしてもちろんニュースアイテムを含んでいることでしょう。- 右上のAddメニューを使って、Factory-based Type Informationを選びます。
Press Releaseを入力して、Use default type informationの所で、CMF Default: News Itemを選択します。そしてこのフォームを完了するためにAddを押します。Plone内の各コンテンツタイプはその概要を説明した情報を持っています。これらはメニューにリストされています。前記でニュースアイテムを選んだということは、プレスリリースは最初はニュースアイテムと同じプロパティと構成を持っています。
portal_typesリストの中で、Press Releaseという名前の新しくできたコンテンツタイプが見つかります。Ploneに普通のユーザとしてアクセスした時には、プレスリリースオブジェクトを追加できるようになっていることにも気がつくことでしょう。
今のところ、プレスリリースオブジェクトはそれほど印象的なわけではありません。それは異なる名前を持つにもかかわらず、ニュースリリースとまったく同じです。portal_typesツールの中で、新しく作られたプレスリリースオブジェクトを選択します。これはニュースアイテムからのものとわかるこのタイプのプロパティを表示します。例えば、Description欄は「News Items contain ...」となっています。これはプレスリリースのための説明であり、例えば、「Press Releases contain news for the public」のようにより適切なものに変更される必要があります。
これらの値を変えることにより、コンテンツの見え方を変えることができます。
コンテンツタイプツール値
Filter content typesが許されているなら、このリストで定義されたコンテンツのタイプだけしか追加されません。私たちの2番目の目標を達成するために、ユーザに違う見え方を提供するようにコンテンツタイプのテンプレートを変更する必要があります。portal_types ツールの中で、Press Releaseを選び、それからActionsタブを選びます。これは各コンテンツタイプのアクションをリストします。これらのアクションがコンテンツのページの上の方に横長に現れるタブと同じであることにたぶん気がつくでしょう。
このケースでは、私たちが変更したいアクションはViewアクションです。このアクションはユーザーがコンテンツにアクセスする時に、デフォルトで表示されるページです。各アクションはそれが呼ばれた時に呼び出されるページテンプレートを指し示します。このコンテンツはNews Itemをベースにできているため、viewのアクションはnewsitem_viewを指し示していることでしょう。Ploneスキンを通して検索すると、newsitem_viewは実際のところportal_skins/plone_content/newsitem_viewに関連していることがわかります。
ビューを変更するのに新しいページを作ります。その一番簡単な方法はZMIの中でオブジェクトを選んで、customizeボタンをクリックすることです。これでcustomフォルダーの中にオブジェクトのコピーが作られ、portal_skins/customでアクセスすることができます。とはいえ、このオブジェクトの名前はアクションの中で指定したものとまだ同じでままです。これらのオブジェクトを区別できるようにするために、このオブジェクトの名前をnewsitem_view から pressrelease_viewに変更します。そしてportal_types/Press Releases/manage_editActionsFormsに戻って、Viewアクションを見つけて、それをnewsitem_viewからpressrelease_viewへ変更します。これでプレスリリースのための新しいアクションは新しいページテンプレートを指し示します。
さあこれで残っているのは会社の宣伝文句が文書の最後の部分に入るようにviewを変更することです。これは必要なHTMLがページに追加されるようにpressrelease_viewを変更するという簡単なことです。例えば次のようにになります。
<p tal:condition="not: len_text"
i18n:translate="no_body_text">
This item does not have any body text, click the edit tab to change it.
</p>
次のような追加をすることでしょう。
<h3>About My Company</h3>
<p>Blah....</p>
これで各ページの下部にコンテンツを追加するという要件を実現させることができました。
コンテンツに簡単な変更を加えるために、コンテンツの再目的化はPloneの中のコンテンツを差し替える簡単な方法です。それで簡単な変更はできますが、元々のコンテンツタイプの守備範囲を超えるような複雑な変更はできません。
コンテンツタイプを作るすべての方法の中で、Zopeプロダクトを作るというのは最も強力であるそのさらに上をいっています。とはいえそれは最も理解するのに複雑でありPythonの知識を要求します。もしあなたが経験豊富なプログラマーであるか、Ploneの内部についてより詳しく知りたいかであれば、これがあなたの選ぶ方法です。プロダクトを書く限界は本当にあなたの想像力です。
この題目はとても深いため、私たちはここですべてを説明することはできません。ここではいくつかのことを前提とします。。
...
CMFTypes はArcheTypesに名前を変えました。そしてあいにくなことに目標が少し動いてしまいました。このプロジェクトの目的は最小のコーディングで簡単にPloneのコンテンツタイプを作成、編集できるようにすることです。それがもう一度一段落したときにはドキュメントが書かれることでしょう。もしあなたが開発者であり、学習したいのであれば、コードに含まれる例がとても役に立つでしょう。 Sourceforge project
Credit: Geoff Davis
フォームを作り、案内するのを簡単にするために、Ploneはフォームとナビゲーションのシステムを持っています。
portal_formツールはフォームのためのバリデーションとナビゲーションサービスを提供します。これを説明する最も簡単な方法はportal_formがどのように働くかを見てみることです。例えばリンクオブジェクトを編集するプロセスです。
リンクを編集するためのURLは../myLink/portal_form/link_edit_formです。編集フォームのHTMLアクションは../myLink/portal_form/link_edit_form自身です。portal_formツールはURLを横取りして新しくサブミットされた値をチェックします。もしportal_formツールが新しい値を見たら、portal_formはportal_properties/form_propertiesシートの中にあるフォームのためのバリデータのセットを見つけて、それをサブミットされた値のところに呼び出します。バリデータの連鎖がある時はsuccessかまたはfailureを返します。Portal_formは次に何が実行するべきかを見るためにportal_properties/navigation_propertiesの中を見て、それを適切な届け先に渡します。portal_formはバリデーションとナビゲーションの発動を取り扱うので、フォーム処理のコードがしなければならないのはオブジェクトを更新することだけです。結果として、単純なモジュラーバリデータとやはり単純なフォーム処理コード、それらすべてがportal_propertiesの中のプロパティシートを使って再構成することができます。
これがフォームのためにportal_formが動作するのに必要なことです。
link_edit_formを参照してください)「form_submitted」という名前の隠れた変数を追加し、その値をtemplate/idに設定します。Portal_form はフォームがサブミットされたか否かを判断するためにREQUEST.form_submittedをテストします。
portal_form.setValidators('link_edit_form', ['validate_id', 'validate_link_edit'])
successかfailureのどちらか)、(2)ディクショナリーの中のエラーメッセージのセット、そして(3)次のナビゲーション状態に応じて渡されるプロパティのディクショナリー。もしバリデータが連鎖の一部であるなら、連鎖の中で直前のバリデータによって返される状態/エラーにアクセスしたいことでしょう。これらの値は「REQUEST['validation_status']」や「REQUEST['errors']」のように指定することで、REQUESTの中で入手が可能です。portal_status_messageにキーを設定することでポータル状態メッセージを渡すことです。ナビゲーションツールはこれらのプロパティを次のナビゲーション状態に考慮した形で次に渡します。次の状態がページテンプレートかPythonスクリプトの場合はREQUESTの中で、次の状態がURLかアクションの場合は問い合わせパラメータとしてです。注意するのは、バリデーションの後でスクリプトを呼び出した場合、スクリプトはREQUESTからportal_status_messageを得て、次のナビゲーション状態に応じてそれを次に渡さなければなりません。
successかfailureであるような状態から成るものです。コンテクストは次のナビゲーション状態で使われます。またコンテクストを返すときにはportal_factoryによってオブジェクトがインスタンス化されます。-- 下記を見て下さい。プロパティのディクショナリは次のナビゲーション状態に応じた形で次に渡されます。portal_navigationの中でセットアップします。下記を見て下さい。portal_navigationツールはフォームでのナビゲーションを取り扱うためのコントローラの一部です。ナビゲーションはportal_propertiesの中のnavigation_propertiesシートを通してすべてを設定することができます。ナビゲーションプロパティの形式は次のようになります。
[type].[action].[status] = [next thing to do]
[タイプ].[アクション].[状態] = [次にすること]
例えば、リンクを編集するためのナビゲーションは次のようになります。
link.link_edit_form.failure = link_edit_form<br/>
link.link_edit_form.success = script:link_edit<br/>
link.link_edit.success = action:view
ナビゲーションツールは設計パターンから状態制御パターンを作り出します。そしてnavigation_propertiesシートは状態遷移テーブルです。上記のナビゲーションプロパティの左側は現在の状態を表し、右側は遷移先を表します。
例えば、
link.link_edit_form.failure = link_edit_form
リンクのlink_edit_formのバリデーションからfailureの結果を受け取った後に、ナビゲーションツールは現在のコンテクスト上でlink_edit_formページテンプレートを再度呼び出すべきであることを意味しています。そして、
link.link_edit_form.success = script:link_edit</code></p>
リンクのlink_edit_formのバリデーションからsuccessの結果を受け取った後に、現在のコンテクスト上でlink_editスクリプトを呼び出すべきということを意味しています。そして、
link.link_edit.success = action:view</code></p>
リンクのlink_editの呼び出しからsuccessの結果を受け取った後に、現在のコンテクスト上でリンクのviewアクションを実行することを意味しています。
右側で定義された遷移は次のようなものです。
さらに言っておくと、遷移はカギ括弧を使って要求からのデータを合体することができます。例えばurl:http://www.zope.org/?myId=[id]はREQUEST.idの値によって置き換えられる [id] によって指定のURLにユーザーを連れて行きます。
Ploneで開発をしていてセキュリティの宣言で何かうまくいかなければ、ログインフォームを得ることでしょう。これは開発の時にはとても役に立つとは言えません。何がいけないのかということについてのについてのより多くの洞察を得ることができるようなメカニズムがあります。
Auto-login page IDの値を消去します。doc/environment.txtを見てください)Editor: Andy McKay $Id: 8,v 1.1.1.1 2003/08/26 17:09:51 tyam Exp $