Login

Template tag for compressed CSS & JS (GAE version)

Author:
jeffar
Posted:
June 30, 2008
Language:
HTML/template
Version:
Not specified
Tags:
templatetag google-app-engine
Score:
0 (after 0 ratings)

Extension of the idea from WuzHere example from Google IO about creating one compressed js or css file. Original code used not very elegant if statements. I've changed it to template tags. On production server it will also use current version id.

Insert code in cssjs.py file in templatetags dir in your application and use as below (more details in docs):

<script type="text/javascript" src="/media/jsmergefile.js"></script>

This code does not compress CSS and JS on the fly, because GAE is read-only and using Datastore is too heavy.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
from django import template
from django.conf import settings
import os

register = template.Library()

def add_vid_to_filename(filename, vid=os.getenv('CURRENT_VERSION_ID', None)):
    """
    Add current version id to passed filename in form:
    filename.ext -> filename.VID.ext
    """
    if not vid:
        return filename
    file_ext = filename.rsplit('.',1)
    if len(file_ext) < 2:
        return file_ext[0]+'.'+vid
    return '.'.join((file_ext[0],vid, file_ext[1]))

def css(parser, token):
    """
    This will use merged css files on production or original ones on development server.

    Usage::

        {% load cssjs %}
        {% css media all.css cssfile1 [cssfile2] .. %} 

    If the code is working on development server, the tag will create several links
    with cssfile1 [cssfile2] etc.
    
    If the code is run on production server, the tag will use all.css and will insert
    version id before file exension.
    
    The HTML output for this will be::

        <link media="all" rel="stylesheet" href="/media/all.1.1.css" type="text/css" />
    """
    tokens = token.contents.split()
    if len(tokens) < 4:
        raise template.TemplateSyntaxError(u"'%r' tag requires at least 3 arguments." % tokens[0])
    if 'Dev' in os.getenv('SERVER_SOFTWARE'):
        return template.TextNode('\n'.join(['<link media="%s" rel="stylesheet" href="%s%s" type="text/css" />' % (tokens[1], settings.MEDIA_URL, css) for css in tokens[3:]]))
    else:
        return template.TextNode('<link media="%s" rel="stylesheet" href="%s%s" type="text/css" />' % (tokens[1], settings.MEDIA_URL, add_vid_to_filename(tokens[2])))

def js(parser, token):
    """
    This will use merged js files on production or original ones on development server.

    Usage::

        {% load cssjs %}
        {% js all.js jsfile1 [jsfile2] .. %} 

    If the code is working on development server, the tag will create several links
    with cssfile1 [cssfile2] etc.
    
    If the code is run on production server, the tag will use all.js and will insert
    version id before file extension.
    
    The HTML output for this will be::
    
        <script type="text/javascript" src="/media/all.1.1.js"></script>
    """
    tokens = token.contents.split()
    if len(tokens) < 3:
        raise template.TemplateSyntaxError(u"'%r' tag requires at least 2 arguments." % tokens[0])
    if 'Dev' in os.getenv('SERVER_SOFTWARE'):
        return template.TextNode('\n'.join(['<script type="text/javascript" src="%s%s"></script>' % (settings.MEDIA_URL, css) for css in tokens[2:]]))
    else:
        return template.TextNode('<script type="text/javascript" src="%s%s"></script>' % (settings.MEDIA_URL, add_vid_to_filename(tokens[1])))

register.tag('css', css)
register.tag('js', js)

More like this

  1. head inclusion middleware by bowdengm 6 years, 6 months ago
  2. Templatetag for JS merging and compression by msaelices 8 years ago
  3. YUI Loader as Django middleware by akaihola 7 years, 4 months ago
  4. Template tags to integrate with modconcat by matthanger 6 years, 1 month ago
  5. A dict template tag by Batiste 7 years, 4 months ago

Comments

dtauzell (on June 30, 2008):

The documentation for the 'css' method doesn't look quite right:

[HTML_REMOVED]

Shouldn't the url be /media/css/all.1.1.css?

#

jeffar (on July 1, 2008):

I've fixed the doc strings and also badly placed 'not' in css function.

@Peritus: I agree that your version is great and I my try it but I really want version IDs, because other way with far future expire (also one of the 14 rules) your user's browser may use outdated CSS or JS if not use Ctrl+F5 keys.

#

phxx (on July 2, 2008):

Can you please use the "python" syntaxhilightning and not the HTML one.

#

Please login first before commenting.