Drupal Twig variable initialization error

The problem I’m trying to solve is this: I need a unique (but human readable) class name to be able to style Taxonomy Term page depending on the term shown. I unsuccessfully tried several approaches, the nearest being this:

  1. Use standard Taxonomy Term View to display the page;
  2. Calcuate class name based on the path alias for the term;
  3. Modify views-view.html.twig template to inject the class name above into one of the divs on the page.

My views-view.html.twig excerpt:

{% set tid = view.argument["tid"].value[0] %}
HEREITIS:{{tid}}<br/>
{% set pathclass = path('entity.taxonomy_term.canonical', {'taxonomy_term': 48}) | replace({'/': '-'}) %}
{%
  set classes = [
    dom_id ? 'js-view-dom-id-' ~ dom_id,
    tid,
    pathclass,
  ]
%}
<div{{ attributes.addClass(classes) }}>

And it produces the result that I could almost work with:

<!-- 💡 BEGIN CUSTOM TEMPLATE OUTPUT from 'sites/bezdatu.test/themes/qq/templates/views/views-view.html.twig' -->
HEREITIS:48<br/>
<div class="view-taxonomy-term contextual-region js-view-dom-id-8549dd661... 48 -category-holiday">

Note that both numbers “48” in the result come from tid variable and “-category-holiday” is correctly calculated based on the hardcoded “48” number. “Hardcoded” however is the only working scenario and I’m at total loss as to why changing

path('entity.taxonomy_term.canonical', {'taxonomy_term': 48})

to

path('entity.taxonomy_term.canonical', {'taxonomy_term': tid})

results in “an unexpected error” saying that I’m passing an empty value:

The website encountered an unexpected error. Try again later.

Symfony\Component\Routing\Exception\InvalidParameterException: Parameter “taxonomy_term” for route “entity.taxonomy_term.canonical” must match “[^/]++” (“” given) to generate a corresponding URL. in Drupal\Core\Routing\UrlGenerator->doGenerate() (line 202 of core/lib/Drupal/Core/Routing/UrlGenerator.php).

The variable is not empty, it is “48” and my only guess is that the twig template gets parsed before the variable value is calculated or view arguments become available. Is there any fix for this or any other simple approach to add path alias as css class name short of fiddling with javascript?

The issue you’re encountering happens because Twig is attempting to render the template before the taxonomy term argument (tid) is fully available for the path() function. The error you’re seeing is related to trying to use tid in the path() function before it’s properly set or resolved.

Here’s how you can fix it and ensure that the term ID (tid) is correctly passed to generate the path dynamically.

Solution: Correct Use of tid in path()

It seems like the problem is due to how Twig is evaluating the tid variable. To ensure that the term ID is correctly used in the path() function, you should extract the tid properly from the view arguments and confirm it’s available when generating the path.

Steps to Fix:

  1. Extract the tid Properly: Instead of accessing the tid like this:

twig

Copy code

{% set tid = view.argument["tid"].value[0] %}

Try using the view argument more reliably. It might be better to use the following:

twig

Copy code

{% set tid = view.args[0] %}

This way, you access the argument directly from the view.args array, assuming your view passes the taxonomy term ID as the first argument.
2. Generate the Path Dynamically: Once you have the tid, you can use it in the path() function without hardcoding it. Use the variable tid directly to generate the canonical path for the taxonomy term:

twig

Copy code

{% set pathclass = path('entity.taxonomy_term.canonical', {'taxonomy_term': tid}) | replace({'/': '-'}) %}
  1. Full Code Example: Here’s your updated views-view.html.twig template snippet with the corrections applied:

twig

Copy code

{# Extract the term ID from view arguments reliably #}
{% set tid = view.args[0] %}

{# Generate the path alias dynamically based on the tid #}
{% set pathclass = path('entity.taxonomy_term.canonical', {'taxonomy_term': tid}) | replace({'/': '-'}) %}

{# Set classes including the term ID and path alias-based class #}
{% set classes = [
  dom_id ? 'js-view-dom-id-' ~ dom_id,
  tid,
  pathclass,
] %}

<div{{ attributes.addClass(classes) }}>
  <!-- Content of the taxonomy term page -->
</div>

Explanation:

  1. Extracting tid: By using view.args[0], we ensure that the term ID is correctly pulled from the view arguments array. This is assuming that the term ID is the first argument passed to the view, which is common for taxonomy term pages.
  2. Generating Path: The path() function now uses the dynamically retrieved tid, and the replace() filter is used to format the path as a valid class name (replacing slashes with dashes).
  3. Assigning Classes: The classes array now includes both the tid and the path-based class, which can be used to style the page depending on the displayed taxonomy term.

Alternative Solution: Use Preprocess Hook

If for some reason Twig doesn’t provide enough flexibility, you can handle this in a preprocess function in your custom theme or module:

php

Copy code

function mytheme_preprocess_views_view(&$variables) {
  // Get the term ID from view arguments.
  if (!empty($variables['view']->args[0])) {
    $tid = $variables['view']->args[0];
    // Load the term entity to access its properties.
    $term = \Drupal\taxonomy\Entity\Term::load($tid);
    if ($term) {
      // Generate the path alias and format it as a CSS class.
      $path = \Drupal::service('path.alias_manager')->getAliasByPath('/taxonomy/term/' . $tid);
      $pathclass = str_replace('/', '-', $path);

      // Add the class to the view's attributes.
      $variables['attributes']['class'][] = 'term-' . $tid;
      $variables['attributes']['class'][] = $pathclass;
    }
  }
}

This preprocess hook ensures that the class is added server-side in PHP before rendering, offering a more flexible solution than Twig alone.


With either approach, you’ll be able to inject a unique, human-readable class based on the term’s alias, allowing you to style the page dynamically.