0

I need to display a field value available to paragraph.html.twig in field.html.twig. I have a paragraph type called buttoncontainer with a field name called field_background_color. I have a paragraph type called button nested within that as per the attached screenshot. I need to make the field_background_color value available to field.html.twig.

Let's say field_background_color equates to #333333

In field.html.twig I want to do something like:

<div style="background: {{ color }};">
    {% for item in items %}
        {{ item.content }} 
    {% endfor %}
</div>  

Is this something that can be done with a preprocess function?

I tried

function mysubtheme_preprocess_paragraph(&$variables) {

  $paragraph = $variables['paragraph'];

  if ($paragraph->getType() === 'sidebar_button_repeater') {
    if (!$paragraph->field_background_color->isEmpty()) {
      $variables['color'] = $paragraph->get('field_background_color')->first()->getValue();
    }
  }
} 

...but it won't output the value in field.html.twig. The goal is simply to allow the user to determine the div background color behind the buttons they create.

Update: I also added:

 {% set paragraph_parent = paragraph.getParentEntity() %}
{% set color = paragraph_parent.field_background_color.0.value %}
Color  is {{ color }}. 

...but that doesn't work in field.html.twig either. It does however work in paragraph.html.twig templates.

I found a very useful link at Access A Referenced Node's Fields - Field Level Templating that may inform a change to the code. Maybe syntax using item? I can return the NESTED paragraph field values using {{ item.content['#node'].field_background_color.value }} but I can't return the PARENT paragraph field value.

My specific version of field.html.twig file is field--paragraph--sidebar-button-repeater.html.twig and {{ item.content }} does natively output the parent field field_background_color value (see img). The problem is how to capture that specific value so I can use it in a situation like: <div style="background: [output from field_background_color ];"> in field--paragraph--sidebar-button-repeater.html.twig. I was hoping some iteration of {{ item.content['#node'].field_background_color.value }} would achieve it. Can some parent parameter be added to capture the field value?

Here's my field--paragraph--sidebar-button-repeater.html.twig code. With the preprocessor function above in mind am I missing anything in set to output {{ color }}

Color is {{ color }} 

    {% for item in items %}
        {{ item.content }}
    {% endfor %}

This works for me but may not be the cleanest way:

{% set bgcolor = "" %}
{% for item in element['#items'] %}
    {% set bgcolor = item.entity.field_background_color.value %}
{% endfor %} 
   


{% if bgcolor == "#d25d12" %}
<div style="background:#d25d12;">
{% for item in items %}
       {{ item.content }}
    {% endfor %}
<div>
{% endif %}

enter image description here

enter image description here

1 Answer 1

1

To have a variable in a field template you need a field preprocess hook:

use Drupal\paragraphs\ParagraphInterface;

function mysubtheme_preprocess_field(&$variables) {

  $paragraph = $variables['element']['#object'];
  if ($paragraph instanceof ParagraphInterface) {
    if ($paragraph->getType() === 'sidebar_button_repeater') {
      if (!$paragraph->field_background_color->isEmpty()) {
        $variables['color'] = $paragraph->get('field_background_color')->value;
      }
    }
  }

} 

Nested Paragraphs

If the field is in the parent paragraph of a nested paragraph:

$parent = $paragraph->getParentEntity();

And get the field value from $parent:

function mysubtheme_preprocess_field(&$variables) {

  $paragraph = $variables['element']['#object'];
  if ($paragraph instanceof ParagraphInterface) {
    if ($paragraph->getType() === 'child_type') {
      $parent = $paragraph->getParentEntity();
      if ($parent instanceof ParagraphInterface) {     
        if ($parent->getType() === 'parent_type') {
          if (!$parent->field_background_color->isEmpty()) {
            $variables['color'] = $parent->get('field_background_color')->value;
          }
        }
      }
    }
  }

}

Why instanceof?

In the comments it was asked why to use instanceof?

In older Drupal versions you would use:

$entity_type = $variables['element']['#entity_type'];
$bundle = $variables['element']['#bundle']; 
if ($entity_type === 'paragraph' && $bundle === 'my_bundle') {
  // This works but your IDE doesn't understand it:
  $parent = $paragraph->getParentEntity();
  ...
}

In OOP code:

if ($paragraph instanceof ParagraphInterface) {
  if ($paragraph->getType() === 'my_bundle') {
    $parent = $paragraph->getParentEntity();
    ...
  }
}

Now it's safe to use methods defined in ParagraphInterface. The IDE will help you with autocomplete and by marking unknown methods causing run-time errors.

11
  • Thanks for helping. I added your preprocess function. So specifically in field.html.twig type templates (e.g field--paragraph--sidebar-button-repeater.html.twig ). do I just add {{ color }} to return the color e.g. Color is {{ color }}? That didn't work for me unfortunately. Also $parent = $paragraph->getParentEntity(); doesn't work for me in field.html.twig. It just works in paragraph.html.twig type templates. This link may lead to a solution: drupal.stackexchange.com/questions/233977/…. Question edited.
    – user111239
    Commented Sep 13, 2023 at 13:10
  • I've added a complete code example for the parent paragraph.
    – 4uk4
    Commented Sep 13, 2023 at 13:18
  • Thanks again. I must be overlooking something stupid my end. It just won't output the value for {{ color }} in field.html.twig or in paragraph.html.twig for that matter. I'll study it harder my end. I must be missing some setting. I appreciate the help! Using Drupal 9.5.10 if that applies.
    – user111239
    Commented Sep 13, 2023 at 13:52
  • My specific version of field.html.twig file is field--paragraph--sidebar-button-repeater.html.twig and {{ item.content }} does natively output the parent field field_background_color value. The problem is how to capture that specific value so I can use it in a situation like: <div style="background: [output from field_background_color ];"> in field--paragraph--sidebar-button-repeater.html.twig. I was hoping some iteration of {{ item.content['#node'].field_background_color.value }} would achieve it. Can some parent parameter be added to capture the field value?
    – user111239
    Commented Sep 13, 2023 at 14:45
  • If you test my code take baby steps. The first code line gets the entity where the field is placed. If it is a paragraph, it gets you to the second line. Put the result of the third line in a variable $variables['child_type'] = $paragraph->getType() and output it in the field template {{ child_type }} and so on ...
    – 4uk4
    Commented Sep 13, 2023 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.