Colocar blocos de forma programática?

14

Estou usando o Drupal 7. No momento, tenho um menu principal de navegação e alternador de idiomas que existe no cabeçalho do meu site. Coloquei-os lá, indo para o CMS> Estrutura> Blocos e arrastando os blocos para a região do cabeçalho.

Como situar programaticamente esses blocos no cabeçalho?

John
fonte
De acordo com sua pergunta sobre como situar programaticamente esses blocos no cabeçalho, sugiro revisar o módulo Exemplos http://drupal.org/project/examples e, especificamente, você pode revisar e ativar o módulo Exemplo de Bloco para testar o trabalho do seu bloco de maneira programática . Eu acho que block_example_block_info()o valor da 'região' pode ser útil para testar.
precisa saber é
John, você chegou a uma resposta para isso?
relipse 14/01

Respostas:

4

Para alterar a região em que os blocos definidos por outros módulos são colocados, você pode implementar hook_block_info_alter () , que recebe os seguintes argumentos:

  • $blocks (passado por referência): a matriz que contém as definições de bloco, codificadas por módulo e delta
  • $theme: o tema para o qual os blocos estão sendo definidos
  • $code_blocks: os blocos conforme definido nas hook_block_info()implementações, antes que seus valores sejam substituídos pelos valores obtidos no banco de dados
kiamlaluno
fonte
3

É legítimo adicionar uma matriz renderizável a qualquer região da página em hook_page_build (). Exemplo do Drupal 7 para adicionar um minipanel à região do rodapé.

<?php
/**
 * Implements hook_page_build().
 */
function MODULE_page_build(&$page) {
  $block = module_invoke('panels_mini', 'block_view', 'blah');
  $blocks['blah'] = array('#markup' => $block['content']);

  $region = 'footer';
  if (isset($page[$region])) {
    $page[$region] = array_merge($page[$region], $blocks);
  }
  else {
    $page[$region] = $blocks;
  }
}

Essa é a mesma técnica que usa o módulo de contexto.

Nota: você não precisa do block.module enable para que isso funcione.

jonhattan
fonte
2

Em D6 seria essencialmente

$block = module_invoke("the_module_name", "block", "view", the_block_delta);
drupal_set_content("the_region_name", theme("block", $block));

Em D7 eu acho que é

$block = module_invoke("the_module_name", "block_view", the_block_delta);
drupal_add_region_content("the_region_name", theme("block", $block));

mas ainda estou me atualizando no D7.

mpdonadio
fonte
Isso não permite que módulos de terceiros alterem o bloco que está sendo produzido, pois os módulos podem implementar hook_block_view_alter que não é chamado com o código mostrado.
kiamlaluno
Acreditar drupal_add_region_content()é um beco sem saída, pois é destinado a páginas de instalação / atualização.
Doublejosh
2

Se você estiver adicionando um bloco personalizado, faça isso usando hook_block_info, configurando a opção status como 1 e a opção region para a região na qual você deseja que o bloco seja inserido.

Exemplo:

MODULE_block_info() {
  $blocks = array();
  $blocks['my_block'] = array(
    'info' => t('My Block Name'),
    'status' => 1,
    'region' => 'THE_REGION_I_WANT',
   );
   return $blocks;
}

Se você deseja alterar um bloco já existente, use hook_block_info_alter (), atualizando as mesmas opções mostradas abaixo.

Exemplo:

MODULE_hook_block_info_alter(&$blocks, $theme, $code_blocks) {
  $blocks['my_block']['status'] = 1;
  $blocks['my_block']['region'] = 'THE_REGION_I_WANT';
}

Para obter mais informações, consulte https://api.drupal.org/api/drupal/modules%21block%21block.api.php/function/hook_block_info/7

Wesley J
fonte
0

Esse código é baseado no @ jonhattan, mas o dele não renderiza o HTML do contêiner do bloco ou os links contextuais. Também forneci uma maneira simples de especificar todos os blocos e regiões em um só lugar.

<?php
/**
 * Implements hook_page_build().
 */
function MODULE_page_build(&$page) {
  global $theme;

  // A list of blocks you wish to display, keyed by region.
  // These are in the format of: 'module_name' => 'delta'.
  $blocks_to_render = array(
    'header' => array(
      'block' => 1,
    ),
  );

  // Add the blocks to each region.
  foreach ($blocks_to_render as $region => $block_list) {
    $block_objects = array();
    foreach ($block_list as $module_name => $delta) {
      $block = block_load($module_name, $delta);
      // Alter some of the defaults to match the current context.
      $block->theme = $theme;
      $block->region = $region;
      $block->weight = 0;
      $block_objects[] = $block;
    }
    $blocks_build = _block_get_renderable_array(_block_render_blocks($block_objects));

    if (isset($page[$region])) {
      $page[$region] = array_merge($page[$region], $blocks_build);
    }
    else {
      $page[$region] = $blocks_build;
    }
  }
}

Nota: Ao contrário do código dele, você precisa do block.module instalado.

hargobind
fonte
-1

Esta não é a melhor forma, mas você pode colocar manualmente o conteúdo na matriz de páginas como esta ...

function mymodule_page_alter(&$page) {
  $my_content = _mymodule_render_mycontent();
  $page['my_region']['my_special_insert']['content']['#markup'] = $my_content;
}

Embora você deva usar o Contexto ou apenas os blocos principais. Criar novos plugins não é tão ruim quanto parece. Apenas nomeie os arquivos corretamente, configure um gatilho e um teste. exemplo .

doublejosh
fonte
De fato, pensando bem, quase me arrependo de postar esta solução. Não faça isso.
doublejosh
-1

você também pode ajustar os blocos no seu tema, como:

/**
 * Implements hook_preprocess_page().
 */
function your_theme_preprocess_page(&$variables) {

  if (drupal_is_front_page()) {
    $variables['page']['region_one'] = $variables['page']['region_two'];
    unset($variables['page']['region_two']);
  }
}
rémy
fonte
Isso não responde à questão de como renderizar blocos ou como identificá-los na marcação.
Christian