# Collections

> Portfolio pieces, team members, products: a kind of thing with a page each. Fields every item has, a list that keeps itself, and one layout around them all.
>
> From the MightyBuilder documentation: https://docs.mightybuilder.ai/dynamic/collections

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](/pages/blocks) — 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](/dynamic/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](/dynamic/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](/dynamic/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:

```liquid
{% 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](/dynamic/what-a-page-knows).

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:

```liquid
{% 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:

```liquid
{% 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:

```liquid
{% 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:

```liquid
<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](/dynamic/a-pages-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:

```liquid
{% 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.
