Sean Jamieson
sean at barriescene.com
Fri Jan 27 20:42:26 EST 2006
OK, so here is my decorator solution: # @template decorator def template( relpath = 'templates', template=None, abspath=None ): def decor( func ): if abspath: path = abspath else: path = os.path.join( os.path.dirname( __file__ ), relpath ) if template: path = os.path.join( path, template ) else: path = os.path.join( path, '%s_%s.kid' % (func.__module__.split('.')[-1], func.func_name) ) def template_wrapper( *args, **kwargs ): kwargs['req'].content_type = 'text/html' values = func( *args, **kwargs ) return Template( file=path, **values ) # just so debug output makes sense template_wrapper.func_name = '%s(%s)' % ( template_wrapper.func_name, func.func_name ) return template_wrapper return decor @template() def index( req ): title = 'some title' message = 'Keep it simple, stupid.' return vars() ... or something like that... Comments? Sean Sean Jamieson wrote: > ...and I completely forgot about decorators, I'm going to come up with > something later, to make this more sane using a decorator. > > > Sean Jamieson wrote: > >> Thanks for all the options Graham. >> >> I've come up with the following code template, if anyone see anything >> obviously wrong/bad please let me know: >> import os >> import sys >> from mod_python import apache, util >> from kid import Template >> >> # this file's current directory >> __dir__ = os.path.dirname( __file__ ) >> >> # set the templates path under this file's directory >> __templates__ = os.path.join( __dir__, "templates" ) >> >> def index( req ): _page='index' >> req.content_type = 'text/html' >> ## function body ## >> return Template( file=os.path.join( __templates__, '%s_%s.kid' % >> (__name__, _page) ), **vars() ) >> >> >> I'm expecting someone might say something about my use of **vars(). >> The overall result of my return Template(..) statement is that it >> will match [script's dir]/templates/[script name]_[function name].kid >> >> Comments? >> >> Sean >> >> Graham Dumpleton wrote: >> >>> >>> On 28/01/2006, at 6:53 AM, Sean Jamieson wrote: >>> >>>> Hello everybody, >>>> I don't know if there's already been a discussion about this, it >>>> seems like a small but obvious issue. >>> >>> >>> >>> >>> Many times. ;-) >>> >>>> The current working directory does not apear to be set when a >>>> mod_python.publisher script runs; or rather it's set to "/" which >>>> is not useful. This becomes quite a pain, as I'm forced to do many >>>> things to work around it. >>> >>> >>> >>> >>> As someone else said, working directory can't be changed because of >>> multithreading >>> abilities of mod_python. >>> >>>> i.e. >>>> 1) I've started using kid templates, and I have to use: >>>> Template( file=req.document_root().'template.kid', ... ) >>>> or >>>> Template( >>>> file=req.document_root().'project_dir/templates/template.kid', ... ) >>>> rather then the more natural: >>>> Template( file='templates/template.kid ) >>>> this should find the 'templates' directory in the same directory as >>>> the running script >>> >>> >>> >>> >>> Don't use req.document_root(). Instead, in that specific Python code >>> file, >>> include at global scope: >>> >>> import os >>> __here__ = os.path.dirname(__file__) >>> __templates__ = os.path.join(__here__,"templates") >>> >>> That will give you the directory that file is located in, in a handy >>> variable >>> which you can then use. >>> >>> Template( file=os.path.join(__templates__,"template.kid") ) >>> >>> This is only useful though if all your publisher handlers are in the >>> one directory. >>> If you have stuff spread over subdirectories, you start having to >>> use relative >>> paths as appropriate in subdirectory handler files. >>> >>> import os >>> __here__ = os.path.dirname(__file__) >>> __templates__ = os.path.join(__here__,"..","templates") >>> >>> Thus, you may be better off doing something like: >>> >>> def _templates(req,path): >>> return os.path.join(req.hlist.directory,"templates",path) >>> >>> ... >>> >>> Template( file=_template("template.kid") ) >>> >>> The req.hlist.directory variable will be set to the directory for >>> which PythonHandler >>> is specified, thus giving you a root anchor point which you can use >>> to describe all >>> paths relative to. Doing this means you have more flexibility as far >>> as moving code >>> files around between directories without having to modify code. >>> >>> The other reference point you might use is: >>> >>> def _templates(req,path): >>> directory = os.path.dirname(req.filename) >>> return os.path.join(directory,path) >>> >>> ... >>> >>> Template( file=_template("templates/template.kid") ) >>> >>> The req.filename object is similar to using __file__ for most cases, >>> but getting the >>> information from the request object instead. >>> >>> You might even create your own derived class from Kid's Template >>> class so you can >>> pass it a 'req' object and relative template file path and have that >>> derived class >>> constructor do the calculation of where the file is relative to >>> PythonHandler root >>> or req.filename. >>> >>> In other words, to be more transparent, the template system would >>> need to know about >>> the environment it is used in. >>> >>>> 2) I have to fully qualify imports from the document root, as the >>>> document root is added to sys.modules, but the current directory is >>>> not. So, if I'm in a subdirectory under the document root I have to >>>> do: >>>> import project_dir.subpackage.module >>>> when the current directory is 'project_dir'. This is silly, I >>>> should be able to import something in, or under, the current >>>> working directory: >>>> import subpackage.module >>> >>> >>> >>> >>> If these packages contain reusable code used across various pages >>> and don't have >>> actual code in them for generating pages, it is not a good idea to >>> put them under >>> your document root. This is because with the right URL they may be >>> able to be >>> invoked by a remote user because of publishers automatic mapping. >>> Thus you need to >>> be very careful. >>> >>> If they do contain code for generating pages, you should not be >>> using "import" >>> to access them as at the same time they could be getting loaded by >>> publisher using >>> a different module loading system which will cause various problems. >>> >>> As suggested by someone else, look at using "apache.import_module()". >>> >>>> I would have to do some hack involving seperating the dirname of >>>> __file__ and adding it to sys.modules >>> >>> >>> >>> >>> I think you must have meant into sys.path. Same above, Modifying >>> sys.path directly >>> in mod_python is not usually a good idea either. The use of >>> PythonHandler will >>> automatically put that root directory in sys.path for you without >>> having to resort >>> to using PythonPath. This all assumes you have already set >>> PythonPath explicitly >>> and aren't using Location directive instead of Directory directive >>> to specify context >>> in which mod_python is used. >>> >>> Graham >>> >>> >>> >> >> _______________________________________________ >> Mod_python mailing list >> Mod_python at modpython.org >> http://mailman.modpython.org/mailman/listinfo/mod_python >> >> > > _______________________________________________ > Mod_python mailing list > Mod_python at modpython.org > http://mailman.modpython.org/mailman/listinfo/mod_python > >
|