9.9.1. Drupal 中的配置管理。导入内容和配置。
当你将配置从一个站点导入到另一个站点时,有些配置需要输出内容,但配置内容本身不包含任何内容。在本教程中,我们将解释如何将区块、节点和分类术语从一个站点转移到另一个站点。
让我们在一个站点上创建一个区块,并将配置转移到另一个站点,你可以在上一篇文章中查看如何将配置从一个站点转移到另一个站点:9.9. 在 Drupal 中使用配置。激活、同步配置,从 DEV 到 LIVE 迁移配置。 激活、同步配置,从 DEV 到 LIVE 的配置迁移。
你会看到这样一个错误:“此区块已损坏或丢失。你可能缺少内容,或者需要启用原始模块。”:
该区块需要一个具有特定 UUID 的实体区块。UUID 是实体的唯一标识符,即使我们在新站点上创建相同内容的区块,配置也不会捕捉到这个区块,因为新区块会有不同的 UUID。你可以在区块的配置中看到所需的 UUID:
不要将区块的 UUID 与配置的 UUID 混淆。问题在于,配置也是 Drupal 中的一种实体,但与区块和节点(内容实体)不同,配置是配置实体。在接下来的课程中,我们将查看 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_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();
}
}
现在你需要将此代码转移到第二个站点,并在该站点运行 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 字段中,你需要指定词典的机器名称(词汇 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);
// 或者
$node->body->format = 'basic_html';
$node->body->value = 'Text about us',
每次添加新的 hook_update_n() 时,你需要运行 update.php。如果你使用 Acquia 或其他自动部署的主机,则此过程是自动化的,你需要明确了解部署将如何进行。
代码示例可以在 GitHub 上查看:
https://github.com/levmyshkin/drupalbook8