[mod_python] Re: FW: Any way to embed Python in HTML?

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]



More information about the Mod_python mailing list