7

I've got a custom content type 'professor', and a 'node--professor.html.twig' in my theme (derived from 'classy') to override the standard markup. The designer wants me to put a list (a view?) of the professor's 'courses' (which is another content type) between the professor's contacts and biography, basically, INSIDE the 'node--professor.twig.html'. Is there a Drupal-way to do it?

And, by the way, what is the main difference between a page with a custom content type and a custom content entity? Do I need to write a module and a content entity, or custom content type can do the trick?

1
  • 1
    Welcome to Drupal Answers. Regarding your 2nd question, you need to make this a separate question (ask a new question about this) as this is not related to twig. Thx
    – No Sssweat
    Commented May 21, 2016 at 5:36

4 Answers 4

16

Download and enable Twig tweak module:

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

And then on your twig template put:

<dd>{{ drupal_view('view_name', 'block_1') }}</dd>
<dd>{{ drupal_block('block_id') }}</dd>

Themers Little Helper

Some of the Filters and functions, backported from TFD7 theme engine and other things that can help a themer getting stuff done without to much hassle :)

{{ drupal_block(block_delta) }}

Bamboo Twig

The Bamboo Twig module provides some Twig extensions with some useful functions and filters aimed to improve the development experience.

Bamboo Twig has a lot of advantages and brings a lot of new features to the Twig landscape of Drupal 8. It boosts performance by using lazy loading, improves the code quality with automated workflow. It also includes automated unit and kernel tests to ensure stability.

{# Render the `system_powered_by_block` block #}
{{ bamboo_render_block('system_powered_by_block') }}
8
  • I'm having trouble using this module. I'm in devel hell looking for an id that will pull the block I want, but no love yet. :( Commented Apr 5, 2018 at 18:37
  • @AyexeM You can get the ID using Devel like this. 1) Place block in a region. 2) Click the downward arrow and click on Devel 3) Click on Variable and look for the ID under the "Settings" array. In this example it would be <dd>{{ drupal_block('system_branding_block') }}</dd> 4) Remove block from region.
    – No Sssweat
    Commented Apr 5, 2018 at 22:10
  • I've been struggling with this as well. The "ID" provided is twofold. One is the block id, the other the plugin id, right? I've tried both. One gives me "This block is broken or missing. etc" and the other renders nothing. Empty template. Block from custom module, and it renders fine if I put it in another region. The docs aren't particularly clear and the above method doesn't apparently work. Really frustrated. Am I missing something?! Worth noting that it doesn't work for existing blocks either, even ones that are rendered on the same damn page...
    – NikLP
    Commented Apr 6, 2018 at 10:39
  • @NikLP did you add the <dd> and </dd> tags?
    – No Sssweat
    Commented Apr 6, 2018 at 11:12
  • I'm supremely confused as to how adding an HTML tag (and one that is part of a list, no less) around the text-only output of a function should stop said function producing an error...?
    – NikLP
    Commented Apr 6, 2018 at 11:20
2

You can create an instance of a block plugin in a custom module in the preprocess hook for your professor content type:

function mymodule_preprocess_node__professor(&$vars) {
  $vars['courses'] = \Drupal::service('plugin.manager.block')
    ->createInstance('professor_courses')
    ->build();
}

I like the simplicity of this approach This creates an instance of a custom block class as a variable in your node template.

You could then output it in node--professor.html.twig like this:

{{ courses }}

If you have a view that you have created that creates a block, you'd have to load the existing instance, which is slightly different.

$block = \Drupal\block\Entity\Block::load('config.id');
$render = \Drupal::entityTypeManager()
  ->getViewBuilder('block')
  ->view($block);
$vars['courses'] = $render;

There's another thread that goes into great detail about loading blocks programmatically.

0

This could be an aside, but for some people it might be of use.

If your list is a view [block], it's worth considering the EVA module, which if memory serves can be moved about between fields in the manage display UI. Not sure how it would fair in the twig stakes, but it's still something to bear in mind.

https://www.drupal.org/project/eva

0

@NikLP I got "This block is broken or missing. etc" until I used the value of the #plugin key in the Devel output for my Custom Block. This was the output in Devel:

Block {#725 ▼
  #id: "mycustomblock"
  #settings: array:7 [▶]
  #region: "content"
  #weight: 0
  #plugin: "block_content:de79f8de-8e8f-4a56-b787-790347b4f104"
   ...

Then in my template, this worked:

{{ bamboo_render_block('block_content:de79f8de-8e8f-4a56-b787-790347b4f104') }}

Using the #id key did NOT work:

{{ bamboo_render_block('mycustomblock') }}

Your Answer

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

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