Collections

All sections and taxonomies.

Info

Collections are automatically added based on Hugolify modules added (Sections) or (Taxonomies)

Options by CMS

New in v2

An option has one name, whatever the CMS. Hugolify writes it the way each CMS reads it, and leaves it out where the CMS has no equivalent.

OptionDecapSveltiaStaticNetlifyPages CMSCloudCannonTina
enable✓✓✓✓✓✓✓
create✓✓✓✓✓✓✓
fields✓✓✓✓✓✓✓
filter✓✓✓✓–––
exclude––––✓––
path✓✓✓✓✓✓✓
media_folder✓✓✓✓–––
slug✓✓✓✓–––
sortable_fields✓✓✓✓✓––
summary✓✓✓✓–✓–
summary_fields–✓✓–✓––
thumbnail–✓–––✓–
view_filters✓✓✓✓–––
view_groups✓✓✓✓–––
reorder–✓–––––
bulk_edit–✓–––––
icon–✓–––✓–
nested✓✓✓✓✓––
card_preview–––––✓–

Enable or disable collections

/config/_default/params.yaml

admin:
  collections:
    indexes:
      enable: true
    pages:
      enable: true
    # e.g. set to false to disable posts even if you load hugolify-theme-posts
    posts:
      enable: false
    # …

Order and group collections

New in v2

Collections are listed in the order of collection_groups: the groups as they come, and the collections of each group as they are listed. '*' stands for every enabled collection that no group names, in alphabetical order.

/config/_default/params.yaml

admin:
  collection_groups:
    - heading: Content
      collections: [pages, indexes]
    - heading: News
      collections: [posts, posts_categories, posts_tags]
    - heading: Other
      collections: ['*']
    - heading: Settings
      collections: [menus, config]

Quote the '*': in YAML, a bare * starts an alias.

Left undefined, the order is pages and indexes, then every other collection in alphabetical order, then menus and config:

admin:
  collection_groups:
    - collections: [pages, indexes]
    - collections: ['*']
    - collections: [menus, config]

To list every collection in alphabetical order, as v1 did, keep a single group holding '*'.

  • Without '*', the collections that no group names come last, in a group of their own. A collection never drops out of the list: to hide one, disable it.
  • A disabled collection is skipped, an unknown name is skipped with a warning, and a collection listed twice keeps its first place.
CMSResult
Sveltia CMSOrder, and a divider between two groups
Decap CMS, Netlify CMS, Static CMSOrder
Pages CMS, TinaOrder
CloudCannonGroups with their heading, once collection_groups is set

The heading is read by CloudCannon only. It requires one on each group, so it keeps its own order until collection_groups is set. A Sveltia CMS divider is a plain line, without a label.

Enable or disable file creation

/config/_default/params.yaml

admin:
  collections:
    pages:
      create: false

Pages CMS reads it as operations.create, CloudCannon as disable_add, Tina as ui.allowedActions.create.

Override fields avalaible for a collection

/config/_default/params.yaml

admin:
  collections:
    pages:
      fields:
        - draft
        - title_page
        - description
        - featured_image
        - body

Add filter

/config/_default/params.yaml

admin:
  collections:
    pages:
      filter:
        - field: isPage
          value: true

Add path

/config/_default/params.yaml

admin:
  collections:
    pages:
      path: "{{slug}}"

Media folders of a collection

Decap, Sveltia, Static and Netlify CMS

The uploads of a collection go to the global folders. Give the collection folders of its own:

/config/_default/params.yaml

admin:
  collections:
    persons:
      media_folder: /assets/images/persons
      public_folder: /images/persons

Add slug

/config/_default/params.yaml

admin:
  collections:
    pages:
      slug: "{{id}}"

Add sortable fields

New in v2

The fields of the Sort menu, in order. It replaces the sortable string of v1.

/config/_default/params.yaml

admin:
  collections:
    posts:
      sortable_fields:
        - field: date
          default_sort: desc
        - title
        - commit_date
  • default_sort sorts the list by that field when it opens: asc (or true) or desc. One field takes it.
  • commit_date and commit_author sort by the last commit, in the CMS that read the Git history.
  • A label replaces the label of the field in the Sort menu. Decap CMS alone reads it.

Left undefined, each CMS offers its own defaults, such as the title and the date.

CMSResult
Decap CMSsortable_fields, with default_sort and label on the field
Sveltia CMSsortable_fields, as a { fields, default } object once a field sorts by default
Static CMSsortable_fields, as a { fields, default } object
Netlify CMSsortable_fields, field names alone
Pages CMSview.sort, and view.default for the field sorting by default, without commit_date and commit_author
CloudCannon, TinaNothing: CloudCannon keeps its own Sort menu

Add summary

/config/_default/params.yaml

admin:
  collections:
    pages:
      summary: "{{title}}"

CloudCannon shows it as the text of the card, the title standing in when it comes out empty. A field is written in its own way, {{title}} - {{date}} becoming {title} - {date}, and a transformation after a pipe is dropped, as the two CMS do not share their names.

Add summary fields

New in v2 Sveltia CMS, Static CMS and Pages CMS

