I'm struggling to combine two almost identical sidebar templates.

I’m working on a site that has:

  1. a blog channel section with an index template that ‘includes’ a ‘sidebar-main.html’ template
  2. a structure section with a page template that ‘includes’ the same ‘sidebar-main.html’ template
  3. a category template that lists blog posts for a single category, but which ‘includes’ a different ‘sidebar-category.html’ template

The ‘sidebar-main.html’ and ‘sidebar-category.html’ templates are almost identical. Their main function is to offer the user a choice of an 'All categories' menu sorted by category, or a 'Top categories' menu sorted by number of posts, selectable in the entry control panel.

The 'sidebar-main.html template starts:

<div class="sidebar column">

    <div  class="sticky-container" data-sticky-container>
        <div class="sticky" data-sticky data-anchor="stickyAnchor" data-sticky-on="large" style="width:100%">

    {% if entry.sidebarContent is defined %}

        {% for block in entry.sidebarContent %}

            {% if block.type == "sidebarWidget" %}
                {% if block.widget.contains('topCategories') %}

                <h4 class="section-title">Top categories</h4>
                <div class="card">
                    <div class="card-section">

                    {% set entryIds = craft.entries.section('blog').ids() %}
                    {% set allCats = craft.categories.relatedTo(entryIds).level(1).find() %}
                    {% set catArray = {} %} 

                    {% for category in allCats %}
                      {% set catArray = catArray | merge({(category.slug):craft.entries.relatedTo(category).total() }) %}
                    {% endfor %}

                    {% set catArray = catArray|sort|reverse %}

                    {% for catSlug, entryCount in catArray | slice(0,3) %}
                    {% set category = craft.categories.slug(catSlug).first() %}

                    {% if loop.first %}
                        <div class="row">
                            <div class="first-column small-6 large-12 columns">
                    {% endif %} 

                                    <li class="clearfix">
                                        <a href="{{ category.url }}">{{ category.title }}&nbsp;</a>
                                        <div class="count">{{ entryCount }}{% if entryCount == 1 %}&nbsp;post{% else %}&nbsp;posts{% endif %}</div>

And the 'sidebar-category.html' template is identical to this, except that entry.sidebarContent is replaced by category.sidebarContent. This works fine, with no errors or problems (except it's not DRY). However, if I can eliminate the use of 'category.sidebarContent', then I can split up the combined template to enable its use in 404 and search etc pages.

I hope all that makes some sort of sense, and thanks for any suggestions!


You could pass the content to the sidebar include, as follows:

{% include 'sidebar-template' with {
    content: entry.sidebarContent
} only %}

The sidebar template would then use content, rather than entry.sidebarContent.

It's also worth taking a look at Twig embeds, which can be very useful in situations such as this.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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