This package contains the reference implementation of PXTL only. The reference implementation is suitable for batch jobs, testing and development, and allows DOM trees to be transformed and returned directly without serialisation.
The reference implementation is, however, too slow for use as a full templating solution for production web sites except on simple low-traffic sites or where an output-cacheing scheme is in use. An optimised implementation which only outputs serialised documents will be included as part of this package in the future to cater for production web use.
The pxtl package requires Python 1.5.2 or later, and is known to work up to at least Python 2.3. Python 1.6 is required if Unicode characters are to be handled correctly.
For details of the PXTL language itself, please see the accompanying language documentation.
The ‘pxtl’ directory is a pure-Python package which can be dropped into any directory on the Python path. Appropriate paths might be /usr/lib/python2.2/site-packages/ (Linux), C:\Python22\Lib\site-packages (Windows) or many other possibilities depending on your setup.
If you want pxtl to work out where to install itself automatically, and
pre-compile some bytecode, open a command line (shell),
cd
into the directory containing setup.py, and enter:
python setup.py install
Installing this way requires Python 1.6 or later (or the distutils module to be otherwise installed).
Normally it is expected that a PXTL page will be invoked and processed by a CGI script or other component of a web application framework.
It is, however, also possible to have a web server call a PXTL template directly. The template can contain code to process form submissions, take actions and output a page. This is the ‘server pages’ model employed by frameworks such as ASP and JSP.
This is not usually considered an ideal approach to web application architecture, but it can be useful for rapid prototyping. To enable PXTL to work this way you must configure your web server to associate .px files with PXTL.
To enable PXTL server pages in Apache, create a .cgi file executable by Apache (eg. in the cgi-bin directory, with read and execute permission for all), containing:
#!/usr/bin/python
import os, pxtl
pxtl.processFile(os.environ['PATH_TRANSLATED'], headers= 1)
Change the hashbang on the first line if your Python is
elsewhere (enter which python
to find out). Add the argument debug= 1
to the last line if you want PXTL to output a debugging page in
case of errors.
Finally, add the following configuration directives to Apache‘s httpd.conf (or .htaccess):
AddHandler pxtl-template .px
Action pxtl-template /cgi-bin/pxtl.cgi
Change the Action path if your CGI script is elsewhere.
To enable PXTL server pages in IIS, open Internet Services Manager (from Administrative Tools) and get the ‘Properties’ of the web site you wish to configure. Go to the ‘Home Directory’ tab, choose ‘Configuration...’ and add an application mapping for extension ‘.px’ with the value:
"PYPATH\python.exe" -u "PXPATH\pxtl\__init__.py" "%s"
If you want to use PXTL’s debugging page if an error occurs in the template code, add a -d switch:
"PYPATH\python.exe" -u "PXPATH\pxtl\__init__.py" -d "%s"
‘PYPATH’ must be substituted for the place where your Python executable is stored, for example ‘C:\Python23’; ‘PXPATH’ must be substituted for the place where your pxtl package is stored, for example ‘C:\Python23\Lib\site-packages’.
Use the function pxtl.processFile
to load a PXTL
document, run its code, and output the transformed file.
import os, pxtl
pxtl.processFile(os.path.join(templateDir, 'hello.px'))
The first parameter path is required; it holds the local pathname of the template to process. There are several further optional parameters:
writer: a stream-like object to which to send the results. If
this is not given, standard output (sys.stdout
) is
used.
globals: a dictionary to be used as ‘global scope’ for Python code in the template. Any values in the dictionary can be accessed by template code as a variable with the same name as the dictionary item’s key; any global variables written by template code will be stored in the directory and may be read by the caller after the template has run. If this parameter is not given, a new, empty scope is created.
debug: if set to a true value, any exceptions that occur in running template code will be caught, and a helpful debugging page output instead of an error. This is very useful for testing code, but should not be used in a production environment as the amount of information it reveals may constitute a security risk.
headers: if set to a true value, the output will be prefixed with an appropriate HTTP ‘Content-Type’ header for the document. This may save CGI script authors a little effort.
dom: a DOM implementation to use for PXTL’s XML work. This must provide a DOMImplementation interface supporting the W3C DOM Level 3 Core/XML and Load specifications. If this parameter is not given, PXTL uses its built-in DOM implementation ‘pxdom’.
pxtl.processFile
will forward to either the reference
or the optimised implementation, whichever is likely to work best. At the
moment, only the reference implementation is available, but later releases
will usually forward to the optimised implementation. If you need to call
either implementation directly (eg. for testing) import the relevant
module from the package and use pxtl.reference.processFile
or pxtl.optimised.processFile
.
If you want pxtl to transform DOM trees directly, rather than dealing
with the serialised XML documents, you should use the
pxtl.reference.Transformer
class.
import pxtl.reference
t= pxtl.reference.Transformer()
transformedDocument= t.transformDocument(document)
The object passed to transformDocument
must
implement the Document interface from the DOM Level 2 Core/XML standard. If
the document uses <px:import>
elements, it
must also support DOM Level 3 Core/XML and Load.
The document object is generally transformed in-place. However in certain cases (particularly, changing a doctype with non-pxdom implementations) a copy may be made. In this case transformDocument will return the new copy instead of the original document.
After transformation, the Transformer object has the following readable properties:
px:doctype
attribute, this is guessed as either ‘xml’ or ‘xhtml’.
px:doctype
attribute,
None
if not specified
px_mark
processing instruction and XML-type
import
elements.
The Transformer object may be re-used.
The pxtl package contains one other function that applications may
occasionally want to use: the function decodeText
,
part of the pxtl.utilities module, takes a string as encoded by
the px_name
PI/pseudo-PI and returns the
original, decoded string. This may be needed if such a value is
submitted in a form.
The pxtl package includes a complete stand-alone pure-Python DOM 3
Core/XML and Load/Save implementation, which it uses by default. If
you want to use it in your script, for example to create a DOM tree
to pass to a Transformer, use the module pxtl.pxdom
as a DOMImplementationSource:
import pxtl.pxdom
implementation= pxtl.pxdom.getImplementation('')
Then use DOM 3 methods such as createDOMParser. Alternatively, the pxdom
module offers the same convenience methods parse
and
parseString
as minidom does.
More information on pxdom and using it in other applications.
Any DOM implementation supporting Level 3 Core/XML and Load can be used
by the pxtl package, by passing its DOMImplementation object in the
dom parameter to processFile
, or
one of its Document objects to Transformer.TransformDocument
.
Unfortunately at the time of writing the commonly-used DOM implementations ‘minidom’ (part of the standard library, and updated by the PyXML package) and ‘4DOM’ (part of PyXML) do not support this. There are also some known compliance issues; further, some older versions are quite badly bugged.
To aid interoperability with applications that use these implementations, the pxtl package includes a module that provides wrappers to them, which support just enough DOM Level 3 for pxtl to work. Some of the bugs in older versions that affect pxtl are also dynamically patched. There are still issues (for example comments, CDATA sections and entity references may go missing with minidom), but generally pxtl should run.
Use the function pxtl.fixdom.getImplementation
to access these wrapper implementations. The function takes one
parameter, name, which should be either ‘4DOM’ or ‘minidom’.
The relevant DOMImplementation object is returned. To create a document
from it, use the method createDOMParser on it, then call parseURI on the
DOMParser object. Other DOM 3 Load methods are not supported.
It should be noted that the techniques used to patch the implementations are unreliable, and the end results might not be completely stable. It is possible future versions of minidom and 4DOM will break the fixdom patches to them. It is also possible future versions may support DOM Level 3 well enough to be used directly.
4Suite’s cDomlette and pDomlette/FtMinidom implementations are not supported by fixdom, and are unlikely to be, as they deliberately provide only a limited subset of DOM methods.
Copyright © 2003, Andrew Clover. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
The name of Andrew Clover may not be used to endorse or promote products derived from this software without specific prior written permission.
This software is provided by the copyright holder “as is” and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. in no event shall the copyright owner be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage.