I'll give you my specific use-case here and then see if it might also be more generally applicable in other scenarios: We have a new Craft PRO site running happily, and in our /templates/ we have a _layout.html file that every other template then uses and extends. That _layout includes common <head> content, main navigation, footers, etc. Nothing surprising.

But on one sub-page we are displaying Google Maps using various calls to Google's Mapping API. One requirement for the Google Maps, however, is that the tag trigger Google's JS when the page loads and unloads:

  <body onload="load()" onunload="GUnload()">

Currently that <body> tag is in _layout.html so that it can be consumed by the mapping page. But for all other pages it's superfluous, and throws a minor error in the JS console when you inspect the page.

My question is: Is there a way to write a page template so that it _extends another base template but also overwrites just a small portion of it? For instance, could I remove the onload / onunload values from _layout.html and somehow have my mapping page INSERT them back into the <body> tag for just that page?

Or is there a more elegant way to have my mapping page draw upon _layout.html but keep the onload / onunload calls isolated to just that page? Or maybe have _layout.html look for what page is calling it and then return one <body> tag for the mapping and another <body> tag for all other pages?

The Google Maps API makes it pretty clear that this JS function be called at the <body> level, and not just on a <div>.


You could define a variable in you child template:

{% set bodyAttributes = 'onload="load()" onunload="GUnload()"' %}

And then output the value in your parent _layout.html template. Use the is defined test, so that not every template extending this file has to have that variable defined. I'm using ternary syntax here, to keep the code nice and lean:

<body {{ bodyAttributes is defined ? bodyAttributes : '' }}>

As I generally like to have as few logic in my Twig output tags as possible (in particular when they output classes and attributes to already cluttered HTML tags), I would write that code like so:

{% set bodyAttributes = bodyAttributes is defined ? bodyAttributes %}

<body {{ bodyAttributes }}>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.