diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index 8d527df..a518c13 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -2294,20 +2294,37 @@ function theme_mark($variables) {
}
/**
- * Preprocesses variables for theme_item_list().
+ * Preprocesses variables for item list templates.
+ *
+ * Default template: item-list.html.twig.
*
* @param array $variables
- * An associative array containing theme variables for theme_item_list().
- * 'items' in variables will be processed to automatically inherit the
- * variables of this list to any possibly contained nested lists that do not
- * specify custom render properties. This allows callers to specify larger
- * nested lists, without having to explicitly specify and repeat the render
- * properties for all nested child lists.
+ * An associative array containing:
+ * - 'items' in variables will be processed to automatically inherit the
+ * variables of this list to any possibly contained nested lists that do
+ * not specify custom render properties. This allows callers to specify
+ * larger nested lists, without having to explicitly specify and repeat the
+ * render properties for all nested child lists.
+ * - title: A title to be prepended to the list.
+ * - type: The type of list to return (e.g. "ul", "ol").
*/
function template_preprocess_item_list(&$variables) {
+ $variables['title'] = (string) $variables['title'];
+ // Change the name since 'type' clashes with #type.
+ $variables['tag'] = $variables['type'];
+
+ // Prepare for adding classes to each item.
+ $num_items = count($variables['items']);
+ $i = 0;
foreach ($variables['items'] as &$item) {
+ $i++;
+ $attributes = array();
// If the item value is an array, then it is a render array.
if (is_array($item)) {
+ // List items support attributes via the #wrapper_attributes property.
+ if (isset($item['#wrapper_attributes']) && is_array($item['#wrapper_attributes'])) {
+ $attributes = $item['#wrapper_attributes'];
+ }
// Determine whether there are any child elements in the item that are not
// fully-specified render arrays. If there are any, then the child
// elements present nested lists and we automatically inherit the render
@@ -2337,66 +2354,28 @@ function template_preprocess_item_list(&$variables) {
}
}
}
- }
-}
-
-/**
- * Returns HTML for a list or nested list of items.
- *
- * @param $variables
- * An associative array containing:
- * - items: A list of items to render. Allowed values are strings or
- * render arrays. Render arrays can specify list item attributes in the
- * #wrapper_attributes property.
- * - title: The title of the list.
- * - type: The type of list to return (e.g. "ul", "ol").
- * - attributes: The attributes applied to the list element.
- */
-function theme_item_list($variables) {
- $items = $variables['items'];
- $title = (string) $variables['title'];
- // @todo 'type' clashes with '#type'. Rename to 'tag'.
- $type = $variables['type'];
- $list_attributes = $variables['attributes'];
-
- $output = '';
- if ($items) {
- $output .= '<' . $type . new Attribute($list_attributes) . '>';
-
- $num_items = count($items);
- $i = 0;
- foreach ($items as &$item) {
- $i++;
- $attributes = array();
- if (is_array($item)) {
- if (isset($item['#wrapper_attributes'])) {
- $attributes = $item['#wrapper_attributes'];
- }
- $item = drupal_render($item);
- }
- $attributes['class'][] = ($i % 2 ? 'odd' : 'even');
- if ($i == 1) {
- $attributes['class'][] = 'first';
- }
- if ($i == $num_items) {
- $attributes['class'][] = 'last';
- }
- $output .= '
' . $item . '';
+ else {
+ // Turn the item into an array if it wasn't one already.
+ $item = array('#markup' => $item);
}
- $output .= "$type>";
- }
- // Only output the list container and title, if there are any list items.
- // Check to see whether the block title exists before adding a header.
- // Empty headers are not semantic and present accessibility challenges.
- if ($output !== '') {
- if ($title !== '') {
- $title = '' . $title . '
';
+ // @todo remove after http://drupal.org/node/1649780 lands.
+ $attributes['class'][] = ($i % 2 ? 'odd' : 'even');
+ if ($i == 1) {
+ $attributes['class'][] = 'first';
+ }
+ if ($i == $num_items) {
+ $attributes['class'][] = 'last';
}
- $output = '' . $title . $output . '
';
+
+ // In order to avoid '..is not a valid render element' errors in render(),
+ // use the #-prefixed #wrapper_attributes property to store item wrapper
+ // attributes for Twig.
+ $item['#wrapper_attributes'] = new Attribute($attributes);
}
- return $output;
+ // These are the top level list attributes.
+ $variables['attributes'] = new Attribute($variables['attributes']);
}
/**
@@ -2645,9 +2624,6 @@ function template_preprocess(&$variables, $hook) {
'title_attributes' => clone $default_attributes,
'content_attributes' => clone $default_attributes,
);
-
- // Initialize html class attribute for the current hook.
- $variables['attributes']['class'][] = drupal_html_class($hook);
}
/**
@@ -3121,6 +3097,7 @@ function template_preprocess_region(&$variables) {
$variables['content'] = $variables['elements']['#children'];
$variables['region'] = $variables['elements']['#region'];
+ $variables['attributes']['class'][] = 'region';
$variables['attributes']['class'][] = drupal_region_class($variables['region']);
$variables['theme_hook_suggestions'][] = 'region__' . $variables['region'];
}
@@ -3194,6 +3171,7 @@ function drupal_common_theme() {
),
'item_list' => array(
'variables' => array('items' => array(), 'title' => '', 'type' => 'ul', 'attributes' => array()),
+ 'template' => 'item-list',
),
'more_help_link' => array(
'variables' => array('url' => NULL),
diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index 42f22fa..0d9236b 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -550,6 +550,7 @@ function template_preprocess_block(&$variables) {
// Create the $content variable that templates expect.
$variables['content'] = $variables['elements']['#children'];
+ $variables['attributes']['class'][] = 'block';
$variables['attributes']['class'][] = drupal_html_class('block-' . $variables['block']->module);
// Add default class for block content.
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index dd87b29..0a322d5 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -1707,6 +1707,7 @@ function template_preprocess_comment(&$variables) {
}
// Gather comment classes.
+ $variables['attributes']['class'][] = 'comment';
// 'published' class is not needed, it is either 'preview' or 'unpublished'.
if ($variables['status'] != 'published') {
$variables['attributes']['class'][] = $variables['status'];
diff --git a/core/modules/system/templates/item-list.html.twig b/core/modules/system/templates/item-list.html.twig
new file mode 100644
index 0000000..60825c4
--- /dev/null
+++ b/core/modules/system/templates/item-list.html.twig
@@ -0,0 +1,41 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a list or nested list of items.
+ *
+ * Available variables:
+ * - items: A list of items to render. String values are rendered as is.
+ * Each item can also be an associative array containing:
+ * - data: The string content of the list item.
+ * - children: A list of nested child items to render that behave
+ * identically to 'items', but any non-numeric string keys are treated as
+ * HTML attributes for the child list that wraps 'children'.
+ * - attributes: The attributes applied to the list item.
+ * - title: The title of the list.
+ * - type: The type of list to return (e.g. "ul", "ol").
+ * - attributes: The attributes applied to the list element.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_item_list()
+ *
+ * @ingroup themeable
+ * @see http://drupal.org/node/1910996 To deprecate this
+ * @see http://drupal.org/node/1842140 To remove heading tag and div
+ */
+#}
+{% if items is not empty %}
+{% spaceless %}
+
+ {% if title is not empty -%}
+
{{ title }}
+ {%- endif %}
+ <{{ tag }}{{ attributes }}>
+ {% for item in items -%}
+ {# Get list item attributes from render array property. #}
+ {% set li_attributes = item['#wrapper_attributes'] %}
+ {{ item }}
+ {%- endfor -%}
+ {{ tag }}>
+
+{% endspaceless %}
+{% endif %}