Una de las grandes ventajas de las vistas con argumentos en Drupal es el juego que te permiten con las taxonomías, de forma bastante simple, podemos hacer que se nos muestre información relacionada con ciertas categorías, y complicándolo un poquito más, podemos realizar cosas como las que pregunta cdp en este comentario:

Quiero hacer una vista que al hacer click sobre un nodo me muestre todos los nodos que tengan los mismos tags que el nodo sobre el que se ha hecho click. He creado el vocabulario, pero por ahora no he conseguido crear una vista que me muestre los nodos comunes a los vídeos. ¿Solucionaría mi problema una vista con argumentos?

Es decir, en una vista de tipo bloque, mostrar todos los nodos que compartan tags con el que estamos visualizando. Esto también se puede hacer con las vistas con argumentos

Nota: Para estos ejemplos he creado varios nodos con ciudades, cada ciudad pertenece a un país y tiene un idioma, ambas características marcadas por la taxonomía.

Oskar me sugirió en este comentario mostrar en algun sitio de los artículos sobre drupal los detalles sobre módulos, versiones, etc y me ha parecido una muy buena idea, y mi aproximación final fue crear una subcategoría para poder gestionar la información de cada post.
Me gusta mucho el bloque flotante que tienen en lullabot en alguno de sus posts para mostrar el contenido relacionado y he intentado hacer algo parecido. A la derecha de este texto lo podéis ver (si entráis en el detalle, en portada no se muestra).

Voy a intentar contaros cómo lo he hecho.

en el interfaz de drupal

A través del interfaz de drupal y el módulo taxonomía del core, he creado un vocabulario aparte llamado "drupal" para poner la información relacionada. Como opciones he seleccionado Jerarquía simple para poder tener términos relacionados padres-hijos y Selección múltiple para poder seleccionar más de un término por artículo.
En este caso he utilizado los términos padres como títulos de la sección (pej. módulos o versión) y los hijos son los detalles del bloque (views, 5x, ...).
La selección múltiple tiene el inconveniente de que es necesario crear el término a través del interfaz y no lo puedes hacer desde el mismo post. Se podrían utilizar módulos como el Hierarchical Select para resolver esto.

en el template.php

Aquí es donde viene "lo gordo". En el fichero template.php de nuestro theme, podemos modificar las variables que se pasan a los ficheros de phptemplate tpl.php, de esta forma, podemos hacer que las variables $links, $content o $terms entre otras muestren la información que queramos.
Para conseguir que este segundo vocabulario se mostrara como yo quería, era necesario modificar la variable $terms, para que mostrara un div con la información extra solamente si ésta existe. Para acceder y modificar las variables de phptemplate, se usa el array $vars, en este caso $vars['terms'].
En los comentarios del código aclaro el funcionamiento:

Este post es parte de una serie de explicaciones de cómo funcionan las vistas con argumentos, anteriormente he hecho una introducción a las vistas y otra a CCK.

Antes de comenzar, lo mejor es que quede claro lo qué es un argumento para las vistas de Drupal y su diferencia con los filtros.

Un argumento es un parámetro que se pasa a una vista y que se utiliza dentro de ésta para generar contenido dinámico que cambia según el argumento.
La diferencia con los filtros, es que el filtro es una forma de diferenciar contenido de forma estática por cada vista, es decir, que si filtramos por el tipo de contenido story, la vista siempre nos devolverá tipos de contenido story, sin embargo, si utilizamos el tipo de contenido como un argumento para una vista, si la url es nombre-de-la-vista/story nos mostrará tipos de contenido story, pero si accedemos a la url nombre-de-la-vista/page, nos mostrará tipos de contenido page.

Como primer ejemplo, voy a mostrar cómo se crea una vista que recibe como argumento el id del usuario y muestra el contenido que éste ha creado, de forma que, si accedemos a otro id, nos muestre el contenido de ese otro usuario.

paso a paso

  • Accedemos a nuestro sitio como administradores
  • Vamos a Administrar » Views » Add
  • Ponemos el nombre de la vista, por ejemplo, contenido-del-usuario y elegimos el tipo Página
  • Ponemos la URL de la vista y elegimos los parámetros que nos convengan, tipo de vista, el título, el número de nodos por página, etc
  • Seleccionamos los campos a mostrar, por ejemplo, el título del nodo, el contenido y su taxonomía

