1. アドオンプロダクト開発者向けマニュアル
    1. 1. 導入
      1. 導入
        1. ところで、ほんとにプロダクトを開発しなければならないの?
      2. プロダクト開発者向けメーリングリスト
      3. 高品質なアドオンプロダクトとは
        1. 拡張性と単純性のバランス
        2. Zope 3の開発テクニックの使用
        3. Archetypesの活用
        4. うまく設計されたユーザインターフェイス
        5. セキュリティ
        6. 国際化 (i18n)
      4. プロダクトの命名
    2. 2. コーディングの指針
      1. 全般
      2. コーディング規約一般
      3. 私は如何にして心配するのを止めてAPIを愛するようになったか
      4. Developer Documentation
        1. Testing and DocTests
      5. ドキュメント作成用の便利なプロダクト
    3. 3. "ワーストプラクティス"、あるいはやるべきでないこと
      1. TALESにロジックを記述しない
      2. オブジェクトデータベースにリレーショナルモデルを無理強いしない
      3. ロールではなくパーミッションのみをチェックする
      4. REQUEST.AUTHENTICATED_USER を使わない
      5. サイトのセキュリティを管理するのにAuthenticatedロールを使用しない
      6. proxyロールは使用しない
      7. メソッドには必ずセキュリティ宣言を追加する。デフォルトはpublicだ!
      8. カタログの結果に対してgetObjectをコールしない
      9. contentValuesやobjectValuesを使用しない
      10. スクリプトの返り値はオブジェクトではなく辞書(のリスト)とする
      11. 表示の際には値の計算を行わない
      12. 表示の際にはオブジェクトを"さわらない"
    4. 4. さぁできた!公開しよう!
      1. 他のプロダクト開発者との連携
      2. Plone.orgでの公開
      3. Plone Collectiveへのアップロード
      4. ドキュメントの作成
      5. コミュニティへの参加

アドオンプロダクト開発者向けマニュアル

アドオンプロダクトを開発するにあたってのベストプラクティスを解説します。

1. 導入

このドキュメントの対象読者、そして高品質なプロダクトを作成するにあたっての考え方を示します。

導入

Ploneのコアは非常に美しく設計されており、たいていのことを行ってくれます。しかも、ただ単にこなすのではなく、うまい具合に処理してくれるでしょう。しかし、Ploneの豊富な機能の多くは、アドオンプロダクト群によって実現されているのです。アドオンプロダクトを使用すると、Ploneの機能を拡張することができます。Ploneのコアコンポーネントの多くは、もともとアドオンプロダクトとして開発が始められたものです。また、作成したコードを共有したり再利用したりするための手段としても、アドオンプロダクトは最適です。

この文書の目的は、優れたアドオンプロダクトを作成してPloneコミュニティに貢献したいという開発者を支援することです。また、すでにアドオンプロダクトの開発経験がある人たちにとっても、よりよいコーディングスタイルを身につけるという意味で役立つことでしょう。

ところで、ほんとにプロダクトを開発しなければならないの?

たいていの人は、新しいプロダクトを書き始める前にまず既存のプロダクトに手を入れることを選びます。新しいプロダクトをゼロから書き始めようとする前にまずはPlone.orgのプロダクト一覧Plone Collective (Ploneプロダクト用の共有SVNリポジトリ)をチェックしてみましょう。あなたが作ろうとしているプロダクトと同じようなものが既に存在するかもしれません。

Ploneコミュニティの長期的な目標は、同じような問題を微妙に異なる手法で解決するプロダクトをたくさん用意するのではなく、高品質で汎用的なプロダクトを厳選して提供することにあります。Ploneのアドオン開発者たちは、新たな人材が仲間入りすることを心待ちにしています。既存のプロダクトの開発を手伝ってくださるかたも大歓迎です!

プロダクト開発者向けメーリングリスト

http://plone.org/support#product-developers

アドオンプロダクトの開発者たちが、プロダクトについての情報を得る場です。Ploneのバージョンアップに関する問題、移行についての情報やアドオン開発についての一般的な質問などが話題となっています。

