0

I have a content type tagged with various vocabularies. Each vocabulary has terms which I want to style with particular colours based on the vocabulary. For example, say I have a "Fruits" vocab which has term 'apple' and 'banana' and a "veggies" vocab with 'onion' and 'carrot'. I want to colour the apple and banana tags RED and the onion and carrot tags BLUE *in same node. Say I've a content type "article" which is tagged with apple from the fruits vocab and carrot from the veggies vocab. 'apple' should have a RED background and 'carrot' and BLUE background. Another content node has apple and banana for tags and they should both be RED.

I've found the following code, but it only works when the page I am viewing is the "apple" page - that is, I'm reading the page for the vocab term apple, NOT a content type tagged with apple. It DOESN'T work for tags in other content types and I'm failing miserably to find the right code.

function MYTHEME_preprocess_field__entity_reference(&$variables) {
  if (\Drupal::routeMatch()->getRouteName() == 'entity.taxonomy_term.canonical') {
  // load the term entity and get the data from there
  $term = \Drupal::routeMatch()->getParameter('taxonomy_term');
  $variables['vocab'] = $term->bundle();
  }
}

My theme has custom twig files for field--entity-reference.html.twig

and I'm trying to use the preprocess function above. Nothing I can find anywhere addresses this; what gives?

  • There is a lot missing here. First I don't think is the right hook. You either want node, or field (to loop the field items in either) and based on that, create new variables. Two, you don't need to check the route, this route only returns true if you are looking at the term page itself. – Kevin May 17 '18 at 18:33
  • The field--entity-reference.html.twig seems to be correct, because I can work with the individual tags there. for Example: (begin code) <div{{ item.attributes.addClass('taxonomy--item') }}> <a class="btn-small btn-danger" href="{{ item.content['#url'] }}" role="button">{{ mylabel|striptags }} </a> </div> (end code) Soooo, "item.content['#url']" DOES get the correct individual terms. Each one gets the url to its own page. But how can I here find each terms parent? – Poltavets May 17 '18 at 19:16
  • but i see that the preprocess hook is wrong. thanks – Poltavets May 17 '18 at 19:33
  • Some more info. This will get me each tag's uuid --- {{ item.content['#options'].entity.uuid.0.value}} --- But I cannot seem to get the 'vid' value...which is all i really need. – Poltavets May 17 '18 at 19:39
  • After much trial and error THIS WORKS: ——— {{ item.content['#options'].entity.vid.0.value['target_id'] }} – Poltavets May 17 '18 at 19:47
0

Adding the answer now. My final code in the field--entity-reference.html.twig file:

{% for item in items %}
  {% set mylabel %}
    {{ item.content }}
  {% endset %}
  {% set myclass %}
    {{ item.content['#options'].entity.vid.0.value['target_id'] }}
  {% endset %}
  {% set myclass = myclass|replace({'_':'-'}) %}
    <div{{ item.attributes.addClass('taxonomy--item') }}>
      <a class="btn-small btn-primary tag-{{ myclass|trim }}" href="{{ item.content['#url'] }}" role="button">{{ mylabel|striptags }}</a>
    </div>
{% endfor %}

HERE is the code needed in a node to access the parent vocabulary of the taxonomy terms in the node. (That is, individual tags on a content type node).

item.content['#options'].entity.vid.0.value['target_id']

NOTE: This is on Drupal 8.5.3 and none of my "tags" have more than one parent.

0

Just in case someone comes along here, I've left the other answer (now below), but have since found a better solution.

Instead of using the field--entity-reference.html.twig I'm now using field.html.twig. I suspect that eventually this might lead to an 'include' or 'embed' solution, but I'm not there yet.

For now, since my "tags" will never show labels, I only use this code in the field.html.twig file @ {% if label_hidden %}. The code is copied twice (which I don't like and which makes me want to find a different, cleaner solution), once for {% if multiple %} and again for if not multiple, since a node may only have one tag, or several.

Here is the code:

{% if label_hidden %}
{% if multiple %}
<div{{ attributes.addClass(classes, 'field--items') }}>
  {% for item in items %}
  {% set mylabel %}
      {{ item.content }}
  {% endset %}
  {% set myclass %}
    {{ item.content['#options'].entity.vid.0.value['target_id'] }}
  {% endset %}
  {% set cls %}
  {{ ('field_' ~ myclass)|trim }}
  {% endset %}
  {% set cls = cls|replace({' ':''}) %}
  {% if (field_name|trim == cls|trim ) %}
  {% set myclass = myclass|replace({'_':'-'}) %}
  <div{{ item.attributes.addClass('taxonomy--item') }}>
    <a class="btn-small tag-{{ myclass|trim }}" href="{{ item.content['#url'] }}" role="button">{{ mylabel|striptags }}</a>
  </div>
  {% else %}
  <div{{ attributes.addClass(classes, 'field--item') }}>{{ item.content }}</div>
  {% endif %}
  {% endfor %}
</div>
{% else %}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.