Hoy ha salido la versión 5.9 para Drupal que ya corrige el error en los feeds heredado de Drupal 6 que comenté ayer y que provocaba que una traducción en las fechas situara todos los feeds del blog afectado como los primeros en los agregadores.

Han sacado la versión de Drupal 5.9 tan solo unos días después de la 5.8 ya que una de las vulnerabilidades más graves, relacionada con las sesiones, no estaba corregida del todo. La recomendación es realizar el upgrade lo antes posible.

Podéis ver las notas de la release en drupal.org.

Actualización: La versión 5.9 de Drupal ya corrige este comportamiento.
Carlos ya tuvo el problema hace unos meses y todos sus posts salían los primeros en el Planeta de Drupal. Pues bien, como si fuera un virus, la nueva versión de Drupal 5, la 5.8, viene con este bug incorporado, que hace que, cada vez que generes un nuevo post, algunos agregadores pongan todos tus posts los primeros de la lista. Por lo que todos los que hemos actualizado ya, tendremos problemas con los feeds y los agregadores.
Para resolverlo, hay que aplicar el parche del comentario de Damien Tournoud de esta entrada de drupal.org.
Para aplicar un parche en un sistema Linux, podemos seguir las recomendaciones del blog de carlos si usamos linux, pero si no, o si no tenemos acceso por línea de comandos a nuestro server, solamente hay que substituir la línea 1922 del fichero modules/node/node.module, que es esta (antigua)
$extra = array_merge($extra, array(array('key' => 'pubDate', 'value' =>
format_date($item->created, 'custom', 'r')), array('key' => 'dc:creator',
'value' => $item->name), array('key' => 'guid',
'value' => $item->nid .' at '. $base_url,
'attributes' => array('isPermaLink' => 'false'))));

por esta (nueva)
$extra = array_merge($extra, array(array('key' => 'pubDate', 'value' =>
gmdate('r', $item->created)), array('key' => 'dc:creator',
'value' => $item->name), array('key' => 'guid',
'value' => $item->nid .' at '. $base_url,
'attributes' => array('isPermaLink' => 'false'))));

Estas dos sentencias son una sola línea, pero no me cabian en pantalla ;)

Nota: Este post es parte de una serie de posts dedicados a CCK y al uso avanzado de las vistas con argumentos en Drupal.

qué son las vistas

El módulo Views nos permite generar vistas para poder mostrar el contenido que queramos, filtrado y organizado a través de una interfaz que hace la tarea relativamente sencilla. Nos puede servir, por ejemplo, para mostrar solamente los títulos y las imágenes de las páginas publicadas ordenadas por fecha de creación, sin vistas, para poder extraer listados, deberíamos construir un módulo o un bloque con código PHP y consultas SQL manualmente.

¿para qué puedo querer utilizar vistas?

La mayor utilidad de las vistas aparece cuando necesitamos crear tipos de contenido personalizados mediante CCK, a través del interfaz de usuario del módulo Views, podemos filtrar el contenido que pertenezca a uno o varios tipos de contenido y generar listados.

¿cómo se instala?

La instalación no difiere mucho de la de cualquier otro módulo, se debe descargar la versión estable del módulo (es decir, la que no tenga un sufijo dev, rc, alpha o beta) desde la página del proyecto y, una vez descomprimida, se debe copiar la carpeta views al directorio de nuestra instalación de drupal, en el subdirectorio sites/all/modules/ (o sites/midominio.com/modules/ dependiendo de dónde o cómo tengamos drupal instalado).

Nota: Quiero hacer una serie de posts dedicados a las vistas con argumentos en Drupal, pero para hacer esto, me parece mejor explicar antes el modulo de Views, y para darle contexto, el de CCK.

¿qué es CCK?

El Content Construction Kit es uno de los módulos contribuidos, es decir, que no forman parte del núcleo, básicos de Drupal para implementar sitios webs complejos de forma fácil e intuitiva. A través de este módulo, podemos crear tipos de contenido personalizados que nos permitirán tener la información de nuestras páginas más organizada y acesible.

me parece estupendo, pero .... ¿que es un tipo de contenido?

