Como tema de um bloco personalizado

26

Eu criei um bloco usando hook_block_infoe hook_block_themeassim por diante. Mas como posso tema isso?

Eu tenho que trabalhar para retornar uma matriz com as chaves 'subject'e 'content'. Mas eu criei a marcação diretamente no hook_block_view()gancho e não é isso que eu quero.

Nos documentos, diz-se que o conteúdo deve ser retornado preferencialmente como matriz renderizável e não como marcação. Mas o que é essa matriz renderizável ? Eles dizem que devem ser dados em vez de marcação, mas tudo o que vejo nos exemplos é que ele é usado apenas como um invólucro para marcação, então nada foi ganho lá.

Quero poder ter um block--MYMODULE--DELTA.tpl.phpno meu tema, mas como eu o chamo e como posso passar os dados para o bloco?

yunzen
fonte
blog de detalhes: goo.gl/kD3TZu
Suresh Kamrushi
@SureshKamrushi - O OP pede um bloco de tema. O artigo vinculado é sobre como adicionar uma nova região a um tema. O que não é o que o OP pediu.
leymannx

Respostas:

27

A maneira como faço isso é a seguinte ...

function MYMODULE_block_info() {

  $blocks = [];

  $blocks['my_block_machine_name'] = [
    'info'  => t('My Block Title'),
    // @see https://api.drupal.org/api/drupal/includes!common.inc/group/block_caching/7.x
    // You can use different caching options.
    'cache' => DRUPAL_NO_CACHE,
  ];

  return $blocks;
}

function MYMODULE_block_view($delta = '') {

  $block = [];

  switch ($delta) {
    case 'my_block_machine_name':
      // Good idea to check user permissions here.
      if (user_access('access content')) {
        $block['subject'] = t('My Block Title');
        $block['content'] = MY_BLOCK_CONTENT_CALLBACK();
      }
      break;
  }

  return $block;
}

function MY_BLOCK_CONTENT_CALLBACK()() {

  $items = [];

  // This is the simplest kind of renderable array.
  $items['VAR_ONE'] = ['#markup' => 'VAR_ONE_OUTPUT'];

  // Here I added a prefix and a suffix.
  $items['VAR_TWO'] = [
    '#prefix' => '<div class="foo-bar">',
    '#markup' => 'VAR_TWO_OUTPUT',
    '#suffix' => '</div>',
  ];

  // This is where the $items get sent to your my-template.tpl.php template
  // that got registered below.
  return theme('my_cool_block', ['items' => $items]);
}

function MYMODULE_theme() {

  // Here you are registering your template for the block output above.
  $module_path = drupal_get_path('module', 'MYMODULE');

  // Drupal will now look up your modules /theme folder first to grab the
  // template.
  $base = [
    'path' => "$module_path/theme",
  ];

  return [
    'my_cool_block' => $base + [
        // Leave off .tpl.php.
        'template'  => 'my-template',
        // Define variables you want to pass to the template.
        // Here I just pass items, but you can pass any other data as well.
        'variables' => [
          'items' => NULL,
        ],
      ],
  ];
}

E então, em uma subpasta em seu módulo chamada theme, deve haver um arquivo chamado my-template.tpl.phpque poderia ter isso:

<?php 

$items = $variables['items'];

print render($items['VAR_ONE']); 
print render($items['VAR_TWO']); 

E se você quiser, poderá substituir a implementação do módulo "padrão" que acabou de criar my-module.tpl.phpno seu tema, conforme desejar block--MYMODULE--DELTA.tpl.php.

nedwardss
fonte
Mas se eu substituir o tema com um arquivo tpl.php no meu tema, o hook_block_view não será executado e minhas variáveis ​​não serão fornecidas ao arquivo de modelo.
yunzen
@ yunzen - Pode ser necessário esvaziar o cache, tente ir admin/config/development/performancee clicar no clear cachebotão. Você também pode limpar o cache usando drush, ou seja,drush cc all
Cyclonecode 17/17
6

Experimente o módulo Theme Developer . Quando você o habilitou, pode marcar uma caixa de seleção no canto inferior esquerdo da sua página do Drupal. Depois disso, você pode clicar no seu bloco e obter informações úteis, considerando o tema. Você pode ver as possíveis nomeações de arquivo .tpl.php para o seu bloco, por exemplo.

Escolha um desses nomes. O primeiro é o mais específico. Será apenas tema de um bloco. Crie um arquivo com esse nome na pasta do tema, se ainda não estiver lá. Você pode colocá-lo na subpasta se desejar se organizar.

Copie o conteúdo de block.tpl.php no seu arquivo e comece a mudar as coisas da maneira que deseja.

Salve seu arquivo, limpe os caches e recarregue a página.

jiv-e
fonte
5

Já existem várias respostas para esta pergunta, mas tentei fornecer uma abordagem muito simplista. Esperançosamente, identificando para devs a estrutura de matriz esperada pelo Drupal ao retornar o conteúdo do bloco.

Para fazer isso, dividi a questão em exemplos de código separados, como tal,

/**
 * Implements hook_theme().
 */
function examplemodule_theme() {
  return array(
    'examplemodule_output' => array(
      'variables' => array(
        'title' => NULL,
        'content' => NULL,
        'popular_content' => NULL,
       ),
      'template' => 'templates/examplemodule-sweet--block',
    ),
  );
}

Veja uma explicação completa aqui drupal 7, criando blocos personalizados de temas

Nicolas
fonte
3

Esta é uma publicação antiga, mas encontrei uma solução melhor para substituir modelos de bloco de um módulo personalizado para o Drupal 7.

Adicione isso ao seu módulo personalizado:

/**
 * Implements hook_theme().
 */
function MYMODULE_theme($existing, $type, $theme, $path) {

  // Custom template for that overrides the default block.tpl.php.
  $themes['block__my_custom_module'] = [
    'template'      => 'block--my_custom_module',
    'original hook' => 'block',
    'path'          => drupal_get_path('module', 'my_custom_module') . '/templates',
  ];

  return $themes;
}

Então você precisa do seguinte código:

/**
 * Implements hook_block_info().
 */
function MYMODULE_block_info() {

  $blocks = [];

  $blocks['my_custom_module'] = [
    'info'  => t('My Custom Module Block'),
    'cache' => DRUPAL_CACHE_PER_ROLE,
  ];

  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function MYMODULE_block_view($delta = '') {

  $block = [];

  switch ($delta) {
    case 'my_custom_module':
      $block['content'] = _my_custom_module_helper_function();
      break;
  }

  return $block;
}

/**
 * Helper function to generate HTML.
 *
 * @return string
 *   generated HTML
 */
function _my_custom_module_helper_function() {

  $output = '';

  // ...

  return $output;
}

Tudo que você precisa fazer é criar templates/block--my-custom-module.tpl.phpdentro da pasta do seu módulo.

Eu escrevi um tutorial sobre este Tutorial Drupal - Como substituir modelos de bloco de um módulo personalizado

iStryker
fonte