|
Graham Dumpleton
grahamd at dscpl.com.au
Fri Jan 27 16:04:14 EST 2006
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
|