Content that fills itself in
An item's fields
Copy page
Every item of a collection has the same fields — a client and a year on a portfolio piece, a role and a photograph on a team member — and each item has its own value for each. This page is about those fields: the types there are, and how a page prints them.
Fields and values
A collection’s fields are defined once, under Settings › Collections, and an item’s values are filled in on its Fields tab: one box per field, with a label and a line saying what goes there. It is saved as you type.
Each field has a type, and the type is what checks the value:
| Type | For |
|---|---|
telephone, email |
a number to ring, an address to write to |
link |
a page on this site, or an address elsewhere |
address, hours, social |
a postal address, opening times, a social profile |
price, number |
what they say |
date, time, datetime |
a day, a time of day, or both |
image, file |
something from your library |
choice, boolean |
one of a list, or yes and no |
color, font, size, shadow |
a design value for this one item — its own accent colour, say |
text, textarea |
words, when nothing more particular fits |
Two more types hold other fields rather than a value: a group, which gathers
a few fields under one name, and a repeater, which holds
rows of them.
A field can be required. An empty required field stops Publish and names the item, so mark one only when the site cannot do without it.
Printing one
On an item’s own page, its values are item.fields:
<p>Client: {{ item.fields.client }}</p>
In a list of the collection, each item is whatever your loop calls it:
{% for p in collections.portfolio %}
<a href="{{ p.url }}">{{ p.title }}</a> — {{ p.fields.client }}
{% endfor %}
A value nobody has filled in prints nothing. So anything that only makes sense
when the value exists goes inside a plain {% if %} on that same value:
{% if item.fields.email %}
<a href="mailto:{{ item.fields.email }}">{{ item.fields.email }}</a>
{% endif %}
Without the guard, an empty value leaves a button that does nothing. The AI writes the guard for you; it is worth knowing why it is there.
Phone numbers
A phone number is the one value a page shows in two shapes: the one a reader reads, and the one a handset dials. You only store the first.
{% if item.fields.phone %}
<a href="tel:{{ item.fields.phone | tel }}">{{ item.fields.phone }}</a>
{% endif %}
| tel takes whatever you typed and leaves the part a phone can dial — it
keeps a leading + and the digits, and drops the spaces, brackets and dashes
you put in to make it readable. So the number on the page stays exactly as you
wrote it.
It stops at the first thing that is not part of a number, which is deliberate:
0113 496 0000 ext. 2 dials the switchboard rather than a number with a stray
2 on the end.
Links
A website, a map pin, wherever people book — give each a field of type
link. A link is the one kind of value that can fill an href on its own:
<a href="{{ item.fields.booking }}">Book</a>, inside an
{% if item.fields.booking %} like the email above.
That is not fussiness about the others. A link is a value a page hands to the browser as an instruction rather than as words, and the platform only allows that where it can promise the value really is an address — which a link field can, because it checks what you type. A web address kept in a text field can be printed but never clicked, and using one as a link will stop your publish.
A link fills an <a href>. It cannot load a script, embed a frame or send a
form somewhere — a publish will say so if a page tries.
More than one of something
A gallery, the questions on one product, the people on one project: anything an item could have more of is a repeater. Each row has the same fields, and a short key that names it.
A page loops over the rows:
{% for q in item.fields.faqs %}
<h3>{{ q.question }}</h3>
<p>{{ q.answer }}</p>
{% endfor %}
Never by position. “The first question” changes the moment somebody drags the rows into a different order, so publishing refuses it:
<p>{{ item.fields.faqs[0].answer }}</p>
Some values are made of parts — an address has a city, a picture has a
url — and you print the part you want: {{ item.fields.address.city }}. A
picture also has every part a page’s own image has (src, width, height,
webp, avif, alt), so the same <picture> markup works for both.
Changing the fields
A collection’s Fields tab, under Settings, is its fields written out as code. Most people never open it: asking the AI is easier, and it reads the fields before it changes them.
If you do edit it, the change is saved even when a page still reads the field you removed or renamed. Publish then refuses while a listing or the layout still reads it, and the message names the field, so nothing goes live with a hole in it. Fix the page, or ask the AI to, and publish again. A field given a different type starts empty on every item.
The AI never makes a fact up
If it needs a fact you have not given it — a client’s name, say — it leaves the value empty and tells you what is missing. Fill it in on the item’s Fields tab, or tell it in the conversation.