Meta recursion: meta-post about meta-tags

Social media networks like Twitter, Facebook and LinkedIn support the use of <meta> tags in your HTML to provide additional information when displaying links to websites. Facebook and LinkedIn use OpenGraph tags; Twitter accepts some OpenGraph tags plus a few of its own. Providing these tags allows you some customisation of how your pages are displayed when people share links to them through these networks.

I've recently added suport for these tags into Bulrush, the theme currently used on this blog. What this means is that if you drop the link to one of my articles, e.g. http://blog.jonrshar.pe/2015/Jul/06/context-manager-case.html, into the Twitter Cards validator, you will see something like the following:

Twitter Cards Preview

You may wonder how this is implemented. I'm using template inheritance, provided by the Jinja2 template engine, to allow child templates to override their parents via block and extends elements, and the include statement to bring in the defined tags.

There's a single file representing the meta tags (meta_tags.html):

<meta property="og:title" content="{{ SITENAME }}{% if item.title %} - {{ item.title }}{% endif %}">
{% if item.summary %}
  <meta property="og:description" content="{{ item.summary | striptags | truncate(200, end='...') }}">
{% endif %}
<meta property="og:url" content="{{ SITEURL }}/{{ item.url }}">
{% if AVATAR %}
  <meta property="og:image" content="{{ SITEURL }}/images/{{ AVATAR }}">

  <meta name="twitter:image:alt" content="{{ SITENAME }}{% if SITESUBTITLE %} | {{ SITESUBTITLE }}{% endif %}">
{% endif %}
<meta name="twitter:card" content="summary">
{% if TWITTER_USERNAME %}
  <meta name="twitter:creator" content="@{{ TWITTER_USERNAME }}">
  <meta name="twitter:site" content="@{{ TWITTER_USERNAME }}">
{% endif %}

Some of the interpolated variables, like SITENAME, are set in the root pelicanconf.py and made available everywhere in the templates. The with statement extension allows the item to be injected from the template displaying the specific item I want to be tagged when they include the sub-template, e.g. for the articles (see article.html):

{% block tags %}
  {% with item=article %}
    {% include 'meta_tags.html' %}
  {% endwith %}
{% endblock %}

the item is the article object. Similarly, for generic pages like the About page, the injected item is the page object. These both have similar properties, like summary, title and url, so it's easy to plug either of these into the general tag layout. {% block tags %} simply means that the rendered markup will "fill in" the defined block from a parent template, in this case in base.html's <head> element.

Hopefully this demonstrates how useful the template inheritance functionality of Jinja can be. You can see the full commit on GitHub; it took under 30 lines of HTML to add automatically-generated meta-tags to the relevant pages. If you're using Pelican to generate your blog, feel free to give Bulrush a try and let me know what you think. Alternatively, you can use the above ideas to add similar functionality to your own Pelican theme, or any other Jinja2-based site.

Comments !