¿Cómo definir rutas de acceso en Drupal 7?

Definir rutas o URL para nuestros módulos es algo muy habitual, para esto usamos el hook_menu, aquí podemos definir rutas a nuestro gusto, pase de parámetros, permisos de seguridad, función que procesa la solicitud, callback para el uso de AJAX, y otras cosas. Hoy explicamos 4 ejemplos muy comunes para poder sobrevivir, dejando a un lado las opciones que no nos interesan.

Ruta simple:

function rutas_menu() {
  $items['path'] = array( 'title'           => 'Ejemplo de ruta #1',
                          'page callback'   => 'rutas_example_one_form',
                          'access callback' => TRUE);
}

function rutas_example_one_form() {
  $markup = t('Lorem ipsum dolor sit amet, consectetur adipisicing...');
  return array('#markup' => $markup);
}

Esto sería un ejemplo de como accedemos por la URL y los que nos devuelve:

Ruta con pase de un parámetro:

function rutas_menu() {
  $items['path/%'] = array(
    'title'           => 'Ejemplo de ruta #2',
    'page callback'   => 'rutas_example_two_form',
    'page arguments'  => array(1),
    'access callback' => TRUE,
  );
}

function rutas_example_two_form($arg){
  $markup = t('Parámetro del url: ') . $arg;
  return array('#markup' => $markup);
}

Las posiciones inician por el valor 0, podemos ver el siguiente ejemplo de su resultado:

Ruta con pase de parámetros y control de acceso basico:

function rutas_menu() {
  $items['path/id/%'] = array(
    'title'           => 'Ejemplo de ruta #3',
    'page callback'   => 'rutas_example_three_form',
    'page arguments'  => array(2),
    'access callback' => TRUE,
    'access callback' => 'user_is_logged_in',
  );
}

function rutas_example_three_form($arg){
  $markup = t('Parámetro ID del url: ') . $arg;
  return array('#markup' => $markup);
}

En el siguiente ejemplo podemos observar dos resultados; el primero es un acceso negado, el segundo es el resultado cuando el acceso es correcto. Cualquiera de los ejemplos anteriores son ideales para hacer un callback de AJAX, solo debemos cambiar el header de retorno.

Ruta con pase de dos parámetros y callback del formulario:

function rutas_menu() {
  $items['path/four/id/%/%'] = array(
    'title'           => 'Ejemplo de ruta #4',
    'page callback'   => 'drupal_get_form',
    'page arguments'  => array('rutas_example_four_form', 3, 4),
    'access callback' => TRUE,
  );
}

function rutas_example_four_form($form, &$form_state, $arg1, $arg2) {
  $markup = t('Parámetros del url: ') . $arg1 . ', ' . $arg2;
  $form['body'] = array('#markup' => $markup);
  return $form;
}

Este ejemplo es ideal cuando trabajamos con formularios propios.

Es muy importante limpiar el cache luego de modificar la función del menu y sus respectivas funciones de tipo callback.

¿Cómo mostrar una tabla dentro de un modulo de Drupal 7?

Mostrar una tabla de resultados es algo muy habitual, tenemos dos grandes formas de crearla usando las API de Drupal 7, una tabla simple y una con selección simple o múltiple de registros. Vamos a mostrar como se hacen de las dos formas.
 
Tabla simple:
En ésta tabla existe un sort para la columna, para este ejemplo no lo explicamos, ya que simplemente es capturar el valor y modificarlo en la consulta, cosa que no se tratará en este caso. Esto es un ejemplo de lo que se debería ver:

Su código fuente:

function tablas_form($form, &$form_state){
  $header = array(
    array('data' => 'Nombre'   , 'field' => 'firstname' ),
   array('data' => 'Apellido' , 'field' => 'lastname'  ),
   array('data' => 'e-mail'   , 'field' => 'email'      , 'sort' => 'asc'),
 );
 
  $rows[] = array('firstname' => 'Fulano',
                  'lastname'  => 'Mevio',
                  'email'     => '[email protected]');
  $rows[] = array('firstname' => 'Mengano',
                  'lastname'  => 'Tizio',
                  'email'     => '[email protected]');
  $rows[] = array('firstname' => 'Zutano',
                  'lastname'  => 'Caio',
                  'email'     => '[email protected]');
  $rows[] = array('firstname' => 'Perengano',
                  'lastname'  => 'Sempronio',
                  'email'     => '[email protected]');

  $form['tabla'] = array(
    '#theme'  => 'table',
    '#header' => $header,
    '#rows'   => $rows,
    '#empty'  => t('No hay registros.'),
  );
  
  return $form;
}

Tabla de selección simple y multiple:
El código de ambas es identico, solo debemos cambiar el valor del parametro ‘#multiple’ de un TRUE, por un FALSE para tener la opción de selección simple.

