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).