Ok, that is really nice, but when you put your form in template than you get this html fragment in the middle of you html document, and that is not a good practice. A good recommendation is to put all your CSS in head of your document (for example in HEAD), and all your javascripts on end of your html.
So what do we want? We want to all our javascripts and CSS in a context variable so we can write a our base template like:
123456789101112
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><htmlxmlns="http://www.w3.org/1999/xhtml"><head><metahttp-equiv="Content-Type"content="text/html; charset=UTF-8"/> {\% for css in forms_css \%} {\% endfor \%}
</head><body>{ %block body\%} {\%endblock\%}
{\% for js in forms_js %} {\% endfor \%}
</body></html>
With this template we get all our javascripts and CSS injected in html. Nice. But I don’t want to manually put my media files in context every time I want to render template, so I wrote a simple extension of Context (and RequestContext) class, that looks in a context dictionary and looks for any forms that are in it. And adds all javacripts and CSS to context variables forms_js (for javascript), and forms_css(for css).
1234567891011121314151617181920
classFormMediaContext(Context):''' Context that automaticly for all Forms in context adds media to context '''def__init__(self,dict=None,processors=None):Context.__init__(self,dict)contexts_values=[]map(lambdad:contexts_values.extend(d.values()),self.dicts)forms_in_context=[formforformincontexts_valuesifisinstance(form,forms.Form)]forms_js=[]forms_css=[]forforminforms_in_context:forms_js+=[mark_safe(js)forjsinform.media.render_js()]forms_css+=[mark_safe(css)forcssinform.media.render_css()]self.update({'forms_js':list(set(forms_js)),'forms_css':list(set(forms_css))})
Or if you like RequestContext more (like I do), than you can use:
1234567891011121314151617181920
classFormMediaRequestContext(RequestContext):''' Context that automaticly for all Forms in context adds media to context '''def__init__(self,request,dict=None,processors=None):RequestContext.__init__(self,request,dict,processors)contexts_values=[]map(lambdad:contexts_values.extend(d.values()),self.dicts)forms_in_context=[formforformincontexts_valuesifisinstance(form,forms.Form)]forms_js=[]forms_css=[]forforminforms_in_context:forms_js+=[mark_safe(js)forjsinform.media.render_js()]forms_css+=[mark_safe(css)forcssinform.media.render_css()]self.update({'forms_js':list(set(forms_js)),'forms_css':list(set(forms_css))})
Now all that you need to do is to render your template with FormMediaContext(or FormMediaRequestContext), and have now worries about your media files, if you have multiple entries of same file it will be rendered only once.