DRUPAL8模块开发 - DRUPAL8注册LAYOUTS(三)

翻译者:长风Drupal开发: DRUPAL8注册LAYOUTS

原文链接:https://www.drupal.org/docs/8/api/layout-api/how-to-register-layouts

DRUPAL8注册LAYOUTS,添加一个可以修改的class

DRUPAL8注册LAYOUTS,到目前为止,我们还很少写PHP代码,下面给一个例子,用于在layout中添加一个CSS的class类。
namespace Drupal\my_custom_module;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Layout\LayoutDefault;
use Drupal\Core\Plugin\PluginFormInterface;

class MyLayoutClass extends LayoutDefault implements PluginFormInterface {

/**
 * {@inheritdoc}
 */
public function defaultConfiguration() {
return parent::defaultConfiguration() + [
'extra_classes' => 'Default',
];
}

/**
 * {@inheritdoc}
 */
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$configuration = $this->getConfiguration();
$form['extra_classes'] = [
'#type' => 'textfield',
'#title' => $this->t('Extra classes'),
'#default_value' => $configuration['extra_classes'],
];
return $form;
}

/**
 * @inheritdoc
 */
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
// any additional form validation that is required
}

/**
 * {@inheritdoc}
 */
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$this->configuration['extra_classes'] = $form_state->getValue('extra_classes');
}

}

在*.layouts.yml文件中,你可以这样使用。
advanced_layout_3:
label: Advanced Layout 3
category: My Layouts
class: '\Drupal\my_custom_module\MyLayoutClass'
template: templates/advanced-layout-3
library: my_custom_module/advanced-layout-library
regions:
main:
label: Main content

DRUPAL8注册LAYOUTS后,在你的twig模板中,你可以这样输出我们刚刚定义的变量{{ settings.extra_classes }},在templates/advanced-layout-3.html.twig中,你可以这样编写Drupal8的代码。

<div class="my-advanced-layout {{ settings.extra_classes }}">
<div class="main-region">
{{ content.main }}
</div>
</div>

在Drupal8中使用PHP的类的注释来注册layout

在上面所有的例子中,我们都使用*.layouts.yml 文件来注册layout,这是最容易的定义layout的方法。下面我们介绍在Drupal8中使用PHP的类的注释来注册layout,为了达到这个目的,你需要把上面的注册layout的代码放在一个@layout的注释中,如下:
/src/Plugin/Layout/AdvancedLayout4.php

namespace Drupal\my_custom_module\Plugin\Layout;

use Drupal\Core\Layout\LayoutDefault;

/**
 * A very advanced custom layout.
 *
 * @Layout(
 * id = "advanced_layout_4",
 * label = @Translation("Advanced Layout 4"),
 * category = @Translation("My Layouts"),
 * template = "templates/advanced-layout-4",
 * library = "my_custom_module/advanced-layout-library",
 * regions = {
 * "main" = {
 * "label" = @Translation("Main content"),
 * }
 * }
 * )
 */
class AdvancedLayout4 extends LayoutDefault {
// Override any methods you'd like to customize here!
}

使用derivatives注册动态的layouts

第一步,注册一个layout class,例如:
namespace Drupal\my_custom_module\Plugin\Layout;

use Drupal\Core\Layout\LayoutDefault;

/**
 * A layout from our flexible layout builder.
 *
 * @Layout(
 * id = "flexible_layout",
 * deriver = "Drupal\my_custom_module\Plugin\Deriver\FlexibleLayoutDeriver"
 * )
 */
class FlexibleLayout extends LayoutDefault {

/**
 * {@inheritdoc}
 */
public function build(array $regions) {
$render_array = parent::build($regions);
// Since this is a flexible layout builder, you probably need to do
// something special to render the layout, so we override the ::build()
// method which is responsible for creating a render array.
return $render_array;
} }


注意在注释中的layout是没有完成的,(比如缺少一些必要的注册layout的关键字),并且包括一个deriver 字段。
当使用这种方法定义layouts的时候,除非你可以指向一个特定的”templat“或者"theme",你估计需要重写layout的::build()方法,用来提供自定义的代码渲染layout。
下面是一个例子

namespace Drupal\my_custom_module\Plugin\Deriver;

use Drupal\Component\Plugin\Derivative\DeriverBase;
use Drupal\Core\Layout\LayoutDefault;
use Drupal\Core\Layout\LayoutDefinition;

/**
 * Makes a flexible layout for each layout config entity.
 */
class FlexibleLayoutDeriver extends DeriverBase {

/**
 * {@inheritdoc}
 */
public function getDerivativeDefinitions($base_plugin_definition) {
// Here we need to magically get a list of the config entities.
// I leave this as an exercise for the reader. :-)
$config_entities = [];

// Now we loop over them and declare the derivatives.
foreach ($config_entities as $entity) {
// Here we fill in any missing keys on the layout annotation.
$this->derivatives[$entity->id()] = new LayoutDefinition([
'class' => FlexibleLayout::class,
'label' => $entity->label(),
'category' => $entity->getCategory(),
'regions' => $entity->getRegions(),
]);
}

return $this->derivatives;
}

}
备注:DRUPAL8注册LAYOUTS的所有方法中,注册动态的Layout只能在一个模块中进行,在drupal8 的theme中是不能使用PHP的类的注释来定义插件的。 

DRUPAL8注册LAYOUTS的所有字段:

label
layout 的可读名字
category
layout所属的可读的分类
regions
region的数组,关键字是region的机器名字
label (required): region的可读名字
theme
一般可以不用写。
template
用来指定模板文件的文件名,不包括扩展名 .html.twig ,如果使用这个字段,就不能再使用theme字段了。
default_region
默认的regin的机器名字
icon_map
layout的可视化结构
description
layout的可选描述
path
ico或者模板文件的路径。
library
要加入的labrary的名字
如:library: MY_MODULE_OR_THEME/advanced-layout-library