1 from types import StringTypes, ListType
3 from django.template.loader import render_to_string
7 # the need for js_init_chunks is because we need to have the plugins initialized
8 # before the queries fly
9 # and when writing a view it is not very easy to remember in which order
10 # all the js initialization will end up, so we use these 2 categories
11 # as a simple way to enforce this dependency
12 # far from perfect but good enough for now
15 """A class for collecting dependencies on js/css stuff
16 files are expected from your 'static' area, typically 'css/foo.css' or 'js/foo.js'
17 fragments (chunks) is for raw code
18 you can specify a string or a list of strings
19 js_init_chunks get collated with js_chunks but come first
22 keys=[ 'js_files', 'css_files', 'js_init_chunks', 'js_chunks', 'css_chunks' ]
23 def __init__ (self, js_files=None, css_files=None, js_init_chunks=None, js_chunks=None, css_chunks=None):
24 # it's tempting to use sets but sets are not ordered..
25 self.js_files = Prelude._normalize(js_files)
26 self.css_files = Prelude._normalize(css_files)
27 self.js_init_chunks = Prelude._normalize(js_init_chunks)
28 self.js_chunks = Prelude._normalize(js_chunks)
29 self.css_chunks= Prelude._normalize(css_chunks)
32 def _normalize (input):
33 if not input: return []
34 elif isinstance (input, ListType): return input
35 elif isinstance (input, StringTypes): return [ input ]
36 else: return list (input)
38 def add_js_files (self, x):
39 for i in Prelude._normalize (x):
40 if i not in self.js_files: self.js_files.append(i)
41 def add_css_files (self, x):
42 for i in Prelude._normalize (x):
43 if i not in self.css_files: self.css_files.append(i)
44 def add_js_init_chunks (self, x):
45 self.js_init_chunks += Prelude._normalize (x)
46 def add_js_chunks (self, x):
47 self.js_chunks += Prelude._normalize (x)
48 def add_css_chunks (self, x):
49 self.css_chunks += Prelude._normalize (x)
51 def inspect_string (self,msg):
52 result = 'Prelude.inspect %s (%s) with '%(msg,self)
53 result += ",".join( [ "%s->%s"%(k,len(getattr(self,k))) for k in Prelude.keys ] )
55 def inspect (self,msg):
56 print self.inspect_string(msg)
58 # first attempt was to use a simple dict like this
60 # env['js_files']= self.js_files
61 # env['css_files']= self.css_files
62 # env['js_chunks']= '\n'.join(self.js_chunks)
63 # env['css_chunks']='\n'.join(self.css_chunks)
65 # together with this in prelude.html
66 # {% for js_file in js_files %} {% insert_str prelude js_file %} {% endfor %}
67 # {% for css_file in css_files %} {% insert_str prelude css_file %} {% endfor %}
68 # somehow however this would not work too well,
69 # probably insert_above is not powerful enough to handle that
71 # so a much simpler and safer approach is for us to compute the html header directly
72 # this requires to filter on full urls
76 if input.startswith("http://") or input.startswith("https://"):
79 from myslice.settings import STATIC_URL
80 return "%s%s"%(STATIC_URL,input)
82 def prelude_env (self):
84 env['js_urls'] = [ Prelude.full_url (js_file) for js_file in self.js_files ]
85 env['css_urls'] = [ Prelude.full_url (css_file) for css_file in self.css_files ]
86 env['all_js_chunks']= self.js_init_chunks + self.js_chunks
87 env['css_chunks']=self.css_chunks
89 print "prelude has %d js_files, %d css files, (%d+%d) js chunks and %d css_chunks"%\
90 (len(self.js_files),len(self.css_files),len(self.js_init_chunks),len(self.js_chunks),len(self.css_chunks),)
91 # render this with prelude.html and put the result in header_prelude
92 header_prelude = render_to_string ('prelude.html',env)
93 return { 'header_prelude' : header_prelude }