<<< Back to the blog

HOT TIP Using Variables to Store Tag Results

Johnathon Koster
Guest Author Johnathon Koster September 18th, 2023

Hello, everyone! In this Antlers tip, we will look at reusing parts of a template in multiple areas. A typical example of when we might want to do this is outputting the same markup for a navigation menu that will become visible at various breakpoints.

Imagine we had a template similar to the following example:

<div class="hidden xl:block bg-gray-200 p-4">
    <nav>
        <ul class="flex space-x-4">
            {{ nav:main }}
            <li>
                <a href="{{ url }}"
                   class="text-gray-700 hover:text-gray-900">
                   {{ title }}
                </a>
            </li>
            {{ /nav:main }}
        </ul>
    </nav>
</div>

<div class="xl:hidden bg-gray-100 p-2">
    <button id="menuToggle" class="mb-2">Toggle Menu</button>
    <div id="mobileMenu" class="hidden flex flex-col space-y-2">
        <nav>
            <ul class="flex space-x-4">
                {{ nav:main }}
                <li>
                    <a href="{{ url }}"
                       class="text-gray-700 hover:text-gray-900">
                       {{ title }}
                    </a>
                </li>
                {{ /nav:main }}
            </ul>
        </nav>
    </div>
</div>

We are achieving our goal of utilizing the same HTML markup. Still, we are duplicating the Antlers template that produces the shared markup. We can extract the common parts to a partial to clean this up.

In resources/views/_nav.antlers.html:

Have you seen template names with a leading underscore and wondered what that was about? This is a naming convention that helps to differentiate regular templates or layouts from partials. When using the Template Fieldtype, files we name using this convention are hidden by default (as well as any file within the views/partials folder).

<nav>
    <ul class="flex space-x-4">
        {{ nav:main }}
        <li>
            <a href="{{ url }}"
               class="text-gray-700 hover:text-gray-900">
               {{ title }}
            </a>
        </li>
        {{ /nav:main }}
    </ul>
</nav>

With our new partial, our template can now become:

<div class="hidden xl:block bg-gray-200 p-4">
    {{ partial:nav /}}
</div>

<div class="xl:hidden bg-gray-100 p-2">
    <button id="menuToggle" class="mb-2">Toggle Menu</button>
    <div id="mobileMenu" class="hidden flex flex-col space-y-2">
        {{ partial:nav /}}
    </div>
</div>

Fantastic! We’ve cleaned up our template significantly by extracting a partial. However, what if our partial contained some complex logic that took significant time to complete? We are now rendering that partial twice!

We can solve this by assigning the results of the partial tag to a custom variable and using our new variable instead:

{{ _nav = {partial:nav} /}}

<div class="hidden xl:block bg-gray-200 p-4">
    {{ _nav }}
</div>

<div class="xl:hidden bg-gray-100 p-2">
    <button id="menuToggle" class="mb-2">Toggle Menu</button>
    <div id="mobileMenu" class="hidden flex flex-col space-y-2">
        {{ _nav }}
    </div>
</div>

An important thing to note when working with tags and custom variables is that we need to wrap our entire tag call within a set of single curly braces. Without this, Antlers will treat everything as standard variables and modifiers, which can lead to unexpected behavior and errors.

A new feed approaches!