[Templates] Views
Andy Wardley
abw@andywardley.com
Fri, 29 Mar 2002 14:33:01 +0000
On Fri, Mar 29, 2002 at 10:27:48AM +0000, Tony Bowden wrote:
> So, does the silence mean that _no-one_ gets VIEWs then? ;)
It means no-one has the time to formulate a proper answer :-)
Mark's reply covers some of the detail, I can provide a concrete
example.
Here's my xmlview/index template which I use to build index pages.
[% # xmlview/index
#
# Creates an index page from an XML file or source text
#
# The following should be defined:
# * one of xmlfile, xmltext or context (e.g. via WRAPPER)
# * xmlpath(xmlfile) defined as a format or macro to convert
# whatever filename you pass as xmlfile into a full filepath
# * xmllib to give the directory relative to an INCLUDE_PATH where
# the xmlview templates can be found, defaults to 'xmlview'
DEFAULT xmllib = 'xmlview';
IF xmlfile;
xmlfile = xmlpath(xmlfile);
USE xpath = XML.XPath( file = xmlfile);
ELSIF xmltext;
USE xpath = XML.XPath( text = xmltext );
ELSIF content;
USE xpath = XML.XPath( text = content );
ELSE;
THROW xmlview 'none of xmlfile, xmltext or content defined';
END;
VIEW xmlview prefix="$xmllib/views/index/" notfound='xmltag'; END;
xpath.findnodes('section').present(xmlview)
-%]
I can use it like this:
[% INCLUDE xmlview/index xmlfile='perl.xml' %]
or like this:
[% WRAPPER xmlview/index %]
<section>
<about>This section blah blah blah</about>
<page id="foo" title="Foo Page">
<about>
This is the foo page
</about>
</page>
<page id="foo" title="Foo Page">
<about>
This is the foo page
I can put <b>regular XML tags</b> in and stuff
like that.
</about>
</page>
</section>
[% END %]
The xmlview/index template uses XML::XPath to parse the XML, look for
the <section> tag and then process all the content. When it finds an
<about>...</about> tag, for example, the VIEW (called 'xmlview')
translates it into a call to process the template
"$xmllib/views/index/about", and so on.
This template looks something like this:
[% IF (title = item.getAttribute('title')) -%]
<h2>[% title %]</h2>
[% END %]
[% item.content(view) | html_para -%]
The XML:XPath node (<about>) gets passed in as the 'item' variable, the
current view (xmlview) gets aliased to the 'view' variable. So we
fetch the title attribute, and then print all the content via the view.
This ensures that any other tags nested inside the content get mapped
to templates accordingly.
If a template isn't found then the "notfound='xmltag'" comes into play
and the 'xmltag' template is processed. This looks like this (thanks
to the patch from Mark):
[% item.starttag; item.content(view); item.endtag -%]
It simple reconstitutes the original XML tag, allowing you to pass through
regular XHTML markup. But importantly, it still processes all the content
within it through the view.
This example just has simple elements lke <section> <page> and <about>
and anything else, like <b> <img> and so on, gets passed through. I
add a new XML element, say <person>, and simply create a corresponding
'person' template in the right place to transmogrify it. The view
takes care of mapping elements to the right templates.
HTH
A