1

I have the same embed in 2 sections of a site (homepage and blog). There is a slight html/css change but the data is the same.

Is there any way to do a shared partial template?

Would I be using a block? Should I look into using setting a global var?

This is similar to what I was thinking:

{% if page == "homepage" %}
    {% for promo in craft.entries.section('promos').status('live').limit(5) %}
        <div id="promos">
            <div class="promo_item">
                <a href="">
                    <div class="promo_item_img">
                        {% for image in promo.promoImage %}
                            <img src="{{ image.url }}" width="222" height="101">
                        {% endfor %}
                    </div>
                </a>
                <a href="{promolink}"><h2 class="generic_title">| {{ promo.title }}</h2></a>
                <p>{{ promo.promoTagline }}</p>
                        </div>
                    </div>
                {% endfor %}
            {% endif %}

            {% if page == "blog" %}
                {% for promo in craft.entries.section('promos').status('live').limit(5) %}
                    <div class="blog_item_inner blog_item_preorder">
                        <a href="">
                            <div class="blog_item_preorder_img">
                                {% for image in promo.promoImage %}
                                    <img src="{{ image.url }}" width="222" height="101">
                                {% endfor %}
                            </div>
                        </a>
                        <a href=""><h2 class="generic_title">| {{ promo.title }}</h2></a>
                        <p>{{ promo.promoTagline }}</p>
                    </div>
                {% endfor %}
            {% endif %}

Just want to get the best solution in place early.

4

First, create a sub folder in /templates called _partials. The underscore essentially "hides" the templates inside that folder from Craft, i.e. they won't get routed to URLs like a regular template; perfect for any template that isn't going to work on its own.

Inside _partials, create a template called _promos.html or the like. Your Twig code above would work as-is, though I'm making some opinionated improvements below (like setting the promos in one place, checking if we actually have some promos to print, and using the switch tag instead of if for readability:

{% set promos = craft.entries.section('promos').status('live').limit(5) %}
{% if page is defined and promos|length %}
    {% for promo in promos %}
    {% switch page %}

        {% case "homepage" %}
         <div class="promo_item">
             <a href="">
                <div class="promo_item_img">
                {% for image in promo.promoImage %}
                    <img src="{{ image.url }}" width="222" height="101">
                {% endfor %}
                </div>
            </a>
            <a href="{promolink}"><h2 class="generic_title">| {{ promo.title }}</h2></a>
            <p>{{ promo.promoTagline }}</p>
        </div>

        {% case "blog" %}
        <div class="blog_item_inner blog_item_preorder">
            <a href="">
                <div class="blog_item_preorder_img">
                {% for image in promo.promoImage %}
                    <img src="{{ image.url }}" width="222" height="101">
                {% endfor %}
                </div>
            </a>
            <a href=""><h2 class="generic_title">| {{ promo.title }}</h2></a>
            <p>{{ promo.promoTagline }}</p>
        </div>
    {% endswitch %}
    {% endfor %}
{% endif %}

Finally, use the include tag to include the partial in another template. Use the with parameter to set the page variable, and the only directive to make sure the partial can't access any of the data in the parent template (like the entry variable etc). This helps prevent data pollution and variable name collisions (if you need access to the entry variable, you can include it in the with object).

<div id="promos">
    {% include '_partials/promos' with { page : "homepage" } only %}
</div>

For the blog, replace the page property with "blog".

Finally, as far as I can tell, the only difference between the two blocks of Twig are different classes for the containers (blog_item vs. promo_item etc). If possible, I'd consider refactoring your code to use the same classnames both "blog" and "homepage" – this would make your code more lean and DRY, and probably easier to maintain.

If you can't change the classnames, you could also make them dynamic and expose them to the include statement like this:

{% include '_partials/promos' with { page : "blog", classNames : {
    'item' : 'blog_item_inner blog_item_preorder',
    'image' : 'blog_item_preorder_img'
} } only %}

...and then print those classnames inside the partial (which now won't require the switch tag or duplicated markup:

{% set promos = craft.entries.section('promos').status('live').limit(5) %}
{% if classNames is defined and promos|length %}
    {% for promo in promos %}
         <div class="{{ classNames.item }}">
             <a href="">
                <div class="{{ classNames.image }}">
                {% for image in promo.promoImage %}
                    <img src="{{ image.url }}" width="222" height="101">
                {% endfor %}
                </div>
            </a>
            <a href="{promolink}"><h2 class="generic_title">| {{ promo.title }}</h2></a>
            <p>{{ promo.promoTagline }}</p>
        </div>
    {% endfor %}
{% endif %}    
| improve this answer | |
  • I'm going to buy you lots of beers one day, @mmikkel. – Brad Bell Sep 25 '15 at 22:27
  • Lol, I sincerely hope you get the chance to one day, @BradBell ;) – Mats Mikkel Rummelhoff Sep 26 '15 at 16:24

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.