peritus / django_templatecomponents

A django application that makes it easy organize your component source (javascript, css) right in your django templates to to make your website much faster.

This URL has Read+Write access

README.rst

django-templatecomponents

Author: Filip Noetzel
Version: v0.03
Web:http://j03.de/projects/django-templatecomponents/
Git:git clone http://j03.de/git/django-templatecomponents.git/ ( browse, also on github)
Download:django-templatecomponents.tar.gz

A django application that makes it easy to organize your component source (JavaScript, CSS) in your django templates.

Overview

Define your JavaScript and CSS source right beneath the HTML skeleton that it's used on:

template.html:

System Message: ERROR/3 (<string>, line 24)

Unknown directive type "sourcecode".

.. sourcecode:: html+django

  {% css print %}
    a[href]:after{
      content: " [" attr(href) "] ";
    }
  {% endcss %}

  {% css screen print %}
    #clickme { font-weight: bold; }
  {% endcss %}

  {% js client %}
    document.getElementById('clickme').onclick = function() {
      alert('Ugh! I have been clicked');
    }
  {% endjs %}

  <a id='clickme' href="/click/">Click me</a>

This would result in

print.css:

System Message: ERROR/3 (<string>, line 48)

Unknown directive type "sourcecode".

.. sourcecode:: css

    /* extracted css from template '/path/to/template.html' with groups print */
    a[href]:after{
      content: " [" attr(href) "] ";
    }
    /* extracted css from template '/path/to/template.html' with groups print screen */
    #clickme { font-weight: bold; }

screen.css:

System Message: ERROR/3 (<string>, line 59)

Unknown directive type "sourcecode".

.. sourcecode:: css

    /* extracted css from template '/path/to/template.html' with groups print screen */
    #clickme { font-weight: bold; }

client.js:

System Message: ERROR/3 (<string>, line 66)

Unknown directive type "sourcecode".

.. sourcecode:: javascript

    /* extracted css from template '/path/to/template.html' with groups client */
    document.getElementById('clickme').onclick = function() {
      alert('Ugh! I have been clicked');
    }

Benefits

Serve your components from one file

