When changing from Wordpress to Pelican, I found one thing that I did not
like. When inserting images in a post, the image would be inserted as a simple
img
tag in the HTML output. I would like to use figures, like e.g. in
scientific papers, with captions and a frame around.
After some research, I found that
- HTML 5 supports the
figure
andfigcaption
tags. This is exactly what I want! - I can embed any HTML code in the markdown content for Pelican.
- I do not like to mix Markdown and HTML in the content. It's error-prone and much to type.
After some talking to Google and browsing the webs, I found that there is the jinja2content plugin for Pelcian to support Jinja template code inside the post content. Around this plugin I set up a nice solution for adding figures to my posts. The idea is the following:
- Use
jinja2content
to be able to use Jinja template code in posts - Import a file with Jinja macros into every post
- Write a Jinja macro to generate HTML code for a figure with caption.
Set up the Jinja2Content Plugin
The plugin is part of the Pelican plugin repository on Github. It's easy to set up:
- Clone the plugin repository
- Copy the
jinja2content
folder into theplugins
folder of your Pelican project. - Update
pelicanconf.py
to enable the plugin like this:
# pelicanconf.py
PLUGIN_PATHS = ['plugins']
PLUGINS = ['jinja2content']
Now you can use Jinja template code in your posts.
Adding Support for Figures
By default, the jinja2content
plugin searches for templates in the theme
template folder. So you can include or import templates from there. So I create
a template file called macros.html
with a macro to generate HTML code for a
figure and put it into my theme templates
folder.
Note: In the following code examples, all Jinja start and end tags {{
... }}
, {% ... %}
and {# ... #}
are replaced with square
brackets [[ ... ]]
, [% ... %]
and [# ... #]`. Otherwith the Jinja template
engine would try to interpret them in this post. When copy & pasting this code,
you need to replace the braces accordingly!
[# Macro to add a figure with caption to a post. #]
[% macro figure(src, caption='') -%]
<figure>
<a href="[[ '{' ]]attach[[ '}' ]]images/[[ src ]]">
<img src="[[ '{' ]]attach[[ '}' ]]images/[[ src ]]"
title="[[ caption ]]"
alt="[[ caption ]]">
</a>
[% if caption %]
<figcaption>[[ caption ]]</figcaption>
[% endif %]
</figure>
[%- endmacro %]
Now in every post, I need one line of Jinja code to import the macro:
[% import 'macros.html` as m %]
Then I can add figures in the post like this:
[[ m.figure('jinja-macro-for-figure.png', 'Screenshot of the original code of
the `figure` macro.') ]]
The result looks like this:
Support for JINJA2_PREFIX setting
Now writing posts with figures is already easier. But it's still annoying to
include the import
statement at the top of every post.
So I have modified the code of jinja2content.py
to support a post prefix
setting. The read(...)
method now gets the JINJA2CONTENT_PREFIX
variable
from the settings and prepends its content to every post.
def read(self, source_path):
prefix = self.settings.get('JINJA2CONTENT_PREFIX', '')
with pelican_open(source_path) as text:
content = prefix + text
content = self.env.from_string(content).render(**self.settings)
with NamedTemporaryFile(delete=False) as f:
f.write(content.encode())
f.close()
content, metadata = super().read(f.name)
os.unlink(f.name)
return content, metadata
Now I can add the following setting in pelicanconf.py
to automatically import
the macros.html
file to all posts:
# pelicanconf.py
# prefix for all articles
JINJA2CONTENT_PREFIX="{% import 'macros.html' as m %}"
As this string is prepended to each post, it is prepended before the metadata section. So you can use jinja code to even generate metadata. On the other hand, you should not generate any other content, especially no blank lines, as this would terminate the metadata section.