Inspired by http://www.djangosnippets.org/snippets/712/
This loads in css and javascript files where you want them (usually in the head) - but allows you to put them anywhere in your code - i.e. in a TemplateTag.
so your head code will look like this:
<head>
...
<!-- HEAD_init -->
...
</head>
then somewhere in your templates you can load in javascript or css files like so:
<!-- HEAD_include myfile.js myotherfile.css -->
It automatically checks if you've already included the files, and only puts them in once. It automatically figures out if its a javascript or css file by the file name - If you have an irregular filename (i.e. a google maps api script url) you can force it by using either of the following tags:
<!-- HEAD_include_js [my javascript file] -->
<!-- HEAD_include_css [my css file] -->
Or you can write inline code to get rendered in the head:
<!-- HEAD_render
<script>
someJavascriptCall();
</script>
-->
Todo: make it compress the js into one file...
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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | import re
from django.conf import settings
DEFAULT_JS_TAG = '<script type="text/javascript" src="%s"></script>'
DEFAULT_CSS_TAG = '<link rel="stylesheet" type="text/css" href="%s" />'
DEFAULT_JS_DIR = 'js'
DEFAULT_CSS_DIR = 'css'
HEAD_BASE = getattr(settings, 'HEAD_INCLUDE_BASE', settings.MEDIA_URL)
PREFIX_RE = getattr(settings, 'HEAD_INCLUDE_PREFIX_RE', '<!-- *HEAD_')
SUFFIX_RE = getattr(settings, 'HEAD_INCLUDE_SUFFIX_RE', ' *-->')
TAGS = {'js': getattr(settings, 'HEAD_INCLUDE_JS_TAG', DEFAULT_JS_TAG),
'css': getattr(settings, 'HEAD_INCLUDE_CSS_TAG', DEFAULT_CSS_TAG)}
PATHS = {'js':'js/', 'css':'css/'}
HEAD_RE = re.compile(
r'%s(include|version|include_js|include_css|render) +([\s\S]*?)%s' % (PREFIX_RE, SUFFIX_RE))
HEAD_INIT_RE = re.compile(
'%sinit%s' % (PREFIX_RE, SUFFIX_RE))
class HeadLoader:
def __init__(self):
self._components = []
self._js_components = []
self._css_components = []
def add_component(self, new_component_name, component_type = ''):
if component_type == 'js' and not new_component_name in self._js_components:
self._js_components.append(new_component_name)
elif component_type == 'css' and not new_component_name in self._css_components:
self._css_components.append(new_component_name)
elif component_type == '' and not new_component_name in self._components:
self._components.append(new_component_name)
def render(self):
#self._components.reverse()
head = ''
head += '\n' + '\n'.join(self._render_component(component, 'css') for component in self._css_components)
head += '\n' + '\n'.join(self._render_component(component, 'js') for component in self._js_components)
head += '\n' + '\n'.join(self._render_component(component) for component in self._components)
return head
def _has_component(self, component_name):
return component_name in self._components
def _render_component(self, component_name, component_type = ''):
if component_type == '':
# check what sort of component this is - based on the file name either ending with .js or .css
last_three = component_name[-3:]
if last_three == '.js':
component_type = 'js'
elif last_three == 'css':
component_type = 'css'
else:
# we don't know what to do with anything else!
return '<!-- HEAD - unknown compoent type : %s -->' % component_name
# check if we've got an absolute or external js or css file
if component_name[:7] == 'http://' or component_name[:1] == '/':
return TAGS[component_type] % (component_name,)
else:
return TAGS[component_type] % (HEAD_BASE + PATHS[component_type] + component_name,)
class HeadIncludeMiddleware(object):
def process_response(self, request, response):
components = []
js_components = []
css_components = []
extra_head = []
node = HeadLoader()
def collect(match):
cmd, data = match.groups()
if cmd == 'include':
components.extend(data.split())
elif cmd == 'include_js':
js_components.extend(data.split())
elif cmd == 'include_css':
css_components.extend(data.split())
elif cmd == 'render':
extra_head.append(data)
else:
return '<!-- UNKNOWN COMMAND HEAD_%s -->' % cmd
return ''
content = HEAD_RE.sub(collect, response.content)
for component in components:
node.add_component(component)
for component in js_components:
node.add_component(component, 'js')
for component in css_components:
node.add_component(component, 'css')
rendered = node.render() + '\n'.join(extra_head)
content = HEAD_INIT_RE.sub(rendered, content, 1)
response.content = HEAD_INIT_RE.sub(
'<!-- WARNING: MULTIPLE HEAD_init STATEMENTS -->', content)
return response
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
- Help text hyperlinks by sa2812 1 year, 7 months ago
Comments
Markup for the YUI snippet link seems to be reversed.
#
Please login first before commenting.