1

I have a content type (Flower) with two fields: Name and Color.

In my-theme/templates/page.html.twig, I want to print the name and the color of each flower.

<div id="page">
    {% for flower in flowers %}
        <div class="flower-item">
            <h3>{{ [Flower Name Here] }}</h3>
            <p>{{ [Flower Color Here] }}</p>
        </div>
    {% endfor %}
</div>

How can I get all nodes of a given content type and print the values of each node inside page.html.twig?

  • 1
    You would have to provide those templates with the variables you want to output. I think page already comes with the object, but I am not certain. – Kevin Apr 23 at 20:30
  • Install Devel's submodule Kint, put {{ kint() }} in your template to see what you get 7 levels deep. Don't click the + icon unless you have unlimited memory available. – leymannx Apr 24 at 6:38
  • @leymannx I've installed Kint and used {{ kint() }} but didn't found anything related to my custom Content Type. Is that normal? is there any alternative to get my content type without using an external module? – Naourass Derouichi Apr 26 at 23:48
  • 1
    Have you read the answer to the linked question? It's {{ node.field_some_name.value }}. And you don't loop. Drupal isn't WordPress. Normally you'd do all that in "Manage Display" of your content type from the admin UI. Printing node values on page level should be considered bad practice. At best you leave all templates untouched and manage rendering through Drupal's backend. – leymannx Apr 27 at 14:25
  • 1
    Yeah, better use a front page view and have your node printed in a different view mode there. And on the categories page another view and another view mode for your content type. All that can be done just from the UI. In your content type on manage display add new view modes and adjust your fields in there. Then create views, choose a content type and decide which view mode you wanna have them displayed in. – leymannx Apr 27 at 14:58
1

Putting this in page.html.twig is a bad idea. Since this template will be used for every page rendered from Drupal using that theme.

Instead you should simply create a View. Views can be used to query a certain content type and to list nodes in a certain view mode or just certain fields of these nodes (the title and a color field for example). Then configure your view to provide a block and place that block in the region you wanna have the Flowers printed.

Views and block will take care of the caching. And you can use the block's visibility settings to have it displayed only on paths or nodes where you really need it.


If you still insist on coding this in a template (not recommended, too performance-heavy, too much logic in templates) you first have to pass all Flower nodes to the template.

/**
 * Implements template_preprocess_page().
 */
function MYTHEME_preprocess_page(&$variables) {

  $query = \Drupal::entityTypeManager()->getStorage('node')->getQuery();

  // Get all Flower node IDs.
  $nids = $query->condition('type', 'flower')->execute();

  // Load all Flower nodes.
  $nodes = \Drupal\node\Entity\Node::loadMultiple($nids);

  // Pass them to page.html.twig.
  $variables['flowers'] = $nodes;
}

Then in your page.html.twig:

{% for flower in flowers %}
  {{ flower.title.value }}
  {{ flower.field_color.value }}
{% endfor %}
  • Thanks for the detailed example. This is working 100% and I didn't notice any performance issues ! I'm wondering if it's possible to preprocess multiple templates at once and provide them with the same variables in only one function ? – Naourass Derouichi Apr 29 at 15:24
  • 1
    @NaourassDerouichi – Yes, you could also use the more general hook_preprocess(&$variables, $hook). – leymannx May 4 at 21:29
  • 1
    I would rather not put code that queries all the nodes in a theme template, especially if the template is used for every page rendered from Drupal using that theme. That is code for a module. It's rather common for Drupal-beginner developers to add code in theme templates, when the code should be added to a module. Users should be warned that it's wrong. – kiamlaluno Oct 3 at 7:50

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.