{ Fri, 21. Feb 2014 }

Dynamically Loading Assets in mynt

I have been thinking about this one for a while, and this evening I finally had time to test my theory. One issue in web development is loading time - We have to assume not everybody has the same incredible bandwith that we do, so we need to keep the pages we’re serving small. At the same time, we like to use fancy stuff with CSS and JS, which can cause the size of our serves to get quite out of hand.

mynt comes to the rescue with its powerful frontmatter. With a bit of trickery, it allows us to include some scripts only on the pages where we need them. Not all blog posts have code snippets, so it’s pointless to include the pygments CSS on every single page. So, how about we add a custom frontmatter tag to posts containing code? How about… css: [pygments] for example?

First method: Simple

To make this possible, we’ll need to edit two templates: post.html and layout.html. First of all, we’ll add this to post.html:

{% set css = item.css %}

This will export our css frontmatter, so that we can use it in the layout. Talking about layout,

{% for sheet in css %}
<link rel="stylesheet" href="{{ get_asset('css/' + sheet + '.css') }}" type="text/css" media="screen" />
{% endfor %}

This loops over all CSS items (we passed a sequence, remember?), and include the corresponding stylesheet at /assets/css/<item>.css. Something similar can be done for JS, or any other asset you don’t want loaded on ever page.

Second Method: Almost the same thing

I had a chitchat with Anomareh about this, and he suggested modifying config.yml to achieve a similar thing. This is what he came up with:

css: {
    'red': ['a.css'],
    'blue': ['a.css', 'b.css']

And the layout.html would look like this:

{% for sheet in site.css[item.css] %} ... {% endfor %}

This solution is practical if you want to create “sets” of stylesheets, which all need to be loaded together. If you want to load single sheets, I do not see an advantage in using this method, it just adds one more file to edit.

Third method: Using custom Layouts

Something else we came up with, and (at least one of us) very quickly dismissed again, is the usage of a custom layout, depending on the type of post you are wanting to write. This is probably the “purest” (read: non-mynt-specific) way of accomplishing this task.

While this is also a viable solution to this problem, I’m not a big fan of it. Yes, it makes sense when you actually want to use a different layout, but I simply want to include the pygments stylesheet only on pages that need it - the layout would stay the same. By using this solution, I would have to duplicate my post.html layout, and use a different layout frontmatter tag. In theory, there is nothing wrong with that, the problem just starts when I decide to update my post layout - I would have to make the same changes to both files. Of course this can be worked around by making use of jinja’s child templates, but that would add a clusterfuck of template nesting. If you don’t mind these two drawbacks, by all means go for it, but I think it goes against everything mynt stands for - keeping blogging simple. mynt has its powerful frontmatter, so use it!