⚙️

Concrete CMS のテーマでコンテンツの入れ替えに対応する

に公開

コンテンツの入れ替えとは?

Concrete CMS の「コンテンツの入れ替え(Full Content Swap)」とは、テーマをインストールする際に、あらかじめ用意されたページ、ブロック、テーマ設定などのサンプルコンテンツを自動的にサイトに展開する仕組みです。これにより、ユーザーはテーマのデモサイトと同じ状態から編集を始めることができ、初期設定の手間を省けます。テーマ開発者は XML ファイルを用いて、インストール時に読み込まれるコンテンツの構造や内容を定義します。

特に、配布するテーマではコンテンツの入れ替えに対応すると、初期設定の手間が軽減されて利用者にとってはメリットが大きいでしょう。もしテーマを公式マーケットプレイスで販売する場合は、必須で対応することになっています。

この記事では、『Concrete CMS クイックスタートガイド』で解説した「Simple Company」テーマをもとに対応する手順として解説していきます。

https://zenn.dev/hissy/books/a27cc8e9a6d7f8

また、公式ドキュメントでも解説があります。ただ、少し内容が古いのと、説明が不足しているので、本記事ではその辺りを補足しながら解説します。

https://documentation.concretecms.org/developers/pages-themes/designing-for-concrete5/packaging-your-theme/enabling-full-content-swap

テーマのパッケージ化

まず、コンテンツの入れ替えに対応するには、テーマをパッケージ化する必要があります。

パッケージディレクトリへの移動

まず、元々は /application ディレクトリの中にあったテーマやブロックテンプレートを、パッケージディレクトリに移動する必要があります。
下記の表の通りに、テーマとブロックテンプレートを移動してください。

