diff -u b/core/includes/theme.inc b/core/includes/theme.inc --- b/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1066,6 +1066,7 @@ } } + /** * Prepares variables for inline list templates. * @@ -1073,66 +1074,16 @@ * * @param array $variables * An associative array containing: - * - items: An array of items to be displayed in the list. Each item can be - * either a string or a render array. If #type, #theme, or #markup - * properties are not specified for child render arrays, they will be - * inherited from the parent list, allowing callers to specify larger - * nested lists without having to explicitly specify and repeat the - * render properties for all nested child lists. - * - separator: A string to separate list items. + * - items: An array of items to be displayed in the list. * * @see https://www.drupal.org/node/1842756 */ function template_preprocess_inline_list(&$variables) { - foreach ($variables['items'] as &$item) { - $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'])) { - $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 - // array properties of the current list to them. - foreach (Element::children($item) as $key) { - $child = &$item[$key]; - // If this child element does not specify how it can be rendered, then - // we need to inherit the render properties of the current list. - if (!isset($child['#type']) && !isset($child['#theme']) && !isset($child['#markup'])) { - // Since inline-list.html.twig supports both strings and render arrays - // as items, the items of the nested list may have been specified as - // the child elements of the nested list, instead of #items. For - // convenience, we automatically move them into #items. - if (!isset($child['#items'])) { - // This is the same condition as in - // \Drupal\Core\Render\Element::children(), which cannot be used - // here, since it triggers an error on string values. - foreach ($child as $child_key => $child_value) { - if ($child_key[0] !== '#') { - $child['#items'][$child_key] = $child_value; - unset($child[$child_key]); - } - } - } - // Lastly, inherit the original theme variables of the current list. - $child['#theme'] = $variables['theme_hook_original']; - } - } - } - - // Set the item's value and attributes for the template. - $item = array( - 'value' => $item, - 'attributes' => new Attribute($attributes), - ); - - // Since the separator may be user-specified, it must be sanitized. - $variables['separator'] = SafeString::create(Xss::filterAdmin($variables['separator'])); - } + // Since the separator may be user-specified, it must be sanitized. + $variables['separator'] = SafeString::create(Xss::filterAdmin($variables['separator'])); } + /** * Returns HTML for an indentation div; used for drag and drop tables. * diff -u b/core/modules/system/templates/inline-list.html.twig b/core/modules/system/templates/inline-list.html.twig --- b/core/modules/system/templates/inline-list.html.twig +++ b/core/modules/system/templates/inline-list.html.twig @@ -4,11 +4,8 @@ * Default theme implementation for an inline list of items. * * Available variables: - * - items: A list of items. Each item contains: - * - attributes: HTML attributes to be applied to each list item. - * - value: The content of the list element. + * - items: An array of items. * - separator: A string to separate list items. - * - attributes: HTML attributes to be applied to the list. * - empty: A message to display when there are no items. Allowed value is a * string or render array. * @@ -18,7 +15,7 @@ */ #} {%- for item in items -%} - {{ item.value }}{{ loop.last ? '' : separator }} + {{ item }}{{ loop.last ? '' : separator }} {%- else -%} {{- empty -}} {%- endfor -%} reverted: --- b/core/themes/classy/templates/dataset/inline-list.html.twig +++ /dev/null @@ -1,30 +0,0 @@ -{# -/** - * @file - * Theme override for an inline list of items. - * - * Available variables: - * - items: A list of items. Each item contains: - * - attributes: HTML attributes to be applied to each list item. - * - value: The content of the list element. - * - separator: A string to separate list items. - * - attributes: HTML attributes to be applied to the list. - * - empty: A message to display when there are no items. Allowed value is a - * string or render array. - * - * @see template_preprocess_inline_list() - * - * @ingroup themeable - */ -#} -{%- if items or empty -%} - {%- if items -%} - - {%- for item in items -%} - {{ item.value }} - {%- endfor -%} - - {%- else -%} - {{- empty -}} - {%- endif -%} -{%- endif %} only in patch2: unchanged: --- a/core/modules/system/src/Tests/Theme/FunctionsTest.php +++ b/core/modules/system/src/Tests/Theme/FunctionsTest.php @@ -168,6 +168,50 @@ function testItemList() { } /** + * Tests inline-list.html.twig. + */ + function testInlineList() { + // Verify that empty items produce no output. + $variables = array(); + $expected = ''; + $this->assertThemeOutput('inline_list', $variables, $expected, 'Empty %callback generates no output.'); + + // Verify that empty items produce the empty string. + $variables = array(); + $variables['empty'] = 'No items found.'; + $expected = 'No items found.'; + $this->assertThemeOutput('inline_list', $variables, $expected, 'Empty %callback generates empty string.'); + + // Verify that empty text is not displayed when there are list items. + $variables = array(); + $variables['empty'] = 'No items found.'; + $variables['items'] = array('Un', 'Deux', 'Trois'); + $expected = 'Un, Deux, Trois'; + $this->assertThemeOutput('inline_list', $variables, $expected, '%callback does not print empty text when there are list items.'); + + // Verify that a non-default separator is rendered + $variables = array(); + $variables['items'] = array('Un', 'Deux', 'Trois'); + $variables['separator'] = ' and '; + $expected = 'Un and Deux and Trois'; + $this->assertThemeOutput('inline_list', $variables, $expected, '%callback uses a custom separator when provided.'); + + // Verify that HTML separators are properly rendered + $variables = array(); + $variables['items'] = array('Un', 'Deux', 'Trois'); + $variables['separator'] = '
'; + $expected = 'Un
Deux
Trois'; + $this->assertThemeOutput('inline_list', $variables, $expected, '%callback allows HTML in user-provided separators.'); + + // Verify that the separator is sanitized + $variables = array(); + $variables['items'] = array('Un', 'Deux', 'Trois'); + $variables['separator'] = ''; + $expected = 'Unalert("test")Deuxalert("test")Trois'; + $this->assertThemeOutput('inline_list', $variables, $expected, '%callback sanitizes user-provided separators.'); + } + + /** * Tests links.html.twig. */ function testLinks() {