Block com template para Drupal 7

Themed Block é um módulo sandbox que exemplifica a criação programática de um block com template para o Drupal 7.

Não perca tempo lendo este post, baixe o código por git clone e divirta-se:

git clone --branch master panchiniak@git.drupal.org:sandbox/panchiniak/1961770.git themed_block

Se você precisa de mais informações sobre o comando acima, ou quer ver o bixo todo antes de cloná-lo, visite a

Themed Block é um módulo sandbox que exemplifica a criação programática de um block com template para o Drupal 7.

Não perca tempo lendo este post, baixe o código por git clone e divirta-se:

git clone --branch master panchiniak@git.drupal.org:sandbox/panchiniak/1961770.git themed_block

Se você precisa de mais informações sobre o comando acima, ou quer ver o bixo todo antes de cloná-lo, visite a página oficial de instruções para versionamento do Themed Block.

[ironia mode on] Se estas palavras ainda estão sendo lidas, então, ou a árvore não foi suficiente e você precisa de alguma explicação, ou você é a minha mãe. Vou supor que o seu nome não é Izidora e prosseguir com explicações no melhor estilo Livro dos Espíritos. [ironia mode off]

1. Por que Themed Block cria um block com template no diretório theme?

Porque ele quer etiquetar o conteúdo do block com <strong>.

É uma boa prática deixar as etiquetas html fora do código PHP. Por que? Porque, como bem papeou o Sebas:

Embora viva em uma, você não é uma ilha. Alguém, menos afeito ao PHP, pode querer embelezar o seu bloco. Assim, será útil separar em diferentes arquivos o que é funcionalidade, daquilo que é aparência.

 

Em tudo que diga respeito ao Drupal, é muito importante a separação entre funcionalidade, aparência e conteúdo.

 

2. Mas, você ainda não respondeu: por que o diretório theme?

Porque é um nome descritivo, e é útil acompanhar a galera naquilo que é mais usado. Mas, sintaticamente, poderia ser qualquer outro nome.

3. E esse template consiste no quê?

Siga o link da pergunta e veja. Note que embora o arquivo de template seja .php, a intenção é fazê-lo, ao máximo possível, um arquivo HTML. O prefixo tpl, antes de php, indica isso. Perceba que apenas o conteúdo é "printado" pelo PHP, enquanto as etiquetas HTML ficam de fora.

4. Qual é a função do hook_block_info, no arquivo themed_block.module?

Consulte o excelente post do Denis sobre a criação programática de blocos. A conversa aqui é mais específica, pô. Queremos falar sobre block com template, enquanto o Denis já cobriu a criação programática de blocos.

5. Está certo. Então, como funcionam o hook_block_view e o hook_theme?

Quando usamos hooks, é sempre bom olhar a descrição deles na seção de API do Drupal.

/**
 * Implements hook_block_view().
 */
function themed_block_block_view($delta = 'themed_block') {
  if ($node = menu_get_object()) {
    $block['subject'] = t('Themed Block');
    $user = user_load($node->uid);
    $user_home_link = drupal_get_path_alias('user/' . $user->uid);
  }

  return isset($block) ? $block = array(
    'subject' => $block['subject'],
    'content' => theme(
      'themed_block', array(
        'author' =>array(
          'author_name' => l($user->name,$user_home_link),
        ),
      )
    ),
  ):

  FALSE;
}

Essa descrição do hook_block_view nos permite entender o que está acontecendo. Basicamente, em themed_block_block_view, Themed Block diz ao Drupal três coisas:

  1. a identificação do block, que é o valor de $delta, seguindo o que ficara definido em themed_block_block_info;
  2. o subject do block, que poderá ser sobreescrito na página de administração em admin/structure/block/manage/themed_block/themed_block, sob o formulário de Block title e,
  3. o conteúdo do block, que será encapsulado pela função theme, e finalmente lido pelo themed_block_block_theme.

 

Observação: nesse singelo exemplo, o nome do bloco é igual ao nome do módulo que o cria, mas isso não é o ideal. Você deveria usar um nome que descreva os propósitos do block. Se o block se chamasse themed_block_example, por exemplo, teríamos sua administração em admin/structure/block/manage/themed_block/themed_block_example. Esse detalhe é importante, porque o seu módulo poderia criar diversos blocos, cada um com seu prpóprio nome e finalidade.

 

6. Então agora você já sabe o que eu quero saber.

Sei. Agora, você quer saber como funciona themed_block_theme, e qual é a mágica que envia valores ao template. Pois bem. Primeiro, o módulo diz ao Drupal onde vive o querido template. Isso acontece pela variável $path. Em seguida, fazemos retornar desse hook_theme a variável $author de themed_block, conforme o povoamento que se deu em themed_block_block_view. Esses dados ficarão disponíveis para o template, que é identificado em 'template' => 'themed-block-template'. Veja que não deve ser incluída a extensão (.tpl.php) na identificação do arquivo, pois o Drupal cuidará disso.

7. Massa, mas você poderia postar o código inteiro aí? Não quero clicar em nenhum desses links-tentação.

Feito!

<?php
/**
 * @file
 * This is themed_block.module for Drupal
 */

/**
 * Implements hook_help().
 *
 * Displays help and module information.
 */
function themed_block_help($path, $arg) {

  switch ($path) {
    case "admin/help#themed_block":
      return  t('Themed Block creates a themed block.') ;
    break;
  }
}

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

  $blocks['themed_block'] = array(
    'info' => t('Themed Block'),
    'cache' => DRUPAL_NO_CACHE,
  );
  return $blocks;
}

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

  if ($node = menu_get_object()) {
    $block['subject'] = t('Themed Block');
    $user = user_load($node->uid);
    $user_home_link = drupal_get_path_alias('user/' . $user->uid);
  }

  return isset($block) ? $block = array(
    'subject' => $block['subject'],
    'content' => theme(
      'themed_block', array(
        'author' =>array(
          'author_name' => l($user->name,$user_home_link),
        ),
      )
    ),
  ) : FALSE;
}

/**
 * Implements hook_theme().
 */
function themed_block_theme() {

  $path = drupal_get_path('module', 'themed_block') . '/theme';
  return array(
    'themed_block' => array(
      'variables' => array('#author' => NULL),
      'path' => $path,
      'template' => 'themed-block-template'
    ),
  );
}

8. Ah, posso fazar mais duas perguntas?

Aff... Sim, diga.

9. Uhm... você está impaciente?

Não, pode perguntar.

10. Como faço para ver o danado do block, e o que significa ($node = menu_get_object())?

As duas perguntas estão relacionadas. A função menu_get_object, por padrão, retorna o node que estiver sendo exibido. Portanto, se e apenas se estiver sendo exibido algum node, a variável $node passa a armazenar o objeto, e o operador = deixa de ser falso. Em outras palavras, como pretendemos enviar para o bloco o nome do autor do node que esteja sendo exibido, então só queremos exibir o bloco quando houver algum node cujo autor possa ser exibido. Capitice?

O objeto node armazena muitas informações úteis, mas não armazena o nome do autor do conteúdo, embora armazene o número de identificação do famigerado usuário. Assim, Themed Block usa user_load para obter o nome a partir do(a) user id entregue pelo objeto node. Belezinha? Finalmente, tudo isse é entregue ao precioso template na forma de um link para a home page do usuário/autor. Na prática, você poderá ver o resultado desta arte habilitando o block Themed Block em /admin/structure/block.

Agradecimentos vão para Ferrari, Sebas, e toda a galera da Taller. Sem contar, é claro, os eternos agradecimentos à Izidora (in memorian).