コンテンツオブジェクトの操作

コンテンツオブジェクトを生成・削除・修正する方法について学びます。

これはifPeople(http://www.ifpeople.net)のPlone/Zopeトレーニングのために書かれた、Plone APIの紹介資料です(Plone 2.0と2.1に対応)。原文はEmanuel Sartor(http://www.menttes.com)によって書かれ、Natalia B. Bidartによって英訳されました。スペイン語バージョンはhttp://www.ifpeople.net/fairsource/courses/material/apiPloneで見ることができます。
Page 2 of 5.

ポータルのコンテンツ(ドキュメント、画像、リンク、フォルダ、ニュース、ファイルなど)を保存しておくために、Ploneインターフェイスから追加されるオブジェクトのことをコンテンツオブジェクトと呼ぶことにします。

コンテンツオブジェクトはPythonで書かれたスクリプトによって操作することが可能です。すなわち、コンテンツオブジェクトは生成したり、修正したり、削除したりすることができるのです。たとえば状態を変えたり、それぞれのオブジェクトが持っている情報にアクセスすることができるのです。

例1:Pythonスクリプトからコンテンツオブジェクトへアクセスする

まず最初にPloneインターフェイスからコンテンツオブジェクトを追加します。それから下記のような流れに従ってスクリプトからアクセスしてみることにします。

  • my_documentというIDでドキュメント(ページ)を追加します。もしかしたらタイトルだけを追加するようになっているかもしれませんが、そのときは My Documentというタイトルでページを追加します(半角英数字などで書かれたタイトルを持つコンテンツオブジェクトであれば、ほぼ同じIDが自動的に生成されます)。
  • ZMIからPloneのサイトフォルダへアクセスし、portal_skins/customへ行きます。そこで下記のような内容のスクリプト(Script (Python))を追加します。
    from Products.CMFCore.utils import getToolByName
    
    urltool = getToolByName(context, "portal_url")
    portal  = urltool.getPortalObject()
    document = getattr(portal, "my_document")
    print document.Title()
    print document.CookedBody()
    return printed

上記の例ではgetToolByNamegetattrといった関数や、getPortalObjectTitleCookedBodyといったメソッドを利用しています。少し詳しく見てみましょう。

  • getToolByName(obj, name, default=[]) これはCMFモジュールからインポートされています。これはオブジェクトに関係した名前によるツールを返します。
  • getattr(object, name[, default]) これはZopeの関数で、オブジェクトのnameアトリビュート(文字列)を返します。もしオブジェクトがnameアトリビュートを持っていない場合には、(3番目の引数がセットされていなければ)AttributeErrorが起こります。
  • hasattr(object, name) これはZopeの関数で、オブジェクトのアトリビュートに文字列引数であるnameがあればTrueを、そうでなければFalseを返します。
  • getPortalObject(self)これはProducts.CMFCore.URLTool.URLToolのクラスメソッドです。Portalオブジェクトを返します。

例2: Pythonスクリプトからドキュメントのコンテンツを修正する

例1で見たスクリプトを修正して、 print ブロックの前に下記の内容を追加しましょう。

document.edit(text_format="html",
              text="<div><b>This is a new text...</b></div>")

editメソッドは下記のように使うことができます。

  • edit(self, text_format, text, file="", safety_belt="") このメソッドはCMFDefaults.Document.Document クラスに属しています。text_formathtmlstructured-text、あるいはplainをとることができます。textがドキュメントの内容になります。

例3: Pythonスクリプトからコンテンツオブジェクトをコピー&ペーストする

  • ページの時と同じようにしてmy_folderというIDのフォルダを生成します。
  • 下記のようなスクリプトによってmy_documentがmy_folderへコピーされます。
    from Products.CMFCore.utils import getToolByName
    
    urltool = getToolByName(context, "portal_url")
    portal  = urltool.getPortalObject()
    cb_copy_data = portal.manage_copyObjects(["my_document"])
    folder  = getattr(portal, "my_folder")
    folder.manage_pasteObjects(cb_copy_data)
    

ここで大切なメソッドを確認しておきましょう。

  • manage_copyObjects(self, ids=None, REQUEST=None, RESPONSE=None) Method from OFS.CopySupport.CopyContainerクラスのメソッドです。これはidsリストによって指定されたオブジェクトを内部のペーストボードにひも付けします。
  • manage_cutObjects(self, ids=None, REQUEST=None) 上記のカット版です。
  • manage_pasteObjects(self, cb_copy_data=None, REQUEST=None) これはOFS.CopySupport.CopyContainerクラスのメソッドです。manage_copyObjectsmanage_cutObjectsによってひも付けされたオブジェクトをペーストします。

例4: ythonスクリプトによってコンテンツオブジェクトを削除する

次のようなスクリプトによってコンテンツオブジェクトを削除することができます。

from Products.CMFCore.utils import getToolByName

urltool = getToolByName(context, "portal_url")
portal  = urltool.getPortalObject()
portal.manage_delObjects(["my_document"])

manage_delObjectsがポイントです。

  • manage_delObjects(self, ids=[], REQUEST=None) Method from CMFPlone.PloneFolder.BasePloneFolderクラスのメソッドです。ids リストによって指定されたエレメントがすべて削除されます。

例5: Pythonスクリプトによってドキュメント、フォルダ、イベントを生成する

次のスクリプトを見てください。

from Products.CMFCore.utils import getToolByName

urltool = getToolByName(context, "portal_url")
catalogtool = getToolByName(context, "portal_catalog")
portal = urltool.getPortalObject()
# create a document
doc = portal.invokeFactory("Document", "test_doc")
document = getattr(portal, "test_doc")
#document.setTitle("Test document")
#document.setDescription("This is the description of a test document")
document.editMetadata(title="Test document",
                      description="This is the description of a test document",
                      subject="")
document.edit(text_format="html",
              text="<b>This is a test document!<b>")

# create a folder
fld = portal.invokeFactory("Folder", "test_folder")
folder = getattr(portal, "test_folder")
folder.setTitle("My Folder")
folder.setDescription("This is the description of a test folder")
catalogtool.refreshCatalog()

# create an event
evt = folder.invokeFactory("Event", id="event")
event = getattr(folder, "event")
event.edit(title = "Foo",
           start_date="2003-09-18",
           end_date="2003-09-19",
           location="home",
           description="This is the description of a test event")
event.editMetadata(subject="Appointment")

上記のスクリプトで利用されているメソッドについて説明します。

  • editMetadata(self, obj, allowDiscussion=None, title=None, subject=None, description=None, contributors=None, effective_date=None, expiration_date=None, format=None, language=None, rights=None, **kwargs) これはCMFPlone.PloneTool.PloneToolクラスのメソッドです。
  • invokeFactory(self, type_name, id, RESPONSE=None, args, *kw) type_nameは生成しようとしているコンテンツタイプの名前です。これはlportal_typesツールにある名前と同じであることに注意してください(ただしPloneのユーザインターフェイスに表示される名前とは異なっている場合もあります)。 id は新しく生成しようとしているオブジェクトのIDです(オブジェクトのURLになります)。このメソッドはオブジェクトのコンストラクタメソッドに渡されるための引数もとることが可能です。一番よく使われるのはtitleです。
  • refreshCatalog(self, clear=0) このメソッドはself内部のオブジェクトを再インデクスします。

例6: Pythonスクリプトからドキュメントの状態を変更する

次のスクリプトを見てください。

from Products.CMFCore.utils import getToolByName

urltool = getToolByName(context, "portal_url")
portal  = urltool.getPortalObject()
document = getattr(portal, "my_document")
review_state = document.portal_workflow.getInfoFor(document, "review_state", "")
print "The initial state is: " + review_state + "\n"

if not review_state in ("rejected", "retracted", "private"):
    document.portal_workflow.doActionFor(document, "hide", comment="")
review_state = document.portal_workflow.getInfoFor(document, "review_state", "")
print "The final state is: " + review_state + "\n"
return printed

ここでは2つのメソッドがポイントとなります。

  • getInfoFor(self, ob, name, default=[], wf_id=None, args, *kw) CMFCore.WorkflowTool.WorkflowToolクラスのメソッドです。これはオブジェクトのワークフローに関係した特定のプロパティを返します。
  • doActionFor(self, ob, action, wf_id=None, args, *kw) Is a method from CMFCore.WorkflowTool.WorkflowToolクラスのメソッドです。これはオブジェクトのワークフローに対してactionを実行します。