高品質なアドオンプロダクトとは

Ploneのプロダクトには、非常にシンプルなものからきわめて複雑なものまで幅広いものがあります。そのため、あるプロダクトが "高品質である" かどうかを判断する基準をはっきり決めることはできません。とはいえ、高品質なプロダクトの多くは次の基準を満たしているということはいえるでしょう。

拡張性と単純性のバランス

よくできたアドオンプロダクトは、カスタマイズしやすいように設計されています。たとえば、新しいコンテンツタイプを追加して独自のロジックや機能を組み込んだりするのも簡単です。また、そのプロダクト内のコンテンツタイプのサブクラスを簡単に作れるようにもなっているはずです。

と同時に、シンプルであることも大切です。まるで新たなフレームワークであるかのようにあらゆる箇所をカスタマイズ可能にしてしまうよりも、"ここだけを変更すればすべてうまくやってくれる" という設計のほうがよいでしょう。

Zope 3の開発テクニックの使用

Zope 3の登場により、Ploneコミュニティはコンポーネント化の恩恵を大いに受けられるようになりました。複雑なプロダクトは、Zope 3コンポーネント(インターフェイス、ビュー、アノテーション、……)として複数のプロダクトやライブラリ、メソッドやクラスに分けてしまいましょう。そうすれば、別のプロダクトで再利用がしやすくなります。

アドオンプロダクトの開発でZope 3のテクニックを使うための方法は、以下が参考になるでしょう。

  • b-org: Martin Aspeliによる詳細なチュートリアル。Plone Conference 2006におけるMartinのプレゼンの映像でも同じ内容を取り扱っています。
  • 同じくPlone Conference 2006で行われたRocky Burtのチュートリアル"Developing Plone Products Using Zope 3 Technologies"も一見の価値ありです。その内容はここで、そして映像はここで見られます。

Archetypesの活用

Archetypesは、Ploneがコアコンテンツを作成する際に使用しているフレームワークです。そのため、アドオンプロダクトの多くもArchetypesを使って新たなコンテンツタイプを作成しています。Archetypesをうまく使えば、頑丈で信頼性が高く使いやすいプロダクトを作ることができるでしょう。

Archetypesについて詳しく知りたい方は、以下をごらんください。

うまく設計されたユーザインターフェイス

Ploneは、そこらにあるさまざまなコンテンツ管理システムの中でも最も便利で使いやすいものです。アドオンプロダクトを開発する際にも、ユーザインターフェイスに十分な注意を払うようにしましょう。たとえば、

  • Plone 3.0以降では、アドオンプロダクトを開発する際にKSS javascript フレームワークを活用することができます。javascriptを適切に使用すれば、より使いやすいリッチなユーザインターフェイスを構築できることでしょう。しかし、javascriptを使えないブラウザでも使えるようにしておくことが大切です。
  • 編集画面では、Archetypesやformlibの適切なウィジェットを使うようにします。以下が参考になるでしょう。
  • 一般ユーザ用の設定は、Ploneのコントロールパネルから行えるようにします。プロダクトの設定を行うために、わざわざZMIやファイルシステムまで使わなければならないなんてことは避けましょう。

セキュリティ

Zopeのおかげで、Ploneは非常にセキュアなシステムとなっています。PHP/MySQLで作ったどこかのコンテンツ管理システムとは違い、一般的な攻撃の被害を受けることはないでしょう。とはいえ、すべてのアドオンプロダクトが安全であるとは限りません。中にはセキュリティ上の問題のあるプロダクトもあるでしょう。あなたがプロダクトを開発する際には、セキュリティにも十分注意するようにしましょう。

Ploneにおけるセキュリティについては、以下が参考になります。

国際化 (i18n)

Ploneは世界中で使われています。また、Ploneの国際化機能はかなりの優れものでもあります。ただ、この機能の恩恵を受けるためにはアドオンプロダクト側で国際化に対応させる必要があります(「外国語なんて話せないよ」って人たちも心配無用。国際化に対応させるのはとても簡単だし、外国語に関する知識もいらないんです!)。

