docs
docs copied to clipboard
Antlers: handle_prefix docs
Add documentation for handle_prefix.
The following can be used as a starting point for anyone looking to get it over the finish line (from https://stillat.com/blog/2022/04/22/managing-fieldset-handles-with-antlers-runtime) 🥳
A common design pattern when building Statamic sites is to use fieldsets to create reusable fields across different collections, forms, or pages. Additionally, it is also not uncommon to see specific partials created to display these fieldsets. This is nice since it allows for the same template code and groups of fields to be managed in a central location, and helps to keep things well organized and clean.
As an example, we could have the following fieldset to manage Frequently Asked Questions:
title: FAQ
fields:
-
handle: faq
field:
collapse: false
sets:
questions:
display: Questions
fields:
-
handle: question
field:
input_type: text
antlers: false
display: Question
type: text
icon: text
listable: hidden
instructions_position: above
read_only: false
-
handle: answer
field:
antlers: false
display: Answer
type: textarea
icon: textarea
listable: hidden
instructions_position: above
read_only: false
display: Questions
type: replicator
icon: replicator
listable: hidden
instructions_position: above
read_only: false
We could create a partial named components/faq.antlers.html
with the following template that would render our fieldset:
<dl>
{{ faq }}
<dt>{{ question }}</dt>
<dd>{{ answer }}</dd>
{{ /faq }}
</dl>
and simply include the following in other templates when we wanted to reuse our Frequently Asked Questions template:
{{ partial:components/faq }}
Working with Fieldset Prefixes
The previous example works great when field names do not change. However, because fieldsets can be prefixed, it becomes difficult to create truly reusable partials when targeting fieldsets (or when you may want to render the same group of fields multiple times on the same page, each with a different prefix). Let's assume that the previous fieldset was imported twice within the same blueprint. Once without a prefix, and a second time with the product_
prefix:
title: Home
sections:
main:
display: Main
fields:
-
handle: title
field:
type: text
required: true
character_limit: 0
display: Title
validate:
- required
-
import: faq
-
import: faq
prefix: product_
Our page would now contain a faq
and product_faq
variable, each with their own list of Frequently Asked Questions. With this setup, we could either duplicate our partial or simply alias the single variable to render both:
{{ partial:components/faq }}
{{ partial:components/faq :faq="product_faq" }}
This technique works well when the imported fieldsets are small (such as in this example), but can quickly become tedious if the imported fieldset contains many different fields. This often leads to attempts to writing invalid Antlers code like the following:
{{# Inside `components/faq.antlers.html`. #}}
<dl>
{{ {prefix}faq }}
<dt>{{ question }}</dt>
<dd>{{ answer }}</dd>
{{ /{prefix}faq }}
</dl>
{{# In another file. #}}
{{ partial:components/faq prefix="product_" }}
Even if the above had worked, it would make handling the non-prefixed case much more difficult. To help with this situation, Antlers Runtime supports the concept of forcing the Runtime to check if a variable exists with any given prefix, before falling back to the normal cascade rules.
Fieldset Prefixes and Variable Names
To have the Runtime check if variables exist with a prefix, you simply need to add the handle_prefix
parameter to either the partial
tag or the scope
tag:
{{ partial:components/faq }}
{{ partial:components/faq handle_prefix="product_" }}
When the Runtime encounters the handle_prefix
parameter, every variable will be checked to see if it exists with a prefix (but only within the partial or scope tag on which it was applied).
When the above code is being evaluated, it would be as if we had written this Antlers instead:
<dl>
{{ faq }}
<dt>{{ question }}</dt>
<dd>{{ answer }}</dd>
{{ /faq }}
</dl>
<dl>
{{ product_faq }}
<dt>{{ question }}</dt>
<dd>{{ answer }}</dd>
{{ /product_faq }}
</dl>
The first partial call would render like normal, because no prefix was specified. However, in the second partial call we are specifying the product_
prefix. Because a product_faq
variable does exist, that will be used instead of the faq
variable (if no prefixed match was found, Antlers will revert back to normal variable Cascade logic).
The scope
tag version might look something like this:
{{ scope handle_prefix="product_" }}
<dl>
{{ faq }}
<dt>{{ question }}</dt>
<dd>{{ answer }}</dd>
{{ /faq }}
</dl>
{{ /scope }}