Justin Duke

Using webassets with Pelican

If you are like me, you are an idiot.

More specifically, you are an idiot about how to handle static files with Python stuff – compiling your SASS, minifying and gzipping your jank, uglifying your javascript, all of that stuff.

Until very recently, my process of compiling of all of that stuff prior to pushing it for S3 for Film Scripts Online, one of my new Pelican projects, was something along these longs:

  1. Run scss manually.
  2. Modify my Makefile to uglify and compress my js.
  3. Fiddle around with s3cmd to try and gzip on upload.
  4. Watch as everything is ruined forever for reasons beyond my understanding.
  5. Cry to self, drink Bulleit, hit make s3_upload and hope that things improve on their own.

In my most recent attempt to solve this issue, for this very blog – also written in Pelican – I stumbled upon webassets, a beautiful and wonderful solution.

The only problem with this wonderful and beautiful solution is that appears to be entirely undocumented. Parts of it appear – on the plugin read, on Pelican’s readthedocs, on webasset’s readthedocs, frustrated blog posts – but hey, let’s try and actually compile the process of doing this all in one place!

So here goes, the full list of jank you a to do.

(I’m using sass/cssmin as the example here, but the same generic process applies to everything else. The full rundown of webasset functionality is here.)

1. Install some stuff.

sudo gem install sass

sudo pip install cssmin

sudo pip install webassets

As a general rule of thumb, webassets has support for all of the plugins you’d want but it doesn’t actually come installed with them. Google is your friend here: as long as you install something that comes in the form of a Python module or a CLI, you should be good to go.

2. webasset-ify your theme.

Since pelican’s wizardry only goes so far, you need to actually activate it as a plugin in your pelicanconf.py file 1:

PLUGIN_PATHS = [THEME + "/plugins"] # alternatively, ["/path/to/wherever/plugins/are"]
PLUGINS = ['assets']

3. Plug in your plugins.

Now throw them wherever you define your static assets in your theme, hopefully in a base.html or header.html:

{% assets filters="scss,cssmin", output="css/main.css", "css/main.scss", "css/sortable-tables.css", "css/footnotes.css" %}
    <link rel="stylesheet" href="/{{ ASSET_URL }}">
{% endassets %}

A couple things here to note:

  • You can chain filters, like I do by first passing it through scss to compile my SASS and then to cssmin to minify everything.
  • Most minification/uglification is actually disabled in DEBUG (aka running ./develop_server) which is totally great except I didn’t realize it and was super confused as to why it wasn’t working at first.
  • You only specify one output 2 but you can specify an infinite amount of input arguments like I do: those are available within the block as ASSET_URL.
  • By default, webassets will be reading and writing from the theme folder of the output directory. If you have your theme set up in a standard way, this is good – items in your static folder will end up there automatically.

4. Bask in the infinite glow.

That’s it! It’s super easy and will considerably lessen the effort of your static asset management. Hope this helped!

  1. This is actually my one nitpick with the entire process, since you’re generally using webassets at the theme level and not the blog level. It’s fine for my use case, but sort of icky that you’d have to go through this process to properly use some random theme that uses webassets. [return]
  2. To my understanding, this is unambiguously a good thing: three calls for 100KB worth of data is worse than one call for 100KB worth of data due to the additional latency of each request. [return]
Liked this post? You should subscribe to my newsletter and follow me on Twitter.

(I've got an RSS feed, too, if you'd prefer.)