Hugolify is a Hugo framework that integrates several Headless, initially Netlify CMS then Decap CMS and Sveltia CMS. Recently I added compatibility with Pages CMS. Now I’m trying to add CloudCannon.
Hugolify is supposed to build the config file (via Hugolify Admin) for the CMS based on the requirements and settings. It has a library of collections, fields and blocks to simplify this CMS configuration.
I am currently working on the cloudcannon branch of:
The important question for me is: It is possible to use _inputs in array and object rather than structures?
You can configure the keys that are present inside of an object or array. But the syntax where you have an _inputs key inside of another inputs options is invalid. For example, this:
image:
name: Images
options:
_inputs:
alt:
comment: For an image that conveys information (leave blank if decorative image)
name: Text alternative
options:
required: false
type: text
required: false
subtype: object
Should instead become this:
image:
type: object
name: Images
options:
subtype: object
image.alt:
type: text
comment: For an image that conveys information (leave blank if decorative image)
name: Text alternative
options:
required: false
The key difference being the use of dot syntax to configure an alt input inside of the image input. Just plain alt would work as well, but that wouldn’t be scoped to just alt inputs inside of image inputs — instead it would target any input on your site with the key of alt.
Hope that makes sense and answers your question! Let us know if not, or if you have any other questions.
Looks almost there. The issue is that you’re trying to use the config under _inputs to create new keys, when the _inputs config is just used to configure keys. In other words, adding an entry for heading.text in your _inputs config will target a key of text that is nested under a heading key, and allow you to configure how that key will look and behave in CloudCannon. It won’t create the key under heading though.
To define which keys would be added to the heading object input when an editor adds something, you can use another structure like you’ve used for the blocks array. This would tell CloudCannon what the object should look like that gets added to heading. Then on that structure definition you can define the input behaviour for title, surtitle, and text.
I’ve modified your latest config so that there is a valid structure to add to the heading key. Also, the collections_config_override key is deprecated now, and the i18n key doesn’t do anything in CloudCannon.
# Config
collections_config_override: false # Deprecated key here
paths:
static: static
uploads: static/images/uploads
# Snippets
_snippets_imports:
hugo: true
# Collections
collections_config:
products:
_inputs:
blocks:
options:
structures: _structures.blocks
type: array
date:
instance_value: NOW
name: Date
options:
required: true
type: datetime
title:
comment: Displayed in tabs, search results, and in SMS/Messages/Social networks
preview
name: Page title
options:
required: true
type: text
comment: All products
create:
path: '[relative_base_path]/{year}/{slug}'
disable_add: false
disable_add_folder: true
i18n: true # This key doesn't exist in CloudCannon
name: Products
path: content/products
schemas:
default:
path: archetypes/products.md
# Structures
_structures:
blocks:
style: modal
values:
- _inputs:
background:
name: With a background?
options:
required: false
type: switch
heading:
name: Heading
options:
required: false
structures: _structures.block_heading
type: object
label: Title
preview:
icon: format_h2
text:
- key: title
- Title
value:
background:
heading:
block_heading:
values:
- value:
title:
surtitle:
text:
_inputs:
surtitle:
name: Surtitle
options:
required: false
type: text
text:
name: Text
options:
allow_resize: false
initial_height: 100
required: false
type: markdown
title:
name: Title
options:
required: false
type: text
Is it possible to specify a output key for un input?
I have different fields that have the same output key but not the same type. Sometimes I call one, sometimes the other. So I’m struggling to specify it in the root _inputs.
Example:
text_markdown:
key: text
name: Text
type: markdown
text_area:
key: text
name: Text
type: textarea
text:
key: text
name: Text
type: text
I think there is some confusion around how our inputs work in CloudCannon. We don’t have an output key for our input config. The name of the key under _inputs specifies which key name the input configuration is targeting.
This (below) is invalid config. Both key and name aren’t valid input config here in CloudCannon.
_inputs:
text_markdown:
key: text
name: Text
type: markdown
This (below) isvalid config for a key of text_markdown.
_inputs:
text_markdown:
label: Text
type: markdown
This would provide configuration for any keys of text_markdown that CloudCannon sees. So the frontmatter for a markdown file might look like:
---
title: Just an example
text_markdown: >-
Here is some *text* that is markdown in frontmatter. The key for this input is called **text_markdown**
---
Some markdown body content here to show this is a md file.
We’d see inputs for both title and text_markdown even without any input config defined. You then define input config for title and text_markdown if you want any of the defaults CloudCannon has provided to be different. You can see in the screenshot, title is still exposed to an editor without any input config required - it’s using the default of a text input. We’ve given the key of text_markdown a label of Text.
This is fundamentally different to some CMS’s which require input configuration for a key before an editor has the ability to edit the value of that key. CloudCannon is the other way around - where we expose all the editable fields, and then you can opt to hide/configure them if you need.
Hope that clears it up! Let me know if there’s still any confusion.
Ah, I see now! Here’s how you would add config for that.
_inputs:
heading:
type: object
options:
structures: _structures.heading
data:
type: object
options:
structures: _structures.data
_structures:
heading:
values:
- value:
title:
text:
_inputs:
text:
type: markdown
data:
values:
- value:
title:
text:
_inputs:
text:
type: text # or could do `type: textarea`
We tell CloudCannon that the heading and data inputs (frontmatter keys) are type: object, and which structures those object inputs should use.
A structure tells CloudCannon what to add to an object (or array) type input if it’s empty.
The structure value has the key of text, since this is what you want the actual key called when the object is added to the page in CloudCannon.
Each structure has different configuration for text. That config is scoped to each structure. One structure’s text input is a markdown input, and the other structure’s text input is a normal text input.
Looks like you’ve got some paths config that is more specific for that image input than the global paths that you define at the root of the CloudCannon configuration file.
I can see you have some structures config that will override the global paths config for images, since the one defined in a structure is more specific in our configuration cascade.
Alternatively, you could clear the more specific config defined at the structure level so that the structure falls back to use the global paths config.
You can set value_key to what you want to map the values for the select to. CloudCannon will look for that key in frontmatter, as is happening with title in your example. path and url are special keys where, if they are not set in the front matter, CloudCannon will instead generate suitable values for them.
We’ve discussed this internally, and have decided to add the keys filename, and filename_without_ext to the keys that CloudCannon will generate if they are not present in a collection item’s frontmatter, but are set as the value_key. This update went out with today’s release.
Setting one of these new keys (filename or filename_without_ext) as the value of value_key should do what you’re looking for.
Hey Seb That is a good point! On reflection, I think it’s actually probably best to store the full path in the frontmatter.
We could make a special value_key option that transforms _index.md into the name of the containing folder, but I think this would just be pushing the problem around. Really, we (the CloudCannon team) want to surface some raw values that you can control with your SSG templating to get exactly what you want, instead of trying to have a separate option to cover each foreseeable use case.
I’m assuming that you’re using the value of this select to grab a file from your site and render some details about it - is that right? I’m wondering if you save the full path to the file in your frontmatter and use Go templating to resolve this as needed. I’m not much of a Hugo expert so hopefully this isn’t too crude, but I think this could look something like: