Open erquhart opened 6 years ago
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.
@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.
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
@dafrie How can we add more keys under the alias?
For example:
project: &PROJECT
- { name: title, widget: string }
- { name: description, widget: string }
collections:
- name: public
...
fields: *PROJECT
- { name: type, widget: hidden, default: page }
Doesn't seem to work.
@erquhart For us this feature would improve the "page building" power of variable-type lists. For example, in defining a list of 'atoms' like,
Followed by composed 'molecules' like,
I'm currently looking into whether we can use aliases to accomplish this for now but like seeing that your team is considering a more official feature.
A different approach (that might touch on the "why not to do this" front) would be to leave the config spec alone and leverage the existing relation feature. I'll explain:
Atomic models can already live at the top level, then be linked by relation into object and variable-type list widgets to compose more complex models. This is actually more like how Contentful does it: when you set up a variable-type list model you can use checkboxes to choose which models are linkable, then when entering data you use a UI similar to Netlify CMS's relation feature where you pick which one you want from a select. The main difference is a "Create new item" option at the top of the dropdown with a circular UX flow that jumps you out of the current page into the component model page, lets you save that and then return to your preserved in-progress page edit.
That flow might be a pretty big UI lift for your team, but would be a way to avoid adding the complexity of field-set lookups in the config file. Devs can just make a variable-type list with relation entries, which surfaces the dropdown of existing entries and could be extended with a new property like create: true
. It's also a solid "page builder" UX model proven out for years by Contentful. True, you end up with many more top-level models, but your UI is already built to handle that, so really it's just a way to quickly create new sub-models and keep working in the surrounding context such as a page. I think it's good in that it reinforces content composition which adds flexibility for editors, vs. a more-complex config model aimed only at devs.
Again, I still like the field group idea but wanted to point out how your current UI and powerful variable-type lists and relation features mean you're just one "Create new item" UI feature away from supporting this in your current version! 🌞
- 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.