Graham Dumpleton
grahamd at dscpl.com.au
Fri Oct 27 23:32:35 EDT 2006
On 28/10/2006, at 7:44 AM, Sebastian Celis wrote: > Hello, > > I am new to this list and have just recently begun to work on a > project where I wish to use mod_python.publisher and cheetah to drive > an entire web application. I apologize if the following topics have > been discussed to death recently, but I have read through the > documentation on both sites and have searched through the mailing-list > archives and while I have seen similar discussions, I have yet to find > definitive answers. I am able to get most things to work, however I > can't help but feel that there are better ways of approaching some of > my situations. > > First, I'll quickly describe my directory structure: > > /var/www/app -- The base directory to the web application. This will > directly contain most of the python files that correspond directly to > URLs. For example, index.py, login.py, etc. In this directory. > /var/www/app/templates -- Contains all of my cheetah templates. > /var/www/app/include -- Contains the python utility modules I am > writing specifically for this application. > > Now, onto the questions. > > > 1) Importing compiled cheetah templates > > Assume I have code like the following in /var/www/app/test1.py > > ###################################### > from mod_python import apache > from Cheetah.Template import Template > > def index(req): > req.content_type = "text/html" > > dict = {'title': 'My Title!', 'message': 'Hello world!'} > templateModule = apache.import_module("templates/myTemplate") Using '/' in the module name like this is not portable and is dependent on peculiarities of the behaviour of Python on a specific platform. It will not for example work on Mac OS X and also possibly not on Windows. > t = getattr(templateModule, "myTemplate")() > searchList = t.searchList() > searchList.insert(0, dict) > > return(t.respond()) > ###################################### > > Is this the best way to import template modules and then evaluate > them? No, in as much as you are having to create a parallel hierarchy of publisher handlers for each Cheetah page. You would be better off using a custom handler which does the dispatch direct to the compiled Cheetah template classes. See the mod_python handler described in: http://wiki.cheetahtemplate.org/cheetah-recipes.html > 2) Modifying PythonPath prevents modules from being imported > > Inside file /var/www/app/test2.py, I have the following code: > > import config > (or) > config = apache.import_module("config") > > Both of these commands load /var/www/app/config.py, and seem to work > fine. However, if I add > > PythonPath "['/var/www/app/templates']+sys.path" > > to my apache configuration, I get an error next time I run test2.py. > > ### > Mod_python error: "PythonHandler mod_python.publisher" > > Traceback (most recent call last): > > File "/usr/lib/python2.4/site-packages/mod_python/apache.py", line > 299, in HandlerDispatch > result = object(req) > > File "/usr/lib/python2.4/site-packages/mod_python/publisher.py", > line 213, in handler > published = publish_object(req, object) > > File "/usr/lib/python2.4/site-packages/mod_python/publisher.py", > line 412, in publish_object > return publish_object(req,util.apply_fs_data(object, req.form, > req=req)) > > File "/usr/lib/python2.4/site-packages/mod_python/util.py", line > 439, in apply_fs_data > return object(**args) > > File "/var/www/app/test2.py", line 8, in index > config = apache.import_module("config") > > File "/usr/lib/python2.4/site-packages/mod_python/apache.py", line > 461, in import_module > f, p, d = imp.find_module(parts[i], path) > > ImportError: No module named config > ### > > Why does this initially work but then stop working once I add a > directory to my path? I can fix it by adding '/var/www/app' to my > PythonPath as well, but I don't understand why it didn't work before > that. That is just how mod_python has always worked. Setting PythonPath stops mod_python looking in the directory the handler was specified for. Yes it is a pain. FWIW, this behaviour changes in mod_python 3.3 where the whole issue of module importing is dealt with a bit differently and is much more consistent and predictable. Current versions of mod_python have a lot of issues when it comes to the module importer. You should really have a read of: http://www.dscpl.com.au/wiki/ModPython/Articles/ ModuleImportingIsBroken > 3) Cheetah and #include > > I have read a lot about why mod_python sets the current working > directory to '/', but this seems to be causing some larger problems > when cheetah comes into play. (3) and (4) discuss two issues that I > am having trouble with. > > Here is /var/www/app/templates/testPage.tmpl: > ### > #include 'header_include.tmpl' > <head> > <title>$title</title> > </head> > <body> > <p>$message</p> > </body> > #include 'footer_include.tmpl' > ### > > However, as this actually tries to load /header_include.tmpl and > /footer_include.tmpl instead of the ones located in my templates > directory, this will not work. If you are going to use compiled templates, you are possibly better off using a site page base class and have specific pages extend that page. These common blocks are then accessible through the base class. This means you get the benefit of compiled code for the included blocks as well, instead of it having to be interpreted each time. > I came up with two workarounds, > however I don't really love either: > > a) > > ### > #include os.path.join(os.path.dirname(__file__), > 'header_include.tmpl') > <head> > <title>$title</title> > </head> > <body> > <p>$message</p> > </body> > #include os.path.join(os.path.dirname(__file__), > 'footer_include.tmpl') > ### > > b) > > Actually pass $templatesDir into all of my templates and then > instead call: > > ### > #include os.path.join(templatesDir, 'header_include.tmpl') > <head> > <title>$title</title> > </head> > <body> > <p>$message</p> > </body> > #include os.path.join(templatesDir, 'footer_include.tmpl') > ### > > I guess I'm leaning toward (a), but both seem cumbersome and slower > than necessary. Is there a better way to do this? If my memory of Cheetah is correct, then extending from a site page which has reusable bits like this as I describe above is better. > 4) Cheetah and inheritance > > Assume these two files: > > /var/www/app/templates/overall_base.tmpl > ### > <?xml version="1.0" encoding="UTF-8"?> > <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" > "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> > <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> > <head> > <title>$title</title> > </head> > <body> > $bodyContent > </body> > </html> > ### > > /var/www/app/templates/overall_base_extender.tmpl > ### > #overall_base = apache.import_module("overall_base") > (or) > #from overall_base import overall_base > > #extends overall_base > #def title > Welcome to Foo > #end def > #def bodyContent > Hello world! > #end def > > This second file only works if I add /var/www/app/templates to my > PythonPath. And, due to (2) above, I then also have to add > /var/www/app to PythonPath. Is this really necessary?= With the version of mod_python you are using, yes it is necessary. > #overall_base = apache.import_module("overall_base", > path=[os.path.dirname(__file__)]) > > doesn't seem to work inside the cheetah template file. Even > > #sys.path.append(os.path.dirname(__file__)) > #overall_base = apache.import_module("overall_base") That one I am not sure about. You may be hitting one of the other problems with PythonPath based module importing which is you can't easily have the same name module in different directories and be sure you import the one you want. In general I wouldn't recommend using apache.import_module() within Cheetah templates explicitly. > doesn't seem to work. Is there any way to get inheriting templates to > work without modifying PythonPath to include all the directories where > my base templates might be located? Not really. > I apologize for the huge length of this e-mail. I am still fairly new > to mod_python and cheetah, but so far I really like what I see. I > just feel like there are a few issues I need to wrap my head around > before I can really dive into developing applications. Any pointers > or help with these issues that you can provide would be greatly > appreciated. Things are a bit easier to manage and easier to predict when mod_python 3.3 can be used. Version 3.3 of mod_python hasn't been released yet, but is quite close. If you want to try the source for mod_python out of the Subversion repository, then can suggest better ways of doing things. Graham
|