URLs
For URL handling XIST uses the module
ll.url
. Refer to its documentation
for the basic functionality (especially regarding the methods
__div__
and relative
).
When XIST parses an XML resource it uses a so called “base” URL. This base URL can be passed to all parsing functions. If it isn't specified it defaults to the URL of the resource being parsed. This base URL will be prepended to all URLs that are read during parsing:
>>>
from ll.xist import parse
>>>
from ll.xist.ns import html
>>>
node = parse.parsestring('<img src="eggs.png"/>', base="root:spam/index.html")
>>>
print node.bytes()
<img src="root:spam/eggs.png" />
For publishing a base URL can be specified too. URLs will be published relative to this base URL with the exception of relative URLs in the tree. This means:
- When you have a relative URL (e.g.
#top
) generated by aconvert
call, this URL will stay the same when publishing. - Base URLs for parsing should never be relative: Relative base
URLs will be prepended to all relative URLs in the file, but this will not be
reverted for publishing. In most cases the base URL should be a
root
URL when you parse local files. - When you parse remote web pages you can either
omit the
base
argument, so it will default to the URL being parsing, so that links, images, etc. on the page will still point back to their original location, or you might want to use the empty URLURL()
as the base, so you'll get all URLs in the page as they are. When XIST is used as a compiler for static pages, you're going to read source XML files, do a conversion and write the result to a new target file. In this case you should probably use the URL of the target file for both parsing and publishing. Let's assume we have an URL
#top
in the source file. When we use the “real” file names for parsing and publishing like this:node = parse.parsefile("spam.htmlxsc", base="root:spam.htmlxsc") node = node.conv() node.write(open("spam.html", "wb"), base="root:spam.html")
the following will happen: The URL
#top
will be parsed asroot:spam.htmlxsc#top
. After conversion this will be written tospam.html
relative to the URLroot:spam.html
, which results inspam.html#top
, which works, but is not what you want.When you use
root:spam.html
both for parsing and publishing,#top
will be written to the target file as expected.
Pretty printing XML
The method pretty
can be used for pretty printing XML.
It returns a new version of the node, with additional white space between the
elements:
from ll.xist.ns import html node = html.html( · html.head( · · html.title(u"foo"), · ), · html.body( · · html.div( · · · html.h1(u"The ", html.em(u"foo"), u" page!"), · · · html.p(u"Welcome to the ", html.em(u"foo"), u" page."), · · ), · ), ) print node.pretty().bytes()
This will print:
<html> · <head> · · <title>foo</title> · </head> · <body> · · <div> · · · <h1>The <em>foo</em> page!</h1> · · · <p>Welcome to the <em>foo</em> page.</p> · · </div> · </body> </html>
Element content will only be modified if it doesn't contain
Text
nodes, so mixed content will not be touched.
Automatic generation of image size attributes
The module ll.xist.ns.htmlspecials
contains an element autoimg
that extends ll.xist.ns.html.img
.
When converted to HTML via the convert
method the size of the image will be determined and the height
and width
attributes will be set accordingly (if those attributes
are not set already).
Embedding Python code
It's possible to embed Python code into XIST XML files. For this
XIST supports two new processing instructions:
pyexec
and pyeval
(in the module
ll.xist.ns.code
). The content of
pyexec
will be
executed when the processing instruction node is converted.
The result of a call to convert
for a pyeval
processing instruction is whatever the
Python code in the content returns. The processing instruction content is treated as the body
of a function, so you can put multiple return statements there.
The converter is available as the parameter converter
inside
the processing instruction. For example, consider the following XML file:
<?pyexec · # sum · def gauss(top=100): · · sum = 0 · · for i in range(top+1): · · · sum += i · · return sum ?> <b><?pyeval return gauss()?></b>
Parsing this file and calling
convert
results in the following:
<b>5050</b>