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:
<?php /** * 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() ->getViewBuilder('block') ->view($a2a_block); 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 }} </div> {% 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.