Content that fills itself in
Collections
Copy page
A collection is a kind of thing your site has many of, where each one gets a
page of its own — articles, portfolio pieces, team members, products. Every
site starts with one, articles, which is the blog.
A collection or a block
The question that tells them apart is whether each thing needs its own page.
- Your phone number and address, shown in the footer of every page: a block — the footer — written once and embedded everywhere.
- Twelve wedding cakes, each with photographs, the couple’s names and the year, each at its own address: a collection, with fields for what every cake has.
Fields and items
A collection’s fields say what each item has — a client, a year, an author. The collection itself holds no values; its items do.
An item is a whole page: a title, its own content, its own settings and pictures, drafts, revisions and Publish — plus a value for each of the collection’s fields.
Every collection has a row of its own in the rail, under Forms — Articles is one. It opens on the collection’s items, the way Pages opens your pages: add one, open one, hide one, put one in the trash. An item opens in the same editor as a page, with one extra tab, Fields, which is a form for its values.
Setting a collection up is a different job, so it is somewhere else: Settings › Collections, where you make a new one and open any of them on three tabs:
- Fields — what each item has, written out as code. Asking the AI is the easier way to change it.
- Settings — its title and name, where the items live, whether they nest, whether they go in your feed, and the icon its rail row shows. Their order is not set here: you drag the items into it on the collection’s own screen.
- Layout — the markup every item’s page is wrapped in.
You can just ask
Add a portfolio collection for our cakes: the couple’s names, the year, and which tiers they had.
The AI makes the collection, gives each field the right type, and can make the items too. It never invents a value: whatever you have not told it stays empty, and it says so.
Where the items live
Every item is at the collection’s slug and then its own:
Portfolio /portfolio/smith-wedding
Articles /articles/a-year-of-sourdough
Change the slug on the Settings tab and every item moves together, each one leaving a redirect behind at the next Publish. No page owns an item, so moving or renaming the page that lists them moves no item. See Articles, which is the same thing said about the blog.
Items under items
Switch on Hierarchical on the collection’s Settings tab and its items can sit under one another, the way pages do. Drag an item to the right, under the one above it, and its address takes that item’s:
Services /services/dental
/services/dental/implants
Moving an item moves everything under it, each leaving a redirect behind. Switching Hierarchical off moves every nested item to the top level of the collection, and the tab warns you how many first; each keeps a redirect from its old address.
An item’s slug cannot be all digits — a year belongs in the title — and cannot
be size, first, last or length, which mean something else to a list.
Listing them
A collection is a list:
{% for p in collections.portfolio %}
<a href="{{ p.url }}">
<h3>{{ p.title }}</h3>
{% if p.fields.year %}<p>{{ p.fields.year }}</p>{% endif %}
</a>
{% endfor %}
Each item has everything a page has in a list — title, url, date,
excerpt, image, tags, parent, order — and its own values under
fields. See What a page knows about another page.
The list comes in your order: the one you drag the items into on the collection’s screen, a new item arriving at the top. That suits a portfolio you want to lead with your best work. A blog wants dates instead, so it sorts:
{% assign posts = collections.articles | sort: "date" | reverse %}
In a hierarchical collection, the top level is the items with no parent, and
one item’s children are the ones whose parent is its path:
{% assign top = collections.services | where: "parent", "" %}
{% for s in top %}
<h3><a href="{{ s.url }}">{{ s.title }}</a></h3>
{% assign kids = collections.services | where: "parent", s.path %}
{% for k in kids %}<a href="{{ k.url }}">{{ k.title }}</a>{% endfor %}
{% endfor %}
One item, by its slug:
{% assign cake = collections.portfolio["smith-wedding"] %}
{% if cake %}
<a href="{{ cake.url }}">{{ cake.title }}</a>
{% endif %}
A collection is only its items. There is no collections.portfolio.title:
words about the collection — a blog’s introduction — belong on the page that
lists it.
The layout
Every item in a collection usually shares a shape: the title at the top, the byline, the fields laid out the same way, a link back to the list. Writing that into every item means changing every item when the shape changes.
The Layout tab is that shape, written once. It is html, CSS and JS like
any page’s, and it wraps every item’s page. Put {% item_body %} exactly once,
where the item’s own content goes:
<article class="cake">
<h1>{{ item.title }}</h1>
{% if item.fields.couple_names %}
<p class="couple">{{ item.fields.couple_names }}</p>
{% endif %}
{% item_body %}
<a href="/portfolio">All our cakes</a>
</article>
While an item’s page is being served, item is that item and item.fields
are its values. page is the item too, so everything on
A page’s own details works here as well.
Leave the layout empty and each item is simply its own page.
A block that behaves differently on an item
A header or footer block is on every page, items included. When it needs to do something only on an item, ask whether there is one:
{% if item %}
<a href="/portfolio">Back to the portfolio</a>
{% endif %}
When a field changes
Remove or rename a field that a listing or the layout still reads, and Publish refuses until they stop reading it — the message names the page and the field. A field marked required stops Publish while any item has it empty, and the message names the item. Taking a collection down is refused while it still has items.