Hello,

I'm new to Drupal and developing a theme for a site on Drupal 8. I want to add a preprocess hook to my THEME.theme file that looks up taxonomy terms for nodes.

I'd like different sections of the site to have different colour schemes, so for each section I intend to have a library of section-specific CSS files in addition to the global_styles library that has styles for all pages. I think the way to do this is to use THEME_preprocess_node() in my THEME.theme file, as described here. This hook would look for specific taxonomy terms applied to that node and attach different libraries for different terms. I can then change the theme for any node by changing a single taxonomy term.

I'm OK with the php side of things, but I'm really stuck with how I go about getting the taxonomy terms for a node - presumably they are somewhere in $variables?

I'd really appreciate any help you can offer.

Thanks! Chris

Comments

gavrochelegnou’s picture

I had a similar problem that i used by adding a class to the body tag depending on the current node's taxonomy :
I guess you could use that or use the code to add another css file

I used it in mytheme_preprocess_html() :

function mytheme_preprocess_html(&$variables) {
  // Get current node 
  $node =\Drupal::routeMatch()->getParameter('node');
  $taxo = $node->name_of_your_taxonomy_field->referencedEntities();
  $value_of_a_field = $taxo->name_of_a_field_in_taxo->getValue();
  $variables['taxo_dynamic_body_class'] = $value_of_a_field[0]['value']
}
Jeff Burnz’s picture

Are you declaring those libraries manually or do you want them dynamically created on the fly (library definitions can be automated)?

If you're creating them manually its just a matter of re-working gavrochelegnou code and using attached:

$variables['#attached']['library'][] = 'themename/libraryname';

chris5156’s picture

Thanks for your replies!

I'm afraid I am having trouble getting this to work. I don't think I understand what you mean by name_of_your_taxonomy_field and name_of_a_field_in_taxo.

I have a vocabulary of six terms which are used to indicate the section of the website for each node. Each node then has a field called "Department", with a machine name "field_department", that references one of those six terms. I think the problem is that I don't understand how those terms are then stored by Drupal, or how the vocabulary, term and field relate to the values I need to enter in gavrochelegnou's code.

It looks like line 4 should read $taxo = $node->field_department->referencedEntities(); - but I have tried all sorts of things on the following line and just get a 500 server error. I'm also having no luck using print_r or var_dump to interrogate the variables to see what I should be calling!

chris5156’s picture

Thought I should check back in with the solution I found, in case anyone else is looking to do the same.

Turns out that in D8 this is much easier to do using twig templates.

The field containing the taxonomy term should be added to the page display, so that when the page renders, Drupal inserts the field data into the page. Ordinarily this would turn up as one of the taxonomy terms down at the bottom of the page. In my case, the machine name of this field is field_department.

There then needs to be a twig template at templates/field/field--field-department.html.twig.

Within that template file, the name of the taxonomy term selected can be found by referencing items[0]['content']['#plain_text']. So it is then simply a matter of using some if...elseif looping to discover the value and load the right library, and omitting any code that would output the field to the user, like so:

{% if items[0]['content']['#plain_text'] == 'Section 1' %}
{{ attach_library('theme/section1') }}
{% elseif items[0]['content']['#plain_text'] == 'Section 2' %}
{{ attach_library('theme/section2') }}
...
{% endif %}

Works perfectly for me, and is very simple and versatile.