I wish to use a custom item list template in a module that changes the <h3>
tag. The items I am rendering are link render arrays.
When I use the default template, a link render array works correctly and outputs the links. When I use a custom template, the links no longer appear. Am I missing a step?
This is the code I am using in the module.
function mymodule_theme($existing, $type, $theme, $path) {
return [
'mymodule__item_list' => [
'variables' => [
'items' => [
'attributes' => [],
'value' => [],
],
'title' => '',
'list_type' => 'ul',
'wrapper_attributes' => [],
'attributes' => [],
'empty' => NULL,
'context' => [],
],
'template' => 'mymodule--item-list',
],
];
}
The /templates/mymodule--item-list.html.twig template file contains the following code.
{#
/**
* @file
* Custom theme implementation for an item list.
*
* 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.
* - title: The title of the list.
* - list_type: The tag for list element ("ul" or "ol").
* - wrapper_attributes: HTML attributes to be applied to the list wrapper.
* - 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.
* - context: A list of contextual data associated with the list. May contain:
* - list_style: The custom list style.
*
* @see template_preprocess_item_list()
*
* @ingroup themeable
*/
#}
{% if context.list_style %}
{%- set attributes = attributes.addClass('item-list__' ~ context.list_style) %}
{% endif %}
{% if items or empty %}
{%- if title is not empty -%}
<p><strong>{{ title }}</strong></p>
{%- endif -%}
{%- if items -%}
<{{ list_type }}{{ attributes }}>
{%- for item in items -%}
<li{{ item.attributes }}>{{ item.value }}</li>
{%- endfor -%}
</{{ list_type }}>
{%- else -%}
{{- empty -}}
{%- endif -%}
{%- endif %}
In the module, I assemble the link items into the unordered list using the following code.
// $foo and $bar are set from the code before this.
$commonlyUsedForItems = [];
foreach ($commonlyUsedfor as $name) {
$url = Url::fromRoute('mymodule.page', [], [
'query' => [
'foo' => $foo,
'bar' => $bar,
'name' => $name,
],
]);
// Create an array of link render arrays.
$commonlyUsedForItems[] = [
'#type' => 'link',
'#title' => $this->t($name),
'#url' => $url,
];
}
$commonlyUsedForRenderArray = [
'#theme' => 'mymodule__item_list',
'#type' => 'ul',
'#title' => 'Commonly used for:',
'#items' => $commonlyUsedForItems,
'#attributes' => ['class' => 'commonlyUsedFor'],
'#wrapper_attributes' => ['class' => 'container'],
];
The code above works correctly changing '#theme' => 'mymodule__item_list',
to '#theme' => 'item_list',
.
The code as it is kind of works, but it prints out empty bullet points.
I know I could revert the $commonlyUsedForItems
array to markup and hardcode the HTML, but I am trying to keep HTML and PHP separated as much as I can.
Do you have any idea?