Twig Render This is a module that allows you to render fields and entities inside your Twig templates. In this article we'll see an example usage.
A few days ago I decided that I want to add Author block bellow my articles on the site. This is how the block looks like:
I had several ideas about the implementation. In the end, I decided to create a pseudo field that is attached to the Article content type like this:
/**
* Implements hook_entity_extra_field_info().
*/
function gn_core_entity_extra_field_info() {
$extra_field = [];
$extra_field['node']['article']['display']['field_author_block'] = [
'label' => t('Author block'),
'weight' => 100,
'visible' => TRUE,
];
return $extra_field;
}
/**
* Implements hook_ENTITY_TYPE_view().
*/
function gn_core_node_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
if ($view_mode == 'full') {
if ($display->getComponent('field_author_block')) {
$build['field_author_block'] = [
'#theme' => 'author_block',
'#entity' => $entity,
];
}
}
}
As you can see I'm passing the entity variable to the author-block.html.twig template that looks like this:
<div class="author-block row">
<div>
<h4>{% trans %}About author{% endtrans %}</h4>
</div>
<div class="col-md-3">
<img src="{{ file_url(entity.getOwner().get('user_picture').entity.getFileUri()) }}" class="img-circle" />
</div>
<div class="col-md-9">
{{ entity.getOwner().get('field_bio')|renderThis }}
</div>
</div>
The entity that I'm passing is the Article content type. And since every article has an author (user entity), you can use the getOwner() method to get the article's author. Once you have the author, you can construct the block which in my case has only two fields, an image, and a short biography.
As you may know, you can print fields inside Twig templates in two different ways. You can either get a raw field value and construct the HTML code yourself, or you can use the rendered array. I'm using the raw field value to print the user picture. And for printing the Bio field I wanted to use the rendered array. The only problem is that I don't have it. This is not a rendered field value:
entity.getOwner().get('field_bio')
This is just an entity field. It's not rendered. That's why I'm using the renderThis filter to render the field_bio field.
{{ entity.getOwner().get('field_bio')|renderThis }}
What this filter does, is that it takes a field and it renders it. To use the renderThis filter you have to install the Twig Render This module. You can install it like this:
composer require drupal/twig_render_this
For more information about the module and how to use it, please read this tutorial.