-
-
Notifications
You must be signed in to change notification settings - Fork 73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement: Extending another config #407
Comments
In connection to this, maybe it would also be a good feature to add a packages.json parameter that can contain the configuration or a path to the configuration (ie "extends @davidsneighbour/frontmatter-config") |
I like the idea but got a couple of concerns. Yet another place to configure Front MatterYou can override the config using the Although the base gets loaded first, then the local Online vs offlineI see you entered an URL; this assumes you are working online which is not always the case. It might not be an issue for the initial configuration, but once you have done the configuration. It might be the author is doing some offline changes and does not have access to the base file. Ideas I can think of:
VersioningIs the base file something you'll version? What if you introduce something new or remove something? All of a sudden, the experience for the user will be different. By having a local file, they keep working with the same version. Of course, it might be harder to update. Merges/overridesIf you configure settings in the base and apply new settings in the local version. Are they merging with the base settings or overriding settings? Like with VS Code settings, if you update a setting in the current project, it overrides what is defined globally. For this base concept, on some settings, it would be useful, I think to merge instead of override. Although it could cause some conflicts. package.json@davidsneighbour, not all projects will have a |
@estruyf I completely blacked that out. Front Matter is not a node package, so discard my idea. :) |
@davidsneighbour, no worries, always good to share your ideas 💚 |
A few thoughts: On yet another place to configureI think this is different enough to be worth doing as (all?) SSGs support theming, which usually includes some specific opinions about metadata, snippets, data structures, etc. Without a way to extend, everyone has to manually copy the right settings into the right keys in their configuration file and try to keep them up to date. This is okay for a single theme/module, but if you're using several together, that becomes more and more complex to manage. I would expect that this is something theme authors (or enthusiasts) provide, rather than a best practice for configuring Front Matter for a single project. Specifically for
On offline vs onlineI would expect first initialization to give me the same default configuration anyone not using Maybe a way to handle this would be to cache the remote configuration blob (maybe in On VersioningThinking on this, here's how I might handle it as an extendable config author:
The other (similar, but not requiring me to publish them anywhere but GitHub) option is to use tags to reference versioned files. I'm less likely to do that personally but that wouldn't require any specific architecture. I think letting users know about new versions etc is neat but out of scope for this, especially in the first iterations. On Merging and OverridingI think for clarity it's probably useful to distinguish what we mean by each. For merging, I mean that if a given value for a key (even deeply nested) does not exist, it is added. For overriding, I mean that if a given value for a key conflicts with another, the "latest" value wins, replacing the earlier one. I think if a first pass on this feature was merge-only, that would probably make enormous sense. I see some possibility for configurable override, but after thinking through how you might do that I'm finding myself firmly in the "punt that for later, if it ever seems like it actually matters it can be looked at again" camp. I think this also means that from a "what do I do to get the canonicalized config settings" the answer is the same at each step:
Additional ConsiderationsI think there's a possibility for some more delightful UX around this (where did this setting come from?) but like overrides and update notifications etc, I think it's a later concern compared to being able to extend the config at all. Presumably, documenting the settings provided by an extendable config is the job of that config's author (like me), and I doubt any user is going to accidentally end up extending a config vs following directions from a theme author. |
Thank you for the reply @michaeltlombardi this clarifies things a lot.
For the configuration part, first, the
This makes sense, and we could introduce show a notification once the remote file changes with a message saying: Do you wish to update?
Wouldn't this mean that the user needs to update the reference in their
For merging I was thinking like the example you gave above:
That last part makes me think.
|
Ah, that makes sense!
I think that's reasonable to do, even if it's just a quick hash comparison or something.
Oops! I was missing a sentence. So in this hypothetical example, I publish the same file to two locations:
And then when I need to make a breaking change, I would continue to publish the old
Agree with the flow you outlined on merging, I think that makes plenty of sense. For configuration, I think this could be iterative - step one, follow default logic as defined by the updated schema for extensible/overridable. In this case, to support picking and choosing what people can import, you would be stuck as a (module? package? extension?) developer writing small extensible JSON files, maybe with a meta file - so With that in place, we could consider supporting a Once we have some info to look at / see how that works in practice, I think I definitely see some value in being able to define a per-extension settings config, but the shape of that seems like a lot to chew on - probably useful, but definitely needing lengthy thought. Maybe I just want the snippets, which is easy enough, but maybe I want only a specific snippet, or I want all but a specific snippet, or I want the snippets as-is but I want to override one of them, etc. That definitely gets hairy quick, so my thought is to kinda noodle through those things alongside the minimal/basic implementation iterations with an understanding for extension config authors that this is still being worked out. |
@davidsneighbour @michaeltlombardi first external config support functionality got added and is up for its first tests. How it worksIn the Here is an example: "frontMatter.extends": [
"https://beta.frontmatter.codes/demo/frontmatter.extends.json",
"./config/frontmatter.config.json"
],
The order in how configuration gets applied
|
@davidsneighbour @michaeltlombardi have you been able to try it out? Any feedback or things you are missing? |
@estruyf I've been wrapping a big refactor for my site/theme, which prepped me for this. My main question right now is whether I need to compose the big JSON blob as an external reference or if I can publish them in the split-out layout I have now. In other words, can I publish a {
"$schema": "https://beta.frontmatter.codes/frontmatter.schema.json",
"frontMatter.framework.id": "hugo",
"frontMatter.content.publicFolder": "static",
"frontMatter.content.sorting": [
{
"id": "byWeight",
"title": "By Weight",
"name": "weight",
"order": "asc",
"type": "number"
}
]
} And then have the split-out pieces, like snippets, in their own blobs:
```jsonc
{
"title": "Button",
"description": "Add a button linking to another page or external site.",
"body": [
"![button:[[&selection]]]([[&url]])",
"{ [[&class]] }"
],
"fields": [
{
"name": "selection",
"title": "Button Text: This displays on the button itself.",
"type": "string",
"single": true,
"default": "FM_SELECTED_TEXT"
},
{
"name": "url",
"title": "Button Url: Specify the URL this button should lead to.",
"type": "string",
"single": true,
"default": ""
},
{
"name": "class",
"title": "Class List: Specify any classes to add to the button in a space-separated list. Each class must have a period (`.`) prefix.",
"type": "string",
"single": true,
"default": ""
}
]
}
```
|
That is correct; I also wanted to make sure a never-ending loop could happen. This might be the case if something needs to be configured correctly. Splitting is possible, but you can only do this for now, as you explained. If this gets well adopted, it would be an excellent next step to put the further effort in it to allow you to insert REFs. |
I'm rewriting my Front Matter configs this week, I'll get them published as extensible configs and share those findings in here when there's something to show for it. I'm very excited because this also dovetails with the JSON schematization I've been doing for site configuration. All going well, this should mean that I'm able to give my users highly functional UIs for managing their content metadata, configuration, and snippets without much work on their end. Once I'm able to figure out a coherent way to do custom scripts from an extended config, that will also really help smooth out their authoring experience. |
Looking forward to hearing more about it! Thanks @michaeltlombardi. |
@estruyf a few notes:
Given:
|
|
|
This change takes advantage of the improvements to the memo module to publish an initial group of configs for FrontMatter users. This initial pass doesn't do any further work with the documentation, it just makes the composed configurations available for testing. This is in support of estruyf/vscode-front-matter#407, which adds the `frontMatter.extends` key.
@estruyf got a very rough prototype up and functional (just tested!) locally: {
"$schema": "https://beta.frontmatter.codes/frontmatter.schema.json",
"frontMatter.extends": [
"https://deploy-preview-44--platen.netlify.app/frontmatter/platen.json",
"https://deploy-preview-44--platen.netlify.app/frontmatter/toroidal.json",
"https://deploy-preview-44--platen.netlify.app/frontmatter/schematize.json"
],
"frontMatter.site.baseURL": "https://platen.io"
} Pulling together the composed configs without being able to somehow specify I wanted them to recurse was a little bit of work but I got there in the end. I need to have a longer think about whether/how to pull in other information and how to approach scripts. |
This change takes advantage of the improvements to the memo module to publish an initial group of configs for FrontMatter users. This initial pass doesn't do any further work with the documentation, it just makes the composed configurations available for testing. This is in support of estruyf/vscode-front-matter#407, which adds the `frontMatter.extends` key.
This change extends the functionality of memo for documenting a hugo theme to enable a theme author to publish [FrontMatter][01] config files, which users can then reference in their own projects instead of having to find and copy all the values. This change is in support of estruyf/vscode-front-matter#407, which adds the `frontMatter.extends` key. In this basic implementation: - An author can define `memo.front_matter.configs` in their site params or on a particular page to publish one or more configurations. The implementation requires that the configurations be defined as assets. The implementation allows you to specify the config path as a remote asset, a site asset, or a page asset and resolves the config path to the appropriate asset. Authors can define either the `definition` or `merge` key in an item but not both. Items with the `definition` key publish a single config and have the option to specify the site-relative publish path with the `publish` key. Items with the `merge` key merge the values from multiple configs to publish as a merged blob to the site-relative path defined by the mandatory `publish` key. - Memo has been updated to take advantage of the merge-from-data feature in Platen to allow setting the site parameters in a data file. - The new configuration options are validated before use, warning and discarding invalid values.
Is your feature request related to a problem? Please describe.
I've been working through configuring Front Matter for my site and my configuration (without adding the data types for my data files) has been getting long. I'm currently at ~750 lines and adding the data schemas will add another 500+, plus additional short codes etc.
I'm also a hugo theme developer and maintainer with multiple themes, but no way to provide my users defaults for Front Matter when using my themes.
Describe the solution you'd like
I would like an extensibility model similar to markdownlint or vale, which would allow me to package up Front Matter configuration items (data types, snippets, sorting options, content types, etc) for my users to take advantage of and extend or override as needed.
In the Front Matter config, something like:
Where the configurations are merged in the order that they are specified, with any new items from
local.frontmatter.json
added to the settings in the remote config, and items in this config added to that merged config.Any subkeys with the same name would replace existing keys, so if I had this config in
local.frontmatter.json
:and this one in
frontmatter.json
at the project root:The second definition of
Hint
would be used, making the valid choices includeexample
andimportant
as well asinfo
,warning
, anddanger
.This would allow me to supercharge the usability of my themes for my users and make maintenance a little easier on myself at the same time.
Describe alternatives you've considered
I could resolve this with custom scripting (probably rising to the level of a toolkit or small app), but that would be another thing to require my users to install/track/manage, which is always extra friction.
I can see a potential for publishing Front Matter configuration setting packages that Front Matter could be aware of, but that seems like much more effort and would require a lot of UI and workflow updates and be difficult/costly to maintain (though possibly high value for users).
Additional context
I'm coming at this from both a "I have to maintain a very big complex configuration for myself" and "I would like to make delightful UX/DevX for users of my themes" which are separate but related use cases that could both benefit from a feature like this.
I'm fairly ignorant of typescript and VS Code development, but I would be happy to test this and help pitch in however you think helpful, if this feature is something you think worth bringing into the project. And if not, I'm also willing to write some scripts and document those as a workaround/prototype.
The text was updated successfully, but these errors were encountered: