I'm familiar with the Drupal 8 theming API, including the 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 from :-(

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.

Thoughts or suggestions greatly appreciated.

Comments

anthony.bouch’s picture

Okay I see clues here in template_preprocess_field - https://api.drupal.org/api/drupal/core%21includes%21theme.inc/function/t...

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 for convenience.

I just need to work out how the 'element'/field is created, or retrieved from the node, or content variables in $variables.

anthony.bouch’s picture

Thanks to a relpy from http://drupal.stackexchange.com/questions/193717/render-node-fields-and-... as well as a few more tests...

Both...

{{ node.field_application_purpose.fieldDefinition.label }}

and...

{{ content.field_application_purpose['#title']

work.

However, node.field_application_purpose.fieldDefinition.label is more reliable, as the content field could disappear if the view mode for the node is changed.

kienan91’s picture

Hi I used {{ node.field_application_uses.value }} this only show format string not HTML . So how to show field format HTML

Jeff Burnz’s picture

just print the field from content - this will render all the field markup:

{{ content.field_application_uses }}

kienan91’s picture

I mean only get value of fields for my wrapper html . For example display HTML Tabs Boostrap

<ul class="nav nav-tabs">
  <li class="active"><a data-toggle="tab" href="#home">{{node.field_aaa.fieldDefinition.label}}</a></li>
  <li><a data-toggle="tab" href="#menu1">{{node.field_bb.fieldDefinition.label}}</a></li>
  <li><a data-toggle="tab" href="#menu2">{{node.field_ccc.fieldDefinition.label}}</a></li>
</ul>

<div class="tab-content">
  <div id="home" class="tab-pane fade in active">
    {{ node.field_aaa.value }}
  </div>
  <div id="menu1" class="tab-pane fade">
     {{ node.field_bb.value }}
  </div>
  <div id="menu2" class="tab-pane fade">
     {{ node.field_ccc.value }}
  </div>
</div>

So {{node.my_field.value}} show only format string .. I want format HTML.

kienan91’s picture

Finaly ! I had print format HTML for value . Used word "raw" in twig http://twig.sensiolabs.org/doc/filters/raw.html

{{ node.name_field.value|raw }}

Jeff Burnz’s picture

You better know that is safe output then, right?

From https://www.drupal.org/node/2357633:

Using the |raw filter should also be avoided whenever possible, particularly if you are outputting data that could be user-entered. See https://www.drupal.org/node/2296163 for more information on auto escape in Drupal 8...

People who do this sort of thing and don't know much about security or allow users to enter content please do not complain when your site is hacked. Just saying it like it is.

serverjohn’s picture

I am not a security expert but after some experimenting I found a way to sanitize the field but still gets you the field to render HTML. You use a filter that is NOT raw

{{ node.name_field.value|t }}

This reference sent me in the right direction. Look under the #trans filter. 

sutharsan’s picture

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.

-- Erik

Jeff Burnz’s picture

Thats pretty nifty, thanks for posting it, good example of how to add twig filters also.

GodZiLA’s picture

thank you SO much, i've get tired to print field value without label and your module help me do that!

benandunt’s picture

Hey, I also came across this problem while I was theming with D8, but it doesn't end here. I have a textfield with unlimited allowed number of values. How can I get the values of each textfield into the node template? And what about entity references? How can I get the values of each field from the referenced entity into the node template (and what if there are multiple references)?
I really don't like to create a field template for each field because I have around 15 content types with an average of 5 fields each (I would end up with 75 templates!!).

gagarine’s picture

On http://drupal.stackexchange.com/questions/208723/iterate-through-multipl... I found this "solution":

{% for key, item in content.field_tags if key|first != '#' %}
  <div class="item-{{ key + 1 }}">{{ item }}</div>
{% endfor %}

But this is very ugly and I will love to see a better way to do that.

https://interface-network.com - Interface Network is an action and research technology governance agency.

Jeff Burnz’s picture

he he, yeah, I wrote that, it is a bit ugly, without the check for keys starting with a # you will get an error.

Jeff Burnz’s picture

Are you wanting to print specific fields from the multivalve fields and/or the entity references? What I mean is, is the idea to layout the node template and print specific field items in various places within that layout? I'm just trying to clarify exactly what you want to achieve.

gagarine’s picture

FYI I opened a issue now: https://www.drupal.org/node/2776307

Basically I want to do what I can do in the field template directly in the node template. On some project this can greatly reduce the complexity of the theme.

For example I need to add "," between a field's values (a multiple value entity references field rendered in label). So I have a field template with:

{% for item in items %}
  {{ item.content }}{% if not loop.last %},{% endif %}
{% endfor %}

And in my node template I have:

{% if content.field_facilities is not empty %}
   <p>{{ content.field_facilities }}</p>
{% endif %}

But I would prefer to have a similar code directly in my node template like:

{% if content.field_facilities is not empty %}
   <p>
     {% for item in content.field_facilities %}
       {{ item.content }}{% if not loop.last %},{% endif %}
     {% endfor %}
   </p>
{% endif %}

https://interface-network.com - Interface Network is an action and research technology governance agency.

benandunt’s picture

I just like to to everything in the node template respectively in the paragraph (from the paragraphs module) template :-)
If I have a content type wich is an entity reference (multiple allowed) to another content type wich has fields like image, text (multiple allowed), clear text etc. I'd like to print every single value of each field wherever I want to inside the node resp. the paragraph template (even splitting up the Image in URL, alt text, etc.). But as I see this is just not possible at the moment and I hope this will be possible in the near future.

gagarine’s picture

If you have time, please add your use case on https://www.drupal.org/node/2776307 . Has you say it's not possible, so we need use case information to check if it's somethings that is needed and what is the best way to solve that.

https://interface-network.com - Interface Network is an action and research technology governance agency.

Jeff Burnz’s picture

I don't really follow what you are describing, and what you are saying is "not possible" (what are you saying is not possible?), theres just not enough detail in your question/comment to give qualified feedback.

gagarine’s picture

It was a reply to @benandunt

I want to inside the node resp. the paragraph template (even splitting up the Image in URL, alt text, etc.). But as I see this is just not possible at the moment and I hope this will be possible in the near future.

I simply encouraged @benandunt to write his use case on the corresponding issues https://www.drupal.org/node/2776307 . I don't think the forum is appropriate to such discussion that certainly involve code change.

https://interface-network.com - Interface Network is an action and research technology governance agency.

benandunt’s picture

Sorry for the confusion. I need some more experience in D8 to make some valid questions. The main problem I have now is with the module "Paragraphs" and not the core itself (so nothing to add to the existing core issue). I will get back to that as soon as I know more.

Jeff Burnz’s picture

@@benandunt - ok, what I mean is, just simplify down what you want to achieve, I mean make it really simple and clear, I'm not asking for technical details, just accurate information - for example in which node is the paragraph - the referenced node, or? To answer questions just imagine that I am blind and need very clear simple instructions, I understand the Drupal theme system very well, but its also very complex and it really makes a huge difference even small simple details such as that.

Jeff Burnz’s picture

@gagarine - my comment was addressed to benandunt, i am trying to help him, he is more than welcome to post his issue here and discuss solutions.