まずはこのあたりから見てみましょう。

プロダクトの命名

よい名前をつければ、他の人たちにそのプロダクトの中身をわかってもらいやすくなります。Unfortunately, the Plone and Zope communities have a history of coining awkward product names. Here are some recommendations for choosing a great product name.

Renaming a product is painful because of migration hassles for later releases, so getting the project name right the first time around will save you work later.

  • 他で使われておらず、覚えやすいもの。かつ既存のプロダクトと似た名前ではないこと。
  • 覚えやすく、かつそのプロダクトの機能がわかりやすい名前にすること。
  • プロダクト名に "Plone" を含めないこと。それがPloneのプロダクトであることは、言われなくてもわかっています。もしどうしてもPloneという名前を使いたいのなら、"XYZ for Plone"のようにしておいたほうがまだましです。Plone® は世界各国でPlone Foundationの登録商標となっており、Ploneを含む名前のプロダクトはPlone? Foundationが作ったものだと誤解される可能性があります。これは、あまり好ましい状況ではありません。
  • "AT" "CMF" "NG" といったわかる人にしかわからないような略語は避け、そのプロダクトが使用している技術を反映したような名前にすること。
  • 自分の所属する会社名とか納品先の会社名をプロダクト名の先頭につけないようにすること。
  • Don't lowercase your human-readable product names just because Zope 3 convention is for lowercase names in code.

