[Templates] Views
Mark Fowler
Mark Fowler <mark@indicosoftware.com>
Fri, 29 Mar 2002 13:50:08 +0000 (GMT)
On Fri, 29 Mar 2002, Tony Bowden wrote:
> So, does the silence mean that _no-one_ gets VIEWs then? ;)
No, just that I was very busy ;-)
The main thing I use views for is
a) Rendering Pod::POM (Pod -> Templates)
b) Rendering XML.
Hmm more detail.
VIEWs are a collection of templates that you can bundle up as one thing
and pass around. Importantly, views are self aware, and thus a view can
call other blocks to render out part of the object it's been asked to
render.
For example, a Pod::POM view has blocks named "head1" "head2" "item" and
so forth. Critically the template code that displays this doesn't have to
care about how to render child elements. They just say "render children
with this view too" and they do so. For example, a head1 element may just
say to recursively render it's children after the text. It doesn't care
that they happen to be items or whatever...they're just rendered.
The same is true for XML. For example, I'm working on systems that pull
out chunks of XML using XPath. The way it works is this:
I have a plugin that knows how to get at sections of my XML. It's built
ontop of the XML::Path plugin, so when I call "title" from the plugin it
uses some XPath expression to get a XML::XPath::Node::Element back that
represents the "tree" of XML at this point. Now the important thing is
that the main template doesn't know or care that the object it's been
handed back is an XML node or not. It just renders it with the view.
The XML::XPath plugin made the XML nodes "view aware". This means that
they know if they're told to render with a view then they should pick the
element in the view with the same name as the node tag. The <p> elements
are rendered with the 'p' blocks, the 'i' elements are rendered with the
'i' blocks and so on. Since the title is just plain text it'll just be
rendered with the default 'text' block.
Where this gets funky is where you have things like your plugin returning
the the "middle_bit". Now the main template doesn't know what XML this
contains. It could contain a list of <p> with text in them, and probably
does, but it likewise could contain a <p> followed by <img> or whatever.
Or it could contain a <pony/> tag which maps to the 'pony' block. It just
renders them out and things that can contain other things can quite happily
naively rendering the XML as a tree, with each block saying "er, I look
like this, followed by my children, whatever they look like with this
view, and followed by this bit more".
So we can turn "<p>This is some <funky>crazy</funky> text</p>" into
"<p>This is some <font color="red">crazy</font> text</p>" by having a
"funky" block in our view like so:
[% BLOCK funky -%]
<font color="red">[% item.content(view) %]</font>
[%- END %]
See that funky doesn't know or care what it's children look like - they
can take care of themselves.
Of course this is a very brief explanation of a very powerful feature.
I'll have to write more. And I will, or rather, I am. Expect me to
complete the rendering XML with HTML documentation somewhen in the near
future.
Later.
Mark.
--
Mark Fowler
Technology Developer
http://www.indicosoftware.com/