Cómo tema un bloque personalizado

26

He creado un bloque usando hook_block_infoy hook_block_themey similares. Pero, ¿cómo puedo tema?

Lo tengo funcionando para devolver una matriz con las teclas 'subject'y 'content'. Pero creé el marcado directamente en el hook_block_view()gancho y eso no es lo que quiero.

En los documentos se dice que el contenido debería devolverse preferiblemente como una matriz renderizable y no como un marcado. Pero, ¿qué es esta matriz renderizable ? Dicen que debería ser datos en lugar de marcado, pero todo lo que veo en los ejemplos es que solo se usa como envoltorio para el marcado, por lo que no se gana nada allí.

Quiero poder tener un block--MYMODULE--DELTA.tpl.phptema en mi tema, pero ¿cómo lo llamo y cómo puedo pasar los datos al bloque?

Yunzen
fuente
blog de detalle: goo.gl/kD3TZu
Suresh Kamrushi
@SureshKamrushi - OP pregunta por un bloque. El artículo vinculado trata sobre agregar una nueva región a un tema. Que no es lo que solicitó OP.
leymannx

Respuestas:

27

La forma en que hago esto es la siguiente ...

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,
        ],
      ],
  ];
}

Y luego, en una subcarpeta en su módulo llamado theme, debería haber un archivo llamado my-template.tpl.phpque podría tener esto en él:

<?php 

$items = $variables['items'];

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

Y si quisieras, podrías sobrescribir la implementación del módulo "predeterminado" que acabas de crear my-module.tpl.phpen tu tema como desees block--MYMODULE--DELTA.tpl.php.

nedwardss
fuente
Pero si anulo el tema con un archivo tpl.php en mi tema, el hook_block_view no se ejecutará y mis variables no se darán al archivo de plantilla.
Yunzen
@yunzen: es posible que deba vaciar su caché, intente ir admin/config/development/performancey haga clic en el clear cachebotón. También puede borrar el caché usando drush, es decirdrush cc all
Cyclonecode
6

Prueba el módulo de desarrollador de temas . Cuando lo haya habilitado, puede marcar una casilla en la esquina inferior izquierda de su página de Drupal. Después de eso, puede hacer clic en su bloque y obtener información útil teniendo en cuenta el tema. Puede ver los posibles nombres de archivo .tpl.php para su bloque, por ejemplo.

Elige uno de esos nombres. El primero es el más específico. Solo tendrá un tema de bloque. Cree un archivo con ese nombre en su carpeta de temas si aún no está allí. Puede ponerlo en una subcarpeta si desea organizarse.

Copie el contenido de block.tpl.php en su archivo y comience a cambiar las cosas como desea.

Guarde su archivo, borre cachés y vuelva a cargar la página.

jerga
fuente
5

Ya hay varias respuestas para esta pregunta, pero he tratado de proporcionar un enfoque muy simplista. Con suerte, identificando a los desarrolladores la estructura de matriz esperada por Drupal al devolver el contenido de su bloque.

Para hacer esto, he dividido la pregunta en ejemplos de código separados como tales,

/**
 * 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',
    ),
  );
}

Vea una explicación completa aquí drupal 7 creando bloques personalizados de temas

Nicolas
fuente
3

Esta es una publicación antigua, pero he encontrado una mejor solución para anular plantillas de bloques de un módulo personalizado para Drupal 7.

Agregue esto a su 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;
}

Entonces necesitas el siguiente 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;
}

Todo lo que tienes que hacer es crear templates/block--my-custom-module.tpl.phpdentro de la carpeta de tu módulo.

He escrito un tutorial sobre este Tutorial de Drupal - Cómo anular plantillas de bloque de un módulo personalizado

iStryker
fuente