How to integrate twig generated html into a wysiwyg field

In many cases we would like to integrate dynamic content inside of redactional content. One solution to take care of that request is to define blocks (collection filed type) in your content type and specify a type attribute on each block item. I.e. 'Rich text', 'Last news', ... It works but the content management might become very complex.

Here is a trick to keep you content type simple. In this example, we asume that the WYSIWYG filed will contains a %last_updates% pattern

# First we are saving our generate html in a Twig variable
{% set lastUpdates %}
 <ul>
  {% set docItems = emsch_search('page', {
   "query": {
   "bool": {
      "must": [{
           "term": {
               "type": {
                   "value": "doc"
               }
           }
      }]
   }
   },
   "sort": {
     "_finalization_datetime": {
         "order": "desc",
             "missing": "_last",
             "unmapped_type": "long"
         }
     }
   }) %}
   {% for item in docItems.hits.hits %}
    <li><a href="{{ 'ems://object:page:'~item._id }}">{{ item._source|locale_attr('title_') }}</a></li>
   {% endfor %}
 </ul>
{% endset %}

# Than we replace the %last_updates% pattern by the html content
{{ source|locale_attr('body_')|replace({'%last_updates%': lastUpdates})|emsch_routing}}

Notice that we don't  need pass the twig generated html to the emsch_routing filter. But we are generating ems links. Those internal links are treated later with the rest of the wysiwyg content. So be carefull of the order of the filters: replace than emsch_routing.

Please consider to document those available WYSIWYG variables in the helpbox of the field in elasticms.

You may also wants, for performances reason, to test if this substitution is really needed:

# First we are saving our generate html in a Twig variable
{% set lastUpdates = '' %}
{% if '%last_updates%' in source|locale_attr('body_') %}
    {% set lastUpdates %}
        <ul>
          ....
        </ul>
     {% endset %}
{% endif %}

# Than we replace the %last_updates% pattern by the html content
{{ source|locale_attr('body_')|replace({'%last_updates%': lastUpdates})|emsch_routing}}