文書操作
コンテンツオブジェクトの操作
コンテンツオブジェクトを生成・削除・修正する方法について学びます。
ポータルのコンテンツ(ドキュメント、画像、リンク、フォルダ、ニュース、ファイルなど)を保存しておくために、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
上記の例ではgetToolByNameやgetattrといった関数や、getPortalObject、TitleやCookedBodyといったメソッドを利用しています。少し詳しく見てみましょう。
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_formatはhtmlやstructured-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_copyObjectsやmanage_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を実行します。