Un tipo de contenido (content type) es parte de esta terminología (o casi podríamos llamarlo idioma) que utiliza Drupal, se refiere a un elemento (de tipo nodo) con características y atributos propios. Es decir, que, gracias a CCK, podemos construir nuestros propias entidades de información a través de una interfaz de usuario.

las cosas se entienden mejor con ejemplos...

Se pueden buscar centenares de ejemplos, en el caso de una aplicación de organización de restaurantes, podríamos crear un tipo de contenido restaurante, con información personalizada, como la localizacíón, una valoración, la carta / menú, etc etc.
Buenos ejemplos de otros módulos que crean tipos de contenido propios son el Simplenews, que crea un tipo de contenido para los boletines de noticias, el Image que lo crea para gestionar las imagenes, o el Poll (parte del core), que crea nodos de tipo encuesta con un campo personalizado para las votaciones.

¿encontraré todos los tipos de campos que necesito utilizar?

Hoy me he peleado con un formulario que tenía que generar "al vuelo" y me he encontrado con dos variantes de este error:

"warning: implode() [function.implode]: Bad arguments. in /includes/form.inc on line 622."
"warning: implode() [function.implode]: Invalid arguments. in /includes/form.inc on line 622."

El problema parece residir en que, cuando generas el formulario que tiene campos de tipo select o checkbox con drupal_render , no inserta todas las propiedades que requiere el modulo form y produce uno de los errores que podéis ver más arriba.

Buscando en drupal.org, he visto una solución a este problema, insertandole estas propiedades, en este caso al select, con la función _element_info .

$form['select']+= _element_info('select');

Donde $form['select'] es el elemento select del formulario que queremos completar.
Es importante que se le añada esta sentencia antes de establecer las propiedades específicas de nuestro form, ya que sino, sobreescribirá varias de ellas y perderemos información.

De todas formas, la forma recomendable de generar un formulario en drupal, que nos evita este tipo de problemas es usar drupal_get_form() en la llamada a la función que genera el formulario, en lugar de drupal_render en la propia función.

Por lo visto, no se puede utilizar la propiedad #required para hacer que los campos de tipo file en los formularios de Drupal sean obligatorios. El problema es que el campo que contiene la ruta del fichero se vacía al realizar la carga, ya que ésta se realiza a nivel de sesión.
Para poder validar si los usuarios rellenan o no un campo obligatorio de tipo file, podemos optar por parchear el core, en el form.inc como sugieren en algunos posts del foro de Drupal.org o podemos validarlo utilizando la variable global $_FILES en el hook validate del propio formulario.
Os dejo un ejemplo:
function member_payment_import_csv_validate($form_id, $form_values) {
foreach($_FILES as $file) { // Se recorre el array $_FILES
if (empty($file['name']['file'])) {
// Y si el nombre del fichero está vacío, devolvemos un error
form_set_error('file',t('Cannot import an empty file'));
}
}
return TRUE;
}

Si estamos desarrollando un sitio en Drupal que utilice Tokens, que son pequeños trozos de texto a modo de comodín que son reemplazados por sus valores definitivos sobre una plantilla definida, puede que queramos añadir algún Token más aparte de los que vienen por defecto con la instalación de Drupal o alguno de sus módulos.

Existen diversos módulos que utilizan Token para funcionar, el ejemplo más claro es el de pathauto que realiza una substitución automática de los títulos de los nodos según los patrones que le indiquemos, o el sistema de comercio electrónico Ubercart.

Por ejemplo, la lista de tokens globales es esta:
Global tokens
[user-name] Nombre del usuario identificado.
[user-id] Id del usuario identificado.
[user-mail] Correo electrónico del usuario identificado.
[site-url] Url del sitio Drupal.
[site-name] Nombre del sitio Drupal.
[site-slogan] Slogan del sitio Drupal.
[site-mail] E-mail de contacto del sitio Drupal.
[site-date] Fecha actual del servidor.

Si quisieramos añadir nuevos comodines, deberemos utilizar las funciones del API del módulo Token; que son los hooks hook_token_list y hook_token_value.

  • hook_token_list sirve para mostrar un listado de los tokens disponibles en el texto a modo informativo.
  • hook_token_value es llamada al realizar las substituciones de los comodines y se encarga de reemplazarlos por sus valores reales.