Custom Fields
The _admin.yml file lives at the root of your site's source directory and defines how editable content is presented to site owners. It controls which files are editable, what form fields appear, and how the site's Jekyll config is managed across environments.
Top-Level Sections
collections: # Editable content collections
forms: # Form submission handling (optional)
roles: # User role definitions (optional)
All sections are optional. An _admin.yml is not required.
Collections
Collections define groups of editable content. There are two types: file collections (edit specific named files) and folder collections (edit a directory of documents).
collections:
- name: data
files: [...] # File collection
- name: posts
folder: _posts # Folder collection
create: true
fields: [...]
File Collections
Edit specific, named files. Used for single pages and data files with unique structures.
collections:
- name: pages
label: Pages
basedir: _pages
i18n: [en, es]
files:
- file: frontpage.html
label: Front Page
readonly:
- layout
- permalink
fields:
- name: title
widget: string
- name: hero
widget: object
fields:
- { name: heading, widget: trix }
- { name: description, widget: textarea }
File collection properties:
name(required) — Unique identifier for the collection.label— Display name. Auto-generated fromnameif omitted.files(required) — List of file definitions (see below).basedir— Common base directory for all files. When set,filepaths are relative to it (e.g.,basedir: _pages+file: frontpage.html→_pages/frontpage.html).i18n— List of language codes. First language is the default. Non-default languages store files under<lang>/relative tobasedir.protected— Iftrue, built pages require authentication to view.
File definitions
Each entry in files describes one editable file:
file(required) — Path to the file (relative tobasedir, or absolute like_data/hero.yml).name— Identifier. Defaults to the filename stem.label— Display name. Auto-generated fromnameif omitted.fields(required) — List of field definitions.readonly— List of field names whose values are preserved from the source file and not shown in the editor.
Supported file formats: .html, .md, .yml, .yaml, .json.
For frontmatter files (.html, .md), the field named content maps to the body text below the YAML front matter.
Folder Collections
Edit a directory of documents that share the same field structure. New documents can be created from the CMS.
collections:
- name: projects
label: Projects
label_singular: Project
folder: _projects
create: true
output: true
path: ""
protected: true
i18n: [en, es]
permalink: /projects/:title/
i18n_permalinks:
es: /es/proyectos/:title/
readonly:
- name: layout
value: project
- name: lang
template: ""
- name: ref
template: "-"
fields:
- name: title
widget: string
- name: content
widget: trix
Folder collection properties:
name(required) — Unique identifier.label— Display name. Auto-generated fromnameif omitted.label_singular— Singular display name (e.g., "Project"). If omitted, strips trailing "s" fromlabel.folder(required) — Directory path relative to site root (e.g.,_posts,_projects).create(required) — Whether users can create new documents.fields(required) — List of field definitions shared by all documents.path— Filename template for new documents. Supports Liquid variables:,,,. Default: ``.identifier_field— Field used for document display name in lists.output— Iftrue, documents generate standalone pages. Triggers Jekyllcollectionsconfig withoutput: true.protected— Iftrue, built pages require authentication to view.readonly— List of auto-populated fields (see Readonly Fields below).i18n— List of language codes. Default-language docs live in the folder root; other languages go in<folder>/<lang>/subdirectories.permalink— URL pattern for output collections (e.g.,/projects/:title/).i18n_permalinks— Map of language code to permalink override. If a language is not listed, the platform auto-generates one by prepending/<lang>/to the base permalink.
Readonly Fields
Readonly fields are auto-populated and hidden from the editor. They work differently in file vs. folder collections.
File collections — readonly is a flat list of field names. Their existing values in the source file are preserved:
readonly:
- layout
- permalink
- lang
Folder collections — readonly is a list of objects with a name and either a static value or a Liquid template:
readonly:
- name: layout
value: project
- name: lang
template: ""
- name: ref
template: ""
Template context includes all frontmatter fields plus:
slug— Slugified titlelang— Current language codefilename— File stem (without extension)
Templates support Liquid filters (e.g., ``).
Field Types (Widgets)
Every field requires a name. The widget property determines the input type and defaults to string if omitted.
Common Field Properties
- name: title # Required — field key in the data file
label: Page Title # Display name (auto-generated from name if omitted)
widget: string # Input type (default: string)
required: true # Whether the field must have a value (default: true)
hint: "Keep it short" # Help text shown below the input
default: "" # Default value for new documents
i18n: true # Internationalization mode (see i18n section)
Text Widgets
string — Single-line text input. This is the default widget.
- name: title
widget: string
textarea — Multi-line plain text.
- name: description
widget: textarea
markdown — Markdown editor.
- name: body
widget: markdown
trix — Rich text editor (Trix). Produces HTML.
- name: bio
widget: trix
Data Widgets
number — Numeric input.
- name: price
widget: number
date — Date picker.
- name: dob
label: Date of Birth
widget: date
datetime — Date and time picker.
- name: published_at
widget: datetime
boolean — Checkbox toggle.
- name: featured
widget: boolean
default: false
hidden — Not displayed in the editor. Used for fixed metadata like layout.
- name: layout
widget: hidden
default: post
Media Widgets
image — Image upload/selector.
- name: hero
label: Hero image
widget: image
video — Video URL or embed.
- name: intro
widget: video
file — General file upload.
- name: document
widget: file
Structured Widgets
select — Dropdown with predefined options.
Options can be simple strings (value is auto-slugified) or objects with explicit label and value:
# Simple string options
- name: breed
widget: select
options:
- Mini Goldendoodle
- Standard Goldendoodle
# Explicit label/value options
- name: category
widget: select
options:
- value: tv-commercials
label: TV Commercials
- value: brand-marketing
label: Brand marketing
relation — Dropdown populated from another collection's documents. The document slug is stored as the value.
- name: case_study
widget: relation
collection: case-studies
required: false
list — Repeatable group of sub-fields. Renders as an ordered list of items the user can add, remove, and reorder.
- name: hero_slides
widget: list
fields:
- name: title
widget: string
- name: image
widget: image
- name: description
widget: trix
Lists can be nested:
- name: questions
widget: list
fields:
- name: text
- name: options
widget: list
fields:
- name: value
- name: label
object — Group of sub-fields rendered as a single unit. Unlike list, there is exactly one instance.
- name: details
widget: object
fields:
- name: location
widget: string
- name: size
widget: string
- name: service
widget: string
Objects can nest other objects and lists:
- name: contact
widget: object
fields:
- name: phone
widget: string
- name: hours
widget: object
fields:
- name: monday_friday
widget: string
- name: saturday
widget: string
- name: social
widget: object
fields:
- { name: facebook, widget: string, required: false }
- { name: instagram, widget: string }
Internationalization (i18n)
Collections with an i18n property support multilingual content.
collections:
- name: pages
basedir: _pages
i18n: [en, es]
files:
- file: frontpage.html
fields:
- name: title
widget: string
- name: coat
widget: string
i18n: true
How it works
- The first language in the list is the default. Its files live in the normal location.
- Other languages store files in a subdirectory named by language code:
- File collections with
basedir: _pages→ default in_pages/, Spanish ines/ - Folder collections with
folder: _puppies→ default in_puppies/, Spanish in_puppies/es/
- File collections with
- When editing a non-default language, only fields with
i18n: true(ori18n: translate) are shown. - The platform auto-generates Jekyll
defaultsentries to setlangon each page.
Field-level i18n
i18n: trueori18n: translate— Field appears when editing any language.i18n: duplicate— Field value is copied from the default language (shown but pre-filled).i18n: false(default) — Field only appears when editing the default language.
Forms
Define form submission handlers. Forms capture data submitted from site visitors.
forms:
- name: contact
label: Contact Form
webhook: https://hooks.zapier.com/hooks/catch/55555555/xxxxxxx/
default: true
- name: interest
label: General interest form
- name: member_onboarding
role: member
Form properties:
name(required) — Identifier matching the form'snameattribute in HTML.label— Display name.webhook— URL to POST submission data to.default— Iftrue, this is the site's default form.role— Links the form to a role. Submissions trigger user registration with that role.
Roles
Define user roles for gated content and registration workflows.
roles:
- name: member
email_confirmation: true
admin_approval: true
- name: coach
email_confirmation: true
admin_approval: true
Role properties:
name(required) — Role identifier (referenced by forms and protected collections).email_confirmation— Require email verification before granting access.admin_approval— Require manual admin approval before granting access.
YAML Formatting Tips
Fields can be written in expanded or compact flow syntax. Both are equivalent:
# Expanded
- name: title
widget: string
# Compact (flow)
- { name: title, widget: string }
Flow syntax works well for simple fields. Use expanded syntax when fields have hint, options, nested fields, or other multi-line properties.
Complete Example
site:
base:
title: Sutton Film Productions
url: "https://suttonfp.com"
baseurl: ""
plugins:
- jekyll-sitemap
- jekyll-seo-tag
prod:
stg:
url: "http://suttonfp-rev.rpstg.lan"
dev:
url: "http://suttonfp-rev.rpdev.lan:5050"
forms:
- name: contact
label: Contact Form
webhook: https://hooks.zapier.com/hooks/catch/55555555/xxxxxxx/
default: true
collections:
- name: data
label: Site data
files:
- label: Team
name: team
file: _data/team.yml
fields:
- name: items
widget: list
fields:
- { name: name, widget: string }
- { name: title, widget: string }
- { name: img, label: Image, widget: image }
- { name: desc, label: Description, widget: trix }
- { name: linkedin, widget: string }
- label: Services
name: services
file: _data/services.yml
fields:
- name: items
widget: list
fields:
- { name: title, widget: string }
- { name: description, widget: trix }
- name: case-studies
folder: _case-studies
label_singular: Case study
create: true
fields:
- { name: layout, widget: hidden, default: case-study }
- { name: title, widget: string }
- { name: image, widget: image }
- { name: content, widget: trix }
- name: videos
widget: list
fields:
- { name: video, widget: video }
- { name: poster, widget: image }
- name: playlists
folder: _playlists
create: true
protected: true
fields:
- name: title
- name: items
widget: list
fields:
- { name: title, widget: string }
- { name: video, widget: video }
- { name: image, widget: image }
- { name: desc, label: Description, widget: trix }