Drupal - How to embed a view in a specific node?

Twig Views Embed

This module allows to embed views with a twig function.

{{ views_embed_view('view_name', 'view_id') }}

The above module was depreciated in favour of

Twig Tweak

Twig Tweak module provides a Twig extension with some useful functions and filters that can improve developer experience.

Ex: <dd>{{ drupal_view('view_name', 'view_machine_name') }}</dd>

You can find the view_machine_name over here


This is the way it worked for me in Drupal 8 beta 12 sub-theme of Classy.

In the your_theme.info.theme file

function stjameskidsclub_preprocess_node(&$variables){
  $stuff  = views_embed_view('policy_documents', 'embed_1', 28);
  $variables["my_view"] = \Drupal::service('renderer')->renderRoot($stuff);
}  

I copied the node.html.twig and surrounded the article tags (or the area you wish to replace) with a twig block. I placed this in the /template/content folder.

{% block replace_area %}
  <article{{ attributes.addClass(classes) }}>

    ...

  </article>  
{% endblock replace_area %}

Then I created a node--2.html.twig (replace 2 with desired node) in the /template/content folder with the following code.

{% extends "node.html.twig" %}

{% block replace_page %}
  {{ my_view }}
{% endblock %}

The first problem you're fighting with is that rendered entities like nodes are now cached by default, so hook_node_view() is only called once after a cache clear/saving that node.

However, this is fairly easy to disable, see settings.local.php.

Then, putting the output of a view in $build is fairly easy and more or less works like in 7.x. Instead of using the embed function, consider using $views = Views::getView() and then $views->buildRenderable()

Two tips:

  • Make the key you use for $build available as an extra field in hook_entity_extra_field_info(), then check the display if the component is enabled (see how user_user_view() does that. That allows you to configure the weight/placement of the view in the UI and also hide it on certain view modes.
  • If your view has a page, then it is a bit more complicated, as the node output is cached. You need to make the cache key aware of the pager then, see comment_entity_build_defaults_alter() for an example (not a view, but that is the closest example that core has).

Tags:

Views

Nodes

8