StianSøiland
stian at soiland.no
Tue Dec 23 02:45:36 EST 2003
On 2003-12-23 00:27:02, Jalil Feghhi wrote: > I am new to mod_python and haven't seen any examples where you can put > python code in HTML pages. Is this not supported? If not supported, is > there any way or work around (other than using the request write method) > to separate HTML writing from coding? Take a look at upcoming PSP from Mod-python 3.1.2b: http://www.modpython.org/live/mod_python-3.1.2b/doc-html/pyapi-psp.html I've also experienced some success with using template engines like Cheetah combined with mod_python. This is how we've done things using cheetah and mod_python's Publisher-handler: Made a general page template MainTemplate.tmpl: #attr title = "Default title" <html> <head> <title>$title</title> </head> <body> <h1>$title</h1> <div class="menu"> menu blabla (details left out) </div> <div class="content"> #def content No content here yet, this is just the base template #end def $content() </div> Here's a specialized page template WelcomeTemplate.tmpl #extends MainTemplate #def content Welcome to our world. Blablabla blablabla. #end def These template-files are compiled with cheetah-compile - which produces a rather nasty .py-file. This file could be imported and used from Python. In .htaccess: SetHandler mod_python PythonHandler mod_python.publisher in welcome.py: from WelcomeTemplate import WelcomeTemplate def index(req): templ = WelcomeTemplate() templ.title = "Welcome, my friend" return templ Blocks made within templates (the #def's) are callable methods from within Python, and therefore templates could be used for smaller building blocks as well. templ.content could be changed to any other template, or even a python function defined somewhere else. Model view controller ===================== In our current ongoing project, Cerebrum, we've succeeded in seperating content from control, and even seperating the model from control. This is the old MVC (model-view-controller) principle as we've used it: model controller view business logic web logic presentation logic (what to do) (what to show) (how to view) python classes python classes cheetah templates representing the for web access, ie. with calls to other data, methods each method accessed templates and for operations from the browser. helper classes in Performs operations on python model and views by calling cheetah templates. Example: ======== code is simplified, and never tested in simplified form. It will probably not work directly. The real code can be viewed on http://cvs.sourceforge.net/viewcvs.py/cerebrum/cerebrum/ under the directories Cerebrum/client and web/ - note however that the code is constantly changing at this part of the web project. Model - Cerebrum/client/BofhModel.py ------------------------------------ class Entity: def __init__(self, server): # xmlrpc-connection self.server = server def fetch_by_id(cls, server, id): # make a new instance of the called-on class, # ie. a Group or Entity entity = cls(server) entity.load_entity_info(id) return entity fetch_by_id = classmethod(fetch_by_id) def load_entity_info(self, id): self.id = id info = self.server.entity_info(id) self.type = info['type'] return info class Group(Entity): def load_entity_info(self, id): info = Entity.load_entity_info(self, id) self.name = info['name'] self.description = info['description'] return info View - web/lib/cereweb/templates/GroupViewTemplate.tmpl -------------------------------------------------------- ## Be international, import function gettext() as _() #from gettext import gettext as _ #def viewGroup(group) <h1>$_("Group") $group.name</h1> $groupInfo($group) #end def #def groupInfo(group) <div class="info"> <dl> <dt>$_("Name")</dt> <dd>$group.name</dd> <dt>$_("Description")</dt> <dd>$group.description</dd> </dl> </div> #end def MainTemplate.tmpl almost like shown in previous text. Controller - htdocs/group.py ---------------------------- from Cerebrum.web.templates.MainTemplate import MainTemplate from Cerebrum.web.templates.GroupViewTemplate import GroupViewTemplate from Cerebrum.client import BofhModel def view(req, id): # Get a generic view (menu, header, footer) page = MainTemplate() # the session and the xmlrpc server connection has been prepared by # a handler in .htaccess server = req.session['server'] # get the object from the model group = BofhModel.Group.fetch_by_id(server, id) # prepare the specialiced view view = GroupViewTemplate() # pass the model to the view page.content = view.viewGroup(group) # and return the final result (within the MainTemplate) # to the browser return page Notice how the controller is rather small and only glues together the view and the model. In this example, the model is just an xmlrpc abstraction, so even the business logic is hidden. In this case the controller actually uses two views, both MainTemplate (the menu, footer, etc.) and GroupViewTemplate. The reason for not subclassing MainTemplate into GroupViewTemplate is that we needed to pass on the chosen group object (from the Model), and that a groupview could be usable from within other views as well. -- Stian Søiland Work toward win-win situation. Win-lose Trondheim, Norway is where you win and the other lose. http://www.soiland.no/ Lose-lose and lose-win are left as an exercise to the reader. [Limoncelli/Hogan]
|