Static CMS
Star StaticJsCMS/static-cms on GitHub
v4.3.0DocsExamplesDemoCommunity

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

NameTypeDefaultDescription
fieldstringThe name of one of the fields in the collection's fields
valuestring
|list of strings
Optional. The desired value or values to match. Required if no pattern provided. Ignored if pattern is provided
patternregular expressionOptional. A regex pattern to match against the field's value
matchAllbooleanfalseOptional. Ignored if value is not a list of strings
  • true - The field's values must include or match all of the filter rule's values
  • false - The field's value must include or match only one of the filter rule's values
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

NameTypeDefaultDescription
patternregular expressionA 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's folder.
  • {{filename}} The file name without the extension part.
  • {{extension}} The file extension.
  • {{media_folder}} The global media_folder.
  • {{public_folder}} The global public_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