3

I have a Paragraphs bundle that has 2 fields. I want to have the value of the first field in the second field's template so I can combine it with {{ loop.index }} to make unique classes for a grid layout.

Is this possible using a preprocess function and a theme template?

4
  • You mean the field.html.twig template? Looking at the available variables there is no access to the entity or other fields. So without altering preprocessors I guess not. Commented Dec 24, 2016 at 20:57
  • Oh, apologies, I understood you wanted to this without a preprocessor. Forget my previous comment... Commented Dec 24, 2016 at 21:01
  • 1
    Instead of adding your div wrappers and class names in field.html.twig use node.html.twig, where you have access to both values. But since you're using paragraphs, in you case, it's probably the paragraphs template file.
    – No Sssweat
    Commented Dec 25, 2016 at 2:25
  • Yes, I am looking for a preprocess way of doing it. I don't think I can do it in the paragraph template because I need the loop.index that is in the field template to make the unique class. Commented Dec 25, 2016 at 16:32

6 Answers 6

10

For non-paragraph fields, there is a node object available in the variables of the field template, so you can put this in a field.html.twig file:

{{ element['#object'].machine_name_of_other_field.value }}
2

Here is a solution that I came up with to solve this in the Paragraph template (paragraph--PARAGRAPH-NAME.html.twig), but I still think there is a better way using a preprocess.

{# Renders Grid Style field. #}
{% if content.field_grid_style|render %}
  {% set grid_style = content.field_grid_style['#items'].getString() %}
{% endif %}

{#
  Loops through the Column field here instead of the field template so we can
  set the grid_style class and add the loop index (key + 1)
#}
{% for key, item in content.field_column_content if key|first != '#' %}
  <div class="{{ grid_style }}--{{ key + 1 }}">{{ item }}</div>
{% endfor %}
0

Here is the solution for rendering one field inside second's field template.

Get the first field value from hook_preprocess_field.

function teachervision_preprocess_file_field(&$variables) {
  if ($variables['field_name'] == 'second_field_machine_name') {
    $node = \Drupal::routeMatch()->getParameter('node');
    $variables['first_field'] = '';
    if ($node && isset($node->first_field_machine_name->value)) {
      $variables['first_field'] = $node->first_field_machine_name->value;
    }
  }
}

Inside field template of second field, you can get this variable 'first_field' and do something like that

{% for item in items %}
  <div{{ attributes.addClass(classes, 'field__first_item') }}>{{ first_field }}</div>
  <div{{ attributes.addClass(classes, 'field__second_item') }}>{{ item.content }}</div>
{% endfor %}

Hope, it makes sense to you.

0

Another option that worked for me. Enable view() in twig templates. See this Drupal 8 tutorial:

  • Whitelist view in your settings.php file.
  • {{ element['#object'].machine_name_of_other_field.view }}
0

This worked for me within my field.twig where field_column_classes is my custom field name.

{% set paragraph_parent = paragraph.getParentEntity() %}
{% set column_classes = paragraph_parent.field_column_classes.value %}
{{ element['#object'].field_column_classes.value }}
0

I use this in my .theme file:

function HOOK_preprocess_field(&$variables) {
  if ($variables['element']['#field_name'] === 'field_name_to_add_the_var_to' && $variables['element']['#object']->hasField('field_name_to_get_the_value_from')) {
    $paragraph_value = $variables['element']['#object']->get('field_name_to_get_the_value_from')->value;

    $variables['custom_value'] = $paragraph_value;
  }
}

Then in the template field_name_to_add_the_var_to.twig.html I can use:

{{ custom_value }}

Your Answer

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

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