tags:

views:

264

answers:

4

Lets say we want a library of javascript-based pieces of functionality (I'm thinking jquery): For example:

  1. an ajax dialog
  2. a date picker
  3. a form validator
  4. a sliding menu bar
  5. an accordian thingy

There are four pieces of code for each: some Python, CSS, JS, & HTML.

What is the best way to arrange all these pieces so that:

  • each javascript 'module' can be neatly reused by different views
  • the four bits of code that make up the completed function stay together
  • the css/js/html parts appear in their correct places in the response
  • common dependencies between modules are not repeated (eg: a javascript file in common)

x--------------

It would be nice if, or is there some way to ensure that, when called from a templatetag, the templates respected the {% block %} directives. Thus one could create a single template with a block each for CSS, HTML, and JS, in a single file. Invoke that via a templatetag which is called from the template of whichever view wants it. That make any sense. Can that be done some way already? My templatetag templates seem to ignore the {% block %} directives.

x--------------

There's some very relevant gasbagging about putting such media in forms here http://docs.djangoproject.com/en/dev/topics/forms/media/ which probably apply to the form validator and date picker examples.

+1  A: 

If more than one page uses a given JS file you should consider concatenating all of them together and minifying the result. This reduces net connects which will improve overall page load time. Don't forget to bump your expire time out to at least a week or two.

Peter Rowell
Thanks Peter. There are js compression routines out there which might be a handy afterthought in a piece of Response Middleware; however this question is about how best to lay out a django project to ease having lots of javascript in the responses without headache from the source getting chaotic. I'm expecting 'includes' and 'templatetags' will be involved somehow.
John Mee
You're right: I had a conversation in my head and only gave you half of it. We tried going the 'use templates to include only the JS files for any given page' route, but within two clicks the user would have sucked down 95% of them anyway. Rather than eat all of those separate downloads and having to deal with the messiness of making sure each page included the right things, we tried shoving all of it into one concatenated file and minifying it. The result was surprisingly small and we then just put the link-tag in the base template. Done.
Peter Rowell
I agree with Peter here -- It is probably easier to just to concatenate them together and let the user download them all at once. Look at django-assets as an easy way to manage the concatenating: https://launchpad.net/django-assets
sheats
A: 

I think you are going to have a hard time keeping all four pieces together and applying them in a fell swoop - simply because some appear in your <head> tags and others in the <body> tags.

What have done is made sure that jQuery is loaded for all pages on my base.html (as well as my base css file) ... then, I have block tags for {% block css %} and {% block js %}. Templates that inherit the base.html file can supply their own javascript and css (and only the stuff that is needed).

I have created some template tags that create ajax functions whose output is based on the object being displayed (for example, including the object_id) -- which cuts down on re-coding.

One thing I haven't tried but am interested in is django-compress.

thornomad
A: 

"How to manage Javascript modules in django templates?" I know, I know! Answer: very hard.

ja
+2  A: 

Been a while since I posted this problem. What I've been doing to solve it is:

  1. write the javascript parts you need as a library which is served statically
  2. call the routines in the static library from the template with your server side values

Restraint is required to write it in such a way that it acts as a client side script only; don't be tempted to try and inject values from the server at the time of serving the js. Ultimately I've found it less confusing to apply server side variables strictly in the html template.

In this way I'm able to:

  1. keep the javascript selectors on html tags inside the same file (ie: the template)
  2. avoid templatetags altogether
  3. re-use each javascript library in different places, and
  4. keep the css/js/html pieces in all the places where they're expected to be found

It's not perfect, but it's getting me by till a neater idea comes along.

For example a js library in "media/js/alertlib.js" might include:

function click_alert(selector, msg){ 
    $(selector).click(function(){ alert(msg) })
}

and the template has:

<script type="text/javascript" src="media/js/alertlib.js"></script>
<script type="text/javascript">
    click_alert('#clickme', {% message %})
</script>

<div id='clickme'>Click Me</div>
John Mee