This plugin makes it possible to use template inheritance.
Please reports bugs and problems with this plugin in this forum thread
<txp:rvm_inherit />
Must be used as a container tag. Should contain only <txp:rvm_block>
, <txp:rvm_child>
and/or <txp:rvm_parent>
tags, although those tags can of course contain other TXP tags.
form="text"
page="text"
The page
and form
attributes are mutually exclusive. If neither is set it, page
is set to ‘default’;
<txp:rvm_block />
Can be used as a self-closing tag and as a container tag.
name="text"
child
nor parent
is set, name
defaults to an empty string. In other cases, an attempt is made to guess the correct name depending on the context where this tag is used.child="integer"
1
it references the contents of the child block in the inheritance chain. If set to 2
it references the contents of the grandchild… etc.parent="integer"
1
it references the contents of the parent block in the inheritance chain. If set to 2
it references the contents of the grandparent… etc.The child
and parent
attributes are mutually exclusive; at most only one of them may be set.
<txp:rvm_child />
Should only be used as a self-closing tag and is merely shorter way to write <txp:rvm_block child="1"/>
name="text"
<txp:rvm_parent />
Should only be used as a self-closing tag and is merely shorter way to write <txp:rvm_block parent="1"/>
name="text"
Using template inheritance, two or more templates can organize themselves into an inheritance chain. These templates can be TXP pages or TXP forms. You can mix forms and pages in an inheritance chain. This plugin treats them as if they were the same.
In the examples given here I’ll only use TXP pages. These examples were borrowed from Mako, which inspired me to write this plugin.
Suppose you have a TXP page ‘default’ that contains:
<html>
<body>
<div class="header">
<rvm_block name="header" />
</div>
<txp:rvm_block>
<div class="footer">
<txp:rvm_block name="footer">
this is the footer
</txp:rvm_block>
</div>
</body>
</html>
And you have an inheriting TXP page ‘daughter’ which contains:
<txp:rvm_inherit page="default">
<txp:rvm_block name="header">
this is some header content
</txp:rvm_block>
<txp:rvm_block>
this is the body content.
</txp:rvm_block>
</txp:rvm_inherit>
The result, when using that ‘daughter’ template, is:
<html>
<body>
<div class="header">
this is some header content
</div>
this is the body content.
<div class="footer">
this is the footer
</div>
</body>
</html>
In this example the body and header content of the ‘daughter’ page override the corresponding parts in the ‘default’ page. Nothing was specified for the ‘footer’ block in the ‘daughter’ template, so that remains as it was in the ‘default’ template.
The named blocks defined in an inherited template can also be nested within other blocks. The name given to each block is globally accessible via any inheriting template. We can add a new block title to our header block in the ‘default’ template:
<html>
<body>
<div class="header">
<txp:rvm_block name="header">
<h2>
<txp:rvm_block name="title" />
</h2>
</txp:rvm_block>
</div>
<txp:rvm_block />
<div class="footer">
<txp:rvm_block name="footer">
this is the footer
</txp:rvm_block>
</div>
</body>
</html>
The inheriting template ‘daughter’ can name either or both of header and title, separately or nested themselves:
<txp:rvm_inherit page="default">
<txp:rvm_block name="header">
this is some header content
<txp:rvm_parent />
</txp:rvm_block>
<txp:rvm_block name="title">
this is the title
</txp:rvm_block>
<txp:rvm_block>
this is the body content.
<txp:rvm_block>
</txp:rvm_inherit>
The result would be:
<html>
<body>
<div class="header">
this is come header content
<h2>
this is the title
</h2>
</div>
this is the body content.
<div class="footer">
this is the footer
</div>
</body>
</html>
Note when we overrode header, we added an extra <txp:rvm_parent />
in order to invoke the parent’s header block in addition to our own. That’s described in more detail below.
You can use multiple blocks with the same name within one template:
<html>
<head>
<title><txp:rvm_block name="title" /></title>
</head>
<body>
<txp:rvm_block name="header">
<h2><txp:rvm_block name="title" /></h2>
</txp:rvm_block>
</body>
</html>
Where above an inheriting template can define <txp:rvm_block name="title">
just once, and it will be used in the base template both in the <title>
section as well as the <h2>
this is the body content.
Sometimes you have an inheritance chain that spans more than two templates. Or maybe you don’t, but you’d like to build your system such that extra inherited templates can be inserted in the middle of a chain where they would be smoothly integrated. If each template wants to define its layout just within its main body, you can’t just call <txp:block />
to get at the inheriting template’s body, since that is only the topmost body. To get at the body of the inheriting template, you use <txp:rvm_child />
.
<html>
<body>
<div class="header">
<txp:rvm_block name="header" />
</div>
<txp:rvm_child />
<div class="footer">
<txp:rvm_block name="footer">
this is the footer
</txp:rvm_block>
</div>
</body>
</html>
Lets also add an intermediate template called ‘daughter’ which inherits from the ‘default’ page:
<txp:rvm_inherit page="default"/>
<ul>
<txp:rvm_block name="toolbar">
<li>selection 1</li>
<li>selection 2</li>
<li>selection 3</li>
</txp:rvm_block>
</ul>
<div class="mainlayout">
<txp:rvm_child />
</div>
</txp:rvm_inherit>
And finally create a ‘granddaughter’ template to inherit from ‘daughter’:
<txp:rvm_inherit page="daughter"/>
<txp:rvm_block name="header">
this is some header content
</txp:rvm_block>
<txp:rvm_block>
this is the body content.
</txp:rvm_block>
</txp:rvm_inherit>
In this setup, each call to <txp:rvm_child />
will render the body of the next template in the inheritance chain (which can be written as ‘granddaughter’ -> ‘daughter’ -> ‘default’). The output we get would be:
<html>
<body>
<div class="header">
this is some header content
</div>
<ul>
<li>selection 1</li>
<li>selection 2</li>
<li>selection 3</li>
</ul>
<div class="mainlayout">
this is the body content.
</div>
<div class="footer">
this is the footer
</div>
</body>
</html>
So above, we have the <html>
, <body>
and header/footer layout of the ‘default’ page, we have the <ul>
and mainlayout section of the ‘daughter’ page, and the main body of the ‘granddaughter’ page as well as its overridden ‘header’ block. The ‘daughter’ template is inserted into the middle of the chain without ‘default’ template having to change anything. Without <txp:rvm_child>
, only the main body of the ‘granddaughter’ template could be used; there would be no way to call the ‘daughter’ body content.
Lets now look at parents; the opposite of children. The parent template is the one immediately preceding the current template. Blocks can call upon their overridden versions. This is not as hard as it sounds. Lets modify the ‘granddaughter’ template to augment the list of selections provided by the ‘toolbar’ block in the ‘daughter’ template:
<txp:rvm_inherit page="daughter" />
<txp:rvm_block name="header">
this is some header content
</txp:rvm_block>
<txp:rvm_block name="toolbar">
<txp:rvm_parent />
<li>selection 4</li>
<li>selection 5</li>
</txp:rvm_block>
<txp:rvm_block>
this is the body content.
</txp:rvm_block>
</txp:rvm_inherit>
Above, we implemented a ‘toolbar’ block, which is meant to override the definition of toolbar within the inherited template ‘granddaughter’. However, since we want the content from that of ‘daughter’ as well, we call it via the <txp:rvm_parent>
tag whenever we want it’s content, in this case before we add our own selections. So the output for the whole thing is now:
<html>
<body>
<div class="header">
this is some header content
</div>
<ul>
<li>selection 1</li>
<li>selection 2</li>
<li>selection 3</li>
<li>selection 4</li>
<li>selection 5</li>
</ul>
<div class="mainlayout">
this is the body content.
</div>
<div class="footer">
this is the footer
</div>
</body>
</html>
and you’re now a template inheritance ninja!