GenericSetup とプロファイル

説明

GenericSetup はアドオンプロダクトのインストールとアンインストール時に Plone サイトのデータベースを変更するためのフレームワークです。 サイトの設定を簡単に変更するための XML に基づくルールを規定します。

はじめに

GenericSetup は Plone サイトに構成をインポートまたはエクスポートするための XML に基づいた方法です。

アドオンプロダクトが Plone サイトのデータベースに対して行う、以下のような事前処理に主に使用されます。

  • CSS ファイルを登録
  • Javascript ファイルの登録
  • 各種プロパティの設定
  • ポートレットの登録
  • portal_catalog への検索問い合わせ用インデックスの登録
  • その他

サイトの構成にアドオン特有の変更を適用したり、アドオンのインストールの実行時に特有の処理を有効にするためにために 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>

アドオン特有の問題

アドオンプロダクトは以下を含んでいるかもしれません。

  • プロダクトをインストーラーからインスロールするときに自動的に実行されるデフォルトの GenericSetup XML プロファイル。プロファイルの名前は “default” になります。
  • portal_setup でのインポートまたはユニットテストのために手動で有効化される他のプロファイル。
  • “Import various” 手順という GenericSetup XML プロファイルのインストール時に毎回実行される python コード。

特殊なインポート手順については以下を参照してください。

有効なプロファイルの一覧

例:

# 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'}
...

プロファイルをインストールする

これはどのようにユニットテストのために特定のアドオンを有効にするかという、ユニットテスト特有の問題です。

PloneTestCase.setupPloneSite

Running add-on installers and extensions profiles for unit tests を参照してください。

手動で行う

特定のテストで必要となるために、プロファイルを手動でインストールしたい場合があります。

プロファイル名は profile-${product name}:${profile id} という書式になります。

ユニットテストの例です。:

# Run the extended profile which will create email_catalog
setup_tool.runAllImportStepsFromProfile('profile-betahaus.emaillogin:exdended')

依存関係

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"
    />
  • source にはアップグレード前のバージョンをワイルドカードを使用指定できます。 バージョン番号で指定された特定のバージョンに対してのみ、アップグレード手順が実行されます。
  • softkey にはアップーグレードを実行する順番を指定するために使用できます。

アップグレード手順のコードは 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 がそのプロダクトについて認識しているアップグレード手順を確認できます。

アドオンプロダクトがインストールの一覧に2度表示される

この現象は、アドオンプロダクトを開発して変更を続けているときに発生することがあります。 アドオンプロダクトの ZCML コードにエラーがあることが、 portal_quickinstaller はプロダクトを2回登録する原因となります。

詳細な情報は以下を参照してください。