Crear formato personalizado para un campo de tipo fecha

27/05/2016
Crear formato personalizado para campo de tipo fecha

En este post descubrirás cómo crear un formato de fecha personalizado en Drupal 7.

Un formato de campo (conocido como field formatter) es una funcionalidad o característica que permite configurar la presentación de un campo para un modo de presentación (predeterminado,  resumen, etc). Por lo general cuando desde el core de Drupal o desde un módulo contribuido se proveen campos para añadir a los tipos de contenido, estos ofrecen formatos de presentación genéricos que si bien son los más usados, no siempre se ajustan a la presentación que necesitamos en nuestros proyectos. 

Como ejemplo, vamos usar un campo de tipo fecha proporcionado por el módulo Date y que está en el tipo de contenido Página básica. Como se puede observar en la imágen siguiente, vemos que en la configuración de la presentación del tipo de contenido para el modo de presentación Predeterminado, el campo Date ofrece tres formatos de presentación posibles (que son configurables) más uno para ocultarlo. El primero mostraría la fecha y la hora, el segundo el tiempo que ha pasado desde la fecha hasta la actualidad y el tercero mostraría la fecha en texto plano.

Ninguno de estos formatos nos sirve puesto que nosotros queremos un formato de presentación que muestre el día y el mes únicamente y además muestre estos valores en dos etiquetas <span> separadas, porque así nos lo exige el área de frontend para que se ajuste al diseño del proyecto.

Pues bien, para crear nuestro formato personalizado programáticamente seguiremos los siguientes pasos:

Paso 1 En el fichero .module del módulo custom o de la feature donde queramos añadir la funcionalidad, añadiremos el siguiente código. Se compone por una parte del hook_field_formatter_info y el hook_field_formatter_view que sirven para registrar el nuevo formato que en nuestro caso aplicaría a los tipos de campo date, datestamp y datetime. Por otro lado se define el hook_theme para registrar la función de tema y dicha función, que renderiza el contenido tal y como queremos que se presente. Es en esta función donde se implementa la lógica del formato.


/**
 * Implements hook_field_formatter_info().
 */
function custom_module_field_formatter_info() {
  return array(
    'custom_date_format' => array(
      'label' => t('Custom date format'),
      'field types' => array('date', 'datestamp', 'datetime'),
      'multiple values' => FIELD_BEHAVIOR_DEFAULT,
    ),
  );
}

/**
 * Implements hook_field_formatter_view().
 */
function custom_module_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $elements = array();
  foreach ($items as $delta => $item) {
    $element = array(
      'element' => $item,
      'field' => $instance,
      'display' => $display
    );
    $elements[$delta] = array(
      '#theme' => 'custom_module_formatter_' . $display['type'],
      '#element' => $element,
      '#field' => $field,
    );
  }

  return $elements;
}

/**
 * Implements hook_theme().
 */
function custom_module_theme() {
  $themes = array(
    'custom_module_formatter_custom_date_format' => array(
      'variables' => array(
        'element' => NULL,
        'field' => NULL,
      ),
    ),
  );
  return $themes;
}

/**
 * Implements theme function
 */
function theme_custom_module_formatter_custom_date_format($vars) {
  $element = $vars['element'];
  $field = $vars['field'];

  // Configure custom date
  $format_date = 'd M';
  $timezone_bd = date_get_timezone_db($field['settings']['tz_handling']);
  $publish_date = DateTime::createFromFormat('Y-m-d H:i:s', $element['element']['value'], new DateTimeZone($timezone_bd));
  $date = format_date($publish_date->getTimestamp(), 'custom', $format_date);
  $date = explode(' ', $date);

  // Declare array for render content with custom format and tags
  $render_array = array(
    'date' => array(
      'date-day' => array(
        '#prefix' =>'<span class="date-day">',
        '#markup' => $date[0],
        '#suffix' => '</span>'
      ),
      'date-month' => array(
        '#prefix' =>'<span class="date-month">',
        '#markup' => $date[1],
        '#suffix' => '</span>'
      ),
    ),
    '#theme_wrapper' => array('container'),
  );

  return render($render_array['date']);
}

Paso 2 Borrar la caché de Drupal.
 

Paso 3 Una vez añadido el código y borrada la caché, tendremos disponible un nuevo formato de fecha en la configuración de la presentación de nuestro tipo de contenido para el campo Date, que se llamará Custom date format.


 

Paso 4 Una vez seleccionado este formato y guardada la configuración de la presentación del tipo de contenido, si creamos un contenido de tipo Página básica, podemos observar que la fecha aparece en nuestro nuevo formato y en dos etiquetas <span> separadas.


Nota: Existen dos hooks (hook_field_formatter_settings_form y hook_field_formatter_settings_summary) que son usados para añadir una sección de configuración del formato, y que veremos próximamente en una nueva entrada.