9.9.1. Drupal での構成管理。コンテンツと構成のインポート。
ある サイトから別のサイトに構成をインポートするとき、コンテンツを出力するにはいくつかの構成が必要ですが、構成自体にはコンテンツが含まれていません。このチュートリアルでは、ブロック、ノード、タクソノミー用語をあるサイトから別のサイトに移す方法を説明します。
あるサイトでブロックを作成し、構成を別のサイトに移しましょう。あるサイトから別のサイトへ構成を移す方法は、前の記事 9.9. Drupal での構成の操作。Active、Sync 構成、DEV から LIVE への構成の移行 で見られます。Active、Sync 構成、DEV から LIVE への構成の移行。

次のようなエラーが表示されます:「This block is broken or missing. You may be missing content or you might need to enable the original module.」:

ブロックは特定の uuid を持つエンティティブロックを必要とします。UUID はエンティティの一意な識別子で、新しいサイトで同じコンテンツの同じブロックを作成しても、このブロックは構成に捕捉されません。というのも、新しいブロックは異なる UUID を持つからです。必要な UUID は、ブロックの構成で見られます:

ブロックの UUID を Config UUID と混同しないでください。実は、構成も Drupal ではエンティティですが、コンテンツエンティティであるブロックやノードとは異なり、構成は config エンティティです。次のレッスンの 1 つで、ContentEntity と ConfigEntity クラスを見ていきます。
これで、ブロックにどの UUID が必要か分かったので、正しい UUID でブロックをデプロイしたときに作成されるように、コードを通じてこのブロックを作成する必要があります。そのために hook_update_n() を使います:
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Extension%
hook_update_n() はカスタムモジュールの .install ファイルに追加する必要があります。更新がモジュールに拾われるように、モジュールは事前にサイトに追加され有効にされているべきです。各新しい hook_update_n() は、update.php を起動するか drush または drupal console を通じてデータベース更新を実行するときに実行されます。先頭の hook_ という単語だけを変える他のフックとは異なり、hook_update_n() では、各更新が独自のバージョンを持つように、末尾の n をより多く変える必要があります。通常、Drupal 8.x では 8000 以上、Drupal 7.x では 7000 以上の数字を使います。つまり、最初の桁が drupal カーネルのバージョンです。
/modules/custom/drupalbook/drupalbook.install:
/**
* Add simple block with text and image.
*/
function drupalbook_update_8001(&$sandbox) {
$uuid = 'dc0876cf-a242-4f4c-af0e-8a27fbe9e142';
$block = \Drupal::entityManager()->loadEntityByUuid('block_content', $uuid);
if (empty($block)) {
$block = \Drupal\block_content\Entity\BlockContent::create([
// Block title.
'info' => 'Simple text block with image',
// Block bundle.
'type' => 'basic',
'uuid' => 'dc0876cf-a242-4f4c-af0e-8a27fbe9e142'
]);
$block->body->value = 'Hello, World!';
$block->save();
}
}
次に、このコードを 2 番目のサイトに移し、そこで update.php ファイルを実行する必要があります:

Drupal がこの更新を見つけ、実行後にブロックが表示されます。
ブロックを作成するコードを見ると、ブロックを作成する前に、ブロックが存在することを確認しています。これは、ブロックがすでに存在するソースサイトを更新するときに、既存の UUID でブロックを作成できないというエラーが出ないようにするためです。
また、ブロックのテキストだけが移され、テキストにオンラインで読み込まれた画像は CKEditor の画像ブラウザを通じて移されない点に注意してください。というのも、ファイルは個別に移す必要があるからです。drush、ssh、ftp 経由でアップロードするか、git に入れることができます(1~2 個のファイルなら。それより多い場合は、画像ファイルで git を詰まらせないほうが良いです)。デプロイのプロセスはプロジェクトごとに異なり、どこでも異なるアプローチが使われるので、プロジェクトにはデプロイプロセスを記述した最低限のドキュメントがあることが重要です。
タクソノミー用語の作成についても同じことが当てはまります。構成では辞書設定とタクソノミー用語のフィールドだけを移し、タクソノミー用語自体は個別に作成すべきです。例えば、次のように:
\taxonomy\Entity\Term;
...
/**
* Create taxonomy term programmatically.
*/
function drupalbook_update_8002(&$sandbox) {
$term = Term::create([
'name' => 'Drupal 8',
'vid' => 'tags',
])->save();
}
vid フィールドには、タクソノミー辞書のマシン名(Vocabulary ID)を指定する必要があります。
ノードを作成するには、おおよそ次のコードを使う必要があります:
/**
* Create node programmatically.
*/
function drupalbook_update_8003(&$sandbox) {
$node = Node::create(['type' => 'page']);
$node->set('title', 'About us');
$body = [
'value' => 'Text about us',
'format' => 'basic_html',
];
$node->set('body', $body);
$node->status = 1;
$node->enforceIsNew();
$node->save();
}
おおよそ、というのも、set() の代わりに単に等号で書くこともできるからです:
= [
'value' => 'Text about us',
'format' => 'basic_html',
];
$node->set('body', $body);
// or
$node->body->format = 'basic_html';
$node->body->value = 'Text about us',
新しい hook_update_n() を追加するたびに、update.php を実行する必要があります。Acquia や自動デプロイ付きの他のホスティングを使っている場合は、このプロセスは自動化されているので、デプロイがどう行われるかを確認する必要があります。
コード例は github で見られます:
https://github.com/levmyshkin/drupalbook8