Netlify-cms: Allow reusable field group definitions in config file

Created on 7 May 2018  路  13Comments  路  Source: netlify/netlify-cms

- Do you want to request a feature or report a bug?

feature

- What is the current behavior?

Reuse of configuration data, such as a group of fields being defined once and used in multiple collections, is dependent on YAML features. These features are difficult to understand and use, and aren't available in simpler formats like JSON.

- What is the expected behavior?

Netlify CMS should provide means for defining reusable configuration subsets, like field groups, that are easy to understand and use, and format independent.

This is based on the conversation in https://github.com/netlify/netlify-cms/issues/1186#issuecomment-382003132.

configuration discussion feature pinned

Most helpful comment

Hi @erquhart !
I'm currently trying to use Netlify CMS to edit my personal web site and i really like what you're trying to do as an open source project 馃憦 馃槂 , but i'm a bit stucked right now with some important features missing..

However, i was going to post that _exact suggestion_ to start with, when i noticed your post.

Defining groups of fields is exactly what i needed because duplicating the same information in different sections is boring and error prone.

Here is what i was longing for (a new section in config.yaml) :

fieldsets:
  - name: "link"
    label: "Link"
    fields:
      - {label: "URL", name: "url", widget: "string"}
      - {label: "Text", name: "text", widget: "string"}
  - name: "button"
    label: "Button"
    fields:
      - {include: "link"}
      - {label: "Type", name: "type", widget: "select", options: ["primary", "info", "success"]}
  - name: "section_background"
    label: "Section Background"
    fields: # The fields for each document, usually in front matter
      - {label: "Background style", name: "bg_class", widget: "select", required: true, default: "white", options: [{label: "Background image (parallax)", value: "parallax-bg"}, {label: "Background image (fixed)", value: "fixed-bg"}, {label: "Grey background", value: "grey"}, {label: "White background", value: "white"}, {label: "Gradient 1", value: "gradient1"}, {label: "Gradient 2", value: "gradient2"}]}
      - {label: "Background Image", name: "bg_image", widget: "image"}
      - {label: "Photographer", name: "photographer", widget: "string"}
      - {label: "Overlay color", name: "overlay", widget: "color"}
  - name: "hero_section"
    label: "Hero section"
    fields:
      - {label: "Title", name: "title", widget: "string"}
      - {label: "Headline", name: "headline", widget: "text"}
      - {include: "section_background"}
  - name: "call_to_action_section"
    label: "Call to action section"
    fields:
      - {include: ["hero_section", "button"]}

Notice how these fieldsets allow for easy composition between them and allow to follow the rules of atomic design.
It's interesting to note also that defining such a fieldset automatically defines a default widget for that group of fields, and that it could allow to declutter the interface by simply replacing the group of fields with a button : "Add link" or "Add Call to Action" when they are empty, and by the rendered widget when these fields have values.

All 13 comments

We should first determine if this is even a good idea at all. Can anyone think of reasons _not_ to do this?

Hi @erquhart !
I'm currently trying to use Netlify CMS to edit my personal web site and i really like what you're trying to do as an open source project 馃憦 馃槂 , but i'm a bit stucked right now with some important features missing..

However, i was going to post that _exact suggestion_ to start with, when i noticed your post.

Defining groups of fields is exactly what i needed because duplicating the same information in different sections is boring and error prone.

Here is what i was longing for (a new section in config.yaml) :

fieldsets:
  - name: "link"
    label: "Link"
    fields:
      - {label: "URL", name: "url", widget: "string"}
      - {label: "Text", name: "text", widget: "string"}
  - name: "button"
    label: "Button"
    fields:
      - {include: "link"}
      - {label: "Type", name: "type", widget: "select", options: ["primary", "info", "success"]}
  - name: "section_background"
    label: "Section Background"
    fields: # The fields for each document, usually in front matter
      - {label: "Background style", name: "bg_class", widget: "select", required: true, default: "white", options: [{label: "Background image (parallax)", value: "parallax-bg"}, {label: "Background image (fixed)", value: "fixed-bg"}, {label: "Grey background", value: "grey"}, {label: "White background", value: "white"}, {label: "Gradient 1", value: "gradient1"}, {label: "Gradient 2", value: "gradient2"}]}
      - {label: "Background Image", name: "bg_image", widget: "image"}
      - {label: "Photographer", name: "photographer", widget: "string"}
      - {label: "Overlay color", name: "overlay", widget: "color"}
  - name: "hero_section"
    label: "Hero section"
    fields:
      - {label: "Title", name: "title", widget: "string"}
      - {label: "Headline", name: "headline", widget: "text"}
      - {include: "section_background"}
  - name: "call_to_action_section"
    label: "Call to action section"
    fields:
      - {include: ["hero_section", "button"]}

Notice how these fieldsets allow for easy composition between them and allow to follow the rules of atomic design.
It's interesting to note also that defining such a fieldset automatically defines a default widget for that group of fields, and that it could allow to declutter the interface by simply replacing the group of fields with a button : "Add link" or "Add Call to Action" when they are empty, and by the rendered widget when these fields have values.

Yep, this looks like a great approach. I was just noticing today that Contentful does just that - everything in the content model is defined as "Content Types", which are named groups of fields.

@tech4him1 @Benaiah @talves thoughts?

Would love to see support for this! Our use-case would be once-defined string translations that we can then set under every locale collection.

Any way I could contribute?

@andreasvirkus sure, a proof-of-concept PR would get the ball rolling.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

This seems like a must have to me. For example, I should be able to define two objects - social (title, description, image) and seo (title, description) to use on all pages, and only have to define them once, instead of defining them for each collection type. Having to define them over and over again seems redundant.

@chriswthomson this ticket is a nice-to-have for the most part. You can already reuse blocks of yaml (source), and you can write your config in js (source).

Sent with GitHawk

@erquhart - OK thanks!

To get aliases working I ended up doing it like this:

aliases:
  - &TITLE {label: 'Title', name: 'title', widget: 'string' }

publish_mode: editorial_workflow
collections:
  - name: 'products'
    label: 'Products'
    folder: 'content/english/products'
    create: true
    fields:
      - << : *TITLE

And just in case you want to alias a list of keys:

project: &PROJECT
  - { name: title, widget: string }
  - { name: description, widget: string }

collections:
  - name: public
     ... 
     fields: *PROJECT
   - name: private
     ....
     fields: *PROJECT 

Another approach is to use manual initialization. Then you can do something like this.

const titleField = { name: 'title', widget: 'string' }

const projectFields = [
  { ...titleField },
  { name: 'description', widget: 'string' }
]

init({
  config: {
    load_config_file: false,
    collections: [
      {
        name: 'public',
        ...
        fields: [...projectFields]
      },
      {
        name: 'private',
        ...
        fields: [...projectFields]
      }
  }
})

Collection summaries do not currently work when using beta manual initialization feature.

Was this page helpful?
0 / 5 - 0 ratings