Cómo añadir nuevos Token en Drupal

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.

Podemos ver esto en funcionamiento en un módulo de ejemplo que he preparado. Este módulo envía un correo a todos los usuarios registrados de nuestro sitio, la plantilla de este mail se puede modificar utilizando tres nuevos tokens definidos con el API: La antigüedad de la cuenta del usuario, su última conexión y el número de roles activados que tiene. Para poder probar este módulo y crear tokens o comodines personalizados, deberemos tener instalada y activada la última versión del módulo Token.

Paso a paso

Primero creamos un elemento de menú para capturar el callback y que la ruta que definamos realice una llamada a nuestra función. En este caso la ruta para visualizar el formulario es admin/settings/demo_token.

'admin/settings/demo_token', 'title' => t('Demo Token Usage'), 'description' => t('Demo use of token'), 'callback' => 'drupal_get_form', 'callback arguments' => array('demo_token_test'), 'access' => user_access('administer site configuration'), ); } return $items; } ?>

El formulario que definimos es una caja de texto de 10 filas que contendrá la plantilla de un mail donde se substituirán los tokens por sus valores. El elemento token_help recoge los valores devueltos por el hook_token_list y muestra una tabla con los tokens disponibles tanto de forma global, como del módulo que especifiquemos, en este caso demo_token.

function demo_token_test() {

$form['mail'] = array(
'#type' => 'textarea',
'#title' => t('Mail for users'),
'#rows' => 10,
'#default_value' => variable_get('demo_token_mail', ''),
);

$form['token_help'] = array(
'#value' => theme('token_help','demo_token'),
);

$form['submit'] = array('#type' => 'submit', '#value' => t('Submit'));

return $form;
}
?>

La función de _submit realiza el envío del formulario y se encarga de guardar en una variable la plantilla del mail para que cuando recarguemos la página se guarden los cambios. (Se muestran gracias a la propiedad #default_value del elemento mail del formulario). Esta función realiza el envío de mails a los usuarios, en caso de no poder utilizar el mail, podéis comentar la llamada a drupal_mail y descomentar la línea que hace una llamada a drupal_set_message para comprobar el funcionamiento sin enviar los correos (es necesario instalar el módulo devel)

La función que realiza la substitución de los comodines o tokens por sus valores es token_replace, que recibe la plantilla del mail, y realiza una llamada al hook_token_values pasándole el módulo del que se necesiten substituir los tokens y un objeto con los datos necesarios para calcular los valores. En caso de necesitar substituir tokens globales y de más de un módulo, podremos usar la función token_replace_multiple.

function demo_token_test_submit($form_id, $form_values) {
variable_set('demo_token_mail',$form_values['mail']);
$sql = "SELECT uid FROM {users} WHERE uid > 0";
$result = db_query($sql);
while ($data = db_fetch_object($result)) {
//drupal_set_message('mail'.dprint_r(token_replace($form_values['mail'],
'demo_token', $data),TRUE));
drupal_mail('',$data->mail,t('Token Demo Test Mail'),token_replace($mail_template,
'demo_token', $data),t('Token Demo Test Mail'));
}
}
?>

Finalmente tenemos las funciones que realizan las capturas de los hooks del API del módulo Token, demo_token_token_list es una captura del hook_token_list y genera un array con los tokens disponibles y su descripción que pueden ser mostradas mediante la función theme('token_help', 'nombre_del_modulo').

function demo_token_token_list($type = 'all') {
if ($type == 'demo_token' || $type == 'all') {
$tokens['demo_token']['age-account'] = t("Age of the account (in days)");
$tokens['demo_token']['last-login'] = t("Last login of the user");
$tokens['demo_token']['role-count'] = t("Role of the user");
return $tokens;
}
}
?>

La función demo_token_token_values captura el hook_token_values y se encarga de calcular los valores a substituir a partir del objeto que se pasa por parámetro. En el ejemplo se realizan los cálculos necesarios para mostrar el último login cuyo formato lo marca la función de Mysql DATE_FORMAT(from_unixtime(login),'%Y-%m-%e') y la diferencia de fechas para mostrar la antigüedad de la cuenta en días period_diff(DATE_FORMAT(now(),'%Y%m%e'), DATE_FORMAT(from_unixtime(created),'%Y%m%e')) . Finalmente, se calcula el número de roles de cada usuario a través de la tabla users_roles y devuelve un array con los tokens definidos en el hook_token_list.

function demo_token_token_values($type = 'all', $object = NULL) {
$values = array();
if ($type == 'demo_token' && is_object($object)) {
$sql = "SELECT DATE_FORMAT(from_unixtime(login),'%Y-%m-%e') last_login ,
period_diff(DATE_FORMAT(now(),'%Y%m%e'),
DATE_FORMAT(from_unixtime(created),'%Y%m%e')) age_in_days
FROM {users} u WHERE uid = %d";
$dates = db_fetch_object(db_query($sql, $object->uid));
$sql = "SELECT count(*) FROM {users_roles} WHERE uid = %d";
$user_roles = db_result(db_query($sql, $object->uid));
$values['age-account'] = (string)$dates->age_in_days;
$values['last-login'] = (string)$dates->last_login;
$values['role-count'] = $user_roles;
}
return $values;
}
?>

Espero que os haya resultado útil.

AdjuntoTamaño
Package icon demo_token.zip1.41 KB

Comentarios

Hola Pedro,

He leído tu tutorial y me ha parecido interesante, estoy comenzando en Drupal y me gustaría poder ser asesorado por ti en lo siguiente,

Tengo una actividad relacionada con este tema en cuestión la problemática que tengo que resolver es personalizar el correo que envíe por PHPMailer, al usuario que crea una cuenta e introduce los datos personales y entre estos una frase o cita personal, esta tiene que verse en el Subject del correo que se le envía cuando debe darse de alta sin envargo solo me remite a poner !username, !url... etc si gustas puedes acceder a la web siguiente que comento http://iemurillo.myinvent.net y ver lo que te comento, al darle click en Crear nueva cuenta... de antemano agradezco cualquier ayuda en lo posible. Si es necesario más información estaré al pendiente.

Saludos Cordiales desde México

Añadir nuevo comentario