Nested Collections - Dynamic Path/Slug

I’m trying to get up and running with Netlify CMS using Jekyll and nested collections.

I’ve thus far re-organized our existing content to be contained to folders according to their slug – e.g. _support/component/how-to-article/index.md .The only roadblock at this point in time is how to have the path set dynamically, based on the slug of the article title , as it’s typed into the editor – similar to this path preview here: https://github.com/netlify/netlify-cms/pull/2897#issuecomment-557940611 – for newly-created articles.

Otherwise, the path field has to be manually exposed, and the user has to type in the folder name manually – which can lead to discrepancies, and is undesirable for the intended use case, which is simplifying the workflow of creating KB articles – not adding extra complexity.

Additionally, it does not appear that {{slug}} is able to be specified for the index_file within the meta parameter.

I’d appreciate any guidance on this as me and my team have been struggling to figure this one out for a while now!

– admin/config.yml –

backend:
  name: github
  repo: ****/****
  branch: netlify-cms
  base_url: https://****
publish_mode: editorial_workflow
site_url: http://localhost:4000
media_folder: 'assets'
collections:
  - name: 'support'
    label: 'Support'
    folder: '_support'
    nested: { depth: 100, summary: '{{meta.path}}'}
    create: true
    fields:
      - label: Title
        name: title
        widget: string
      - label: Body
        name: body
        widget: markdown
    meta: { path: { widget: string, label: 'Path', index_file: 'index', pattern: ['.*',]

Hi @mroark, sorry for only getting to this now?

Can you share the structure of the content you need to support?

Is it all entries at the same level:

_support/component/<title-1>/index.md
_support/component/<title-2>/index.md
_support/component/<title-3>/index.md
_support/component/<title-4>/index.md

or entries at different levels:

_support/component/<title-1>/index.md
_support/component/<title-1>/<title-2>/index.md
_support/component/<title-3>/index.md
_support/component/<title-3>/<title-4>/index.md

For the former you don’t need nested collections and can use:

collections:
  - name: 'support'
    label: 'Support'
    folder: '_support/component'
    path: '{{slug}}/index'
    create: true
    fields:
      - label: Title
        name: title
        widget: string
      - label: Body
        name: body
        widget: markdown

For the latter you should use a nested collection, but you’ll need to create the logic to control the path value yourself if you want to infer it based on the title.
See https://github.com/netlify-labs/netlify-cms-widget-parent/blob/6295f47edd2ac5ba005489344246b8862f378d77/src/ParentWidget.js#L125 for an example

Thanks for the response @erez! Previously, our content was organized to where one folder may contain either one or more .md files, and/or nested folders which then contained the same structure. Take our troubleshooting folder under _support, for example:

├── troubleshooting
│   ├── kvm
│   │   ├── dhcp_discovery.md
│   │   ├── enable_ars_kvm.md
│   │   ├── ipissue_selinux.md
│   │   ├── issues_image_access.md
│   │   ├── issues_instance_create.md
│   │   ├── issues_networking.md
│   │   ├── neutron_faq.md
│   │   └── resizefs_selinux.md
│   ├── troubleshooting_guide.md

In order to reach our current equilibrium – I created a script to create a directory for each .md file, and then place that file within the created folder. The resulting file/directory structure being as follows:

├── troubleshooting
│   ├── kvm
│   │   ├── dhcp_discovery
│   │   │   └── dhcp_discovery.md
│   │   ├── enable_ars_kvm
│   │   │   └── enable_ars_kvm.md
│   │   ├── ipissue_selinux
│   │   │   └── ipissue_selinux.md
│   │   ├── issues_image_access
│   │   │   └── issues_image_access.md
│   │   ├── issues_instance_create
│   │   │   └── issues_instance_create.md
│   │   ├── issues_networking
│   │   │   └── issues_networking.md
│   │   ├── neutron_faq
│   │   │   └── neutron_faq.md
│   │   ├── resizefs_selinux
│   │   │   └── resizefs_selinux.md
├── troubleshooting_guide
│   └── troubleshooting_guide.md

(The filenames could as easily be changed to index.md, but, it didn’t seem to make a difference in our testing.)

Based on the structure of our content, though – it sounds like the latter would be our only option, in lieu of re-organizing such that we don’t have a mix of entries at different levels, as per the latter example.

Is this assumption accurate? And, is there any other way we could be approaching this you think?

Thanks for clarifying @mroark, you’re right you’ll need to use the second option (nested collections).

As mentioned you’ll need to handle any changes to the path on your own so using a custom widget is the best way to go about it.

You can probably use a simplified version of the parent widget I linked to (that one is used to place an entry at any nesting level).

1 Like