From 426a8b00edcbb794d1ca5ab27b441f192604dc11 Mon Sep 17 00:00:00 2001 From: Jason Varga Date: Wed, 9 Sep 2026 16:06:04 -0400 Subject: [PATCH] Document the `include` tag Ref: statamic/cms#15182 --- content/collections/tags/include-exists.md | 39 +++ content/collections/tags/include-if-exists.md | 39 +++ content/collections/tags/include.md | 262 ++++++++++++++++++ content/collections/tags/partial.md | 2 + 4 files changed, 342 insertions(+) create mode 100644 content/collections/tags/include-exists.md create mode 100644 content/collections/tags/include-if-exists.md create mode 100644 content/collections/tags/include.md diff --git a/content/collections/tags/include-exists.md b/content/collections/tags/include-exists.md new file mode 100644 index 000000000..dbcdf3e95 --- /dev/null +++ b/content/collections/tags/include-exists.md @@ -0,0 +1,39 @@ +--- +id: 35ff991a-fb8a-4747-9e12-f64047f0b192 +title: 'Include:Exists' +description: 'Checks if a view exists.' +intro: 'Checks if a view exists.' +parameters: + - + name: src + type: string + description: 'You can pass the name of the view with a parameter instead of tag argument. Example: `src="cards/author"` or `:src="var_name"`.' +--- +## Overview + +You can use this tag to check if a view exists. Useful if you have some sort of dynamic loop. + +::tabs + +::tab antlers +```antlers +{{ if {include:exists src="cards/author"} }} + It exists +{{ else }} + It doesn't. +{{ /if }} +``` +::tab blade +```blade +@if (Statamic::tag('include:exists')->src('cards/author')->fetch()) + It exists +@else + It doesn't. +@endif +``` +:: + +## Related Reading + +This tag goes hand in hand with the [`include`](/tags/include) tag. +You may be interested in the [`include:if_exists`](/tags/include-if-exists) tag to simplify your template. diff --git a/content/collections/tags/include-if-exists.md b/content/collections/tags/include-if-exists.md new file mode 100644 index 000000000..a0ed7502b --- /dev/null +++ b/content/collections/tags/include-if-exists.md @@ -0,0 +1,39 @@ +--- +id: f06c6941-8ad3-4eac-99b1-6d3dea857d57 +title: 'Include:If_Exists' +description: 'Renders a view if it exists.' +intro: 'Renders a view if it exists.' +parameters: + - + name: src + type: string + description: 'You can pass the name of the view with a parameter instead of tag argument. Example: `src="cards/author"` or `:src="var_name"`.' + - + name: '*' + type: mixed + description: 'Any parameter you create will be passed through to the view as a variable.' +--- +## Overview + +You can use this tag to render a view if it exists. Useful if you have some sort of dynamic loop. + +::tabs + +::tab antlers +```antlers +{{ include:if_exists src="cards/author" }} +``` +::tab blade +```blade + +``` +:: + +Practically identical to the [`include`](/tags/include) tag, except if the view doesn't exist it will just output +nothing instead of throwing a "view not found" exception. + +## Related Reading + +This tag goes hand in hand with the [`include`](/tags/include) tag. +You may be interested in the [`include:exists`](/tags/include-exists) tag if you need to do a more +complicated conditional check in your template. diff --git a/content/collections/tags/include.md b/content/collections/tags/include.md new file mode 100644 index 000000000..6d6db30df --- /dev/null +++ b/content/collections/tags/include.md @@ -0,0 +1,262 @@ +--- +title: Include +description: Renders a view without inheriting the surrounding scope +intro: 'A strictly-scoped alternative to the [partial](/tags/partial) tag. Where `partial` shares everything from the surrounding template, `include` only sees what you explicitly pass to it.' +parameters: + - + name: src + type: string + description: | + You can pass the name of the view with a parameter instead of tag argument. Example: `src="cards/author"` or `:src="var_name"`. + - + name: params + type: array + description: | + An array of data to spread into the include as variables. Example: `:params="author"`. + - + name: handle_prefix + type: string + description: | + A prefix to strip from variable names when looking up data. For example, if you have a variable named `hero_title` and use `handle_prefix="hero_"`, you can reference it as `{{ title }}` inside the view. + - + name: cascade + type: string + description: | + Pass `true` to make the [Cascade](/tags/cascade) (page, globals, site, etc.) available inside the view. Off by default. + - + name: when + type: string + description: | + Render the include only if a condition is met. + - + name: unless + type: string + description: | + The converse of `when`. + - + name: "*" + type: mixed + description: | + Any parameter you create will be passed through to the view as a variable. +id: dc16f77a-2b02-40c9-9097-6e94f38edd94 +--- +## Overview + +The [partial](/tags/partial) tag automatically shares every variable from the calling template with the view it renders. That's convenient, but it's also the source of a long line of scoping gotchas: variables set inside a partial leaking back out, parameters from one partial showing up in another rendered later on the page, and front matter hanging around longer than expected. + +The `include` tag renders a view the same way, but doesn't automatically share anything. Only the data you explicitly pass in is available inside the view. + +::tabs + +::tab antlers +```antlers +{{ include:cards/author name="Jimothy" :bio="author_bio" }} +``` +::tab blade +```blade + +``` +:: + +### How It Differs From Partial + +| | `partial` | `include` | +|---|---|---| +| Variables from the surrounding template | All of them | Only what you pass in | +| Variables set inside the view | Can leak back into the page | Stay inside the include | +| The Cascade (page, globals, etc.) | Automatically available | Requires `cascade="true"` | +| Front matter | Visible to other views rendered later | Stays with the include | +| Slots | Rendered up front, passed as strings | Rendered on demand, and can receive data back from the view | + +## Passing Data + +Unlike `partial`, any parameter you set on the tag becomes a variable inside the view, and nothing else does. + +::tabs + +::tab antlers +```antlers +{{ include:cards/author name="Jimothy" role="Editor" }} + +// Inside cards/author.antlers.html +{{ name }} — {{ role }} +``` +::tab blade +```blade + +``` + +```blade +{{-- Inside cards/author.blade.php --}} +{{ $name }} — {{ $role }} +``` +:: + +You can spread an entire array of data using `:params`. Inside the view, use `params` to check what was actually passed in: + +::tabs + +::tab antlers +```antlers +{{ include:cards/author :params="author" role="Editor" }} + +// Inside cards/author.antlers.html +{{ name }}, {{ params:role }} +``` +::tab blade +```blade + +``` +:: + +Use `handle_prefix` to make prefixed keys like `hero_title` available inside the view as both `hero_title` and `title`: + +::tabs + +::tab antlers +```antlers +{{ include:hero :params="entry" handle_prefix="hero_" }} +``` +::tab blade +```blade + +``` +:: + +:::best-practice +To set default values for parameters inside your includes, you can [add YAML front-matter](/variables/#view-frontmatter) to the top of your Antlers include, and reference it with the `view:` prefix. Just like `partial`, this is preferable over defining custom variables inside the view. +::: + +## Slots + +Content between the tag pair becomes the default slot, available inside the view as `{{ slot }}`. + +::tabs + +::tab antlers +```antlers +{{ include:modal title="Delete this entry?" }} +

