Hinzufügen einer Klasse zu einer Drupal-Tabellenzelle mit ['Daten']

11

In Drupal 8 ähnelt das Rendern von Tabellen immer noch Drupal 7. Sie erstellen in PHP mehrdimensionale Arrays von Zeilen und Spalten, die Drupal in a <tr>bzw. <td>s umwandelt . Es gibt immer noch diesen verwirrenden Drupalismus 'data', mit dem Sie Render-Array-Elemente als Zellendaten hinzufügen können (nicht zu verwechseln mit Datenattributen ).

Ich habe eine Site erhalten, auf der der Entwickler "Daten" zum Rendern des Inhalts der Zelle verwendet hat, aber ich kann nicht herausfinden, wie eine Klasse zu <td>den Daten hinzugefügt werden kann.

Ich habe den Quellcode und die Dokumentation für Table.php gelesen und bin mir des neuen bewusst #wrapper_attributes , kann dies aber nicht knacken.

Ich habe mindestens vier Möglichkeiten ausprobiert, um die Klasse hinzuzufügen, und keine funktioniert.

$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'],
  ],
];
James Wilson
quelle

Antworten:

12

Nachdem ich die Frage allgemein geschrieben habe, bin ich wieder zum Testen zurückgekehrt und habe festgestellt, dass Option 5 im OP mit '#wrapper_attributes'derselben 'data'Elementstufe funktioniert. Ich glaube, Drupal 8 hat die Tabelle aggressiv zwischengespeichert, weil meine Änderungen auch nach a nicht angezeigt wurden drush cr.

Die Regeln für das Hinzufügen von Klassen zu Tabellen über Backend-PHP lauten:

  • Tabellenklasse erfordert #attributes.
  • TR-Zeilenklasse innerhalb von TBODY erforderlich #attributes.
  • TD-Zellenklasse innerhalb von TBODY erfordert #wrapper_attributes.
  • TR-Zeilenklasse in THEAD / TFOOT erfordert 'class'und 'data'Container.
    Weder #attributesnoch #wrapper_attributeshier arbeiten.
  • TH / TD-Zellklasse in THEAD / TFOOT erfordert 'class'und 'data'Container.
    Weder #attributesnoch #wrapper_attributeshier arbeiten.
  • Es gibt keine Möglichkeit, eine Klasse direkt zu einem <thead>oder einem <tfoot>Tag hinzuzufügen, ohne eine Zweigvorlage zu überschreiben.

Hier ist das häufigste Beispiel für das Hinzufügen von Klassen zu den <tr>& <td>-Tags innerhalb des Haupttags <tbody>sowie zum <table>Haupttag selbst:

$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'],
      ],
    ],
  ],
];

Beachten Sie, dass der 'class'Container entweder eine Zeichenfolge oder ein Array akzeptiert. Ich empfehle jedoch, immer ein Array zu verwenden.

Ab hier wird die Geschichte komplizierter. Wenn Sie den TR- oder TD / TH-Tags in einem THEAD / TFOOT-Bereich Klassen hinzufügen müssen, ändern sich die Regeln vollständig. Weder #attributesnoch #wrapper_attributesArbeit innerhalb #headerund #footerAbschnitte und versuchen , sie zu nutzen , entstehen sehr seltsame Effekte.

Die Mindeststruktur für Tabellen mit Kopf- / Fußzeilendatenspalten in Drupal 8 lautet wie folgt:

$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',
  ],
];

Sie müssen die tatsächliche Struktur der Daten ändern und zwei Ebenen zusätzlicher mehrdimensionaler Arrays 'class'einführen, um den 'data'Array-Index zu nutzen, für den dann auch der Array-Index eingeführt werden muss. Dies gilt sowohl für das Zeilenelement als auch für die Datenzellenelemente, wie im folgenden Beispiel dargestellt:

$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
        ],
      ],
    ],
  ],
];

Das obige #headerBeispielbeispiel erzeugt:

<table>
  <thead>
    <tr class="thead-tr-class">
      <th>Header 1</th>
      <th class="th-class" colspan="2">Header 2</th>
    </tr>
  </thead>
</table>
James Wilson
quelle
Ich versuche, einen Colspan in der Tabellenüberschrift zu verwenden, aber anhand Ihres letzten Beispiels erhalte ich folgende Fehler:
Adrian Cid Almaguer
Benutzerfehler: "0" ist ein ungültiger Render-Array-Schlüssel in Drupal \ Core \ Render \ Element :: children () (Zeile 97 von core / lib / Drupal / Core / Render / Element.php). Benutzerfehler: "Klasse" ist ein ungültiger Render-Array-Schlüssel in Drupal \ Core \ Render \ Element :: children () (Zeile 97 von core / lib / Drupal / Core / Render / Element.php). Benutzerfehler: "data" ist ein ungültiger Render-Array-Schlüssel in Drupal \ Core \ Render \ Element :: children () (Zeile 97 von core / lib / Drupal / Core / Render / Element.php). Benutzerfehler: "colspan" ist ein ungültiger Render-Array-Schlüssel in Drupal \ Core \ Render \ Element :: children () (Zeile 97 von core / lib / Drupal / Core / Render / Element.php).
Adrian Cid Almaguer
Ich habe gerade eine andere Lösung für den Colspan gefunden. Schauen Sie hier drupal.stackexchange.com/q/245710/28275
Adrian Cid Almaguer