|
Sean Jamieson
sean at barriescene.com
Fri Jan 27 17:41:15 EST 2006
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
>
>
>
|