説明
GenericSetup はアドオンプロダクトのインストールとアンインストール時に Plone サイトのデータベースを変更するためのフレームワークです。 サイトの設定を簡単に変更するための XML に基づくルールを規定します。
GenericSetup は Plone サイトに構成をインポートまたはエクスポートするための XML に基づいた方法です。
アドオンプロダクトが Plone サイトのデータベースに対して行う、以下のような事前処理に主に使用されます。
サイトの構成にアドオン特有の変更を適用したり、アドオンのインストールの実行時に特有の処理を有効にするためにために GenericSetup は最も使用されます。
GenericSetup の XML ファイルは通常アドオンプロダクトの profiles/default フォルダ以下に配置されます。
/@@manage-viewlets ページで表示される viewlet の一覧のように、全ての実行時に変更可能なアイテムは GenericSetup プロファイルのファイルを使用して繰り返し変更が可能です。
GenericSetup プロファイルのファイルを手で編集する必要はありません。 Plone または ZMI(Zope Management Interface)を通して構成のオプションを常に変更することが可能です。 そして、 ZMI にある porta_setup ツールの Export タブを使用して、プロファイルとなる XML ファイルを生成します。
Zope の再起動後でも、直接編集した XML プロファイルのファイルはサイトに対してなにも変更しません。 これは実行時の構成変更したアイテムはデータベースに保存されているためです。 プロファイルのファイルを編集した場合は、 編集したファイルを portal_setup で再インポートするか、Plone のコントロールパネルでアドオンプロダクトを再インストールする必要があります。 インポートを実行すると XML ファイルが読み込まれ Plone のデータベースが変更されます。
ノート
ZCML と GenericSetup の違い
ZCML は Zope の中の 全ての サイト中の Python コードに読み込まれて影響を与えます。 GenericSetup の XML ファイルは Plone サイトとそのデータベースに対してのみ影響を与えます。 GenericSetup の XML ファイルは常にデータベースを変更します。
ZCML と サイト特有の振るまいの関係は、通常 レイヤー を使用して実現されます。 viewlets と views のような ZCML のディレクティブは レイヤー 属性を使用してい特定のレイヤーでのみ有効に登録されます。 GenericSetup XML が portal_setup でインポートされたとき、またはアドオンプロダクトのインストーラーが Plone サイトで実行されたとき、レイヤーはこのサイトでのみ有効になり全ての view はこのレイヤーに登録されます。
<genericsetup> ディレクティブをアドオンプロダクトの configure.zcml で使用します。 “default” という名前のプロファイルは Plone のアドオンインストーラーがデフォルトのプロファイルとして実行します。 ユニットテストなどのために他のプロファイルを使用したい場合は、明確に宣言する必要があります。
プロファイルの XML ファイルはアドオンプロダクトの profiles/default フォルダに配置します。
<configure
xmlns="http://namespaces.zope.org/zope"
xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
i18n_domain="gomobile.mobile">
<genericsetup:registerProfile
name="default"
title="Plone Go Mobile"
directory="profiles/default"
description='Mobile CMS add-on'
provides="Products.GenericSetup.interfaces.EXTENSION"
/>
</configure>
アドオンプロダクトは以下を含んでいるかもしれません。
特殊なインポート手順については以下を参照してください。
例:
# Run the default quick installer profile
setup_tool = self.portal.portal_setup
profiles = setup_tool.listProfileInfo()
for profile in profiles:
print str(profile)
結果:
{'product': 'PluggableAuthService', 'description': 'Content for an empty PAS (plugins registry only).', 'for': <InterfaceClass Products.PluggableAuthService.interfaces.authservice.IPluggableAuthService>, 'title': 'Empty PAS Content Profile', 'version': 'PluggableAuthService-1.5.3', 'path': 'profiles/empty', 'type': 1, 'id': 'PluggableAuthService:empty'}
{'product': 'Products.CMFDefault', 'description': u'Profile for a default CMFSite.', 'for': <InterfaceClass Products.CMFCore.interfaces._content.ISiteRoot>, 'title': u'CMFDefault Site', 'version': 'CMF-2.1.1', 'path': u'profiles/default', 'type': 1, 'id': u'Products.CMFDefault:default'}
{'product': 'Products.CMFPlone', 'description': u'Profile for a default Plone.', 'for': <InterfaceClass Products.CMFPlone.interfaces.siteroot.IPloneSiteRoot>, 'title': u'Plone Site', 'version': u'3.1.7', 'path': u'/home/moo/sits/parts/plone/CMFPlone/profiles/default', 'type': 1, 'id': u'Products.CMFPlone:plone'}
{'product': 'Products.Archetypes', 'description': u'Extension profile for default Archetypes setup.', 'for': None, 'title': u'Archetypes', 'version': u'1.5.7', 'path': u'/home/moo/sits/parts/plone/Archetypes/profiles/default', 'type': 2, 'id': u'Products.Archetypes:Archetypes'}
...
これはどのようにユニットテストのために特定のアドオンを有効にするかという、ユニットテスト特有の問題です。
Running add-on installers and extensions profiles for unit tests を参照してください。
基本的な情報は http://plone.org/documentation/kb/genericsetup/creating-an-uninstall-profile を参照してください。
例としては collective.pdfpeek のソースコード を参照してください。
GenericSetup プロファイルは他のプロダクトのプロファイル(そしてインストーラー)との依存関係を含むことが可能です。
例としてあなたの作成するアドオンプロダクトが collective.basket プロダクトに対しての依存関係がある場合に、以下のように宣言するとプロダクトのインストール時に自動的に関連プロダクトがインストールされます。 このようにすると、アドオンプロダクトから collective.basket プロダクトのレイヤ、ポートレットやその他の必要な全ての機能を必ず使用できます。
<?xml version="1.0"?>
<metadata>
<!-- We do not declare <version> here because Plone 3.3+ picks the version from setup.py file -->
<dependencies>
<dependency>profile-collective.basket:default</dependency>
</dependencies>
</metadata>
configure.zcml の中で collective.basket のプロファイルを宣言します。
<genericsetup:registerProfile
name="default"
title="collective.basket"
directory="profiles/default"
description='Collector portlet framework'
provides="Products.GenericSetup.interfaces.EXTENSION"
/>
ノート
一部の情報はキャッシュによって変更がすぐに反映されません。 そのため metadata.xml を編集した場合は Plone を再起動する必要があります。
プロダクトのバージョンを X から Y にアップグレードするときにだけ実行するような、アップグレードの手順を定義できます。
例として、YOUR.PRODUCT のバージョン 1.2 では MyType コンテントタイプの price フィールドが文字列(string)で定義されており、以前(バージョン 1.1 より前)は浮動小数点(float)だったとします。 アップグレード後にこのフィールドが浮動小数点のままだと異常が発生するため、自動的にフィールドの既存の値を文字列に変換する必要があります。
アップグレード手順をプロファイルに追加します。:
<genericsetup:upgradeStep
title="Convert Price to strings"
description="Price was previously a float field, it should be converted to string"
source="*"
destination="1.2"
handler="YOUR.PRODUCT.setuphandlers.convert_price_to_string"
sortkey="1"
profile="YOUR.PRODUCT:default"
/>
アップグレード手順のコードは setuphandlers.py の中に記述されます。:
def convert_price_to_string(context, logger=None):
"""Method to convert float Price fields to string.
When called from the import_various method, 'context' is
the plone site and 'logger' is the portal_setup logger.
But this method will be used as upgrade step, in which case 'context'
will be portal_setup and 'logger' will be None.
"""
if logger is None:
# Called as upgrade step: define our own logger.
logger = logging.getLogger('YOUR.PRODUCT')
# Run the catalog.xml step as that may have defined new metadata
# columns. We could instead add <depends name="catalog"/> to
# the registration of our import step in zcml, but doing it in
# code makes this method usable as upgrade step as well.
# Remove these lines when you have no catalog.xml file.
setup = getToolByName(context, 'portal_setup')
setup.runImportStepFromProfile(PROFILE_ID, 'catalog')
catalog = getToolByName(context, 'portal_catalog')
brains = catalog(portal_type='MyType')
count = 0
for brain in brains:
current_price = brain.getPrice
if type(current_price) != type('a string'):
voorstelling = brain.getObject()
voorstelling.setPrice(str(current_price))
voorstelling.reindexObject()
count = count + 1
setup.runImportStepFromProfile(PROFILE_ID, 'catalog')
logger.info("%s fields converted." % count)
Zope の再起動後、ZMI の portal_setup ツールの Upgrades タブに、作成したアップグレード手順が表示されます。 プロダクトのプロファイルを選択すると、Zope がそのプロダクトについて認識しているアップグレード手順を確認できます。
この現象は、アドオンプロダクトを開発して変更を続けているときに発生することがあります。 アドオンプロダクトの ZCML コードにエラーがあることが、 portal_quickinstaller はプロダクトを2回登録する原因となります。
詳細な情報は以下を参照してください。