Canonical/elegant/unsurprising way to implement theme configuration flags

I’m writing a theme. One thing that is coming up very often when writing my Twig files is that I have a boolean binary flag (e. g. display_menu: true or similar) and I want to deal with it according to the following logic:

  • Have a default in config.theme.<property>
  • If that default is not overwriten in a page’s frontmatter, use the theme configuration.
  • If that default is overwritten in a page’s frontmatter, use the page configuration.

I assume that this is such a “natural” logic, that a lot of people must have implemented something like this.

The problem of course is handling false values. If, for instance, config.theme.display_hero is true and page.header.display_hero is false, that means a boolean or of the two is true. (Leaving additional issues of the page’s blueprint and saving the page in the admin panel aside for the moment.) What I want, however, is having a way to say “By default, display a hero image on every page. But not on this one.”

This is a question about the most idiomatic and unsurprising way to do it. I can think of a hundred ways to achieve this that are either unelegant or verbose. (E. g. using the numbers 0 to 2 for undefined, true and false instead of booleans.) All of which might make me scratch my head in five years and wonder: “What did I want to do there and why did I write this that way?”

Is there a way to write this in Twig that at a glance would make you think “Ah, sure, that’s about a boolean flag in theme config vs. page frontmatter”?

Hi,
I’m not experimented with grav, but I would try this:

set display_hero = page.header.display_hero|defined(config.theme.display_hero)

ref https://learn.getgrav.org/16/themes/twig-filters-functions#defined

Or

set display_hero = ( page.header.display_hero is defined ) ? page.header.display_hero : config.theme.display_hero

ref https://twig.symfony.com/doc/2.x/tests/defined.html and https://twig.symfony.com/doc/2.x/templates.html#other-operators

1 Like

Lovely! Clear at first glance.

Now I need to make sure that the blueprint form in the admin panel leaves the variable unset by default. But that’s another topic for another thread.

Thank you!