Sphinx front matter and template variables

I'm building a docs-as-code site at work at the moment (you can peek if you like https://developer.aiven.io) and working with ReStructuredText in this setup is new to me. One thing I really missed was the concept of front matter, which I'm not sure is even official or documented but seems to be reasonably widely supported (I promise to save the rant about markdown for another day). It took me a while to figure this out for Sphinx/rst but now I'm looking at it working, I had better write it down before I forget!

All this is on Sphinx 4.0 and Python 3.8, in case this information matters to someone reading this post 10 years from now.

Add fields to your content

Sphinx calls this extra information file-wide metadata, variables that apply in the context of the file they appear at the top of. I'm not sure how many Sphinx installations use something other than one-file-per-page but file-wide works perfectly for me.

Here's how I added a description field to a page (I'm not using the meta markup because I'm actually going to use this field in a twitter card implementation):

:description: This page has an excellent description of how to apply cucumber and unicorns to the problem

Heading 1
#########

More words on the page .....

Note that the extra fields have to be the first thing in the file, before the first heading or other content. This adds any field name you care to invent, and a string value (check the docs for more detail on supported types but basically: use a string) to the meta field for this pae.

Using this data in a template

I'm adding basic Twitter Card support by pasting it straight into base.html. Probably the comments on this post will help me to understand better ways to solve this problem, which is why I love blogging. If there's a specific description set, I want the tag to use it - and if not, we'll just grab the first 120 characters of the page itself. Ready?

<!-- Twitter Cards -->
<meta name="twitter:title" content="{{ docstitle|striptags|e }}">
<meta name="twitter:description" content="{{ meta.description or body|striptags|e|truncate(120) }}">

The {{ meta.description }} field in the template holds the value we defined in each page, and you can also see the or syntax there in case we need to fall back to just using a bit of page content (which hopefully does introduce the intent of the page pretty well anyway!).

This was harder to find an example of than I had expected so hopefully this will help someone else running into it next time.


Also published on Medium.

Leave a Reply

Please use [code] and [/code] around any source code you wish to share.

This site uses Akismet to reduce spam. Learn how your comment data is processed.