Inheriting theme configurations in Grav
Grav's theme inheritance system is great, but how do you retain the configuration options of the parent theme?
Grav's documentation suggests just copying the parent theme's
blueprints.yaml into your new theme if you want to retain the configuration options. But the problem here is that this breaks an aspect of your inheritance - if there's an update to the parent theme's configuration options, you will need to manually copy these over.
But there are actually two better ways to do this!
Theme blueprints can extend other theme blueprints, just like is commonly seen with page blueprints. So if you are inheriting from the default Quark theme, and you just want to add some more options to the bottom, you can just extend the theme's blueprint by adding the following to the top of your theme's
extends@: type: blueprints context: themes://quark
The key here is to recognise that the file you want to extend is called
blueprints.yaml and it lives in the
themes://quark folder. Also, you should note that since you are extending the parent theme's blueprint, you also get the
dependencies etc, from the parent theme, unless you redefine them later in your blueprint or you use
unset-*@ (discussed later).
If you want greater control of where the configuration options get inserted, you need to use
import@. This allows you to dynamically insert a form within another form by putting
import@ where you would normally have
fields. To get the same effect as
extends@, but without the
name etc being brought in, you can use:
... form: import@: type: blueprints context: themes://quark
But importing the configuration options gives more control over the structure of the page, so you could for example import the parent theme's configuration into a separate tab:
... form: fields: tabs: type: tabs fields: custom: type: tab title: "Your own configuration options" fields: ... base: type: tab title: "Quark's configuration options" import@: type: blueprints context: themes://quark
Regardless of whether you use
extends@, you can overwrite, update, and unset any of the configuration options. For example, the Quark theme has an option called
grid-size, which is the maximum width of the theme and has options for
grid-md. If you wanted to add an option for
grid-2x, you just address all of the keys that you need to change (in this case:
options) and then add your own content to it.
... form: import@: type: blueprints context: themes://quark fields: grid-size: options: grid-2x: "Even larger!"
The above snippet would retain all of the other options for
grid-size (so you could still select
grid-md if you want), but appends
grid-2x to the list.
Advanced blueprint options
Grav has lots of really useful advanced blueprint features that let you do more than just add to previously defined form fields, and you can find more details in the Grav documentation.
The most useful options for modifying inherited blueprints are
If you want to completely remove the
grid-size option from the configuration, you can use
unset@ as follows:
form: fields: grid-size: unset@: true
If you want to keep the option, but you want to remove a property from it, you can use
unset-*@. For example, if you want to remove the
size property of
grid-size because you don't want it to be small, you can use
form: fields: grid-size: unset-size@: true
You can also replace the previous definition with a new one. For example, if you want to make
grid-size into a text field, you will want to
replace@ it so that the field gets completely replaced by your new definition.
form: fields: grid-size: replace@: true type: text label: Grid size default: grid-2x
If you really like wide websites, you might want to cut the number of options down to just those that you might use, and you can do this with
replace-options@: true. This will mean that only the previously defined
options are removed, rather than the whole definition, and the options are replaced by the ones defined here.
form: fields: grid-size: replace-options@: true options: grid-lg: "Large" grid-xl: "Extra large" grid-2x: "Even larger!"
You can also change the order that fields appear in using
ordering@. For example, if you think that
grid-size is super important and should be the first field in the configuration page, you can set
ordering@: 0 to place it in the first position (we're counting from 0).
form: fields: grid-size: ordering@: 0
Similarly, if you want it to be the third field, just set
ordering@: 2, and if you want to place it at the end, just set the ordering to a suitably high number.
Note: At the time of writing, the behaviour reported in the documentation differs from the actual behaviour. This article describes the actual behaviour as of June 2020. The documentation says that setting the ordering to
-1 will place the field at the top, but it actually places it one up from the bottom.