The columns of the table view, in order. It replaces the view.fields of Pages CMS.

/config/_default/params.yaml

admin:
  collections:
    persons:
      summary_fields:
        - summary
        - lastname
        - field: contact.email
          label: Email
        - draft
  • summary stands for the entry summary, as in Static CMS.
  • A nested field takes dot notation.
  • A label replaces the header the column takes from its field. Sveltia CMS alone reads it.

Left undefined, Sveltia CMS shows the summary followed by the sortable fields, Static CMS the summary alone, Pages CMS every field.

CMSResult
Sveltia CMStable_columns, with summary written _summary
Static CMSsummary_fields, without labels
Pages CMSview.fields, with summary written title, without labels
Decap CMS, Netlify CMS, TinaNothing: no table view
CloudCannonNothing: see card preview

Name a field of the collection

Sveltia CMS rejects a config whose column names no field of the collection, and shows the error instead of the CMS. Static CMS leaves the column empty, and Pages CMS drops it.

Sveltia CMS also takes its special keys (slug, commit_date, commit_author) and templates such as "{{date | date('YYYY-MM-DD')}}" as columns.

Add thumbnail

New in v2 Sveltia CMS and CloudCannon

The image shown beside each entry of the list, and in the grid view of Sveltia CMS.

A collection with featured_image shows it without a setting: that field is an image object holding the file in src, which Sveltia CMS would not find on its own, as it only looks for an Image field at the root of the entry. Name another field, or none:

/config/_default/params.yaml

admin:
  collections:
    persons:
      thumbnail: image.src # the default with featured_image
    posts:
      thumbnail: false     # no image

A list tries its fields in turn and shows the first one filled, e.g. thumbnail: [image.src, logo.src].

Name an Image field of the collection

Sveltia CMS rejects a config whose thumbnail names no field of the collection, and shows the error instead of the CMS.

CMSResult
Sveltia CMSthumbnail
CloudCannonthe image of the card, preview.gallery.image. A card_preview setting it wins
Other CMSNothing: Decap, Netlify and Static CMS guess the image from the field names, Pages CMS shows an Image field as a column of summary_fields

Add view filters

/config/_default/params.yaml

admin:
  collections:
    pages:
      view_filters:
        - label: 'Posts published in 2020'
          field: date
          pattern: '2020'
        - label: 'Drafts'
          field: draft
          pattern: true

A pattern keeps its type: true matches a boolean field, '2020' a text. Static CMS gets the filters in its own { filters } object, each named after its label.

Add view groups

/config/_default/params.yaml

admin:
  collections:
    pages:
      view_groups:
        - label: 'Draft'
          field: draft
        - label: 'Year'
          field: date
          pattern: '\d{4}'

Static CMS gets the groups in its own { groups } object, each named after its label.

Add reorder

New in v2 Only available with Sveltia CMS

/config/_default/params.yaml

admin:
  collections:
    pages:
      reorder: true

Add bulk edit

New in v2 Only available with Sveltia CMS

Edit the simple fields of many entries at once, in a table that works like a spreadsheet, and save them in a single commit: turn draft on for a batch of posts, fix titles. Filter the list first to edit some entries only.

It is on for every collection, with every simple top-level field as a column: draft, title, date, weight, slug, a select… Only Boolean, Color, DateTime, Number, Relation, Select and String fields can be edited in bulk.

Saved on the branch

Like reordering, a bulk edit is committed to the branch directly. So it is off by default with publish_mode: editorial_workflow or preview, where it would bypass the review.

Turn it off, or pick the columns, for every collection or for one. Fields are named as in the front matter:

/config/_default/params.yaml

admin:
  bulk_edit: false               # every collection
  collections:
    posts:
      bulk_edit: true            # back on for the posts
    persons:
      bulk_edit: [title, draft]  # these columns, in this order

Collection icon

New in v2

An icon is declared per icon set, so the same collection works whichever set the CMS uses. See Setup.

/config/_default/params.yaml

admin:
  collections:
    pages:
      icon:
        bootstrap_icons: file-earmark
        iconoir: page
        lucide: file
        material_icons: description
        material_symbols: description

Nested collections

New in v2

A collection can show its entries as a folder tree and let editors organise them in subfolders. Entries are stored as Hugo branch bundles — an _index file in a folder of its own — so a page can carry children and page resources.

Set the depth globally, or per collection when only one of them is a tree:

/config/_default/params.yaml

admin:
  nested:
    depth: 2 # every collection
  collections:
    docs:
      nested:
        depth: 4 # this one alone, overriding the global

The depth counts path segments below the collection folder, and is what limits how deep an editor may go.

DepthResult
1Nothing emitted — a flat collection
2Folder tree, one level of children
3 and upFolder tree, plus a parent field so an editor picks where a page goes and moves it later

Sveltia CMS

Nested collections used to be Decap-only. Sveltia CMS supports them now, and fixes several long-standing problems of the Decap implementation along the way — entry paths, preview paths, media folders, folder labels and i18n.

