How to no-mincss links with django-pipeline

03 February 2016   2 comments   Python, Web development, Django

Powered by Fusion×

This might be the kind of problem only I have, but I thought I'd share in case others are in a similar pickle.

Warming Up

First of all, the way my personal site works is that every rendered page gets cached as rendered HTML. Midway, storing the rendered page in the cache, an optimization transformation happens. It basically takes HTML like this:

<html>
<link rel="stylesheet" href="vendor.css">
<link rel="stylesheet" href="stuff.css">
<body>...</body>
</html>

into this:

<html>
<style>
/* optimized contents of vendor.css and stuff.css minified */
</style>
<body>...</body>
</html>

Just right-click and "View Page Source" and you'll see.

When it does this it also filters out CSS selectors in those .css files that aren't actually used in the rendered HTML. This makes the inlined CSS much smaller. Especially since so much of the CSS comes from a CSS framework.

However, there are certain .css files that have references to selectors that aren't in the generated HTML but are needed later when some JavaScript changes the DOM based on AJAX or user actions. For example, the CSS used by the Autocompeter widget. The program that does this CSS optimization transformation is called mincss and it has a feature where you can tell it to NOT bother with certain CSS selectors (using a CSS comment) or certain <link> tags entirely. It looks like this:

<link rel="stylesheet" href="ajaxstuff.css" data-mincss="no">

Where Does django-pipeline Come In?

So, setting that data-mincss="no" isn't easy when you use django-pipeline because you don't write <link ... in your Django templates, you write {% stylesheet 'name-of-bundle %}. So, how do you get it in?

Well, first let's define the bundle. In my case it looks like this:

PIPELINE_CSS = {
  ...
  # Bundle of CSS that strictly isn't needed at pure HTML render-time
  'base_dynamic': {
        'source_filenames': (
            'css/transition.css',
            'autocompeter/autocompeter.min.css',
        ),
        'extra_context': {
            'no_mincss': True,
        },
        'output_filename': 'css/base-dynamic.min.css',
    },
    ...
}

But that isn't enough. Next, I need to override how django-pipeline turn that block into a <link ...> tag. To do that, you need to create a directory and file called pipeline/css.html (or pipeline/css.jinja if you use Jinja rendering by default).

So take the default one from inside the pipeline package and copy it into your project into one of your apps's templates directory. For example, in my case, peterbecom/apps/base/templates/pipeline/css.jinja. Then, in that template add at the very end somehting like this:

{% if no_mincss %} data-mincss="no"{% endif %} />

The Point?

The point is that if you're in a similar situation where you want django-pipeline to output the <link> or <script> tag differently than it's capable of, by default, then this is a good example of that.

Comments

Anonymous
Hi Peter,

What I have been made to believe is that the advantage of separate, fixed css files is that they can be cached by the browser. I would like to understand what benefit would in-lining the css provide ? Could you please explain that ?

Regards
Vishal
Anonymous
Read your other post. Understood your point. Thanks.
Thank you for posting a comment

Your email will never ever be published


Related posts

Previous:
Bestest and securest way to handle Python dependencies 01 February 2016
Next:
Whatsdeployed on only one site 26 February 2016
Related by keywords:
Fastest way to uniqify a list in Python 14 August 2006
mincss "Clears the junk out of your CSS" 21 January 2013
premailer.py - Transform CSS into line style attributes with lxml.html 11 July 2009
The awesomest way possible to serve your static stuff in Django with Nginx 24 March 2010
Optimization of getting random rows out of a PostgreSQL in Django 23 February 2011
Gzip rules the world of optimization, often 09 August 2014
Fastest way to thousands-commafy large numbers in Python/PyPy 13 October 2012
premailer now excludes pseudo selectors by default 27 May 2013
mincss in action - sample report from the wild 22 January 2013
mincss version 0.8 is much much faster 27 February 2013
This site is now 100% inline CSS and no bytes are wasted 05 March 2013
Optimizing MozTrap 04 June 2014