Añadir clases CSS a los Campos en Drupal

Template Files y Theme Functions


Todo HTML que Drupal envía al navegador se procesa usando uno de los siguientes métodos, un theme function o  un template file . El cuál está determinado por el módulo que invoca hook_theme () . Si no puede encontrar un template file para el HTML que desea cambiar, es probable que esté siendo creado por theme function. Si bien los dos se ven diferentes en la superficie, ambos hacen esencialmente lo mismo. Toman una $variable array o renderizan $element y devuelven una cadena, la mayoría de las veces, HTML. Los themes anulan tanto los archivos de plantilla como las funciones del theme de manera similar. Copie la función o plantilla existente de un módulo en su tema y edite a su gusto.


Necesitamos copiar el archivo de plantilla core block.tpl.php a nuestro tema y hacer algunas ediciones para tomar el control completo de nuestras clases de bloques.  De forma predeterminada, los campos se representan mediante una función de tema llamada theme_field () en lugar de un template file. Entonces, para modificar la función principal, necesitamos copiar theme_field () en el archivo template.php de nuestro tema y cambiarle el nombre a mytheme_field. Donde mytheme es el nombre de nuestro tema. A continuación, se muestra un ejemplo de cómo debería verse su nueva función de tema.

Snippet
/**
 * Overrides theme_field()
 * Remove the hard coded classes so we can add them in preprocess functions.
 */
 
function mytheme_field($variables) {
  $output = '';
 
  // Render the label, if it's not hidden.
  if (!$variables['label_hidden']) {
    $output .= '<div ' . $variables['title_attributes'] . '>' . $variables['label'] . ': </div>';
  }
 
  // Render the items.
  $output .= '<div ' . $variables['content_attributes'] . '>';
  foreach ($variables['items'] as $delta => $item) {
    $output .= '<div ' . $variables['item_attributes'][$delta] . '>' . drupal_render($item) . '</div>';
  }
  $output .= '</div>';
 
  // Render the top-level DIV.
  $output = '<div class="' . $variables['classes'] . '"' . $variables['attributes'] . '>' . $output . '</div>';
 
  return $output;
}

Notarás que se parece al tema central theme_field () pero con dos diferencias. Eliminamos los atributos de clase codificados de forma rígida de la etiqueta y los content wrapper divs. Esto nos permitirá administrar estas clases con una función de preproceso por campo. Al igual que los archivos de plantilla, puede modificar las variables que se pasan a las theme functions. Echemos un vistazo a nuestra función de preproceso y veamos cómo estamos agregando clases.

Snippet
/**
 * Implements hook_preprocess_field()
 */
 
function mytheme_preprocess_field(&$vars) {
  /* Set shortcut variables. Hooray for less typing! */
  $name = $vars['element']['#field_name'];
  $bundle = $vars['element']['#bundle'];
  $mode = $vars['element']['#view_mode'];
  $classes = &$vars['classes_array'];
  $title_classes = &$vars['title_attributes_array']['class'];
  $content_classes = &$vars['content_attributes_array']['class'];
  $item_classes = array();
 
  /* Global field classes */
  $classes[] = 'field-wrapper';
  $title_classes[] = 'field-label';
  $content_classes[] = 'field-items';
  $item_classes[] = 'field-item';
 
  /* Uncomment the lines below to see variables you can use to target a field */
  // print '<strong>Name:</strong> ' . $name . '<br/>';
  // print '<strong>Bundle:</strong> ' . $bundle  . '<br/>';
  // print '<strong>Mode:</strong> ' . $mode .'<br/>';
 
  /* Add specific classes to targeted fields */
  switch ($mode) {
    /* All teasers */
    case 'teaser':
      switch ($name) {
        /* Teaser read more links */
        case 'node_link':
          $item_classes[] = 'more-link';
          break;
        /* Teaser descriptions */
        case 'body':
        case 'field_description':
          $item_classes[] = 'description';
          break;
      }
      break;
  }
 
  switch ($name) {
    case 'field_authors':
      $title_classes[] = 'inline';
      $content_classes[] = 'authors';
      $item_classes[] = 'author';
      break;
  }
 
  // Apply odd or even classes along with our custom classes to each item */
  foreach ($vars['items'] as $delta => $item) {
    $vars['item_attributes_array'][$delta]['class'] = $item_classes;
    $vars['item_attributes_array'][$delta]['class'][] = $delta % 2 ? 'even' : 'odd';
  }
}

Para mantener la coherencia, hemos estructurado esta función de preproceso como preprocess_block de antes. Analicémoslo y veamos qué estamos haciendo.

Al igual que antes, creamos algunas variables de atajo para que no tengamos que escribir más tarde. Las 3 primeras variables, $name, $bundley $mode. Se utilizan para apuntar a campos individuales por name, bundle (piense en el tipo de contenido) y / o view mode  (avance, completo, etc.). Las siguientes cuatro variables son variables de clase . Representan una matriz de clases para cada uno de nuestros cuatro elementos HTML: el contenedor field wrapper, label, content wrapper y los elementos de un campo individual. 

A continuación, agregamos clases globales a todos los campos, incluidos los que originalmente estaban codificados en la función del tema principal antes de eliminarlos. Si desea o no agregar estas clases, depende de usted. Si no los usa y quiere reducir su huella HTML, por supuesto, elimínelos.

Después de nuestras clases globales, me gusta tener a mano declaraciones de impresión comentadas para cada una de nuestras variables de contexto. Estos simplemente imprimen el valor de la variable de contexto en la pantalla. Al descomentar una de estas líneas, puedo ver rápidamente qué valores se adjuntan a un campo individual para poder orientarlo correctamente.

Ahora entramos en la función donde agregamos clases a los campos específicos. Tenga en cuenta que esta función de preproceso se ejecuta en todos los campos que se representan, por lo que necesitamos una forma de distinguir a qué campos estamos agregando clases. Para eso son las variables de contexto. En el ejemplo anterior, la primera declaración de cambio verifica si este campo se muestra en modo teaser. Si es así, cambie de nuevo el nombre del campo. Si el nombre del campo es node_link , agregue la clase more-link. Si es el cuerpo o el campo de descripción , dos campos que a menudo comparten un significado semántico entre los tipos de contenido, agregue la description class.

La siguiente declaración de cambio es simplemente verificar el nombre del campo y agregar clases independientemente del modo de vista o el tipo de contenido. En este caso, estamos agregando clases al campo de autores de valores múltiples. Queremos que la etiqueta se muestre en línea, que el contenedor de contenido tenga una clase authors y que cada elemento tenga la clase author.

Tenga en cuenta que 'clase' es solo un atributo en la matriz de atributos. Puede ampliar este método aún más y comenzar a trabajar con otros atributos HTML como rel o data. 

Comments