Su código fuente:

function tablas_form($form, &$form_state){
  $header = array ('firstname' => t('First Name'),
                   'lastname'  => t('Last Name'));

  $rows[] = array('firstname' => 'Fulano',
                   'lastname'  => 'Mevio',
                   'email'     => '[email protected]');
  $rows[] = array('firstname' => 'Mengano',
                   'lastname'  => 'Tizio',
                   'email'     => '[email protected]');
  $rows[] = array('firstname' => 'Zutano',
                   'lastname'  => 'Caio',
                   'email'     => '[email protected]');
  $rows[] = array('firstname' => 'Perengano',
                   'lastname'  => 'Sempronio',
                   'email'     => '[email protected]');
  
  $form['table'] = array ('#type'     => 'tableselect',
                          '#header'   => $header,
                          '#options'  => $rows,
                          '#multiple' => TRUE,
                          '#empty'    => t('No hay registros.'));
  
  $form['submit'] = array
  (
    '#type' => 'submit',
    '#value' => t('Enviar'),
  );
  
  return $form;
}

Espero que les haya sido útil.

¿Cómo manejar el cache de un bloque en Drupal 7?

Cuando creamos un módulo posiblemente necesitamos usar una cache evitando que los datos a mostrar no se actualizan constantemente, de ésta forma mejoramos el rendimiento, y más cuando provienen de un servicio de terceros.

Drupal 7 nos ofrece un mecanismo de cache muy flexible y fácil de usar, básicamente consiste en dos métodos, uno que guarda los datos en una determinada estructura con un tiempo de expiración y el otro para poder recuperarlos cuando sea necesario, estos datos se almacenan en la Base de Datos y se actualizan cada ves que se ejecuta la rutina de mantenimiento mediante el cron, siempre y cuando tengamos el cache activo en las opciones de rendimiento.

Como ejemplo de este post, vamos a completar un post anterior que trata de ¿Cómo crear desde cero un Bloque básico en Drupal 7?, es ideal porque realiza una consulta a un servicio de terceros y los valores de la temperatura se actualizan en un determinado tiempo. Por lo que aconsejo revisar en post anterior para entender mejor.

La implementación del cache en éste módulo solo afecta al método “eltiempo_block_view”, dentro colocamos el manejo del cache y dejamos intacta la lógica para obtener los valores del servicio de terceros, quedando de la siguiente forma:

function eltiempo_block_view($delta = ''){
  switch($delta) {
    case 'eltiempo':
      $cache = cache_get('eltiempo', 'cache_block');
      
      if (!empty($cache) && isset($cache->data) && !empty($cache->data) && $cache->expire >= time()) {
        return $cache->data;
      } else {
        $temps = _eltiempo_get_values();
        $theme = theme('eltiempo', array('max' => $temps['max'],
                                         'min' => $temps['min'],
                                         'now' => $temps['now'],
                                         'lup' => date("Y/m/d H:i")));
        $block['subject'] = t('ElTiempo.es');
        $block['content'] = $theme;
        
        cache_set('eltiempo', $block, 'cache_block', time() + (60 * 10));
        return $block;
      }
      
      break;
  }  
}

Como podemos observar en el código fuente anterior, siempre obtenemos los datos de la cache, luego preguntamos si a expirado debidamente para retornar los valores almacenados, de lo contrario volvemos a obtener los valores del servicio a terceros y los asignamos a la cache, es muy importante recordar colocar un tiempo de expiración, en este caso es de 10 minutos.

API a consultar:

Módulo para crear campos personalizados en Drupal 7

Hace unas semanas publique un tutorial de como crear un módulo en el que podías añadir campos personalizados dentro de un un mismo campo, pero hay que estar claro que esto nos lleva mucho mas tiempo y dedicación para lograrlo, y no todos tenemos el tiempo para programar bajo las exigencias que nos encontramos de momento, o las destrezas, por lo menos para mi conseguir una buena documentación de Drupal es todo un problema, casi que uno invierte mas tiempo en documentarse que programando.
Hoy les presento un módulo que nos resuelve la vida, está desarrollado únicamente para la versión 7, se llama Field Collection, y adicionalmente se requiere del módulo Entity API
Luego de instalarlos y habilitarlos debemos crear un field dentro de un tipo de contenido:

Cuando éste ya está asignado podremos ir a Estructura / Field collections, de lo contrario no aparecerá.

De la lista buscamos dicho field y podremos definir field adicionales que lo conformara.

En el tipo de contenido para el usuario obtendría éste resultado:

Ahora si queremos que se vea como una tabla, hay un módulo que se llama

Field Collection Table que nos permite dar ese efecto.