David Lohmeyer's Blog

Repeating blocks of template code in Drupal 8

I've had some trouble using Twig's include statements in Drupal 8 theming.  I'm not sure if this is a bug since it's at Beta 4, but it's sort of annoying.  I include my content areas in page.html.twig in a separate include file in Drupal 6 and insert it into the area I need.  For example, if I have a 3 column layout, I'm changing the Bootstrap classes from "col-md-12" to "col-md-9" and "col-md-3" (for a sidebar) if the sidebars have content in them.  Includes are apparently escaping (?), though, and not printing anything other than the include file's name.  As a workaround... which is hopefully temporary, I opted for blocks.

Here's my initial block definition for my first columnar scenario (no sidebars):

        {# Show if there are no sidebars #}
        {% if (not page.left_top and not page.left_mid) and not page.right_top %}
        <div class="col-md-12 main-bar">
          {% block pagecontent %}
            {% if page.above_content %}
            <div class="row above-content">
              <div class="col-md-12">
                {{ page.above_content }}
              </div><!--/.col-md-12-->
            </div><!--/.row-->
            {% endif %}
            {% if not is_front and title != 'Search' %}
              {{ breadcrumb }}
              {% if title %}
                <h2 class="page-title">{{ title }}</h2>
              {% endif %}
            {% endif %}
            {% if messages %}
              {{ messages }}
            {% endif %}
            {% if page.below_title %}
              <div class="belowtitle">
                {{ page.below_title }}
              </div>
            {% endif %}
            <div class="clear-block contentblk">
              {{ page.content }}
            </div>
            {% if page.content_2col_left or page.content_2col_right %}
              <div class="double-columns row">
                <div class="col col-md-6">
                  {{ page.content_2col_left }}
                </div><!--/.col-md-6-->
                <div class="col col-md-6">
                  {{ page.content_2col_right }}
                </div><!--/.col-md-6-->
              </div><!--/.row-->
            {% endif %}
            {% if page.content_3col_left or page.content_3col_mid or page.content_3col_right %}
              <div class="triple-columns row">
                <div class="col col-md-4">
                  {{ page.content_3col_left }}
                </div><!--/.col-md-4-->
                <div class="col col-md-4">
                  {{ page.content_3col_mid }}
                </div><!--/.col-md-4-->
                <div class="col col-md-4">
                  {{ page.content_3col_right }}
                </div><!--/.col-md-4-->
              </div><!--/.row-->
            {% endif %}
            {% if page.below_content %}
              {{ page.below_content }}
            {% endif %}
          {% endblock %}
        </div><!--/.col-md-12-->
        {% endif %}

Cool.  The stuff inside the {% block pagecontent %} and {% endblock %} is what will repeat in our other sidebar scenarios.  Here's another scenario with the block repeated:

        {# Show if there are left sidebars #}
        {% if (page.left_top or page.left_mid) and not page.right_top %}
        <div class="col-md-3 side-bar left-side-bar">
          {{ page.left_top }}
          {{ page.left_mid }}
        </div><!--/col-md-3-->
        <div class="col-md-9 main-bar">
          {{ block('pagecontent') }}
        </div><!--/.col-md-9-->
        {% endif %}

The bit that's interesting is the {{ block('pagecontent') }} function, which just inserts the earlier block again.

Related Posts