This issue can be closed when #1939008: Convert theme_table() to Twig is committed.

Problem/Motivation

Passing an Attribute object to theme_table() without a class array throws exceptions when sticky headers or responsive headers are used.

This is an example of a render array that would throw exceptions:

$attributes = new Attribute(array('id' => 'blocks'));
drupal_add_tabledrag('blocks', 'order', 'sibling', 'block-weight');
$variables['table'] = array(
  '#theme' => 'table',
  '#header' => $header,
  '#rows' => $rows,
  '#attributes' => $attributes,
);

Relevant snippet from the Attribute change notice:

Classes are an example to use array for. When using array, you must initialize the array first before adding items.

  $variables['item_attribute'] = new Attribute();
  $variables['item_attribute']['class'] = array();
  $variables['item_attribute']['class'][] = 'class-1';

Relevant code from theme_table():

  // Add sticky headers, if applicable.
  if (count($header) && $sticky) {
    drupal_add_library('system', 'drupal.tableheader');
    // Add 'sticky-enabled' class to the table to identify it for JS.
    // This is needed to target tables constructed by this function.
    $attributes['class'][] = 'sticky-enabled';
  }
  // If the table has headers and it should react responsively to columns hidden
  // with the classes represented by the constants RESPONSIVE_PRIORITY_MEDIUM
  // and RESPONSIVE_PRIORITY_LOW, add the tableresponsive behaviors.
  if (count($header) && $responsive) {
    drupal_add_library('system', 'drupal.tableresponsive');
    // Add 'responsive-enabled' class to the table to identify it for JS.
    // This is needed to target tables constructed by this function.
    $attributes['class'][] = 'responsive-enabled';
  }

Proposed resolution

In theme_table(), initialize $attributes['class'] to an empty array if it is not already set.

Remaining tasks

TBD

User interface changes

n/a

API changes

n/a

#1898034: block.module - Convert PHPTemplate templates to Twig
#1898416: filter.module - Convert theme_ functions to Twig

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

steveoliver’s picture

Status: Active » Fixed

Committed this fix in d49269e:

diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 5b7bc50..f6e8e88 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -2199,7 +2199,12 @@ function template_preprocess_table(&$variables) {
       drupal_add_library('system', 'drupal.tableheader');
       // Add 'sticky-enabled' class to the table to identify it for JS.
       // This is needed to target tables constructed by this function.
-      $table_attributes['class'][] = 'sticky-enabled';
+      if (isset($table_attributes['class'])) {
+        $table_attributes['class'][] = 'sticky-enabled';
+      }
+      else {
+        $table_attributes['class'] = array('sticky-enabled');
+      }
     }
 
     // If the table has headers and it should react responsively to columns hidden
@@ -2209,7 +2214,12 @@ function template_preprocess_table(&$variables) {
       drupal_add_library('system', 'drupal.tableresponsive');
       // Add 'responsive-enabled' class to the table to identify it for JS.
       // This is needed to target tables constructed by this function.
-      $table_attributes['class'][] = 'responsive-enabled';
+      if (isset($table_attributes['class'])) {
+        $table_attributes['class'][] = 'responsive-enabled';
+      }
+      else {
+        $table_attributes['class'] = array('responsive-enabled');
+      }
     }
   }

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

star-szr’s picture

Project: » Drupal core
Version: » 8.x-dev
Component: Twig templates conversion (front-end branch) » theme system
Assigned: steveoliver » star-szr
Priority: Normal » Major
Status: Closed (fixed) » Needs review
Issue tags: +Twig
FileSize
1.36 KB

Moving to core queue with a patch and bumping to major, this is blocking at least these two conversions:

#1898034: block.module - Convert PHPTemplate templates to Twig
#1898416: filter.module - Convert theme_ functions to Twig

star-szr’s picture

Priority: Major » Normal

Okay, this might be handled in the theme.inc conversion, stay tuned and sorry for the noise. Downgrading priority for now.

Status: Needs review » Needs work

The last submitted patch, 1868212-3.patch, failed testing.

star-szr’s picture

Status: Needs work » Needs review
FileSize
1.42 KB
1.32 KB

Oops, picked the wrong patch to extract this change from. This one should pass testing.

star-szr’s picture

See #1939008: Convert theme_table() to Twig for the theme.inc conversion issue. This patch could maybe be incorporated there.

star-szr’s picture

FileSize
613 bytes

Simpler patch after having some time to review the Attribute object change notice: http://drupal.org/node/1727592

star-szr’s picture

Maybe the comment could make reference to the Attribute object and even have a link to the change notice as well. Not sure if that's overkill.

star-szr’s picture

After looking into this further, this patch issue may not be blocking Twig conversion after all. The conversions that are throwing exceptions should be fine after #1938904: Convert filter theme tables to table #type and #1938898: Convert block theme tables to table #type land. Still might not be a bad idea to add this, though, because it can cause problems with render arrays that use '#theme' => 'table'.

This code would throw exceptions:

$attributes = new Attribute(array('id' => 'blocks'));
drupal_add_tabledrag('blocks', 'order', 'sibling', 'block-weight');
$variables['table'] = array(
  '#theme' => 'table',
  '#header' => $header,
  '#rows' => $rows,
  '#attributes' => $attributes,
);

This doesn't throw exceptions, but IMO the empty class array shouldn't be needed:

$attributes = new Attribute(array('id' => 'blocks', 'class' => array()));
drupal_add_tabledrag('blocks', 'order', 'sibling', 'block-weight');
$variables['table'] = array(
  '#theme' => 'table',
  '#header' => $header,
  '#rows' => $rows,
  '#attributes' => $attributes,
);
star-szr’s picture

Title: Notice: Indirect modification of overloaded element of Drupal\Core\Template\Attribute has no effect in template_preprocess_table » Passing an Attribute object to theme_table() without a class array throws exceptions

Re-titling.

star-szr’s picture

Issue summary: View changes

Adding blocking issues to summary

star-szr’s picture

Issue summary: View changes

Updating issue summary to use template and reflect current issue status.

steveoliver’s picture

Title: Passing an Attribute object to theme_table() without a class array throws exceptions » Notice: Indirect modification of overloaded element of Drupal\Core\Template\Attribute has no effect
Status: Needs review » Fixed

I'd keep this titled as the error message people will see, and then search for once they hit this issue.

...and close this, since the fix is simple: initialize a variable/element before you use it.

star-szr’s picture

Title: Notice: Indirect modification of overloaded element of Drupal\Core\Template\Attribute has no effect » Notice: Indirect modification of overloaded element of Drupal\Core\Template\Attribute has no effect (theme_table)
Status: Fixed » Postponed

Sorry for the confusion. This patch would really only make sense if Twig conversion wasn't removing theme_table(). But because theme_table() conversion is already under way, this fix can be rolled in there.

So for now, postponing on #1939008: Convert theme_table() to Twig. I'll update the issue summary here and revise the patch at #1939008: Convert theme_table() to Twig to include this logic.

star-szr’s picture

Issue summary: View changes

Add example of a render array that would throw exceptions.

star-szr’s picture

Assigned: star-szr » Unassigned
Status: Postponed » Closed (works as designed)

Closing this out now…

star-szr’s picture

Issue summary: View changes

Add note about why this issue is postponed.