I love the simplicity and configuration friendly setup of GravCMS, and I wish it was more popular than WordPress. However, a challenge with it is that the things that you can easily do with WordPress aren't as well documented in Grav. One of the idea is the notion of widgets. For this piece, we treat widgets as blocks of metadata and content defined from a single source that can be called upon by any page.
There are many places where we can craft this single source: from a custom built plugin, from a theme configuration file (config/themes/themename.yaml
), or even the site.yaml
file, depending on your use case. But in our case, we may want to plug it somewhere in the user/pages
directory if our use case are as follows:
- Our widgets aren't so complex that we need the leverage plugins allow, but
- Our widget headers can be as complex and freeform that it will clutter our
site.yaml
and it will make ourblueprints.yaml
too cumbersome to configure and expose to theadmin
plugin.
In this case we need all the configuration we can get from custom page.headers, but we don't need to craft some php code to make it work.
Thus, our single source will be somewhere in the user/pages/
directory, that is a nonroutable _widgets
folder.
When you update the page headers from the widgets, that widget will be updated on all rendered pages that call it.
For example, in the widgets folder, we can define a single floating banner widget with page.header metadata for visibility, published and unpublish date, and content for the banner. Its purpose will be to post important but temporary notices that the site visitor will notice at first glance upon entering the site. In _widgets/floatingbanner
, we can define the following:
# _widgets/floatingbanner/default.md
---
visible: false
publish_date: 01/23/2020 13:00
unpublish_date: 05/17/2020 00:32
---
I am the floating banner content.
Access the metadata on this widget in a template or template partial of your choice with: {% set floatingbanner = page.find('/_widgets/floatingbanner') %}
.
You may debug this with {{ dump("page.find('/_widgets/floatingbanner') output:", page.find('/_widgets/floatingbanner')) }}
. Make sure that in the debugbar, you are able to access the page headers of your custom widget.
Then call the configuration values of your floating banner widget by tapping into your variable of choice as you would with any grav variable. floatingbanner.header.customvariable
or floatingbanner.content | raw
, and rig the values with the twig logic for your widget.
This is incredibly useful for calling page collections into sidebars or link-heavy magazine-type pages, and rig up as many page collection configurations as you can without being repetitive as you might end up being if you use modular templates.