Agregue una clase a una celda de la tabla Drupal que contenga ['datos']

11

En Drupal 8, lo que hace Tablas es todavía mucho como Drupal 7. construir matrices multidimensionales de filas y columnas en PHP que se transforma en un Drupal <tr>y <td>s, respectivamente. Todavía existe este confuso Drupalismo conocido como 'data'que le permite agregar elementos de matriz de renderizado como datos de celda (que no debe confundirse con los atributos de datos).

Me dieron un sitio donde el desarrollador eligió usar 'datos' para representar el contenido de la celda, pero no puedo entender cómo agregar una clase a <td>los datos.

He leído el código fuente y la documentación de Table.php y estoy al tanto de lo nuevo, #wrapper_attributes pero no puedo descifrarlo.

He intentado al menos cuatro formas de agregar la clase, y ninguna funciona.

$table['row-' . $row_id] = [

  // Option 1: Class appears on <tr> tag
  '#attributes' => [
    'class' => ['option-1-row-attributes'],
    'id' => 'row-' . $row_id,
    'no_striping' => TRUE,
  ],

  // Option 2: Class appears on <td> tag of first column. 
  'item' => [
    '#markup' => $row['my_item']->label(),
    '#wrapper_attributes' => [   
      'class' => ['option-2-markup-wrapper-attributes'],
    ],
  ],

  // In the following section, the only item that works is
  // the class on the <a> tag.
  'edit_operation' => [
    'data' => [
      '#type' => 'link',
      '#url' => Url::fromRoute('my_module.my_route', ['item' => $row_id]),
      '#title' => $this->t('Edit'),
      '#attributes' => [
        // Option 3: Class appears on the anchor tag
        'class' => ['use-ajax', 'option-3-link-attributes'],
        'data-dialog-type' => 'modal',
        'data-dialog-options' => Json::encode([
          'width' => 700,
        ]),
      ],
      // Option 4: Has no effect.
      '#wrapper_attributes' => [
        'class' => ['option-4-data-wrapper-attributes'],
      ],
    ],
    // Option 5: Update: This appears to be the correct solution! 
    // Class appears on the <td>.
    '#wrapper_attributes' => [
      'class' => ['option-5-wrapper-attributes'],
    ],
    // Option 6: Has no effect.
    '#attributes' => [
      'class' => ['option-6-attributes'],
    ],
    // Option 7: Has no effect.
    'class' => ['option-7-attributes'],
  ],
];
JamesWilson
fuente

Respuestas:

12

Después de escribir la pregunta en términos generales, volví a la prueba nuevamente y determiné que la Opción 5 en el OP con '#wrapper_attributes'el mismo nivel del 'data'elemento funciona. Creo que Drupal 8 estaba almacenando en caché la tabla agresivamente, porque mis cambios no aparecían incluso después de un drush cr.

Las reglas para agregar clases a tablas a través de backend PHP son:

  • La clase de mesa requiere #attributes.
  • La clase de fila TR dentro de TBODY requiere #attributes.
  • La clase celular TD dentro de TBODY requiere #wrapper_attributes.
  • La clase de fila TR dentro de THEAD / TFOOT requiere 'class'y 'data'contenedores.
    Ni #attributestampoco #wrapper_attributestrabajo aquí.
  • La clase de celda TH / TD dentro de THEAD / TFOOT requiere 'class'y 'data'contenedores.
    Ni #attributestampoco #wrapper_attributestrabajo aquí.
  • No hay forma de agregar una clase directamente a una etiqueta <thead>o <tfoot>sin anular una plantilla de ramita.

Este es el ejemplo más común para agregar clases a las etiquetas <tr>& <td>dentro de main <tbody>, así como a la <table>etiqueta principal en sí:

