|
Re: Modular Temptales: msg#00049python.cheetah
Alex J. Champandard wrote:
move you data access code / business logic to specific modules and use the "split hierarchy approach" already suggested not too long ago, and first reported here (i think) by peter lyons. i've started to use it recently for a personal project (soon on-line), i've done a couple of minor changes to original proposal, but the concept is the same, basically: 1) wrote your servlet tree hierarchy, you known, the main SitePage.py servlet and the subclasses. 2) wrote your cheetah templates hierarchy, possibly with a SiteTemaplate as baseclass, so you can specify in a WYSIWYG HTML editor all the basic elements of your page (header, footer, nav bars, etc.), also delegate presentational details to CSS helps a lot to keep the HTML clean. 3) allow the SitePage to dinamically import a given template and let SitePage to pass itself to that template, doing this in the template you have access to the entire servlet fields/method. i keep the templates and the servlets on the same folder, other may have different setup but often a subfolder is needed to keep things in order and having everything on the "same level" helps to find out correct modules to load (see setTemplate method below). here there's a portion of my SitePage.py (some code removed for clarity): class SitePage(Page): """Base site page""" def __init__(self): Page.__init__(self) self._templatePath = None self._templateDef = None def setTemplate(self, templateDef): # 1. context.somedir.someservlet --> # 2. context.somedir --> # 3. context.somedir.some_tmpl modulePath = self.__module__.split('.')[:-1] modulePath.append(templateDef) self._templatePath = '.'.join(modulePath) self._templateDef = templateDef def awake(self, transaction): Page.awake(self, transaction) self.onLoad() def onLoad(self): """Called at every servlet request. Subclasses can optionally override it.""" pass ## Content methods ## def writeHTML(self): # do we have a template for this page? if no, use default template = self._templateDef and self.loadTemplate() or self.__defaultTemplate # pass caller servlet as _ var template._ = self template.respond(self.transaction()) def loadTemplate(self): module = __import__(self._templatePath, globals(), locals(), self._templatePath) klass = getattr(module, self._templateDef) return klass() ## Default template ## __defaultTemplate = Template(source=''' <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>Blah</title> </head> <body> you forgot to specify a servlet template. </body> </html> ''') so a servlet of my site that inherits from SitePage looks like this: import blogdb # data access module from SitePage import SitePage class index(SitePage): """Show last published entry""" def onLoad(self): self.setTemplate('index_tmpl') # get last published entry self.entry = blogdb.getEntries(1, 1)[0] setTemplate will load up "index_tmpl" file (a compiled cheetah tmpl). index_tmpl inherits from SitePage_tmpl.html, defined as follows: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>$_.title</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> <link href="/WK/site.css" rel="stylesheet" type="text/css"> </head> <body> <div id="main"> <div id="header"> <h1>deelan.com</h1> </div> <!-- content --> <div id="content"> #block content ***dynamic content goes here*** #end block <p id="copyr">Copyright © 2003. Site powered by <a href="http://www.python.org/">Python</a> ...</p> <!-- /content --> </div> <div id="sidebar"> <!-- sidebar code --> </div> <!-- main --> </div> </body> </html> note that "#block content" will be replaced by subclasses. finally the index_tmpl.html looks like: <!-- #from SitePage_tmpl import SitePage_tmpl #extends SitePage_tmpl --> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <title>index_tmpl</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> </head> <body> <div id="content"> #def content <h2>$_.entry.title</h2> $_.entry.htmlContent #end def </div> </body> </html> with "#def content" i replace "#block content" of the superclass (SitePage_tmpl). note that it's perfectly valid for a servlet to have one, two or more output templates, maybe the choice can be driven by a query string / python code / POST param. also note that a template is not forced to inherit from SitePage_tmpl, it could inherit from a different base tmpl class (incidentaly we are moving to a sort of model-view-controller approach). yes, this approach force you to pre-compile all the tmpl file i usually run a batch file), but i'm planning to tweak "loadTemplate" and allows dinamic compiling of tmpl ...at least for subclasses. it's not difficult to check date/time of "index_tmpl.py" against "index_tmpl.html" and see if it needs to be recompiled. __import__ could be used when the site in published, compiling could be performed while developing the app. but these are only ramdom thoughts. i still have to look at the implementation details. hope this helps. later, deelan ------------------------------------------------------- This SF.net email sponsored by: Enterprise Linux Forum Conference & Expo The Event For Linux Datacenter Solutions & Strategies in The Enterprise Linux in the Boardroom; in the Front Office; & in the Server Room http://www.enterpriselinuxforum.com
|
|
| <Prev in Thread] | Current Thread | [Next in Thread> |
|---|---|---|
| Previous by Date: | Re: Custom Directive Delimiter, Aaron Held |
|---|---|
| Next by Date: | win2003 test fails, Gerry |
| Previous by Thread: | Re: Modular Temptales, Alex J. Champandard |
| Next by Thread: | win2003 test fails, Gerry |
| Indexes: | [Date] [Thread] [Top] [All Lists] |
| News | FAQ | advertise |