2

Seems that all found in the Internet does not work for my case. :/ In general, I need to display an Image and a Project, referenced by the node that has a reference field to my node.

I have:

  • a node of CT Idea (here I want to display my content)
  • a node of CT Example, which has:

    1) a ref field to Idea 2) a ref field to a Media, Image 3) a ref field to a CT Project

I want to display Examples on an Idea page, each Example displays: Description, Image, Project link

I've managed to display the Description, but can not display Image and Project.

Here is the code

in the *.theme file:

function showcase_lite_preprocess_node__idea(&$variables) {
  $current_node = $variables['node'];
  $current_node_id = $current_node->id();

  $query = \Drupal::entityQuery('node');
  $query->condition('type', 'example');
  $query->condition('status', 1);
  $query->condition('field_example_ideas', $current_node_id);
  $nids = $query->execute();
  $relatednodes = Node::loadMultiple($nids);

  if (!empty($relatednodes)) {
    foreach ($relatednodes as $related_node) {
      $related_node_image = $related_node->field_example_image->value;
      $related_node_description = $related_node->field_example_description->value;
      $related_node_project = $related_node->field_example_project->value;

      $variables['related_node_image'] = $related_node_image;
      $variables['related_node_description'] = $related_node_description;
      $variables['related_node_project'] = $related_node_project;
    }
  }
}

In the node--idea.html.twig file:

{% block content %}
    {{ content }}
    {{ related_node_description }}
    {{ related_node_image }}
    {{ related_node_project }}
{% endblock %}

This displays only the Idea content and the Example Description.

It seems to me that the problem is that the format of $related_node_image and $related_node_project does not correspond to what Twig is expecting. But I can not check what is inside the variable, because Kint gives an error of memory limit.

Drupal version: 8.5.3.

1

2 Answers 2

2

To get a renderable output for Twig use EntityViewBuilder::viewMultiple()

    $variables['related_nodes'] = \Drupal::entityTypeManager()
      ->getViewBuilder('node')
      ->viewMultiple($relatednodes, $view_mode, $current_node->language()->getId());

and configure the three fields in the view mode you've specified here.

8
  • Thank you. But where should it be added? After $relatednodes = Node::loadMultiple($nids); line? $view_mode is not defined. Should I write $view_mode = 'full'? Should Iuse only {{ related_nodes }} in the twig file (without project, desctiption, image)?
    – Oksana
    Aug 8, 2018 at 13:31
  • Yes, but use $view_mode = 'custom_view_mode' and configure the three fields in this custom view mode. With full you would get all fields. And then you can print the related nodes as configured in this custom view mode with {{ related_nodes }} in the twig template.
    – 4uk4
    Aug 8, 2018 at 13:52
  • It works! But it displays all node fields [drive.google.com/file/d/1EkKDpZ1fjTCVEp5-ol-drD_QYlQZs3xE/… and if I edit a view mode, I can edit only a title [drive.google.com/file/d/1qgBmQiYMD19-QXCtFwvfxN0mMnZZ3X89/…. How to hide some fields? In code somewhere? @4k4
    – Oksana
    Aug 8, 2018 at 14:29
  • When you add a view mode you can only edit the name, this is correct. After that go to Manage Display of the content type, enable the new view mode in Custom Display Settings at the bottom and then you'll find a new tab at the top to configure the fields for the new view mode.
    – 4uk4
    Aug 8, 2018 at 14:35
  • I've found the tab where to disable fields with Drag&Drop and where to hide labels. Saved, cleared caches, but no changes on my node page. The view mode is created in Content section, machine name is has node at the beginning: $view_mode = 'node.example_img_description_project'. Is it right?
    – Oksana
    Aug 8, 2018 at 15:05
1

Does this necessarily need to be done in Twig? As you can achieve this without any coding with just field formatters and view modes. It will even cover the publication status.

Apart from that, you don't need to fire a query to get the referenced node IDs. You already have the node IDs as target_id in the reference field's values.

$nids = [];
if (!$node->field_example_ideas->isEmpty()) {
  $references = $node->field_example_ideas->getValue();
  foreach ($references as $reference) {
    $nids[] = $reference['target_id'];
  }
}
// This will give you all node IDs.
ksm($nids);

Approach without any code:

You have content type A and content type B. Content type A has a node reference field, referencing content type B. Content type B has an image and now - for simplicity - let's say you want that content type A only displays the image and nothing else of content type B.

  1. Go to Structure > Content types > B > Manage display tab > and add a new view mode (on the very bottom), or use an existing one, let's say Teaser. There you hide all fields except the image field.

  2. Go to Structure > Content types > A > Manage display tab > and here for your reference field choose "Rendered entity", then click on the small gear icon and select a view mode. Now it should say "Rendered as Teaser".

  3. Done :)


Avoid editing templates when it can be done from the UI

There are other alternatives as well, codeword "Pseudo Fields", that prevent using templates to override the UI and therefore make the UI useless in the end. Drop a comment, if the above isn't sufficient.

8
  • Yes, UI is probably the best approach for this example (although questions are often simplified and in reality there might be good reasons to do this in code). But I think you need the database query of the code example to get the related nodes and then you need a View to replace this with a UI solution, which you can attach to the node with EVA.
    – 4uk4
    Aug 6, 2018 at 21:17
  • @4k4 – Fired a vanilla D8 to be 100% sure. You really don't need an extra query. Updated snippet slightly.
    – leymannx
    Aug 6, 2018 at 21:47
  • Thank you @leymannx, but you have misunderstood an important point. You write "Content type A has a node reference field, referencing content type B. Content type B has an image" This would be more easy. But the situation is: "Content type A DOES NOT HAVE a node reference field, referencing content type B. "Content type B has a node reference field, referencing content type A. Content type B has an image". This is needed to simplify the editorial work, so that all references are visible in one place.
    – Oksana
    Aug 8, 2018 at 13:58
  • @4k4 – Ah I see, now I got it. Reverse entity reference! Well, yeah, then there's maybe no pure UI way to accomplish this (,yet. At least until drupal.org/project/reverse_entity_reference would add a dedicated field type for this).
    – leymannx
    Aug 8, 2018 at 19:34
  • @Oksana – Now I got it. Thanks for clarifying. Well, yeah, then 4k4's answer probably is the way to go :)
    – leymannx
    Aug 8, 2018 at 19:41

Your Answer

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

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