Collection Types
All editable content types are defined in the collections
field of your config
file, and display in the left sidebar of the Content page of the editor UI.
Collections come in two main types: folder
and files
.
Folder collections
Folder collections represent one or more files with the same format, fields, and configuration options, all stored within the same folder in the repository. You might use a folder collection for blog posts, product pages, author data files, etc.
Unlike file collections, folder collections have the option to allow editors to create new items in the collection. This is set by the boolean create
field.
Note: Folder collections must have at least one field with the name title
for creating new entry slugs. That field should use the default string
widget. The label
for the field can be any string value. If you wish to use a different field as your identifier, set identifier_field
to the field name. See the Collections reference doc for details on how collections and fields are configured. If you forget to add this field, you will get an error that your collection "must have a field that is a valid entry identifier".
Examples
Basic
collections:
- name: blog
label: Blog
folder: _posts/blog
create: true
fields:
- name: title
label: Title
widget: string
- name: date
label: Publish Date
widget: datetime
- name: thumbnail
label: Featured Image
widget: image
- name: body
label: Body
widget: 'markdown'
With Identifier Field
- name: 'blog'
label: 'Blog'
folder: '_posts/blog'
create: true
identifier_field: name
fields:
- name: name
label: Name
widget: string
- name: date
label: Publish Date
widget: datetime
- name: thumbnail
label: Featured Image
widget: image
- name: body
label: Body
widget: markdown
Filtered Folder Collections
The entries for any folder collection can be filtered based on the values of the fields or on file names. By filtering a folder into different collections, you can manage files with different fields, options, extensions, etc. in the same folder.
The filter
option can take a single filter rule or a list of filter rules. There are two types of filter rules available: field and file.
Field Filter Rule
Name | Type | Default | Description |
---|---|---|---|
field | string | The name of one of the fields in the collection's fields | |
value | string |list of strings | Optional. The desired value or values to match. Required if no pattern provided. Ignored if pattern is provided | |
pattern | regular expression | Optional. A regex pattern to match against the field's value | |
matchAll | boolean | false | Optional. Ignored if value is not a list of strings
|
Filtered by Language
The example below creates two collections in the same folder, filtered by the language
field. The first collection includes posts with language: en
, and the second, with language: es
.
collections:
- name: 'english_posts'
label: 'Blog in English'
folder: '_posts'
create: true
filter:
field: language
value: en
fields:
- name: language
label: Language
widget: select
options: ['en', 'es']
default: 'en'
- name: title
label: Title
widget: string
- name: body
label: Content
widget: markdown
- name: spanish_posts
label: Blog en Español
folder: _posts
create: true
filter:
field: language
value: es
fields:
- name: language
label: Lenguaje
widget: select
options: ['en', 'es']
default: 'es'
- name: title
label: Titulo
widget: string
- name: body
label: Contenido
widget: markdown
Filtered by Nested Field
The example below creates a collection based on a nested field's value.
collections:
- name: 'nested-field-filtered-collection'
label: 'Nested Field Filtered Collection'
folder: '_nested_field'
create: true
filter:
field: nested.object.field
value: yes
fields:
- name: nested
label: Nested
widget: object
fields:
- name: object
label: Object
widget: object
fields:
- name: field
label: Field
widget: select
options:
- yes
- no
Filtered by Tags
The example below creates two collections in the same folder, filtered by the tags
field. The first collection includes posts with the news
or article
tags, and the second, with the blog
tag.
collections:
- name: 'news'
label: 'News'
folder: '_posts'
create: true
filter:
field: tags
value:
- news
- article
fields:
- name: tags
label: Tags
widget: list
default:
- news
- name: title
label: Title
widget: string
- name: body
label: Content
widget: markdown
- name: blogs
label: 'Blogs'
folder: _posts
create: true
filter:
field: tags
value: blog
fields:
- name: tags
label: Tags
widget: list
default:
- blog
- name: title
label: Title
widget: string
- name: body
label: Content
widget: markdown
File Name Filter Rule
Name | Type | Default | Description |
---|---|---|---|
pattern | regular expression | A regex pattern to match against the entry's file name |
Filtered by Tags
The example below creates a collection containing only files named index.md
exactly.
collections:
- name: 'posts'
label: 'Posts'
folder: '_posts'
create: true
filter:
pattern: '^index.md$'
fields:
- name: title
label: Title
widget: string
- name: body
label: Content
widget: markdown
Folder Collections Path
By default Static CMS stores folder collection content under the folder specified in the collection setting.
For example configuring folder: posts
for a collection will save the content under posts/post-title.md
.
You can now specify an additional path
template (similar to the slug
template) to control the content destination.
This allows saving content in subfolders, e.g. configuring path: '{{year}}/{{slug}}'
will save the content under posts/2019/post-title.md
.
Media and Public Folder
By default Static CMS stores media files for all collections under a global media_folder
directory as specified in the configuration.
When using the global media_folder
directory any entry field that points to a media file will use the absolute path to the published file as designated by the public_folder
configuration.
For example configuring:
media_folder: static/media
public_folder: /media
And saving an entry with an image named image.png
will result in the image being saved under static/media/image.png
and relevant entry fields populated with the value of /media/image.png
.
Some static site generators (e.g. Gatsby) work best when using relative image paths.
This can now be achieved using a per collection media_folder
configuration which specifies a relative media folder for the collection.
For example, the following configuration will result in media files being saved in the same directory as the entry, and the image field being populated with the relative path to the image.
media_folder: static/media
public_folder: /media
collections:
- name: posts
label: Posts
label_singular: 'Post'
folder: content/posts
path: '{{slug}}/index'
media_folder: ''
public_folder: ''
fields:
- label: Title
name: title
widget: string
- label: 'Cover Image'
name: 'image'
widget: 'image'
More specifically, saving an entry with a title of example post
with an image named image.png
will result in a directory structure of:
content
posts
example-post
index.md
image.png
And for the image field being populated with a value of image.png
.
Note: When specifying a path
on a folder collection, media_folder
defaults to an empty string.
Available Template Tags
Supports all of the slug
templates and:
{{dirname}}
The path to the file's parent directory, relative to the collection'sfolder
.{{filename}}
The file name without the extension part.{{extension}}
The file extension.{{media_folder}}
The globalmedia_folder
.{{public_folder}}
The globalpublic_folder
.
Nested Collections
Nested collections allow a folder collection to show a nested structure of entries and edit the locations of the entries. This feature is useful when you have a complex folder structure and may not want to create separate collections for every directory.
Example configuration:
collections:
- name: pages
label: Pages
label_singular: 'Page'
folder: content/pages
create: true
# adding a nested object will show the collection folder structure
nested:
depth: 100 # max depth to show in the collection tree
summary: '{{title}}' # optional summary for a tree node, defaults to the inferred title field
# adding a path object allows editing the path of entries
# moving an existing entry will move the entire sub tree of the entry to the new location
path: { widget: string, index_file: 'index' }
fields:
- label: Title
name: title
widget: string
- label: Body
name: body
widget: markdown
Nested collections expect the following directory structure:
content
└── pages
├── authors
│ ├── author-1
│ │ └── index.md
│ └── index.md
├── index.md
└── posts
├── hello-world
│ └── index.md
└── index.md
File Collections
A files
collection contains one or more uniquely configured files. Unlike items in folder
collections, which repeat the same configuration over all files in the folder, each item in a files
collection has an explicitly set path, filename, and configuration. This can be useful for unique files with a custom set of fields, like a settings file or a custom landing page with a unique content structure.
When configuring a files
collection, configure each file in the collection separately, and list them under the files
field of the collection. Each file has its own list of fields
and a unique filepath specified in the file
field (relative to the base of the repo).
Note: Files listed in a file collection must already exist in the hosted repository branch set in your Static CMS backend configuration. Files must also have a valid value for the file type. For example, an empty file works as valid YAML, but a JSON file must have a non-empty value to be valid, such as an empty object.
collections:
- name: pages
label: Pages
files:
- name: about
label: About Page
file: site/content/about.yml
media_library:
folder_support: true
fields:
- name: title
label: Title
widget: string
- name: intro
label: Intro
widget: markdown
- name: team
label: Team
widget: list
fields:
- name: name
label: Name
widget: string
- name: position
label: Position
widget: string
- name: photo
label: Photo
widget: image
- name: locations
label: Locations Page
file: site/content/locations.yml
fields:
- name: title
label: Title
widget: string
- name: intro
label: Intro
widget: markdown
- name: locations
label: Locations
widget: list
fields:
- name: name
label: Name
widget: string
- name: address
label: Address
widget: string