Block API
Обзор
Блоки в Drupal 8 на самом деле состоят из двух отдельных структур API, чтобы создать пользовательский интерфейс, аналогичный тому, который поддерживал Drupal на прошлых итерациях. Этими двумя API-интерфейсами являются Block Plugin API, который является автономным API для многократного использования, и Block Entity API, который является специфическим вариантом использования Drupal 8 для размещения блоков и контроля видимости.
Создание блоков Block Plugin API
Создание блоков, определенных в коде вашего модуля, требует изучения и понимания API плагинов и, в частности, обнаружения плагинов на основе аннотаций, который является механизмом, который Drupal 8 использует для поиска кода, который определяет ваш блок.
Создание пользовательского блока, определенного вашим модулем, включает следующие шаги:
- Создать блочный плагин, используя аннотации
- Расширьте класс Drupal\Core\Block\BlockBase.
- Реализуйте методы из интерфейса Drupal\Core\Block\BlockPluginInterface, необходимые для вашего варианта использования.
Сделайте ваш блок видимым для Drupal и ваших пользователей
Drupal использует стандарт PSR-4 для обнаружения. Предполагая имя модуля fax, код для вашего пользовательского блока (ов) должен быть помещен в fax/src/Plugin/Block/. Каждый файл в этом каталоге должен быть назван в соответствии с классом, который он содержит. Если мы собираемся определить класс FaxBlock, он должен находиться в файле с именем fax/src/Plugin/Block/FaxBlock.php и иметь содержимое в соответствии со следующим примером:
namespace Drupal\fax\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides a 'Fax' block.
*
* @Block(
* id = "fax_block",
* admin_label = @Translation("Fax block"),
* )
*/
class FaxBlock extends BlockBase {
// Override BlockPluginInterface methods here.
}
Свойство id в аннотации определяет уникальный машиночитаемый идентификатор вашего блока и имя блока, которое будет видно из другого кода. Аннотация 'admin_label' определяет удобочитаемое имя блока, которое будет использоваться при отображении вашего блока в интерфейсе администрирования. Доступные свойства аннотации можно найти в \Drupal\Core\Block\Annotation\Block (общедоступные свойства).
Два наиболее распространенных метода для переопределения:
- BlockPluginInterface::build() - который должен возвращать массив визуализации, определяющий содержимое, которое вы хотите, чтобы ваш блок отображал.
- BlockBase::access() - который контролирует видимость блока. Ожидается, что он вернет объект AccessResult.
Добавить пользовательские параметры конфигурации в свой блок
Вы также можете добавить пользовательские параметры конфигурации в форму конфигурации блока, переопределив методы BlockPluginInterface::blockForm() и BlockPluginInterface::blockSubmit(), а затем используя BlockBase::setConfigurationValue() и BlockBase::getConfiguration().
В следующем примере мы добавляем новое текстовое поле в наш метод blockForm(), а затем сохраняем предоставленные пользователем данные в методе blockSubmit(). Код демонстрирует, как значения могут быть получены при построении формы, проверены и обновлены с использованием соответствующих методов.
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Block\BlockPluginInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Cache\Cache;
/**
* Provides a 'Fax' block.
*
* @Block(
* id = "fax_block",
* admin_label = @Translation("Fax block"),
* )
*/
class FaxBlock extends BlockBase implements BlockPluginInterface {
// Access method here ...
/**
* {@inheritdoc}
*/
public function build() {
$config = $this->getConfiguration();
$fax_number = isset($config['fax_number']) ? $config['fax_number'] : '';
return array(
'#markup' => $this->t('The fax number is @number!', array('@number' => $fax_number)),
);
}
/**
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
$form = parent::blockForm($form, $form_state);
// Retrieve existing configuration for this block.
$config = $this->getConfiguration();
// Add a form field to the existing block configuration form.
$form['fax_number'] = array(
'#type' => 'textfield',
'#title' => t('Fax number'),
'#default_value' => isset($config['fax_number']) ? $config['fax_number'] : '',
);
return $form;
}
/**
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
// Save our custom settings when the form is submitted.
$this->setConfigurationValue('fax_number', $form_state->getValue('fax_number'));
}
/**
* {@inheritdoc}
*/
public function blockValidate($form, FormStateInterface $form_state) {
$fax_number = $form_state->getValue('fax_number');
if (!is_numeric($fax_number)) {
$form_state->setErrorByName('fax_number', t('Needs to be an integer'));
}
}
}
Вы также можете использовать метод BlockBase::getConfiguration() в методе build(), чтобы получить данные конфигурации и отобразить их своим пользователям. Метод access() вашего блока также может содержать более сложную логику, чтобы определить, должен ли блок отображаться.
Пример метода условия доступа.
/**
* {@inheritdoc}
*/
public function access(AccountInterface $account, $return_as_object = FALSE) {
return \Drupal\Core\Access\AccessResult::allowedIf($account->isAuthenticated());
}
Вы также можете создать свои собственные условия кэширования
Пример метода с использованием кеш-тегов. Узнайте больше о тегах кеша.
/**
* {@inheritdoc}
*/
public function getCacheTags() {
return \Drupal\Core\Cache\Cache::mergeTags(parent::getCacheTags(), ['node_list']);
}
Если вы хотите изменить максимальное время кэша блока на 0. Подробнее о максимальном возрасте кэша.
public function getCacheMaxAge() {
// If you want to disable caching for this block.
return 0;
}