Conditionally including partials in Statamic 3 using the new 'exists' and 'if_exists' tags

Published October 5th, 2021

The partial tag is a superb way to help modularise your Antlers templates in Statamic 3, and provides an easy way to re-use parts of your template in multiple places. 

Think of the templates required for a Blog with Taxonomy Terms – you are able to view lists of blog posts when you view the blog itself, or view a specific taxonomy term. So you’ll need an index template for the blog, plus a show template for a term listing. But these two layouts share something in common: the way that each blog post gets presented – it’s ‘tile for lack of better word. You’re able to extract your tile markup in to a separate Antlers file, and using the partial tag, you can include that tile in the blog’s index and term’s show template, meaning that if you need to change the way the blog post tile looks, you can change one file, and have it reflected throughout your site. Neat, hey? Don't forget: check out the partial documentation for a refresher if you need.

That’s a simple use case for the partial tag – and another is with SVG icons. You can store all of your icons in separate Antlers files that can be included using the partial tag – if your chevron style changes, you can change once file and have it reflected site wide. So smart.

The two examples above really simple – but what if we go a bit further. What if we had a Taxonomy Term that had a name, but also had an icon you wanted to present along side the Term’s title – so a Term, that when used will include a partial to an SVG icon based on the Term’s slug. Straight forward, right?

Here is the issue – and during dev, you may even encounter it. If you try to include a partial that doesn’t exist, you get a InvalidArgumentException thrown – and tells you exactly what is missing, so that’s great, and easy to fix in dev. But given that Terms may be added and edited by a content author, if a new partial is created that doesn’t have a matching SVG partial, your live production site will throw that same exception. Not good.

For a project I was working on, I wrote a Tag that would return a true or false result if the partial existed. And it worked really well, so got me thinking: surely others would like this too? So I wrote up a little pull request, and with the polish from the Statamic dev team on the if_exists tag), was merged in to Statamic 3.2.7.

This adds two new features to the partial tag:

  1. the ability to check if a partial exists, and return a true or false, allowing you to change template behaviour if it does exist

  2. include a partial only if it exists (but do nothing otherwise)

There are valid uses cases for both of these extensions – there are times you want to check and do something based on that check, and other times you just want to include it if it exists. So let’s look at this – and think back to the Term with SVG icon example above.

Checking if a partial exists using partial:exists

The partial:exists tag will give us a true or false response if the partial exists – meaning we can conditionally alter the template’s behaviour. For our Term and SVG icon example, we want to check:

  • if the icon exists, we can include it and then the Term label with some margin applied to help space.

  • else, we just want the Term label with no margin.

In our {{ if }} statement, we can include the partial:exists tag to do our test:

1{{ if {partial:exists src="partials/my-partial"} }}
2 <!-- The partial exists! Woo! -->
3{{ else }}
4 <!-- Nope, not here. Did you delete it? -->
5{{ /if }}

We now have two pathways where we can include different markup based on whether a partial does or does not exist. In our margin example, this could look like:

1{{ if {partial:exists src="partials/my-partial"} }}
2 {{ partial src="partials/my-partial" }}
3 <span class="ml-2">My Partial was found</span>
4{{ else }}
5 <span>My Partial wasn't found</span>
6{{ /if }}

The partial:exists tag is perfect for when you need to add or alter markup based on a partial’s existence.

Don’t forget: check out the partial:exists documentation.

Including a partial with partial:if_exists

There are also times when you only want to include a partial if it exists, and don’t need to alter any template behaviour if it doesn’t.

In our above example, let’s imagine that the margin we added to the label actually belongs to the SVG partial – this means that we need to :

  • include the SVG partial if it exists, and

  • always output the Term’s title

1{{ partial:if_exists src="partials/my-partial" }}
2<span>Always show this label</span>

The partial:if_exists tag is perfect for when you simply need to include a partial if it exists – and its existence doesn’t impact any other template behaviour or logic.

Don’t forget: check out the partial:if_exists documentation.

Using partial:exists and partial:if_exists with dynamically named partials

If we’re talking about our Taxonomy Terms, that users can create and rename, we have the issue of not actually knowing at dev-time what to include in the partial. Or even if we do, what if it gets renamed or deleted. 

If you’re using Sets in your Bard field type, you might even be using the partial tag with a dynamic variable already – remember this?

1{{ bard_field }}
2 {{ partial src="sets/{type}" }}
3{{ /bard_field }}

The same logic applies to our loop of Taxonomy Terms. So on our blog post, we want to loop through the tags on a post, and for each include an icon and its title.

We can approach this with partial:exists behaviour: 

2 {{ tags }}
3 <li>
4 {{ if {partial:exists src="svg/{slug}"} }}
5 {{ partial src="svg/{slug}" }}
6 <span class="ml-2">{{ title }}</span>
7 {{ else }}
8 <span>{{ title }}</span>
9 {{ /if }}
10 </li>
11 {{ /tags }}

As well as the partial:if_exists behaviour:

2 {{ tags }}
3 <li>
4 {{ partial:if_exists src="svg/{slug}" }}
5 <span>{{ title }}</span>
6 </li>
7 {{ /tags }}

And while these two examples are very similar given the really simple nature of the use case, remember that neither approach is inherently right or wrong - it's all about what you need your templates and partials to do. There are times when you want conditional control based on a partial's existence, and other times where you're happy to just include it if it exists. These two new tags just make it easy to be more creative and logical with your Antlers template creation.

The new partial:exists and partial:if_exists tags are so useful and have so many real-world use cases. Authors can add new tags to their blog posts over time, and while they may miss their icon, at least won’t bring the site down and throw that exception.

I feel like a bit of an outsider when it comes to contributing to open source software (especially after a less-than-welcoming experience with a different large open-source project), but am feeling welcomed by the Statamic team and feel that my contributions are useful not only for my projects, but also may be useful for others too, and these minor (yet positively impactful) additions can help enhance the product without treading on the toes or roadmap of the future of the platform from the core dev team.

You may be interested in...