# An item's fields

> The types a collection's fields can have, how a page prints them, and why a phone number, a link and a picture each get a little more care than the rest.
>
> From the MightyBuilder documentation: https://docs.mightybuilder.ai/dynamic/fields

Every item of a [collection](/dynamic/collections) 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](#more-than-one-of-something).

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`:

```liquid
<p>Client: {{ item.fields.client }}</p>
```

In a list of the collection, each item is whatever your loop calls it:

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

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

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

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

```liquid-invalid
<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.