The parent field differs between the two: Decap gets a custom Hugolify widget, Sveltia its own folder picker. Hugolify writes the Decap widget and label either way, and Sveltia accepts both for compatibility and ignores them, so the same config serves the two.

Pages CMS

Pages CMS shows a nested collection in its tree layout, the _index.md of each folder standing for the folder. It has no parent field: a page stays in the folder it was created in.

The menus collection

New in v2

The menus collection holds the navigation files, written to /data/menu/. Pick which ones it shows with files:

/config/_default/params.yaml

admin:
  collections:
    menus:
      files: [nav-header-primary, nav-footer-primary, nav-legal, nav-social]

Left undefined, the collection ships nav-header-primary, nav-header-secondary, nav-footer-primary, nav-footer-secondary, nav-legal and nav-social.

Header and footer menus each gain three levels, replacing the single menu of v1. Add nav-header-tertiary and nav-footer-tertiary to files to reach the third one.

  • Header — primary, secondary, tertiary
  • Footer — primary, secondary, tertiary

Menus listed in config

The menus used to be files of the config collection. A project that lists nav- files in config.files moves them to menus.files: left there, a menu shows in both collections. A project that sets collection_groups names menus next to config, or the collection joins ’’.

The config collection

The config collection holds the other site files an editor may change — banner, footer, credit, organization, structured data, SEO, llms.txt. Pick which ones it shows with files:

/config/_default/params.yaml

admin:
  collections:
    config:
      files: [banner, footer, credit, blocks, seo]

Left undefined, the collection ships banner, footer, credit, organization, schema, seo, llms and llms-full.

The footer accepts blocks, not just an information text.

Default appearance per block type

New in v2

Add blocks to files and the collection gains a file written to /data/blocks.yml, holding the default ui of each block type. It is the CMS-editable twin of params.blocks.<type>.ui: same shape, read on top of it key by key, so a field left empty falls back to the config instead of erasing it.

The form is generated from admin.blocks.enable, one collapsible section per block type, with the selected-* variants expanded per enabled collection exactly as the block picker expands them. A section arrives open when it already carries a value.

Each section offers the layouts of its block type, as the form of the block offers them, and the carousel settings when the carousel is one of them: a default carousel is set here like a default scroll snap. Every field shows whatever the layout. In the form of a block, choosing a layout reveals the fields that override these defaults, see Fields that depend on another.

Unlike the rest of the config collection, this file is not translated: how a block looks is not language content. Decap CMS saves it keyed by the default language all the same, which the theme reads as well — see With Decap CMS.

See defaults per block

Organization and structured data

New in v2

organization edits /data/organization.yml, the identity of the organization behind the site: legal name, other names, founding date, headcount, languages, areas served, head office and other places, awards, identifiers. The rest of the site may show it too, not only the structured data.

schema edits /data/schema.yml, what only the structured data reads: the schema.org type of the organization, a logo search engines can read, its pages elsewhere, the page listing its offices, and whether email addresses are published.

Like blocks, neither file is translated. The slogan of the organization, translated like the description, goes in seo.

See structured data

llms.txt

New in v2

llms and llms-full edit /data/llms.yml and /data/llms-full.yml, the bodies of the /llms.txt and /llms-full.txt files the theme writes at the root of the site. A body left empty publishes no file.

Like blocks, these files are not translated: agents look for one file at the root, so every language goes in it.

See llms.txt

Create a collection

Use params to create a collection

/config/_default/params.yaml

admin:
  collections:
    new_collection:
      enable: true
      fields:
        - draft
        - title_page
        - description
        - featured_image
        - body

Or add a yml collection file

layouts/
└── partials/
    └── admin/
        └── collections/
            └── types/

A collection file reads its options through one partial each, which writes the option for the CMS in use. The file sets its creation, preview, path and slug itself:

{{ partial "admin/collections/config/create.yml" . }}
{{ partial "admin/collections/config/preview.yml" . }}
{{ partial "admin/collections/config/path.yml" . }}
{{ partial "admin/collections/config/slug.yml" . }}

Then admin/collections/types/_default.yml adds all the others, or the file picks the ones the collection needs:

{{ partial "admin/collections/config/icon.yml" . }}
{{ partial "admin/collections/config/index_file.yml" . }}
{{ partial "admin/collections/config/filter.yml" . }}
{{ partial "admin/collections/config/exclude.yml" . }}
{{ partial "admin/collections/config/reorder.yml" . }}
{{ partial "admin/collections/config/sortable_fields.yml" . }}
{{ partial "admin/collections/config/summary.yml" . }}
{{ partial "admin/collections/config/summary_fields.yml" . }}
{{ partial "admin/collections/config/thumbnail.yml" . }}
{{ partial "admin/collections/config/view.yml" . }}
{{ partial "admin/collections/config/view_filters.yml" . }}
{{ partial "admin/collections/config/view_groups.yml" . }}
{{ partial "admin/collections/config/fields.yml" (dict "collection" .) }}
{{ partial "admin/collections/config/nested.yml" . }}

view.yml writes the view of Pages CMS, built from summary_fields, sortable_fields and nested. A partial writes nothing for a CMS without the option.

See examples in repository