Рейтинг:0

Как расширить класс основного блока SystemBrandingBlock

флаг ph

Пожалуйста, посоветуйте, как мы можем расширить класс основного блока Drupal\system\Plugin\Block\SystemBrandingBlock, чтобы добавить пользовательский метод.

В моем случае я хочу включить функцию buildToArray(), чтобы получить данные блока в формате массива, а не отображаемого массива.

Существующий метод build():

общедоступная функция сборки () {
    $сборка = [];
    $site_config = $this->configFactory->get('system.site');

    $сборка['сайт_лого'] = [
      '#тема' => 'изображение',
      '#uri' => theme_get_setting('logo.url'),
      '#alt' => $this->t('Дом'),
      '#access' => $this->configuration['use_site_logo'],
    ];

    $сборка['имя_сайта'] = [
      '#markup' => $site_config->получить('имя'),
      '#access' => $this->configuration['use_site_name'],
    ];

    $build['site_slogan'] = [
      '#markup' => $site_config->get('slogan'),
      '#access' => $this->configuration['use_site_slogan'],
    ];

    вернуть $сборку;
}

Необходимый метод для добавления:

общедоступная функция buildToArray() {
    $site_config = $this->configFactory->get('system.site');

    возвращаться [
      'site_logo' => theme_get_setting('logo.url'),
      'имя_сайта' => $site_config->получить('имя'),
      'site_slogan' => $this->configuration['use_site_slogan'],
    ];
}
флаг in
Привет и добро пожаловать в Drupal Answers! Не могли бы вы описать, что вы пробовали, что не сработало, и опубликовать соответствующий код?
флаг ph
@Beau Спасибо за ваш комментарий. Я обновил вопрос, сделав его более конкретным.
Рейтинг:0
флаг gb

Если вы используете Drupal 9 и не хотите создавать дублирование блоков, вот самый простой способ переопределить класс блока: Чтобы переопределить класс Block, вы можете использовать hook_block_alter как это.

/**
 * Реализует hook_block_alter().
 */
функция [МОДУЛЬ]_block_alter(&$определения) {
  foreach ($определения как $id => $definition) {
    // Проверьте идентификатор вашего плагина здесь.
    если ($id === 'system_branding_block') {
      // Установите здесь новый класс.
      $definitions[$id]['class'] = 'Drupal\MODULE\Plugin\Block\SystemBrandingBlockAlter';
    }
  }
}

А затем создайте свой новый класс СистемаБрендингБлокАльтер в МОДУЛЬ/src/Плагин/Блок как это:

<?php

пространство имен Drupal\MODULE\Plugin\Block;

используйте Drupal\system\Plugin\Block\SystemBrandingBlock;

класс SystemBrandingBlockAlter расширяет SystemBrandingBlock {
  
  общедоступная функция сборки () {
    $site_config = $this->configFactory->get('system.site');
    возвращаться [
      'site_logo' => theme_get_setting('logo.url'),
      'имя_сайта' => $site_config->получить('имя'),
      'site_slogan' => $this->configuration['use_site_slogan'],
    ];
  }
  
}

Теперь ответственный класс для вашего блока Drupal\MODULE\Plugin\Block\SystemBrandingBlockAlter и нет Drupal\system\Plugin\Block\SystemBrandingBlock

флаг ph
Спасибо большое. Это именно то, что я ищу.
флаг ph
В массиве определений мы можем видеть «поставщик» => «система», но мы переопределим класс блока из нашего пользовательского модуля. Окажет ли это какое-то влияние?
berramou avatar
флаг gb
если вы проверите `'provider' == 'system'`, вы переопределите все классы блоков, созданные системным модулем, а не только SystemBrandingBlock
Рейтинг:0
флаг in

Расширение блока

Чтобы расширить блок, вы определите новый блок, как описано в следующем руководстве, за исключением того, что вы расширите класс Drupal\system\Plugin\Block\SystemBrandingBlock, вместо класса Друпал\Ядро\Блок\БлокБасе. Затем вы можете добавить свой пользовательский метод во вновь определенный блок.

https://www.valuebound.com/resources/blog/drupal-8-how-to-create-a-custom-block-programmatically

Альтернативное рассмотрение

Если то, что вам нужно от СистемаБрендингБлок это просто данные, и не обязательно фактический блок, я бы посоветовал вместо этого определить оказание услуг который предоставляет данные из вашего построить массив () метод.

Ответы на комментарии

Это правда, что это создаст новый тип блока, в дополнение к СистемаБрендингБлок. Блоки управляются, организуются и извлекаются Менеджер плагинов блоков. Вы можете написать декоратор для этой службы и переопределить получитьопределения() способ предотвращения исходного СистемаБрендингБлок быть доступным в качестве определения плагина, достигая эффекта замены оригинального СистемаБрендингБлок с вашим новым блоком.

Мне все еще кажется, что услуга - это то, что вам нужно. Изучив код в оригинале СистемаБрендингБлок определение класса, мы видим, что СистемаБрендингБлок опирается только на одну службу, config.factory. Таким образом, вашему сервису нужно только ввести config.factory службы, чтобы получить информацию, необходимую для построить массив () метод (который может быть лучше переименован как что-то вроде получить информацию о брендинге ()). Определение службы таким образом означает, что вам не нужно беспокоиться о реализации или развертывании блока (что в любом случае не похоже на то, что вам нужно) или необходимости писать декоратор службы.

Имейте также в виду, что SystemBrandingBlock — это не исходный источник данных, а скорее плагин для отображения этих данных в представленном формате. Блок совершенно не имеет значения, если вам нужны только данные.

Наконец, говоря в более широком смысле, Drupal организован в основном вокруг плагинов, сервисов и внедрения зависимостей, и знакомство с этими концепциями даст вам инструменты для систематического решения многих проблем в Drupal.

флаг ph
Спасибо вам за ваши предложения.
флаг ph
Я хочу расширить все доступные блоки. Первый подход «Расширение блока» приводит к дублированию блоков. Второй подход «Из службы». Я не мог получить доступ к защищенным свойствам блока, поэтому мне нужно реализовать логику этого блока в службе.
флаг ph
ваш ответ дал мне другую точку зрения. Спасибо
флаг ph
Насколько я понимаю, мы можем переопределить блоки с помощью hook_block_alter и декоратора плагина. Я ясно насчет крючка. Не могли бы вы привести пример плагина декоратора для блока. Это поможет многим, так как нет надлежащей документации по декоратору плагинов.
флаг in
В Drupal все типы плагинов управляются менеджером плагинов, который является службой. Декоратор плагинов на самом деле является сервисным декоратором для менеджера плагинов. Вот отличное руководство по декораторам сервисов Drupal 8: https://www.phase2technology.com/blog/using-symfony-service-decorators-drupal-8. В вашем случае вы захотите украсить службу, идентификатор которой — «plugin.manager.block». Но я по-прежнему считаю, что собственная служба — это то, что вам действительно нужно, и она потребует меньше усилий.
флаг ph
Спасибо @Beau

Ответить или комментировать

Большинство людей не понимают, что склонность к познанию нового открывает путь к обучению и улучшает межличностные связи. В исследованиях Элисон, например, хотя люди могли точно вспомнить, сколько вопросов было задано в их разговорах, они не чувствовали интуитивно связи между вопросами и симпатиями. В четырех исследованиях, в которых участники сами участвовали в разговорах или читали стенограммы чужих разговоров, люди, как правило, не осознавали, что задаваемый вопрос повлияет — или повлиял — на уровень дружбы между собеседниками.