Drupal personalizando un detalle con el resultado de una vista
Drupal tiene el módulo context, muy util al poder definir reglas para mostrar bloques por contexto. El bloque puede ser el resultado de una view. Las views pueden recibir parámetros, pero cuando es un bloque hay que hacer "ñapa" para recibir el parámetro de la url, por lo que si deseamos mostrar en el detalle del contenido un listado de otros contenidos según la regla de negocio tenemos dos opciones.
Crear una view de tipo bloque y después por context definir la regla para pintar la view o crear una variable en el preprocess del nodo con el resultado de una vista.
La ventaja de hacerlo con context, es que no tiras una línea de código pero el problema es que el bloque lo tienes que ubicar en una de las regiones definidas en el theme. Por otro lado si la vista necesita parámetros, como el $node->nid es algo más complejo.
Pongamos como ejemplo "noticia" (que original), donde va a mostrar el listado de las 5 noticias más recientes que tengan los mismos tag's que la noticia que estamos visualizando.
1.- Creamos la vista que recibe como parámetro el $node->nid para obtener los tags y luego consulta al resto de noticias para obtener el resultado de las 5 noticias a mostrar.
2.- Preprocess de nodo noticia:
function _THEMENAME_preprocess_node__noticia(&$vars){
$nid = $vars['node']->nid;
$view_name = 'noticias';
$display = 'noticias_relacionadas_por_tags';
$args = array($nid);
$view = views_get_view($view_name);
$view->set_arguments($args);
$view->build($display);
$view->execute($display);
$block = $view->render();
$vars['noticias_relacionadas'] = $block ;
}
Ahora en la plantilla de nodo noticia, tenemos una variable $noticias_relacionadas con el resultado de la vista. Esto nos da más control de personalización del detalle, ya que con context estamos "limitados" a las regiones del theme, pero de esta manera la personalización del html en el detalle de la noticia está más controlado.
Drupal crear variables en nodos para personalizar el detalle de un contenido
Cuando trabajamos en la personalización del detalle de contenido, nos puede surgir la necesidad según requisitos de crear alguna lógica para mostrar los atributos de este contenido. Es muy fácil caer en aplicar esa lógica y creación de variables en la propia plantilla php (phptemplates), pero en la medida de los posible lo correcto sería evitar "codificar" en la plantilla.
Pongamos el ejemplo de que estamos mostrando el detalle de un contenido noticia, en donde tiene dos atributos a los que hay que darle importancia:
- Imagen
- Vídeo
Requisitos:
Si la noticia tiene vídeo, mostrar el vídeo y en caso contrario pintar la imagen.
Sería muy sencillo aplicar la lógica en el phptemplate:
if($field_noticia_video_rendered){
print $field_noticia_video_rendered;
}else{
print $field_noticia_imagen_rendered;
}
Como ya sabéis, si el tipo de contenido tiene un definido el campo con nombre field_noticia_imagen y el widget del atributo es de tipo imagen, al pintar $field_noticia_imagen_rendered te pinta el html necesario para renderizar la imagen, lo mismo ocurre con el vídeo.
Bien, hasta aquí hemos cumplido la funcionalidad. Pero... ¿es la manera correcta? tal vez no debería mojarme en decir "correcta" ya que ambas funcionan, pero queda mucho más ordenado si en vez de pintar ese churro lineas en la plantilla simplemente pintamos:
print $field_noticia_multimedia_rendered;
Ahora bien, el tipo de contenido noticia no tiene el atributo multimedia y antes de que interprete la plantilla tenemos que crear la variable.
Es muy improbable que estés haciendo un tema de Drupal de cero, así que en este paso vamos a abrir template.php.
Normalmente en este fichero si partes de un tema base, ya tendrás la función:
THEMENAME_preprocess_node(&$vars, $hook){
...
$function = '_THEMENAME_preprocess_node'.'__'. $vars['node']->type;
if (function_exists($function)) {
$function(&$vars);
}
}
Antes de procesar un nodo se ejecuta esta función, en donde comprobamos si tenemos declarada una función especifica para preprocesar un nodo de un tipo de contenido determinado, como en este caso el type es "noticia" tendremos la función "_THEMENAME_preprocess_node__noticia". Al declarar la función con un guión bajo al inicio del nombre, es una manera de indicar que es una función de ámbito privado y que no es un hook que lo entienda el core.
_THEMENAME_preprocess_node__noticia($vars){
...
}
El parámetro que recibe es un array asociativo que contiene toda la información que necesitamos. Si creamos una nueva key en este array asociativo, lo que vamos a conseguir es que en la plantilla de nodo exista una variable con el nombre de la key que hemos creado en el array.
_THEMENAME_preprocess_node__noticia($vars){
if($vars['field_noticia_video][0]['value']){
$vars['field_noticia_multimedia_rendered'] = $vars['field_noticia_video'][0]['view'];
}else{
$vars['field_noticia_multimedia_rendered'] = $vars['field_noticia_imagen'][0]['view'];
}
}
Una vez creado el preprocess para el tipo de contenido noticia, en la plantilla del nodo noticia tenemos que pintar la variable $field_noticia_multimedia_rendered.
print $field_noticia_multimedia_rendered;
Nos olvidamos de la lógica en la plantilla, para cuando pase diseño a modificarla no se encuentre con esos churros que a veces metemos ![]()
La idea de llamar a la nueva variable $field_noticia_multimedia_rendered es por seguir un poco la nomenclatura de las variables que utiliza Drupal, pero puede ser sólo $multimedia ya que a otra persona que vaya a ver la plantilla le puede llevar a confusión entendiendo que es un atributo del contenido. Esto queda a elección de cada uno.
Drupal el incomprendido y desconocido CMS
Hace ya bastante tiempo, desde que me muevo en la tecnología LAMP, que conozco Drupal. Nunca le dediqué el tiempo necesario para ser conocedor de esa potencia interna que cuando miramos las tripas nos hace dudar que tenga. Drupal es un CMS agnóstico en contenido y que gracias a su extensa comunidad hay una cantidad de módulos y documentación (a veces demasiada) sobre como hacer proyectos en Drupal.
Tal vez, el problema de no haber invertido más tiempo en Drupal es por su sencillez tras la instalación y no conocer lo que realmente podía ofrecer. Una de las razones también muy importantes por las que no me decidía a investigarlo era la parte técnica, donde escasea la POO y hace algo muy raro ![]()
Recientemente en el entorno laboral nos ha surgido la oportunidad de invertir tiempo en conocerlo, realmente me ha sorprendido. La primera sensación en la toma de contacto con el CMS es que se puede desarrollar sites dinámicos sin tirar una línea de código. Esta sensación duró hasta que nos enfrentamos a un proyecto real, en donde funcionalmente podíamos atacar muchos requisitos del proyecto pero a la hora de entrar en las tripas para personalizarlo nos dimos cuenta que hay algo más allá. El código es prácticamente funciones, y el core (no se como lo hace) simula la sobrecarga de métodos pero con funciones en donde parece ser que sólo puede existir una sobre-escritura.
La verdad es que ahora mismo tengo un poco de fascinación por Drupal, y cuando hace unos 3 años un amigo me intentaba vender la "moto" de Drupal yo siempre le ignoraba
lo siento Diego! ha tenido que ser tres años más tarde.
Supongo que a partir de ahora, retomaré el blog con algún que otro artículo de Drupal.