This action cannot be undone.

+{{ /include:modal }} + +// Inside modal.antlers.html +

{{ title }}

+
{{ slot }}
+``` +::tab blade +```blade + +

This action cannot be undone.

+
+``` + +```blade +{{-- Inside modal.blade.php --}} +

{{ $title }}

+
{{ $slot }}
+``` +:: + +### Named Slots + +Define named slots with `slot:name` pairs. A view can give a named slot a fallback by wrapping its own content in a matching pair. + +::tabs + +::tab antlers +```antlers +{{ include:modal title="Delete this entry?" }} + {{ slot:footer }}{{ /slot:footer }} +

This action cannot be undone.

+{{ /include:modal }} + +// Inside modal.antlers.html +

{{ title }}

+
{{ slot }}
+
{{ slot:footer }}No footer provided{{ /slot:footer }}
+``` +::tab blade +```blade + + +

This action cannot be undone.

+
+``` + +```blade +{{-- Inside modal.blade.php --}} +

{{ $title }}

+
{{ $slot }}
+
No footer provided
+``` +:: + +Slots only render when the view actually uses them, and a slot is re-rendered each time the view outputs it — which means a view can pass data back into a slot and render it once per iteration of a loop: + +::tabs + +::tab antlers +```antlers +{{ include:table :rows="rows" }} + {{ slot:row }}{{ cell }}{{ /slot:row }} +{{ /include:table }} + +// Inside table.antlers.html +{{ rows }}{{ slot:row :cell="value" }}{{ /rows }}
+``` +::tab blade +```blade + + {{ $cell }} + +``` + +```blade +{{-- Inside table.blade.php --}} +@foreach($rows as $row)@endforeach
+``` +:: + +## The Cascade + +Includes don't see the [Cascade](/tags/cascade) by default. Pass `cascade="true"` when you want it: + +::tabs + +::tab antlers +```antlers +{{ include:site_header cascade="true" }} +``` +::tab blade +```blade + +``` +:: + +## Conditional Rendering + +You can render an include only if a condition is met, using `when` and its converse, `unless`. + +::tabs + +::tab antlers +```antlers +{{ include:promo :when="show_promo" }} +``` +::tab blade +```blade + +``` +:: + +## Using With Modifiers + +Because the `include` tag is a tag and not a variable, you can't pipe it through [modifiers](/modifiers) directly. To apply modifiers to an include's rendered output, wrap it in a [sub-expression](/antlers#sub-expressions) using curly braces. + +```antlers +{{ { include:component } | spaceless }} +``` + +## Related Reading + +You may also be interested in the [`include:exists`](/tags/include-exists) or [`include:if_exists`](/tags/include-if-exists) tags. diff --git a/content/collections/tags/partial.md b/content/collections/tags/partial.md index 253e3ae85..4c8f99e97 100644 --- a/content/collections/tags/partial.md +++ b/content/collections/tags/partial.md @@ -235,3 +235,5 @@ Everything inside the `{ ... }` is parsed first, and the result is then passed t If you haven't read up on [views](/views) yet, you should. It's considered fundamental knowledge, like knowing that seals are just dog mermaids. 🐕 🧜‍♀️ You may also be interested in the [`partial:exists`](/tags/partial-exists) or [`partial:if_exists`](/tags/partial-if-exists) tags. + +If you'd rather a view *not* inherit anything from the surrounding template, take a look at the [`include`](/tags/include) tag.