Como colocar programaticamente um bloco?

10

Na interface do usuário, você pode adicionar um bloco em uma região dessa maneira:

  1. Vá para Admin -> Estrutura -> Layout do bloco (/ admin / structure / block).
  2. Clique no botão "Inserir bloco" ao lado do nome da região.

Eu quero fazer a mesma coisa, mas programaticamente. Como adicionar um bloco existente a uma região e salvá-lo? Esse bloco deve ser exibido nessa região e estar disponível na página de layout do bloco .

user3554770
fonte
Depois de criar o bloco que você pode rearranjar a posição do bloco de: site_name / admin / estrutura / bloco
Crazyrubixfan
Suponho que você digitou incorretamente "atribuir um bloco a uma região".
Cilefen
@IcecreamJelly o que estou tentando fazer é fazer isso programaticamente. cilefen, sim, que é o que eu média% -)
Jmzea
@ ShawnConn obrigado, isso é semelhante, mas não exatamente o mesmo. Eu encontrei a resposta em outro lugar.
Jmzea #

Respostas:

9

Para fornecer um bloco de plug - in, você pode criar uma matriz de configurações e transmiti-lo \Drupal\block\Entity\Block::create()para criar o objeto Block e salvar a instância.

Por exemplo, se você deseja adicionar um bloco PHP de Execute Devel ao tema 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();
Shawn Conn
fonte
Oi, preciso de ajuda. Eu criei um bloco personalizado usando a interface do usuário e quero colocar na região do rodapé programaticamente para fins de teste. Eu não sei como obter plug-in a partir de blocos personalizados criados por UI .. obrigado
Mudassar Ali
Faça isso como outra pergunta. Os comentários não são para fazer perguntas.
Shawn Conn
já está lá. drupal.stackexchange.com/questions/207042/...
Mudassar Ali
Qual é o id aqui? é o mesmo que o nome do bloco?
Crazyrubixfan
@RubberDuckIsKing Acredito que você pode nomear o idque quiser, desde que seja único. Por exemplo, você pode querer começar com o nome do módulo de seu no.
Parag
7

Você pode usar o módulo Twig tweak :

O módulo Twig Tweak fornece uma extensão Twig com algumas funções e filtros úteis que podem melhorar a experiência do desenvolvedor.

E então na sua região de modelo de galho:

{{ drupal_block('block_id') }}
rpayanm
fonte
O problema com esta solução é que os twig tweaks ainda exigem que você coloque o bloco e, em seguida, 'desabilite'.
Lexicant
6

Cada exemplo de um bloco (que "tipo bloco", a configuração e o posicionamento) é uma entidade de configuração: \Drupal\block\Entity\Block. Então, tudo que você precisa fazer é criar uma nova instância desta entidade com os detalhes corretos e pronto.

Isso pode ser feito, mas é muito complexo, você precisa entender o sistema de plugins, bloquear o sistema de plugins e muito mais.

Você pode dar uma olhada \Drupal\block\BlockForm::submitFormpara ter uma idéia disso ou \Drupal\simpletest\BlockCreationTrait::placeBlock. Você pode pensar se isso é algo que você realmente precisa, a visibilidade do bloco é bastante complexa.

googletorp
fonte
4
Além das condições de visibilidade, não acho que seja tão complicado. \ Drupal \ simpletest \ BlockCreationTrait :: placeBlock () é provavelmente um exemplo melhor de se olhar, você também pode apenas importar alguns arquivos de configuração exportados.
Berdir 05/04
@ Berdir Obrigado pelo link para a característica de teste, acrescentou. Como o Drupal 8 ainda é tão jovem, muitas pessoas não sabem muito sobre o sistema de plugins e a documentação pode usar mais casos de uso, etc., o que pode dificultar o trabalho de muitos desenvolvedores.
googletorp
Felix Eve tem a melhor resposta. Não é um complexo maluco.
kratos
@kratos A resposta que Felix forneceu não está resolvendo a questão de como colocar um bloco "programaticamente", mas usa arquivos de configuração. A configuração só pode ser importada via drush, interface de sincronização de configuração ou instalação do módulo. Se ele precisa acontecer, durante a execução, pós fx salvar de uma seção frontpage tipo de nó etc, seria inútil para usar esta estratégia :)
googletorp
4

Estou apenas aprendendo D8, mas parece que encontrei uma maneira muito mais fácil de colocar um bloco programaticamente (pareceu bastante intimidador depois de ler a resposta do googletorp!)

Quando ativei meu módulo personalizado que definiu o bloco, queria que o bloco fosse automaticamente colocado na região correta. As etapas que eu usei para conseguir isso são:

  1. Ative o módulo e coloque o bloco usando a interface do usuário em /admin/structure/block
  2. Vá para a página de exportação da configuração de item único em admin/config/development/configuration/single/export
  3. Selecione o bloco Tipo de configuração e, para o Nome da configuração, selecione o bloco que você acabou de colocar usando a interface do usuário e copie o código gerado.
  4. No seu módulo, crie a pasta /config/install/
  5. No código de texto gerado, a área informa o nome do arquivo que você precisa usar. Crie este arquivo no /config/installdiretório e copie o código lá.
  6. Agora, quando você desinstala seu módulo e o reativa, o bloco será automaticamente colocado.
Felix Eve
fonte
você não precisaria remover o UUID para que isso funcionasse para outros desenvolvedores ou ambientes?
Powpow12
Sim - remover o UUID seria uma boa ideia.
Felix Eve
Você também pode usar o console do Drupal, que se encarrega de automatizar algumas dessas tarefas: hechoendrupal.gitbooks.io/drupal-console/content/en/commands/…
Beau
2

O exemplo acima está próximo o suficiente, mas ainda não está correto. A idéia é que você precise criar seu próprio ID da instância do bloco (no meu caso devel_execute_php_1112 (talvez porque tentei fazê-lo funcionar 1112 vezes, ele permanecerá um mistério)) e, em seguida, o ID do bloco real (aquele que é declarado para os blocos personalizados na anotação) e o tema. Em seguida, basta definir a região e você estará pronto para ir. Criou uma instância de um bloco na região desejada.

$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: Na verdade, verifiquei mais tarde o comentário acima - e está certo. Simplesmente não está claro que o id seja algo que você precise criar. Como redenção do meu comentário coxo, publicarei uma solução sobre como criar uma instância de bloco de uma entidade de bloco personalizada:

$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');

basicamente o mesmo, mas para um plug-in você escreve block_content: uuid_of_custom_block_entity_instance

Nikolay Borisov
fonte