Overview
The collection tag is one of main workhorses of your Statamic frontend. It’s like an Eloquent model in Laravel or “The Loop” in WordPress – it’s how you get data from everywhere (other than the current entry and global variables) into your view.
Example
A basic example would be to loop through the entries in a blog collection and link to each individual blog post:
<ul>
{{ collection from="blog" }}
<li><a href="{{ url }}">{{ title }}</a></li>
{{ /collection }}
</ul>
You can also use the shorthand syntax for this. We prefer this style ourselves.
<ul>
{{ collection:blog }}
<li><a href="{{ url }}">{{ title }}</a></li>
{{ /collection:blog }}
</ul>
If you’d like to fetch entries from multiple collections, you’ll need to use the standard syntax.
{{ collection from="blog|events" }}
To get entries from all collections, use the wildcard *
. You may also exclude collections when doing this.
{{ collection from="*" not_from="blog|events" }}
Filtering
There are a number of ways to filter your collection. There’s the conditions syntax for filtering by fields, taxonomy filter for using terms, and the custom filter class if you need extra control.
Conditions
Want to get entries where the title has the words “awesome” and “thing”, and “joe” is the author? You can write it how you’d say it:
{{ collection:blog
title:contains="awesome"
title:contains="thing"
author:is="joe"
}}
There are a bunch of conditions available to you, like :is
, :isnt
, :contains
, :starts_with
, and :is_before
. There are many more than that. In fact, there’s a whole page dedicated to conditions - check them out.
Taxonomies
Filtering by a taxonomy term (or terms) is done using the taxonomy
parameter, similar to the conditions syntax mentioned above.
To show entries with the harry-potter
term within the tags
taxonomy, you could do this:
{{ collection:blog taxonomy:tags="harry-potter" }}
It is important that the collection has been configured to use this taxonomy in order to filter the results based on the passed in term.
There are a number of different ways to use this parameter. They are explained in depth in the Taxonomies Guide
Published Status
By default, only published
entries are included. Entries can be queried against draft
, scheduled
, or expired
status with conditions on status
like this:
// Include draft entries
{{ collection:blog status:in="published|draft" }}
// Only include expired entries
{{ collection:blog status:is="expired" }}
// Exclude published entries
{{ collection:blog status:not_in="published" }}
Custom Query Scopes
Doing something custom or complicated? You can create query scopes to narrow down those results with the query_scope
or filter
parameter:
{{ collection:blog query_scope="your_query_scope" }}
Pagination
To enable pagination mode, add the paginate="true"
parameter, along with the limit
parameter to specify the number of entries in each page.
{{ collection:blog limit="10" paginate="true" as="posts" }}
{{ if no_results }}
<p>Aww, there are no results.</p>
{{ /if }}
{{ posts }}
<article>
{{ title }}
</article>
{{ /posts }}
{{ paginate }}
<a href="{{ prev_page }}">⬅ Previous</a>
{{ current_page }} of {{ total_pages }} pages
(There are {{ total_items }} posts)
<a href="{{ next_page }}">Next ➡</a>
{{ /paginate }}
{{ /collection:blog }}
In pagination mode, your entries will be scoped (in the example, we’re scoping them into the posts
tag pair). Use that tag pair to loop over the entries in that page.
The paginate
variable will become available to you. This is an array containing data about the paginated set.
Variable | Description |
---|---|
next_page |
The URL to the next paginated page. |
prev_page |
The URL to the previous paginated page. |
total_items |
The total number of entries. |
total_pages |
The number of paginated pages. |
current_page |
The current paginated page. (ie. the x in the ?page=x param) |
auto_links |
Outputs an HTML list of paginated links. |
links |
Contains data for you to construct a custom list of links. |
links:all |
An array of all the pages. You can loop over this and output {{ url }} and {{ page }}. |
links:segments |
An array of data for you to create a segmented list of links. |
Pagination Examples
The auto_links
tag is designed to be your friend. It’ll save you more than a few keystrokes, and even more headaches. It will output an HTML list of links for you. With a large number of pages, it will create segments so that you don’t end up with hundreds of numbers.
It’s clever enough to work out a comfortable range of numbers to display, and it’ll also throw in the prev/next arrow for good measure.
Maybe the default markup isn’t for you and you want total control. You’re a maverick. That’s cool, we roll that way sometimes too. That’s where the links:all
or links:segments
array variables come in. These give you all the data you need to recreate your own set of links.
-
The
links:all
array is all the pages withurl
andpage
variables. -
The
links:segments
array will contain the segments mentioned above. You’ll be able to accessfirst
,slider
, andlast
, which are the 3 segments.
Here’s the auto_links
output, recreated using the other tags, for you mavericks out there:
{{ paginate }}
<ul class="pagination">
{{ if prev_page }}
<li><a href="{{ prev_page }}">«</a></li>
{{ else }}
<li class="disabled"><span>«</span></li>
{{ /if }}
{{ links:segments }}
{{ first }}
{{ if page == current_page }}
<li class="active"><span>{{ page }}</span></li>
{{ else }}
<li><a href="{{ url }}">{{ page }}</a></li>
{{ /if }}
{{ /first }}
{{ if slider }}
<li class="disabled"><span>...</span></li>
{{ /if }}
{{ slider }}
{{ if page == current_page }}
<li class="active"><span>{{ page }}</span></li>
{{ else }}
<li><a href="{{ url }}">{{ page }}</a></li>
{{ /if }}
{{ /slider }}
{{ if slider || (!slider && last) }}
<li class="disabled"><span>...</span></li>
{{ /if }}
{{ last }}
{{ if page == current_page }}
<li class="active"><span>{{ page }}</span></li>
{{ else }}
<li><a href="{{ url }}">{{ page }}</a></li>
{{ /if }}
{{ /last }}
{{ /links:segments }}
{{ if next_page }}
<li><a href="{{ next_page }}">»</a></li>
{{ else }}
<li class="disabled"><span>»</span></li>
{{ /if }}
</ul>
{{ /paginate }}
Aliasing
Often times you’d like to have some extra markup around your list of entries, but only if there are results. Like a <ul>
element, for example. You can do this by aliasing the results into a new variable tag pair. This actually creates a copy of your data as a new variable. It goes like this:
{{ collection:blog as="posts" }}
<ul>
{{ posts }}
<li><a href="{{ url }}">{{ title }}</a></li>
{{ /posts }}
</ul>
{{ /collection:blog }}
Scoping
Sometimes not all of your entries have the same set of variables. And sometimes the page that you’re on (while listing entries in a Collection, for example) may have those very same variables on the page-level scope. Statamic assumes you’d like to fallback to the parent scope’s data to plug any holes. This logic has pros and cons, and you can read more about scoping and the Cascade here.
You can assign a scope prefix to your entries so you can be sure to get the data you want. Define your scope and then prefix all of your variables with it.
# Page data
featured_image: /img/totes-adorbs-kitteh.jpg
{{ collection:blog scope="post" }}
<div class="block">
<img src="{{ post:featured_image }}">
</div>
{{ /collection:blog }}
You can also add your scope down into your alias loop. Yep, we thought of that too.
{{ collection:blog as="posts" }}
{{ posts scope="post" }}
<div class="block">
<img src="{{ post:featured_image }}">
</div>
{{ /posts }}
{{ /collection:blog }}
Combining both an Alias and a Scope on a Collection Tag doesn’t make a whole lot of sense. You shouldn’t do that.
Parameters
from|folder|use string|array
The name of the collection(s). Pipe separate names to fetch entries from multiple collections. You may use *
to get entries from all collections.
not_from|not_folder|dont_use string|array
When getting all collections with *
, this parameter can accept a pipe delimited list of collections to exclude.
collection tag part
The name of the collection when using the shorthand syntax. This is not actually a parameter, but part of the tag itself. For example, {{ collection:blog }}
.
show_unpublished boolean *false*
Unpublished content is, by it's very nature, unpublished. That is, unless you show it by turning on this parameter.
show_published boolean *true*
Setting this to false
will prevent published entries from being displayed. Pairs nicely with show_unpublished="true"
to only show drafts.
show_future boolean *false*
Date-based entries from the future are excluded from results by default. Of course, if you want to show upcoming events or similar content, flip this switch.
show_past boolean *true*
Just like show_future
, but for entries in the past.
since string/var
Limits the date the earliest point in time from which date-based entries should be fetched. You can use plain English (PHP's strtotime
method will interpret. eg. last sunday
, january 15th, 2013
, yesterday
) or the name any date variable.
until string/var
The inverse of since
, but sets the max date.
sort string
Sort entries by field name (or random
). You may pipe-separate multiple fields for sub-sorting and specify sort direction of each field using a colon. For example, sort="title"
or sort="date:asc|title:desc"
to sort by date then by title. To sort manually, use sort="order"
. (Make sure to set max depth to 1 for your collection).
limit integer
Limit the total results returned.
filter|query_scope string
Apply a custom query scope
offset integer
The number of entries the results should by offset by.
taxonomy mixed
A multitude of ways to filter by taxonomies. More details
paginate boolean *false*
Specify whether your entries should be paginated.
as string
Alias your entries into a new variable loop.
scope string
Scope your entries with a variable prefix.
locale string
Show the retrieved content in the selected locale.
redirects|links boolean *false*
By default, entries with redirects will be filtered out. Set this to true
to include them.
Variables
Variable | Type | Description |
---|---|---|
first |
boolean |
Is this the first item in the loop? |
last |
boolean |
Is this the last item in the loop? |
count |
integer |
The number/index of current iteration in the loop, starting from 1 |
index |
integer |
The number/index of current iteration in the loop, starting from 0 |
order |
integer |
The number/index of the item relative to the collection, not affected by any sort/filter parameters on the tag. Note: this is only available on collections where the order is set to number. |
no_results |
boolean |
Returns true if there are no results. |
total_results |
integer |
The total number of results in the loop when there are results. You should use |
entry data |
mixed |
Each result has access to all the variables inside that entry ( |