Extending functionality¶
This section assumes you know your way around Wagtail. If you need to get up to speed, please work through the following brief sections in the official Wagtail guides. They won't take long and cover essential concepts well.
Development flow¶
Design philosophy
Every site created with Birdbox runs off a fork of the main project.
If you want to add a new page type, or block type, or anything else to a site that's build from Birdbox, the ideal place is directly within the core mozmeao/birdbox
project.
We will soon support a way to limit which page types are available purely via configuration, so a growing number of page and block types in the core kit will not mean that forked sites will have too many choices for site editors, causing them confusion or creating an inconsistent look.
Contributions to mozmeao/birdbox
should be made via Pull Request, as with all other mozmeao
projects.
Making changes downstream only
If you make a fork from the mozmeao/birdbox
and then choose to add/extend that forked codebase, there is a real risk that you'll make it hard - or even impossible - to bring it back in sync with the upstream original project, particularly if the changes you make involve database migrations from adding or amending Pages or Blocks.
We're not saying you cannot do this, but is is highly discouraged if you think the forked site will need to benefit from future upstream changes.
Important: If you "cut loose" your forked project, remember that you're now responsible for tracking and applying security patches - you won't necessarily be able to sync with mozmeao/birdbox
to get them.
Birdbox-specific behaviour¶
While most of a Birdbox site is "standard Wagtail", there is some custom behaviour that is worth noting.
Frontend Media¶
Websites often feature static assets generated by a bundler step that outputs a single CSS or JS file. However, because Birdbox sites give editors access to more Protocol components than they may need, we did not want to load one single large lump of CSS or JS that covers all protocol components.
Instead, we've elected to include the CSS and JS required for a particular Protocol component only when it's included on the page, in a pattern similar to how Django Forms have a Media
object.
We do this by specifying a frontend_media
property on each custom StructBlock
, and at render time we gather URIs for them all and output a deduplicated list of tags into the template.
Future improvements to explore:
- Support bundling commonly grouped assets, to reduce the number of files loaded while also avoiding loading a monolithic JS or CSS file.
- Evaluate
django-compressor
as an easy way to do the above.
How to¶
...turn a Protocol component into a StreamField block¶
- Define a new block in Python in
microsite/blocks.py
with the fields/content items that the Protocol component needs (e.g. title, description, image) - Add a new HTML template fragment for the new block in
microsite/templates/blocks/
- Base the markup on the HTML in the Protocol docs' examples
- Remember to circle back and reference the template filename in the Python block definition - see other blocks for examples
- If JS or CSS is needed for the component, configure webpack to build it - see
src/css/protocol/card.scss
as an example or this FAQ.- Remember to circle back to the Python nlock definition to set the
frontend_media
property so that this CSS/JS gets included on page load
- Remember to circle back to the Python nlock definition to set the
- Find the page (in
microsite.models
) with aStreamField
that you want the new component to be available in. Add it to the list of blocks that are available. just makemigrations
thenjust migrate
to udpate the database.- In the Wagtail CMS admin, amend an instance of the relevant page to use your new block - you should be able to see it in the live preview. Usually it takes a bit of tweaking to get the page to look as you intend. You can publish the local page and view it directly while you refine your HTML/CSS/JS, of course.
- If you need to add custom CSS to override what's in Protocol, ideally please add it to the relevant CSS file in Birdbox for the component. If there is nowhere relevant to put it, such as for layout or element-level styling, please add it to
src/css/birdbox-protocol-overrides.css