diff --git a/includes/common.inc b/includes/common.inc index 631d246..21c7f3e 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -6809,7 +6809,7 @@ function drupal_common_theme() { 'variables' => array(), ), 'table' => array( - 'variables' => array('header' => NULL, 'rows' => NULL, 'attributes' => array(), 'caption' => NULL, 'colgroups' => array(), 'sticky' => TRUE, 'empty' => ''), + 'variables' => array('header' => NULL, 'footer' => NULL, 'rows' => NULL, 'attributes' => array(), 'caption' => NULL, 'colgroups' => array(), 'sticky' => TRUE, 'empty' => ''), ), 'tablesort_indicator' => array( 'variables' => array('style' => NULL), diff --git a/includes/theme.inc b/includes/theme.inc index ed34b82..70efbb3 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -1895,24 +1895,24 @@ function theme_breadcrumb($variables) { * - header: An array containing the table headers. Each element of the array * can be either a localized string or an associative array with the * following keys: - * - "data": The localized title of the table column. - * - "field": The database field represented in the table column (required - * if user is to be able to sort on this column). - * - "sort": A default sort order for this column ("asc" or "desc"). Only - * one column should be given a default sort order because table sorting + * - data: The localized title of the table column. + * - field: The database field represented in the table column (required if + * user is to be able to sort on this column). + * - sort: A default sort order for this column ("asc" or "desc"). Only one + * column should be given a default sort order because table sorting * only applies to one column at a time. * - Any HTML attributes, such as "colspan", to apply to the column header * cell. * - rows: An array of table rows. Every row is an array of cells, or an * associative array with the following keys: - * - "data": an array of cells + * - data: an array of cells * - Any HTML attributes, such as "class", to apply to the table row. - * - "no_striping": a boolean indicating that the row should receive no + * - no_striping: a boolean indicating that the row should receive no * 'even / odd' styling. Defaults to FALSE. * Each cell can be either a string or an associative array with the * following keys: - * - "data": The string to display in the table cell. - * - "header": Indicates this cell is a header. + * - data: The string to display in the table cell. + * - header: Indicates this cell is a header. * - Any HTML attributes, such as "colspan", to apply to the table cell. * Here's an example for $rows: * @code @@ -1924,9 +1924,11 @@ function theme_breadcrumb($variables) { * // Row with attributes on the row and some of its cells. * array( * 'data' => array('Cell 1', array('data' => 'Cell 2', 'colspan' => 2)), 'class' => array('funky') - * ) + * ), * ); * @endcode + * - footer: An array of table rows which will be printed within a + * tag, in the same format as the rows element (see above). * - attributes: An array of HTML attributes to apply to the table tag. * - caption: A localized string to use for the tag. * - colgroups: An array of column groups. Each element of the array can be @@ -2053,45 +2055,51 @@ function theme_table($variables) { $ts = array(); } - // Format the table rows: - if (count($rows)) { - $output .= "\n"; - $flip = array('even' => 'odd', 'odd' => 'even'); - $class = 'even'; - foreach ($rows as $number => $row) { - // Check if we're dealing with a simple or complex row - if (isset($row['data'])) { - $cells = $row['data']; - $no_striping = isset($row['no_striping']) ? $row['no_striping'] : FALSE; - - // Set the attributes array and exclude 'data' and 'no_striping'. - $attributes = $row; - unset($attributes['data']); - unset($attributes['no_striping']); - } - else { + // Rows and footer have the same structure. + $sections = array( + 'rows' => 'tbody', + 'footer' => 'tfoot', + ); + foreach ($sections as $section => $tag) { + if (!empty($variables[$section])) { + $output .= "<" . $tag . ">\n"; + $flip = array('even' => 'odd', 'odd' => 'even'); + $class = 'even'; + foreach ($variables[$section] as $number => $row) { $cells = $row; $attributes = array(); - $no_striping = FALSE; - } - if (count($cells)) { - // Add odd/even class + $no_striping = $section === 'footer'; + + // Check if we're dealing with a simple or complex row. + if (isset($row['data'])) { + $cells = $row['data']; + $no_striping = isset($row['no_striping']) ? $row['no_striping'] : $no_striping; + + // Set the attributes array and exclude 'data' and 'no_striping'. + $attributes = $row; + unset($attributes['data']); + unset($attributes['no_striping']); + } + + // Add odd/even class. if (!$no_striping) { $class = $flip[$class]; $attributes['class'][] = $class; } - // Build row - $output .= ' '; - $i = 0; - foreach ($cells as $cell) { - $cell = tablesort_cell($cell, $header, $ts, $i++); - $output .= _theme_table_cell($cell); + // Build row. + if (!empty($cells)) { + $output .= ' '; + $i = 0; + foreach ($cells as $cell) { + $cell = tablesort_cell($cell, $header, $ts, $i++); + $output .= _theme_table_cell($cell); + } + $output .= " \n"; } - $output .= " \n"; } + $output .= "\n"; } - $output .= "\n"; } $output .= "\n"; diff --git a/modules/simpletest/tests/theme.test b/modules/simpletest/tests/theme.test index f1a743e..5e986c9 100644 --- a/modules/simpletest/tests/theme.test +++ b/modules/simpletest/tests/theme.test @@ -170,6 +170,27 @@ class ThemeTableTestCase extends DrupalWebTestCase { } /** + * Test that the 'footer' option works correctly. + */ + function testThemeTableFooter() { + $footer = array( + array( + 'data' => array(1), + ), + array('Foo'), + ); + + $table = array( + 'rows' => array(), + 'footer' => $footer, + ); + + $this->content = theme('table', $table); + $this->content = preg_replace('@>\s+<@', '><', $this->content); + $this->assertRaw('1Foo', 'Table footer found.'); + } + + /** * Tableheader.js provides 'sticky' table headers, and is included by default. */ function testThemeTableStickyHeaders() {