
Drupal 8: Hook_theme_suggestions_alter
Autor: fjavimartin
Fecha de Creación: 13/11/2018
Categorías:
En este artículo descubriremos como utilizar el hook_theme_suggestions_alter para añadir nuestras propias sugerencias a los nombres de los templates que drupal nos ofrece.
1. Información para debug
Una vez que hemos habilitado el debug de twig en drupal podremos ver las distintas sugerencias que podremos utilizar para los nombres de los templates con los que generar el código de los distintos componentes que formen nuestra web.
El código incluido entre el html de nuestro sitio con las distintas sugerencias será muy parecido a lo siguiente:
<!-- THEME DEBUG -->
<!-- THEME HOOK: 'block' -->
<!-- FILE NAME SUGGESTIONS:
* block--bloquecontactanos.html.twig
* block--block-content--4dcb780d-09e7-4535-be6b-d9035be391ee.html.twig
* block--block-content.html.twig
X block.html.twig
-->
<!-- BEGIN OUTPUT from 'core/modules/block/templates/block.html.twig' -->
En este caso estamos viendo la sugerencia que drupal nos ofrece cuando pinta un bloque:
- En primer lugar nos informa del hook encargado de dibujarlo. Si quisiéramos acceder a las distintas variables que finalmente se pasan al template bastaría con añadir a nuestro theme el hook_preprocess_block().
- Después vemos las distintas sugerencias para el nombre del template encargado de pintar el elemento actual, en nuestro caso un block. Aparecerá marcado con una X el nombre del template que estamos utilizando ahora mismo.
- Por último nos informa de la ubicación del template actual.
Con toda esta información lo tenemos todo para ir a buscar el actual template, copiarlo en nuestro theme y modificarlo a nuestro gusto.
2. Motivos para añadir un sugerencia
Parece que con la anterior información lo tenemos todo para triunfar…….pues no. Si observamos las sugerencias ofrecidas en el anterior apartado solamente podremos personalizar el template de nuestro block cuando queramos hacerlo para un bloque concreto, pero…..
¿Que pasa si queremos utilizar el mismo template para los bloques ubicados en una misma región?
¿Que pasa si queremos utilizar el mismo template para los bloques de un tipo determinado?
¿Que pasa si queremos utilizar el mismo template para bloques de un tipo determinado ubicado en un sitio determinado?
Pues bien, si queremos dar respuesta a las preguntas anteriores tendremos que añadir nuestras propias sugerencias.
3. Implementando el hook_theme_suggestions_alter()
Antes de nada echamos un ojo a la descripción que encontraremos en la api de drupal sobre este hook:
This hook is invoked for all theme hooks, if you are targeting a specific theme hook it's best to use hook_theme_suggestions_HOOK_alter().
Correcto!!!!! En nuestro ejemplo estamos implementando este hook para un block por lo que el nombre del método a utilizar será hook_suggestions_block_alter().
/**
* Implements hook_theme_suggestions_block_alter.
* Add two new suggestions per block:
* - Suggestion with block region
* - Suggestion with block region and bundle type
* @param array $suggestions
* @param array $variables
*/
function themename_theme_suggestions_block_alter(array &$suggestions, array $variables) {
$id = $variables['elements']['#id'];
$block = \Drupal\block\Entity\Block::load($id);
$region = $block->getRegion();
if (isset($variables['elements']['content']['#block_content'])) {
$blockcontent = $variables['elements']['content']['#block_content'];
$bundle = $blockcontent->bundle();
}
else {
$bundle = $block->bundle();
}
$suggestions[] = $variables['theme_hook_original']. '__' . $bundle;
$suggestions[] = $variables['theme_hook_original']. '__' . $region;
$suggestions[] = $variables['theme_hook_original']. '__' . $region . '__' . $bundle;
}
Cuando se ejecute nuestra función estaremos pintando un bloque SEGURO!!!!!!! Capturamos el identificador del bloque y mediante el método estático de la entidad block cargamos nuestro bloque para obtener el resto de información que necesitaremos para crear nuestra sugerencia personalizada:
$bundle → Nos dará el tipo de bloque.
$region → Nos dará la región en la que está ubicada el bloque.
En cuanto tenemos toda esta información solamente nos queda crear la cadena de texto con todas las variables anteriores y añadirla en el array suggestions.
En este caso hemos personalizado la sugerencia para un bloque, pero podemos hacer lo mismo con…….una vista!!!!
/**
* Implements hook_theme_suggestions_views_view_unformatted_alter
* @param array $suggestions
* @param array $variables
*/
function themename_theme_suggestions_views_view_unformatted_alter(array &$suggestions, array $variables) {
$view = $variables['view'];
if (isset($view)) {
$id = $view->id();
$current_display = $view->current_display;
$suggestions[] = $variables['theme_hook_original']. '__' . $id . '__' . $current_display;
}
}
En este caso hemos utilizado el mismo hook que antes, pero hemos metido en la sugerencia tanto el nombre de la vista como el display. De esta manera podremos personalizar el template para una vista/display determinado. Si quisiéramos personalizar la sugerencia para un mismo display que queramos utilizar en varias vistas con el mismo nombre……...a practicar!!!!!!
Espero que hayáis disfrutado del artículo y os haya resultado útil.
Referencias
http://www.e-quipos.es/blog/drupal-8-configurando-el-entorno-de-desarrollo-y-habilitar-debug-en-twig