Drupal 8: How to put a View or Block between the Content and Comments

I’m not going to discuss this code much, but in short, the source code below is for a Drupal 8 preprocess_node function that I use to set variables for (a) a custom view and (b) a custom block. I set the variables in this function, and then display them in my node.html.twig file like this:

{{ similar_by_terms }}

and this:

{{ my_books }}

Putting a View and a Block between Content and Comments

The slightly longer story is that what I am trying to do is to place a custom View and a custom Block in between my Content and the comments on that content. The way I did this was to modify my node.html.twig file to look like this:

{{ content.body }}

<h2>Similar content</h2>
{{ similar_by_terms }}

<h2>My Books</h2>
{{ my_books }}

{{ content.comment }}

This works because I create the variables named similar_by_terms and my_books in the preprocess_node function that I show below.

My Drupal 8 preprocess_node function

This is how I build those custom Drupal 8 variables in my template_preprocess_node file:


 * working off of this:
 * drupal.stackexchange.com/questions/186246/how-to-print-core-block-or-views-block-in-node-html-twig-drupal-8
function aadotcom_preprocess_node(&$variables) {

    # this creates a variable named 'similar_by_terms' that i can use in the twig template files.
    # this is the machine name shown at 'admin/structure/views'
    $variables['similar_by_terms'] = views_embed_view('0_similar_by_terms');
    # this creates a variable named 'my_books' that i can use in the twig template files.
    # this works, from:
    # drupal.stackexchange.com/questions/195916/render-a-custom-block-programmatically/195917#195917
    # block_num needs to be right. block_name doesn't seem to matter.
    $block_entity = Drupal\block_content\Entity\BlockContent::load(26);
    $block_view = \Drupal::entityTypeManager()->getViewBuilder('block_content')->view($block_entity, 'foo bar');
    if ($block_view) {
        $variables['my_books'] = $block_view;

Update: Drupal 8.2 and 8.3

I just used this technique again to add the AddToAny module to this website, and here’s the code I put in the aadotcom_preprocess_node function in my .theme file to make that happen:

# see drupal.stackexchange.com/questions/171686/how-can-i-programmatically-display-a-block
$a2a_block = \Drupal\block\Entity\Block::load('addtoanybuttons');
$a2a_block_view = \Drupal::entityTypeManager()
if ($a2a_block_view) {
    $variables['add_to_any'] = $a2a_block_view;

This is a little different than the technique shown above, and I can confirm that it works with Drupal 8.2 and 8.3. Once I created that code, I added this code to my node.html.twig file:

{{ content.body }}

    {% if node.getType not in ['text', 'misc' ]  %}
        <div class="add_to_any">
            {{ add_to_any }}
    {% endif %}

<div class="content_category">{{ content.category }}</div>
<div class="content_tags">{{ content.tags }}</div>

There may be other ways to get Drupal block content in-between the contents and comments, but I know that this technique works, so I use it.

The Drupal 8 theme file name

For the record, this custom template function goes in a file named mytheme.theme in my custom theme directory. So if my theme is named “foo”, I will have a directory named themes/foo under my Drupal 8 installation directory, and this file will be named foo.theme.

Honestly, I don’t completely understand the $block_view code completely at this time. This is a slightly modified version of the code that I found at the stackexchange.com URL that I show in the comments.