Как программно разместить блок?

10

Из пользовательского интерфейса вы можете добавить блок в регион следующим образом:

  1. Зайдите в Админ -> Структура -> Блок макета (/ admin / структура / блок).
  2. Нажмите на кнопку «Поместить блок» рядом с названием региона.

Я хочу сделать то же самое, но программно. Как добавить существующий блок в регион и сохранить его? Затем этот блок должен отображаться в этом регионе и быть доступным на странице макета блока .

user3554770
источник
После создания блока вы можете изменить положение блока из: site_name / admin / structure / block
Crazyrubixfan
Я предполагаю, что вы опечатали "назначить блок региону".
cilefen
@IcecreamJelly То, что я пытаюсь сделать, это сделать это программно. cilefen, да, это то, что я имею в виду% -)
jmzea
@ShawnConn спасибо, это похоже, но не совсем то же самое. Я нашел ответ где-то еще.
августа

Ответы:

9

Чтобы предоставить блок плагина, вы можете создать массив настроек и передать его \Drupal\block\Entity\Block::create()для создания объекта Block и сохранения экземпляра.

Например, если вы хотите добавить PHP- блок Devel Execute в тему Seven:

$values = array(
  // A unique ID for the block instance.
  'id' => 'devel_execute_php_1',
  // The plugin block id as defined in the class.
  'plugin' => 'devel_execute_php',
  // The machine name of the theme region.
  'region' => 'content',
  'settings' => array(
    'label' => 'Execute PHP',
  ),
  // The machine name of the theme.  
  'theme' => 'seven',
  'visibility' => array(),
  'weight' => 100,
);
$block = \Drupal\block\Entity\Block::create($values);
$block->save();
Шон Конн
источник
Привет, мне нужна помощь. Я создал пользовательский блок с помощью пользовательского интерфейса и хочу разместить его в нижнем колонтитуле программно для целей тестирования. Я не знаю, как получить плагин из пользовательских блоков, созданных пользовательским интерфейсом .. спасибо
Мудассар Али
Задайте это как еще один вопрос. Комментарии не для того, чтобы задавать вопросы.
Шон Конн
его уже там. drupal.stackexchange.com/questions/207042/…
Мудассар Али
Какой здесь идентификатор ? это так же, как имя блока?
Crazyrubixfan
@RubberDuckIsKing Я считаю, что вы можете назвать idвсе, что вы хотите, если оно уникально. Например, вы можете запустить его с именем модуля его в.
Параг
7

Вы можете использовать модуль настройки Twig :

Модуль Twig Tweak предоставляет расширение Twig с некоторыми полезными функциями и фильтрами, которые могут улучшить опыт разработчика.

И затем на вашей области шаблона ветки:

{{ drupal_block('block_id') }}
rpayanm
источник
Проблема с этим решением состоит в том, что настройки ветки все еще требуют, чтобы вы поместили блок и затем «отключили» его.
лексикант
6

Каждый экземпляр блока (который «блок типа», конфигурации и размещения) является конфигурация лицо: \Drupal\block\Entity\Block. Поэтому все, что вам нужно сделать, это создать новый экземпляр этой сущности с правильными деталями, и все готово.

Это можно сделать, но это безумно сложно, вам нужно понять систему плагинов, систему блоков плагинов и многое другое.

Вы можете посмотреть, \Drupal\block\BlockForm::submitFormчтобы почувствовать это или \Drupal\simpletest\BlockCreationTrait::placeBlock. Вы можете подумать, если это то, что вам действительно нужно, видимость блока довольно сложна.

googletorp
источник
4
Не считая условий видимости, я не думаю, что это так сложно. \ Drupal \ simpletest \ BlockCreationTrait :: placeBlock (), вероятно, является лучшим примером для просмотра, вы также можете просто импортировать некоторые экспортированные файлы конфигурации.
Бердир
@Berdir Спасибо за ссылку на тестовую черту, добавил ее. Поскольку Drupal 8 еще очень молод, многие люди не очень много знают о системе плагинов, и документация может использовать больше вариантов использования и т. Д., Что может затруднить работу многих разработчиков.
googletorp
У Феликса Ева лучший ответ. Это не безумный комплекс.
Кратос
@kratos Ответ, который дал Феликс, на самом деле не решает вопрос о том, как разместить блок «программно», а использует конфигурационные файлы. Конфиг можно импортировать только через drush, интерфейс синхронизации конфигурации или установку модуля. Если это должно произойти, во время выполнения, после сохранения файла FX типа узла главной страницы и т. Д., Было бы бесполезно использовать эту стратегию :)
googletorp
4

Я только изучаю D8, но мне кажется, что я нашел гораздо более простой способ программно разместить блок (это показалось довольно пугающим после прочтения ответа googletorp!)

Когда я включил свой пользовательский модуль, который определил блок, я хотел, чтобы блок автоматически помещался в правильную область. Шаги, которые я использовал для достижения этой цели:

  1. Включите модуль и разместите блок с помощью пользовательского интерфейса в /admin/structure/block
  2. Перейдите на страницу экспорта конфигурации Single Item по адресу admin/config/development/configuration/single/export
  3. Выберите тип блока конфигурации и в качестве имени конфигурации выберите блок, который вы только что разместили с помощью пользовательского интерфейса, а затем скопируйте сгенерированный код.
  4. В вашем модуле создайте папку /config/install/
  5. Под сгенерированным кодом textarea он сообщает вам имя файла, которое вам нужно использовать. Создайте этот файл в /config/installкаталоге и скопируйте туда код.
  6. Теперь, когда вы удалите модуль и затем включите его, блок будет автоматически размещен.
Феликс Ева
источник
Разве вам не придется удалять UUID, чтобы это работало для других разработчиков или сред?
powpow12
Да - удаление UUID было бы хорошей идеей.
Феликс Ив
Вы также можете использовать консоль Drupal, которая занимается автоматизацией некоторых из этих задач: hechoendrupal.gitbooks.io/drupal-console/content/en/commands/…
Бо
2

Приведенный выше пример достаточно близок, но все еще не верен. Идея состоит в том, что вы должны придумать свой собственный идентификатор экземпляра блока (в моем случае devel_execute_php_1112 (возможно, потому что я пытался заставить его работать 1112 раз, он останется загадкой)), а затем фактический идентификатор блока (тот, который объявляется для пользовательских блоков в аннотации) и темы. Тогда просто установите регион, и все готово. Создан экземпляр блока в нужном регионе.

$blockEntityManager = \Drupal::service('entity.manager')->getStorage('block');
$block = $blockEntityManager->create(
  array(
      'id'=> 'devel_execute_php_1112',
      'plugin' => 'devel_execute_php',
      'theme' => 'seven'
  )
);
$block->setRegion('content');
$block->save();

edit1: я на самом деле позже проверил комментарий выше - и это правильно. Просто не ясно, что id - это то, что вы должны придумать. В качестве погашения за мой отстойный комментарий я опубликую решение о том, как создать экземпляр блока пользовательской сущности блока:

$blockEntityManager = \Drupal::service('entity.manager')->getStorage('block');
$block = $blockEntityManager->create(
  array(
      'id'=> 'ggggggggsssssss',
      'plugin' => 'block_content:79d53b4e-9e60-4f97-befc-101da919bb7a',
      'theme' => 'visitb_he_theme'
  )
);
$block->setRegion('content');

в основном то же самое, но для плагина вы пишете block_content: uuid_of_custom_block_entity_instance

Николай Борисов
источник