July 19th, 2006 posted by Bender Rodríguez
Wherein we discuss the annals of creating a very handy template protocol for a custom CMS, allowing the end user to use templates from the database or from the file system
although the kind folks in the django community who hang out at the google groups water cooler argued that it would be rather easy to develop a template loader that renders pages from templates stored in a database, and that in fact the django loader system and template architecture were designed with just this scenario in mind, it was not as easy as i had hoped. in the end, however, i learned a great many things about the django rendering system from templates to custom template tags to context processors to the inner workings of Django's Context and RequestContext classes.
the template loader
first i had to create a template loader. i based the code on the hugo's incantations contained in his util bundle aptly named "stuff". very nice. as it was based on an ancient django dialect now only spoken by the old ones, i had to translate some of the code to work with the current development branch. not much problem there, and since i already had my database model for storing the pages, page parts, layouts, and snippets based on the radiant cms data model, i thought that i had a pretty good head start. all was going well, i was able to pull a template out of the database and render a page in the public portion of the website, until i tried to access the admin site. massive errors everywhere thrown by the Layout class, which was claiming that the selected query returned no results. i still do not have a firm grasp on how the template loader system actually works, but it certainly does not work as described in the documentation, which states that the loader will go through the list of template loaders and try to find a template match. when it fails to find one in the first one, go on to the second one, etc. in the end, if no template is found, then throw an exception. one my custom database loader could not find a template, it would throw an exception and that was the end of the process, despite the presence of a try/catch/except structure that should handle the exception properly, throwing a TemplateDoesNotExist exception which simply passes control on to the next step.
anyway, once i accepted that this was a problem out of my control and that since no one responded to my post to the groups about it i was affraid that it was in fact a flaw in my algorithm, a flaw which i was not and still cannot detect, i moved on to the next part of the problem, which when fixed would render moot the previous problem. for some reason, the database loader was not finding the admin templates in the database (which is logical since they are not stored there but are stored in the file system in the django source) and throwing an exception and dying when it could not find said templates. so i was all like, right, we'll just tell the database loader never to look for admin templates:
path = name.split ( '/' )
if path[0] != 'admin' and path[0] != 'widget':
"name" is the name of the template with path information (e.g. admin/base_site.html). i'll come back to the "widget" bit in a moment. anyway, that worked out just fine, until you want to do anything that is dynamically rendered from your models. lists worked fine, but edit/add and a few other things i can't remember at the moment, all caused the database loader to throw an exception claiming that it could not find the template. after hours of combing through the debug code spewed out by django (a very useful bit of spew by the way, once you learn how to read it) and following the path of execution calls, i discovered that django was looking for some widget templates that did not exist in the database either. anyway, adding the above && logic in the IF statement solved the problem and i have not looked back since, although i should one day, but not now. teehee.
0 Comments,
0 trackbacks
(Trackback URL)
"Everybody believes in something and everybody, by virtue of the fact that they believe in something, use that something to support their own existence."
Frank Zappa