Question

What’s the best way to keep related files together in Django?

In addition to our HTML templates, most views have at least one additional JavaScript file, and possibly an additional CSS file. For example:

  • item_detail.html
  • item_detail.js
  • item_detail.css

We want to keep these files side-by-side if possible, so we don't have to look in two or three directories to find them.

Update: I do know that it’s dumb to defeat caching and that’s not what I’m asking. Each page loads several JavaScript and CSS items that are properly cached. For example:

<!-- at top of file -->
<link rel="stylesheet" href="/master/css/site-main.css">

<!-- at bottom of file -->
<script type="text/javascript" src="/master/js/jquery.js"></script>
<script type="text/javascript" src="/master/js/site-main.js"></script>

That part is fine.

In addition to this, each page loads page-specific JavaScript and CSS:

<link rel="stylesheet" href="/static/css/widgets/item_detail.css">
<script type="text/javascript" src="/static/js/widgets/item_detail.js"></script>

In this example, item_detail.js would have event handlers that are needed on the item detail page (only).

Unfortunately this means that I now have several parallel directory structures for this view:

  • my_site
    • widgets
      • item_detail.htmlThis is the view
    • static
      • css
        • item_detail.cssThis is the view-specific CSS
      • js
        • item_detail.jsThis is the view-specific JavaScript

What I want is this:

  • my_site
    • widgets
      • item_detail.htmlThis is the view
      • item_detail.cssThis is the view-specific CSS
      • item_detail.jsThis is the view-specific JavaScript

Due to the way views work in Django, it’s not clear to me that this is possible.

Was it helpful?

Solution

If you are just organizing stuff for development, you can symlink you template dir with all template, css and js files to directory you are serving static files too.

So from your example: add my_site/widgets to Django TEMPLATE_DIRS config and cp -s my_site/widgets to directory you have your static files in.

This is dirty hack and, please, don't use it in production as it is very insecure IMHO. But if you want to have neatly organized project in development stage - then I see this as one possible solution.

And also consider that this might give you loads of headache when you move from development to production as stuff WILL fail.

OTHER TIPS

I agree with freiksenet. A solution to the problem he adresses could be aggregating the various css and js files. The whole site then uses just one css and one js file. The first load would be higher, yes, but a big part of the speed of a site is in downloading files, and if caching is done right, aggregation of these files helps imho.

I unfortunately don't have an answer to your main question.

I keep javascript in files separated by function and combine them into a single minified js file with a pre-commit hook (right after the tests run).

for example: I have several jquery-ui dialogs on the site I'm currently working on. Each dialog's functionality is broken off into it's own js file for maintainability. And all the needed js files are "included" on the development pages using a short base.js file like so:

function include(filename) {
    document.write(unescape("%3Cscript src='" + filename + "' type='text/javascript'%3E%3C/script%3E"));
}

// include-js (external)
include('/site_media/jquery-plugin1.js');
include('/site_media/js-sources/dialog1.js');

my pre-commit hook does a regex on this file...

include\('/site_media/(.*)'\);

and feeds all the files into YUI compressor.

So I guess the answer to your question is... I put them wherever makes sense to me logically, because on the live site, it'll all be in the minified JS file(s) anyway

You don't want to have your templates available as static files -- they may contain sensitive information or details about the page's implementation which are not appropriate for the public to see.

CSS and JS do not have to be segregated into separate directories -- simply place them in the static/ directory.

  • my_site/
    • widgets/
      • item_detail.html
    • static/
      • item_detail.css
      • item_detail.js

One approach I’m testing:

  • my_site/
    • widgets/
      • item_detail.html
      • item_detail.css
      • item_detail.js

These are not shared statically. Instead, in the HTML template:

<script type="text/javascript" charset="utf-8">
    {% include "widgets/item_detail.js" %}    
</script>

(Similar code for CSS.) I would only do this for page-specific JavaScript and CSS, not site-wide stuff that can benefit from caching.

This dumps the actual JavaScript and/or CSS right into the template, yet allows me to keep them in separate files for development purposes. This is nice, development-wise but defeats some JavaScript and CSS caching, but only for page-level stuff that’s not re-used on any other page.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top