5

I'm familiar with the Drupal 8 theming API, including hook_preprocess_HOOK(), as well as all of the theme template suggestions available when Twig debug is enabled.

However, what I would love to be able to do is to control all of the individual fields and optional labels for a node, inside the node--tool--full.html.twig template. (My content type machine name is tool.)

I also know that I can simply leave out the call to {{ content }} in the Twig template and call fields individually like this.

{{content.body}}
{{content.field_application_purpose}}
{{content.field_application_uses}}

And of course, if I want complete control over a field, including rendered markup (for example, field_application_uses), I can create another template (field--node--field-application-uses--tool.html.twig) and then wrap the field and its label in any markup I'd like.

So far so good.

But how can I control all of this from within the node template, in this case node--tool--full.html.twig?

My node is translatable, including the field label.

What I'd like to do, instead of having to create field templates for every field on the node/content type/bundle, is something like this.

<article{{ attributes.addClass(classes) }}>
  ...
  <div class="application-purpose">
    <h3>{{ node.field-application_purpose.label}}</h3>
    <p>{{ node.field-application_purpose.value }}</p>
  </div>

  <div class="application-uses">
    <h3>{{ node.field_application_uses.label}}</h3>
    <p>{{ node.field_application_uses.value }}</p>
  </div>
  ...
</article>

The above template snippet works for the value, but not for the label, and I spent hours trying to work out where to get the label.

In field--node--field-application-uses--tool.html.twig, the label is available as a variable, but how can I retrieve this at the node template level?

I'd ideally like to keep all of the fields and their markup in a single template, the node template, as opposed to having to create a template for each field.

  • Okay I see clues here in template_preprocess_field - api.drupal.org/api/drupal/core%21includes%21theme.inc/function/… Label is actually derived from element title. I also don't mind calling theme_preprocess_node__tool__full in order to retrieve these values and assign them to $variables. I just need to work out how the 'element' is created, or retrieved from the node, or content variables in $variables. – Blue Waters Mar 6 '16 at 14:29
  • I think that its not a good approach, was you doing. Its better override fields templates to have more control and how each entity will render. Someone (even you), can forget where these fields are defined. Drupal has all (most) the tools to you not to have break any 'rules', if break any, something unexpected can occur. Drupal is a well designed system to allow any modification and the most important to allow reuse code. – Vagner Mar 6 '16 at 14:45
5

The label is in the field definition, you have to add fieldDefinition before label:

{{ node.field_myfield.fieldDefinition.label }}

To explain this, node is the node object. Content is the render array of the fields, that are build as configured in the view mode. In node you find the raw values and definitions of all fields of the node. In content you only find those fields that are in included in the view mode and they are already formatted as configured in the view mode. You also find each of the fields as object in content, but you cannot be sure, that the field is there, because if someone later removes the field from the view mode, your code will get a null value.

  • Thanks - that worked. content.field_application_purpose['#title'] - also works. Is there any tradeoff? – Blue Waters Mar 6 '16 at 15:16
  • Ignore me - the tradeoff is as you've described. If the view mode is altered, and the field removed, it won't be available from the content render array. Thanks for the solution, and helpful explanation. – Blue Waters Mar 6 '16 at 15:35
  • I would also suggest using devel kint(), it will really help you dig into the array of variables available to you. – Danny Englander Mar 6 '16 at 16:33
2

I've created this module that lets you print the field label and field value individually: https://www.drupal.org/sandbox/sutharsan/2763183

<strong>{{ content.field_name|field_label }}</strong>: {{ content.field_name|field_value }}

Let me know if it is useful to you I will promote it to a full project.

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.