元のテーマ パッケージ化するための移動先
/application/themes/simple_company packages/theme_simple_company/themes/simple_company
/application/blocks/* /packages/theme_simple_company/themes/simple_company/blocks/*

パッケージコントローラーを作成

次に、パッケージコントローラーを作成します。下記の内容で、 /packages/theme_simple_company/controller.php を作成します。

<?php

namespace Concrete\Package\ThemeSimpleCompany;

use Concrete\Core\Package\Package;
use Concrete\Core\Page\Theme\Theme;

class Controller extends Package
{
    protected $pkgHandle = 'theme_simple_company';
    protected $appVersionRequired = '9.0.0';
    protected $pkgVersion = '1.0.0';

    public function getPackageName()
    {
        return t('Simple Company');
    }

    public function getPackageDescription()
    {
        return t('A simple theme for a company website.');
    }

    public function install()
    {
        $pkg = parent::install();

        $theme = Theme::getByHandle('simple_company');
        if (!$theme) {
            Theme::add('simple_company', $pkg);
        }

        return $pkg;
    }
}

パッケージコントローラーでは、パッケージのハンドル名、パッケージ名等の基本情報の設定と、パッケージインストール時に simple_company テーマをインストールする処理のみが含まれています。

パッケージコントローラー自体については『Concrete CMS 実践入門』でも解説していますので、詳しくお知りになりたい方はそちらも参照してください。

https://zenn.dev/hissy/books/e3750b3e398d84

page_theme.php の名前空間を変更

パッケージ直下に移動してきた /packages/theme_simple_company/themes/simple_company/page_theme.php の名前空間を修正する必要があります。元々は

<?php

namespace Application\Theme\SimpleCompany;

であった名前空間を

<?php

namespace Concrete\Package\ThemeSimpleCompany\Theme\SimpleCompany;

に変更します。

以上で、テーマのパッケージ化が完了しました。
管理画面からパッケージをインストールし、「Simple Company」テーマを有効にしてください。

サンプルコンテンツのインストールに対応

これまでの手順で配布可能なテーマとしての対応は完了していますが、ここからはサンプルコンテンツのインストールに対応していきましょう。

コンテンツを登録

インストールされたテーマを使って、サンプルサイトのコンテンツを完成させてください。

Migration Tool アドオンをインストール

コンテンツが完成したら、コンテンツをエクスポートするための「Migration Tool」アドオンをインストールしてください。

https://github.com/concretecms/migration_tool

出力バッチを作成

Migration Tool がインストールできたら、[管理画面>システムと設定>Migration Tool>Export Content]にアクセスしましょう。

次に「Add Batch」ボタンをクリックして、任意の名前で出力バッチを作成してください。

「Add Content to Batch」ボタンをクリックして、コンテンツの検索画面に移動しましょう。

「Choose Item Type」からコンテンツの種類を選んで「実行」ボタンをクリックしてから、作成したコンテンツを選んで「Add to Batch」ボタンをクリックして出力バッチに登録していきます。作成していない、CMSのインストール時に最初からあったものについては選択する必要はありません。『Concrete CMS クイックスタートガイド』で解説した「Simple Company」テーマの場合、コンテンツの種類は、下記のものをエクスポートする必要があります。

  • Trees
  • エクスプレスエンティティ
  • コンテナ
  • テーマ
  • ページ
  • 属性キー

全て登録できたら、「Back to Batch」ボタンをクリックして、バッチに登録されたコンテンツを確認しましょう。

必要なコンテンツが全て揃っていれば、「Export Batch」ボタンをクリックして出力画面に移動してください。

一覧表示されているファイルにチェックを入れて「Download Files」ボタンをクリックして、ファイルマネージャーにアップロードされているファイルをダウンロードしてください。

次に、パッケージディレクトリ( packages/theme_simple_company )直下に content_files ディレクトリを作成してください。
ダウンロードしたzipファイルを展開し、中身のファイルを作成した content_files ディレクトリに入れてください。

最後に、「Download XML」ボタンをクリックしてXMLファイルをダウンロードしましょう。
ダウンロードした export.xmlcontent.xml にリネームしてパッケージディレクトリ直下に入れてください。

パッケージコントローラーを変更

インストールすべきコンテンツとファイルを設置できたら、最後にパッケージコントローラーを一部変更します。

protected $pkgAllowsFullContentSwap = true; を追加するだけです。

<?php

namespace Concrete\Package\ThemeSimpleCompany;

use Concrete\Core\Package\Package;
use Concrete\Core\Page\Theme\Theme;

class Controller extends Package
{
    protected $pkgHandle = 'theme_simple_company';
    protected $appVersionRequired = '9.0.0';
    protected $pkgVersion = '1.0.0';
    protected $pkgAllowsFullContentSwap = true; // 追加

    public function getPackageName()
    {
        return t('Simple Company');
    }

    public function getPackageDescription()
    {
        return t('A simple theme for a company website.');
    }

    public function install()
    {
        $pkg = parent::install();

        $theme = Theme::getByHandle('simple_company');
        if (!$theme) {
            Theme::add('simple_company', $pkg);
        }

        return $pkg;
    }
}

エレメントファイルを作成

コンテンツの入れ替え時に、画面に表示する注意書きを設定することができます。パッケージディレクトリ内に elements/dashboard/install.php ファイルを作成すると、そのファイルが画面にインポートされます。この記事で紹介しているパッケージの場合は /packages/theme_simple_company/elements/dashboard/install.php になります。

公式ドキュメントには必須ファイルと書かれていますが、おそらく古い情報で、なくても問題ありません。

下記は、ファイルの一例です。

<?php defined('C5_EXECUTE') or die("Access Denied."); ?>

<div class="alert alert-danger">
    <?php  echo t('<strong>Attention!</strong> Clearing your site\'s content prior to installing this theme is highly recommended.')?>
</div>

実際に読み込まれた画面がこのようになります。

以上で、サンプルコンテンツのインストールへの対応が完了です。別のサイトにパッケージをアップロードして、インストールを試してみましょう。上記画面で「はい」を選択してインストールを行い、サイトのコンテンツが差し代わることを確認しましょう。

XMLファイルを修正

残念ながら、Migration ToolでエクスポートしたXMLファイルがそのまま使えれば良いのですが、エラーになる場合もあります。

エラーが出た場合は、XMLファイルを修正する必要があります。例えば、次のようなXMLでエラーが出る場合があります。

<?xml version="1.0" encoding="UTF-8"?>
<concrete5-cif version="1.0">
  <trees>
    <tree type="topic" name="News Category" default="1">
      <topic name="Category A"/>
      <topic name="Category B"/>
      <topic name="Category C"/>
    </tree>
  </trees>

このXMLの場合、 default="1" を取り除くとうまくいきます。

他にも、下記のようなSQLエラーが出る場合があります。

Doctrine\DBAL\Exception\DriverException:
An exception occurred while executing 'INSERT INTO btAccordion (bID, initialState, itemHeadingFormat, alwaysOpen, flush) VALUES (?, ?, ?, ?, ?)' with params [37, "openfirst", "h2", "", ""]:

SQLSTATE[HY000]: General error: 1366 Incorrect integer value: '' for column 'alwaysOpen' at row 1

btAccordion テーブルの alwaysOpen フィールドへ挿入しようとしている値が数値でないことによるエラーです。

XMLの <alwaysOpen/><alwaysOpen>0</alwaysOpen> に置換することで、値が数値となり、エラーを回避することができます。

これら以外にもエラーが出る可能性がありますが、基本的にはMigration Toolでエクスポートしたデータがそのままインポートできないのはコアのバグと考えて差し支えないです。見つけた方は、もし可能であれば Concrete CMS の公式GitHubリポジトリにIssueを立てて報告していただけると嬉しいです。

まとめ

本記事では、Concrete CMS のテーマにおいて「コンテンツの入れ替え(Full Content Swap)」に対応するための手順を、テーマのパッケージ化からサンプルコンテンツの作成、エクスポート、インストール処理の調整に至るまで詳しく解説しました。この機能を活用することで、テーマの利用者はデモサイトと同じ状態から編集を始められ、初期設定の手間を大きく削減できます。特にテーマを配布・販売する場合には、ユーザーの利便性を高めるためにも積極的に対応することが推奨されます。Migration Tool の出力に起因するインポートエラーへの対処法も紹介しましたので、スムーズな導入の参考にしていただければ幸いです。

Discussion