A Jinja Altair/Vega Template
The Altair Template
This is the Jinja template to get altair-vega into posts. To use it add .. template: altair.tmpl
to the post metadata. It is located at themes/custom-jinja/templates/altair.tmpl
The Tangle
Here's the tangle that creates the template file.
{# -*- coding: utf-8 -*- #}
<<altair-helper-import>>
{% extends 'post.tmpl' %}
{% block extra_head %}
{{ super() }}
<<altair-macro-call>>
{% endblock %}
Altair Helper Import
Both this template and the index.tmpl
template need to import the vega library I made a macro to do it and put it in a separate file (altair_helper.tmpl
) so we need to import that macro here.
{% import 'altair_helper.tmpl' as altair with context %}
The Altair Macro Call
Here's where we call the macro to insert the script
tag to get vega.
{{ altair.altair_scripts() }}
The Altair Helper Template
This is the template file that contains the functions (macros) to check whether the HTML to work with vega should be added or not. It is located at themes/custom-jinja/templates/altair_helper.tmpl
It's used by both the altair.tmpl
template (above) and the index.tmpl
template that's used for the latest posts.
The Tangle
{# -*- coding: utf-8 -*- #}
<<vega-scripts-macro>>
<<vega-post-macro>>
<<vega-index-macro>>
Vega Scripts Macro
This adds the vega library to the HTML HEAD as well as defining an "error" class that gets used if there's an error in rendering the vega chart. It has the versions hard-wired into it so it will need to be changed if we want to use a different version of vega, vega-lite, or vega-embed.
{# macro to add the altair-vega.js code tags #}
{# and define an error color class #}
{% macro altair_scripts() %}
<style>
.error {
color: red;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@5"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@5.6.1"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@6"></script>
{% endmacro %}
Vega Post Macro
Here's a macro that gets called to set up a single post (as opposed to a post in the latest-posts feed). It adds the vega-imports to the document HEAD if there's a .. has_altair
field in the meta data. I don't think this works yet - there needs to be more work done on the post
template or I need to make a real plugin.
{# macro for a single post #}
{# `post`: a Post object #}
{% macro altair_scripts_ifpost(post) %}
{% if post.meta("has_altair") %}
{{ altair_scripts() }}
{% endif %}
{% endmacro %}
Vega Index Macro
This is the macro that adds the vega libraries if the post is in the posts feed and it has been set in the metadata.
{# macro used by feed page with multiple posts (e.g. index.tmpl) #}
{# 'posts': list of Post objects #}
{# jinja doesn't support comprehensions so we have to use a for-loop #}
{# the ~post.meta~ object is a Functionary object #}
{# the metadata is in a dictionary that's in a dictionary #}
{# if you try ~post.meta.has_altair~ it will fail because you need the language you're using as a key #}
{# e.g. ~post.meta.en.has_altair~ #}
{# to not refer to the langugage you need to call it like a function, passing in the "has_altair" key as an argument #}
{% macro altair_scripts_ifposts(posts) %}
{% set altair_added = False %}
{% for post in posts %}
{% if (post.meta("has_altair") or post.meta("template") == "altair.tmpl") and not altair_added %}
{% set altair_added = True %}
{{ altair_scripts() }}
{% endif %}
{% endfor %}
{% endmacro %}