decaporg / decap-cms

A Git-based CMS for Static Site Generators
https://decapcms.org
MIT License
17.98k stars 3.05k forks source link

Make nested collections work with a flat content structure #4972

Open martinjagodic opened 3 years ago

martinjagodic commented 3 years ago

As discussed in #4969, I would like to see nested collections work with the flat content structure.

Currently, nested collections work with only one type of content structure, where every markdown file has to be in its own folder:

content
└── pages
    ├── authors
    │   ├── author-1
    │   │   └── index.md
    │   └── index.md
    ├── index.md

I would like to see it work also with a flatter structure, like this one:

content
└── pages
    ├── authors
    │   ├── author-1.md
    │   └── index.md
    ├── index.md
erezrokah commented 3 years ago

Hi @martinjagodic, thank you for opening the issue. This would be great to have.

Would the logic be to treat any non index.md file as a child of the index.md file for UI purposes? We do want to show author-1.md only when someone navigates to authors correct? See https://netlify-cms-widget-parent.netlify.app/#/collections/pages: image image

martinjagodic commented 3 years ago

@erezrokah yes, this is how I imagine it.

dylanirlbeck commented 3 years ago

I'd also love to see this feature!

dylanirlbeck commented 3 years ago

@erezrokah Can you outline the expected work for this feature? Trying to gauge what the commitment would be in case I have time to contribute.

erezrokah commented 3 years ago

Hi @dylanirlbeck, thanks for initiating!

I would classify this as medium size effort for someone who is not familiar with the CMS codebase.

The relevant code is here: https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-core/src/components/Collection/NestedCollection.js

To resolve the issue we would need to consider file siblings of index.md as children (this only happens for directories next to index.md).

Dirklectisch commented 3 years ago

I had a quick look at what the current behaviour is. Looks like non index files are currently shown one level higher than they should be in the entries listing.

Screenshot 2021-08-19 at 13 18 18 Screenshot 2021-08-19 at 13 17 28

One open question is probably if non index files should also show up in the menu structure. What should happen if you click one of those files, would you be able to create new files in that position of the structure. Should the underlying system convert the single file to the folder structure if you do?

Matt-Freeland commented 3 years ago

I've also run into this issue trying. Stuff gets pretty strange when there is on index.md file.

My project is organized into folders like this

content
└── Category
    ├── Subcategory
    │   ├── sub-thing.md
    │   └── sub-thing2.md
    ├── Subcategory-2
    │   ├── another-sub-thing.md
    │   └── another-sub-thing-too.md
    ├── thing.md

Here is my config.yaml

collections:
  - name: "demo"
    label: "Docs"
    label_singular: 'Doc'
    folder: "demo"
    create: true
    slug: "{{slug}}"
    nested: 
      depth: 100 
      summary: "{{slug}}"
    summary: "{{filename}}"
    extension: mdx
    format: frontmatter
    fields: 
      - {label: "Sidebar Label", name: "sidebar_label", widget: "string", required: false}
      - {label: "Title", name: "title", widget: "string"}
      - {label: "ID", name: "id", widget: "string"}
      - {label: "Sidebar Position", name: "sidebar_position", widget: "number", value_type: "int", min: 0, required: false}
      - {label: "tags", name: "tags", widget: "list", default: ["demo"], required: false}
      - {label: "Body", name: "body", widget: "markdown", required: false}
    meta: { path: {label: 'Path', widget: 'string', index_file: slug }}

The output from the CMS is this: image

Note that the second subfolder is entirely missing - but all the files are there. Is there a known workaround for this?

tangleMesh commented 3 years ago

I would also love to see such a feature added. We do also have a more complex structure like the one mentioned by @Matt-Freeland and it is not possible for us to create different collections for the subfolders.

content
└── Category
    ├── Subcategory
    │   ├── sub-thing.md
    │   └── sub-thing2.md
    ├── Subcategory-2
    │   ├── another-sub-thing.md
    │   └── another-sub-thing-too.md
    ├── thing.md

Could it be possible to simply extend the behavior of index_file by making fields values available like

meta: { path: { label: 'Path', widget: 'string', index_file: '{fields.filename}' }}

With this solution it could be possible to enable custom file names and flat hierarchies in subfolders without much effort? @erezrokah

erezrokah commented 3 years ago

Could it be possible to simply extend the behavior of index_file by making fields values available like

meta: { path: { label: 'Path', widget: 'string', index_file: '{fields.filename}' }}

With this solution it could be possible to enable custom file names and flat hierarchies in subfolders without much effort? @erezrokah

Thanks @tangleMesh, with your suggestion - what would be the index file sub-thing.md or sub-thing2.md? That is, what would show up as the parent in the tree, and which entries will be the children?

I think the logic to implement is still this one:

Would the logic be to treat any non index.md file as a child of the index.md file for UI purposes?

That is, the index file is the parent, and any sibling is a child.

If anyone wants to contribute, the code is here: https://github.com/netlify/netlify-cms/blob/bb7174d3b7cec3f0d45d6158043ae1b4d3182009/packages/netlify-cms-core/src/components/Collection/NestedCollection.js

adunkman commented 2 years ago

👋 Hiya!

I’d love to take a pass at implementing this — @eric-gade and I are finding a need for it on a current project. We poked around a bit, and have also come across the index.md issue being discussed.

I think what makes the most sense (to me, at least) is, for nested collections, always show folders in the left navigation and only immediate children of that folder as pages in the main list view. Here’s a few examples — I’ll note that this goes against the idea of "filtering" as implied by the URL structure of "filter" but seems to be the simplest:

Filesystem Shown in left navigation Shown in main list view
  • nested-collection
    • index.md
  • nested-collection (selected item)
  • index.md
  • nested-collection
    • index.md
    • about.md
    • sub-collection
      • index.md
  • nested-collection (selected item)
    • sub-collection
  • index.md
  • about.md
  • nested-collection
    • index.md
    • about.md
    • sub-collection
      • index.md
  • nested-collection
    • sub-collection (selected item)
  • index.md

(and so on — the pattern repeats recursively).

The effect of this behavior change:

I think I have this mostly implemented, but will button it up tomorrow and send a pull request over if I don’t hear any significant objections. 🙂