$table = [
  '#type' => 'table',
  '#attributes' => [
    'class' => ['table-class'],
  ],
  'row1' => [
    '#attributes' => [
      'class' => ['tr-class'],
    ],
    // Table data cell using 'data' for renderable elements.
    'column1' => [
      'data' => [
        '#type' => 'link', // Or any other renderable thing.
        '#attributes' => [
          'class' => ['link-class'],
        ],
        // Other elements required to render the link go here...
      ],
      '#wrapper_attributes' => [ // Watch out!
        'class' => ['td-class'],
      ],
    ],
    // Table data cell using '#markup'.
    'column2' => [
      '#markup' => '<span>' . $this->t('text') . '</span>',
      '#wrapper_attributes' => [   
        'class' => ['td-class'],
      ],
    ],
  ],
];

Tenga en cuenta que el 'class'contenedor aceptará una cadena o una matriz, pero sugiero usar siempre una matriz.

A partir de aquí, la historia se vuelve más complicada. Si necesita agregar clases a las etiquetas TR o TD / TH dentro de un área THEAD / TFOOT, las reglas cambian por completo. Ni #attributestampoco #wrapper_attributesen el interior de trabajo #headery #footersecciones y tratando de utilizar los produce efectos muy extraños.

La estructura mínima básica para tablas con columnas de datos de encabezado / pie de página en Drupal 8 es la siguiente:

$table = [
  '#type' => 'table',
  // Produces <thead> <tr> <th>
  '#header' => [
    'Header 1',
    'Header 2',
    'Header 3',
  ],
  // Produces <tbody> <tr> <td>
  'row1' => [
    'Body 1',
    'Body 2',
    'Body 3',
  ],
  // Produces <tfoot> <tr> <td>
  '#footer' => [
    'Footer 1',
    'Footer 2',
    'Footer 3',
  ],
];

Debe cambiar la estructura real de los datos e introducir dos niveles de matrices multidimensionales adicionales, a fin de aprovechar el 'class'índice de matriz que requiere también introducir el 'data'índice de matriz. Esto se aplica tanto al elemento de fila como a los elementos de celda de datos, como se ve en el siguiente ejemplo:

$table = [
  '#type' => 'table',
  // This example works the same way for '#footer'.
  '#header' => [
    // First, introduce an extra level to the array to provide a
    // place to store the class attribute on the <tr> element inside
    // the <thead>.
    [
      'class' => 'thead-tr-class',
      // Next place the columns inside a 'data' container, so that
      // the 'class' can be used.  '#wrapper_attributes' will not
      // work here.
      'data' => [
        // The following line produces data inside a <th>
        // without any class.
        'Header 1',

        // The following lines produce data inside a <th>
        // with a class: th-class.
        [
           'class' => 'th-class',
           'data' => 'Header 2',
           'colspan' => 2
        ],
      ],
    ],
  ],
];

El ejemplo de #headerejemplo anterior produce:

<table>
  <thead>
    <tr class="thead-tr-class">
      <th>Header 1</th>
      <th class="th-class" colspan="2">Header 2</th>
    </tr>
  </thead>
</table>
JamesWilson
fuente
Estoy tratando de usar un colspan en el encabezado de la tabla, pero usando su último ejemplo obtengo estos errores:
Adrian Cid Almaguer
Error de usuario: "0" es una clave de matriz de procesamiento no válida en Drupal \ Core \ Render \ Element :: children () (línea 97 de core / lib / Drupal / Core / Render / Element.php). Error del usuario: "clase" es una clave de matriz de renderización no válida en Drupal \ Core \ Render \ Element :: children () (línea 97 de core / lib / Drupal / Core / Render / Element.php). Error del usuario: "datos" es una clave de matriz de renderización no válida en Drupal \ Core \ Render \ Element :: children () (línea 97 de core / lib / Drupal / Core / Render / Element.php). Error de usuario: "colspan" es una clave de matriz de renderización no válida en Drupal \ Core \ Render \ Element :: children () (línea 97 de core / lib / Drupal / Core / Render / Element.php).
Adrian Cid Almaguer
Acabo de encontrar otra solución para el colspan, eche un vistazo aquí drupal.stackexchange.com/q/245710/28275
Adrian Cid Almaguer el