At the risk of courting controversy, here are some "good" product names and some "less good" ones. (Remember: we love all add-on product developers, even if we don't love all the product names! :)

よい名前の例あまりよくない名前の例
"Wicked" - a wiki productATSchemaEditorNG
"Iterate" - product for document stagingKukit (turned out to be a Norwegian expletive!)
"Quills" - a blogging productCMFSin
"Bling" - a javascript productmxmContacts

2. コーディングの指針

Ploneコミュニティには、より効率的によいコードを書くための知恵がたくさん蓄積されています。ここでは、その概要だけを示します。

全般

Joel Burtonのチュートリアル「Best Practices for Plone Development(日本語訳)」は、Ploneの開発を始めようとする人にとっては必読のドキュメントです。このドキュメントには、ファイルシステムを扱うコードの基本やソースコード管理の方法、設定の管理、ドキュメントの作成、デバッグおよびテストなど幅広い内容が網羅されています。中には少々古くなってしまっているところもあります(設定管理の部分など)が、開発に関するテクニックを身に着けるには最適です。

コーディング規約一般

  • アドオンプロダクトのロジックの大半はPythonで書かれています。このガイドラインを参考にすると、あなたの作成するプロダクトのコードがよりわかりやすいものとなるでしょう。
  • Ploneコミュニティでは、標準規格への準拠やアクセシビリティの確保を重視しています。正しい形式のXHTMLやTALES、そしてCSSを使用するようにしましょう。HTMLやCSS、RSSが標準に準拠しているかどうかは、W3Cのツールで調べることができます。
  • Ploneのアドオンプロダクトでは、DTMLは使わないようにしましょう。ZopeそのものはDTMLスクリプト言語をサポートしていますが、現在はDTMLに代わってTALが用いられるようになっています。

私は如何にして心配するのを止めてAPIを愛するようになったか

Ploneのイケてるところのひとつが、その豊富なAPIです。Ploneのウェブインターフェイス上からできることなら何でも、ファイルシステム上のコードからPlone APIでも行うことができます。「で、いったいどんなAPIがあるの?どうやってそのAPIを見つけるの?」と思われる方は、以下のプロダクトを参考にするといいでしょう。

DocFinderTab
DocFinderTabを使用すると、ZMIから見える任意のオブジェクトのAPIをウェブ経由で調べられるようになります。これはソースコードを直接眺めるよりもかなり便利です。基底クラスのメソッドもすべて確認できるからです。また、基底クラスの順に並べ替えて表示されるので、デバッガで調べるよりも便利です。このプロダクトは、きわめて簡単にインストールして使用することができます。まだ使ったことがないという人は、今すぐインストールしてみましょう。これは、Zopeに標準で搭載されていてもおかしくないようなプロダクトです。
Clouseau
Clouseauは、AJAXを使用したインタラクティブなZope/Pythonプロンプトです。これを使用すると、Ploneの内部からZopeやPythonを直接操作できるようになります。使うのも簡単で依存性もなく、非常に便利です。
他のプロダクトのInstall.pyファイル
何かの設定をする方法を知るために最適な方法は、他のプロダクトがそれをどのように実装しているのかを調べることです。お気に入りのプロダクトのInstall.pyを調べてみましょう。たとえば、新しいワークフローをディスクからインストールする方法が知りたければ、PloneHelpCenterを調べるといいでしょう。

Plone APIのすばらしい解説が、以下のサイトにあります。

Developer Documentation

Testing and DocTests

Plone開発者の間には、テスト駆動ソフトウェア開発の文化が強く根付いています。Ploneコミュニティのメンバーの中には、テストスクリプトの内容を見てアドオンプロダクトの出来を判断するという人も大勢います。きちんとしたテストを書いておくと、そのプロダクトが確実に動作することを保証できるようになります。また、誰かがそのプロダクトに手を加える際にも既存の機能を破壊してしまうことがなくなります。

PloneやZope? 3の開発者であるPhillip von Weitershausen (PhiliKON)は、テストについて次のようなアドバイスをしています。

  • The top-level *.txt texts should be unit tests if you're writing a basic Zope 3-style component. Unit tests means you should be using DocTestSuite/DocFileSuite from zope.testing.doctest, not any of the convoluted ZopeTestCase test suites. If your test needs set-up, only load as much as you need. Avoid loading ZCML in a unit test.
  • Tell a story into which you involve the reader using first person plural ("we"). Create the component, walk through its API, explain tough edge cases and why it's necessary to watch out for them (and to test them). I know, this takes time.
  • If you're writing functional tests, talk to the application using the test browser (Products.Five.testbrowser.Browser, docs in zope.testbrowser/README.txt). It's a great way of testing interactive UIs in a doctest, and the result is very readable.

Phillipは、次のような結論に達しました。

Just because you write doctests doesn't mean you've also written docs. Testing and documenting is hard and doing them at the same time can mean you consolidate effort, but it also means you need think hard. Writing good tests, especially writing good doctests, is much more challenging than the coding itself. Be prepared to spend more time on this than the actual coding."

テストに関するすばらしい情報が、Martin Aspeliによるチュートリアル"Ploneによるテスト"で見られます。

また、doctestとepydocによるアジャイルドキュメンテーションも参考になるでしょう。

ドキュメント作成用の便利なプロダクト

以下のプロダクトを使用すると、自分で作成したアドオンプロダクト用のドキュメントを作成する際に役立つでしょう。

DCWorkflowGraph
DCWorkflowGraphを使用すると、ワークフローを図に変換することができます。
DCWorkflowDump
DCWorkflowDumpは、ZMIで作成したワークフローをPythonのコードに落とします。これを使用すると、ワークフローをファイルシステムベースのプロダクトとすることができます。
EpyDoc
Epydocは、Zopeに同梱されているものよりも賢くて高機能なモジュールです。あなたの作成したプロダクトについての、見栄えのいいAPIドキュメントを作成してくれます。もちろん自作のプロダクトだけでなくZopeやPloneそのもののドキュメントを作成することも可能です。また、ドキュメントをPDF化することもできます。このPDFは顧客に見せるのにも耐えうる高品質なものなので、この手のドキュメントを作成する手間を省くことができます。docstringの内容がそのままドキュメントになるので、よりよいdocstringを書くための動機付けとしても有用です。

3. "ワーストプラクティス"、あるいはやるべきでないこと

Stefanのプレゼンテーション"Top Twenty Plone Pitfalls(Ploneの落とし穴 ベスト20)"と多少関連しています。

Plone Conference 2006で、Stefan Holek ("lurker")が"Top Twenty Plone Pitfalls"というプレゼンテーションを行いました。この内容はここからダウンロードできます。あるいはオンラインで見ることも可能です。

彼が挙げた落とし穴の多くは、アドオンプロダクトの開発者にもあてはまるものです。そこで、そのいくつかを「ワーストプラクティス」としてまとめておきます。

TALESにロジックを記述しない

テンプレートはプレゼンテーション層を受け持つものです。本来の目的でのみ使用するようにしましょう。アプリケーションのロジックはすべて、Pythonのコード(スクリプトやツール)に追い出すべきです。テンプレート内で複雑な条件式を使用しているのなら、立ち止まってちょっと考えてみましょう。「これって、どうにかしてPythonスクリプトにできないかな?」TALESで、「python:」は使わないようにしましょう。これを使い出すと、コードの保守性が一気に下がります。デバッグもしにくくなりますし、他の人が読んでも意味がわからなくなってしまいます。

Stefanは、冗談で(半ば本気で?)こんな提案をしています。「テンプレート内で"python:"を1回使うごとに、Plone Foundationに寄付をするようにしよう \(^o^)/」

オブジェクトデータベースにリレーショナルモデルを無理強いしない

ZODBを、まるでMySQLであるかのように使わないでください。ZODBはオブジェクトデータベースであり、リレーショナルデータベースではないのです。アプリケーションを設計する際は、オブジェクト指向で考えるようにします。「テーブルの中の各行がひとつのレコードを表しており……」という考え方は捨てましょう。しかし、どうしてもリレーショナルデータモデルが必要だというのなら、RDBMSをPloneで使用することには何の問題もありません。この場合は、データベースコネクタを用いてZSQLでRDBMSとのやり取りをすることになるでしょう。

以下のリソースが参考となります。

ロールではなくパーミッションのみをチェックする

  • オブジェクトやメソッドの保護はパーミッションによって行われているのであり、ロールによるものではないからです。
  • チェックには、portal_membership.checkPermissionを使用します。

REQUEST.AUTHENTICATED_USER を使わない

  • AUTHENTICATED_USERは安全ではなく、はるか昔に非推奨扱いになっています。
  • 代わりにportal_membership.getAuthenticatedUserを使用します。

サイトのセキュリティを管理するのにAuthenticatedロールを使用しない

  • Authenticatedは、システムが使用するロールです。
  • 自前のカスタムロールを作成して使用しましょう。

proxyロールは使用しない

  • Proxyロールは、*nixにおけるSUIDスクリプトと似ています。
  • そのスクリプトが何を行うのかに注意しましょう。結果的に、あなたのサイトにセキュリティホールを作ってしまうかもしれません。

メソッドには必ずセキュリティ宣言を追加する。デフォルトはpublicだ!

  • アイテムはほとんどのZope2オブジェクトの基底クラスとなり、保護されていない属性にアクセスできてしまいます。
  • 「ツール」には特に注意が必要です。メソッドは通常publicにすることになるので、自前でセキュリティチェックを行う必要があります。

カタログの結果に対してgetObjectをコールしない

  • getObjectは、内部的にrestrictedTraverseを使用します。
  • 必要な情報はすべてカタログのメタデータに追加しましょう。

contentValuesやobjectValuesを使用しない

  • contentValues/objectValuesは、配下のオブジェクトを"立ち上げ"ます。つまり、ディスクからメモリに読み込みます。
  • ちなみに、objectIdsは使っても大丈夫です。でも、contentIdsはいけません。

スクリプトの返り値はオブジェクトではなく辞書(のリスト)とする

  • オブジェクトはメモリにキャッシュされません。
  • Objectsはセキュリティチェックの対象となります。
  • Pythonスクリプトは真っ先にキャッシュの対象となります。

表示の際には値の計算を行わない

  • 編集時に計算を済ませ、その結果を保存します。

表示の際にはオブジェクトを"さわらない"

  • オブジェクトを閲覧する際にデータベースへの書き込みが発生してはいけません。
  • 不意に手を加えてしまうことは多々あります。Undoタブをチェックしてみましょう。

4. さぁできた!公開しよう!

作成したプロダクトを公開すれば、世界中の人たちにそれを使ってもらうことができます。ここでは、リリースパッケージを作成するための方法やPloneコミュニティに参加して他のメンバーと交流するための方法を説明します。

プロダクトを公開するとは、単にそのコードをダウンロードできるようにするだけのことではありません。Ploneコミュニティの他のメンバーが、あなたのプロダクトを発見できるように、そしてダウンロードして使い始められるように、そしてプロダクトの改善に協力してくれるように持ち込む方法を、ここで説明します。

他のプロダクト開発者との連携

他のプロダクト開発者と知り合いになれば、さまざまなアドバイスを受けることができるでしょう。多くのプロダクト開発者はproduct-developers メーリングリストをチェックしています。まずはここに参加してみましょう!

Plone.orgでの公開

プロダクトを公開したら、plone.org/products にそのプロダクトのエントリを作成しなければなりません。ここには、最新リリースだけでなく過去のリリースについての情報も掲載します。最初のバージョンを公開するまでは、まだエントリを作成する必要はありません。

Plone Software Center (plone.org/products を管理しているところ) では、コードの公開場所だけでなく非常に便利な機能を提供しています。これは、プロダクトを保守したりコードを改善したりするのに非常に役立つでしょう。特に次の2つはお勧めです。

  • Issue tracker: 特別な理由がない限り、各プロダクトは Plone.org/products 配下に個別のバグトラッカーを公開しなければなりません。そうすれば、プロダクトのユーザがバグ報告を気軽にできるようになります。
  • Roadmap: 開発が活発に進んでいるプロジェクトの場合は、将来の機能追加予定や機能追加要望をここで管理します。

ヒント: あるプロダクトを採用するかどうかを決めるのに、実際に動作するサンプルを参考にするという人が多いようです。可能なら、プロダクトの説明の中に実際の動作例へのリンクを記載しておくようにしましょう。

Plone Software Centerの使い方については、http://plone.org/documentation/tutorial/plone-software-center が参考になります。

Plone Collectiveへのアップロード

一般に公開するプロダクトは、公開SVNリポジトリからソースを取得できるようにしておくべきです。特別な理由がない限り、通常はPlone Collectiveのリポジトリを使用します。公開SVNリポジトリが利用できなければ、コミュニティのメンバーがあなたのプロダクトの開発を支援することができません。Collectiveとは、Ploneコミュニティが用意している最もアクセスしやすいリポジトリのことです。

ドキュメントの作成

Ploneのエンドユーザ向けに機能を公開するプロダクトについては、エンドユーザ向けのドキュメントが必要です。特別な理由がない限り、通常はPlone.org/productsを使用します。これにより、ファイルシステムへのアクセス権がない人にも簡単に閲覧できるようになります。

  • すべてのプロダクトにはINSTALLあるいはREADMEというドキュメントを含めなければいけません。このドキュメントでは、プロダクトをインストール/アンインストールする方法や依存するプロダクト/ライブラリなどについて説明します。
  • 可能なら、インテグレータ向けのドキュメントも用意します。このドキュメントでは、プロダクトのカスタマイズや拡張の方法を説明します。
  • ライセンス(GPLがお勧めです)について記述したファイルや開発者のクレジットが必要です。また、適切なバージョン番号をつけるようにしましょう。

コミュニティへの参加

Ploneの最大の強みは、ユーザや開発者のコミュニティです。Ploneの世界で成功しているプロダクトの多くは、その開発者自身がPloneコミュニティに深く参加しています。Ploneコミュニティに参加することで、Plone開発者としてより成長することができるでしょう。オープンソースコミュニティは、お互いの信頼関係で成り立っています。他のメンバーにあなたのことを知ってもらえばもらうほど、あなたのコードに対しての信頼度も向上するでしょう。また、そのプロダクトの開発を続けていくにあたっての協力も得やすくなります。

  • 新しいアドオンプロダクトを公開した場合は、それをproduct-developersやplone-usersといったメーリングリストで発表しましょう。
  • アドオンプロダクトを開発する過程でなにか疑問が生じたら、product-developersメーリングリストで相談してみるといいでしょう。