(see also rule #1)

You can arrange your template component blocks in (multiple) groups, to access them by different urls (Here, print.js will contain the concatenated content of the first two blocks).

One can imagine groups for

  • printing CSS
  • screen CSS
  • presentation CSS
  • additional CSS and JavaScript for authenticated / paying users
  • CSS for browers with enabled or disabled JavaScript
  • CSS and JavaScript for mobile devices
  • CSS and JavaScript for legacy browsers
  • Splitting the initial payload
  • Splitting JavaScript in 25K-Slices for the iPhone

Usage

Static file generation

While you want your template components be processed on the fly while developing, you can generate static files from your template components upon each deployment:

System Message: ERROR/3 (<string>, line 107)

Unknown directive type "sourcecode".

.. sourcecode:: default

  $ ./manage.py generate_templatecomponents
  Generating print.css
  Generating screen.css
  Generating screen.js

Priority based block dependency

Some CSS Rules and JavaScript might depend on each other (Specific CSS rules override basic CSS Rules; some of your JavaScript depends on your favorite ajax library).

Each block can have a priority, the following example illustrates this:

template1.html:

System Message: ERROR/3 (<string>, line 125)

Unknown directive type "sourcecode".

.. sourcecode:: js+django

  {% js xlib 5 %} x = x + 1; {% endjs %}

template2.html:

System Message: ERROR/3 (<string>, line 131)

Unknown directive type "sourcecode".

.. sourcecode:: js+django

  {% js xlib 10 %} var x = 1; {% endjs %}

This would ensure, the javascript block from template2.html appears above the one from template1.html:

xlib.js:

System Message: ERROR/3 (<string>, line 140)

Unknown directive type "sourcecode".

.. sourcecode:: javascript

  /* extracted javascript from '/path/to/template2.html' with priority 10 with groups screen*/
  var x = 1;

  /* extracted javascript from '/path/to/template1.html' with priority 5 with groups screen*/
  x = x + 1;


It is recommended to give a high priority for JavaScript libraries, a lower for custom built library code and a very low priority for custom code snippets.

Including external libraries

You can easily include additional static files (like JavaScript libraries, CSS frameworks, ..), by specifying them in your settings.py:

System Message: ERROR/3 (<string>, line 158)

Unknown directive type "sourcecode".

.. sourcecode:: python

  TEMPLATECOMPONENTS_ADDITIONAL = {
      os.path.join(MEDIA_ROOT, 'js/prototype.js'):     'js 10 script',
      os.path.join(MEDIA_ROOT, 'js/scriptaculous.js'): 'js 9 script',
      os.path.join(MEDIA_ROOT, 'js/effects.js'):       'js 8 script',
      # ..
  }

This way, you can avoid putting third party code in your templates/ directory and adding django template tags in the first and last line.

Preprocessing JavaScript and CSS with Django Templates

You can use every aspect of the django template language and all the builtin template tags and filters.

However, the context that is available within the templatecomponent-tags only contains settings (with the contents of your settings.py).

Note

The {% css %} and {% js %} blocks are evaluated once at deployment time, when you generate the static files.

Examples

Settings-dependent inclusions

System Message: ERROR/3 (<string>, line 194)

Unknown directive type "sourcecode".

.. sourcecode:: js+django

  {% js script %}
    var pageTracker = _gat._getTracker("{{ settings.GOOGLE_ANALYTICS_KEY }}");
    pageTracker._trackPageview();
  {% js %}

Debug-build

System Message: ERROR/3 (<string>, line 204)

Unknown directive type "sourcecode".

.. sourcecode:: js+django

  {% js script %}
    var complex = function() {
      {% if settings.debug %}
        console.log("Complex function invoked");
      {% endif%}
      var x = 5;
      // very complex code..
    }
  {% js %}

CSS Variables

System Message: ERROR/3 (<string>, line 219)

Unknown directive type "sourcecode".

.. sourcecode:: css+django

  {% css style %}
    body {
      background-color: {{ settings.colors.background }};
    }
  {% endcss %}

Installation

Download

Using git:

System Message: ERROR/3 (<string>, line 235)

Unknown directive type "sourcecode".

.. sourcecode:: bash

  git clone http://j03.de/git/django-templatecomponents.git/

Using tarball:

System Message: ERROR/3 (<string>, line 241)

Unknown directive type "sourcecode".

.. sourcecode:: bash

  curl 'http://j03.de/git/?p=django-templatecomponents.git;a=snapshot;sf=tgz' > django-hashedmedia.tar.gz
  tar -xvzf django-templatecomponents.tar.gz
  rm django-templatecomponents.tar.gz

Put the folder django-templatecomponents somewhere in your $PYTHONPATH (presumably your project folder, where your manage.py lives).

Configuration

Adopt your development urls.py like this:

System Message: ERROR/3 (<string>, line 255)

Unknown directive type "sourcecode".

.. sourcecode:: python

  if settings.DEBUG:
      urlpatterns += patterns('',
          (r'^static/(?P<path>.*\.(js|css))$', 'templatecomponents.views.generate'),

          # make sure to have the above rule before your
          # django.views.static.serve rule

          (r'^static/(?P<path>.*)$', 'django.views.static.serve', {
            'document_root': settings.MEDIA_ROOT
          }),
      )

Misc

Syntax highlighting in vim

To get the syntax highlighting for the (now embedded) css and javascript in vim, create a file at ~/.vim/after/syntax/htmldjango.vim with the following contents:

System Message: ERROR/3 (<string>, line 278)

Unknown directive type "sourcecode".

.. sourcecode:: vim

  syn region javaScript start=+{% js+ keepend end=+{% endjs %}+me=s-1 contains=@htmlJavaScript,htmlCssStyleComment,htmlScriptTag,@htmlPreproc
  syn region cssStyle start=+{% css+ keepend end=+{% endcss %}+ contains=@htmlCss,htmlTag,htmlEndTag,htmlCssStyleComment,@htmlPreproc

What next ?

License

django-templatecomponents is licensed as Beerware, patches (including documentation!) and suggestions are welcome.