Import/Include with implicit defaults and partial replacements

Bruno Harbulot <[email protected]>
Newsgroups gmane.comp.web.freemarker.user
Message-ID <[email protected]>
Hello,

I'm wondering if it's possible to rely on a default layout with implicit 
calls to macros with FreeMarker (more specifically for HTML templates). 
I'm comparing this to what Genshi [1] does in Python, mostly via its 
py:match directive.

For example, in Genshi, considering these two files:

* 'core.html'

<html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:xi="http://www.w3.org/2001/XInclude"
       xmlns:py="http://genshi.edgewall.org/"
       py:strip="">
     <py:match path="head">
         <head>
             <title py:with="title=list(select('title/text()'))">
                 <py:choose test="">
                     <py:when test="title">${title}</py:when>
                     <py:otherwise>Default Title</py:otherwise>
                 </py:choose>
             </title>
             <link rel="stylesheet" type="text/css" href="screen.css" />
             ${select("*[local-name() != 'title']")}
         </head>
     </py:match>
</html>


* 'test.html'

<html xmlns="http://www.w3.org/1999/xhtml"
       xmlns:xi="http://www.w3.org/2001/XInclude"
       xmlns:py="http://genshi.edgewall.org/">
     <xi:include href="core.html" />
     <head>
         <title>Test title</title>
         <script src="test.js"></script>
     </head>
     <body>Body test 1.</body>
</html>



The output would be:

<html xmlns="http://www.w3.org/1999/xhtml">
         <head>
             <title>
                     Test title
             </title>
             <link rel="stylesheet" type="text/css" href="screen.css"/>
             <script src="test.js"/>
         </head>
     <body>Body test 1.</body>
</html>




This allows for the general layout to be defined in one file and the 
page-specific layout to be defined in another.

I've found two similar ways to do this with FreeMarker:

1. Have 'core.html' include another file whose name is passed as a 
parameter to define the content of <body/> for example.
In this case, the template that's loaded from the API is 'core.html', 
and the model has to include the names of what to include.

2. Using imports and macros, as described in [2]. This way, I can define 
a macro for the head or the body, for example, and use 'nested' to fill 
in the elements. However, these macros have to be called explicitly and 
'nested' can only be used for one blob of included text as far as I 
understand. Parameters can also be used, but they have to be explicitly 
defined in the macro.


Neither of these approaches seem to be able to do what Genshi can do via 
py:match, that is, take an existing element and replace it while 
including part of its contents.
The key points in the previous example being the 'py:match' element and 
the '${select(...)' within, that copies all elements but <title/> that 
has been replaced.

This is a simple example, but this allows for the definition of more 
complex layouts with pre-defined default values that can be customised a 
bit more easily than via the explicit use of macros or includes.
For example, the body could comprise a set of menus that are common to 
the core layout and any page, and a specific page could add an item by 
just defining that menu again in HTML (perhaps the py:match test could 
have flags to choose whether to replace or add to an element).

The difference with what I've been able to achieve with FreeMarker so 
far (options 1 and 2 above) is that the inclusion/import already sets up 
the layout implicitly unless it's re-defined/enhanced, instead of having 
to call all the customisable macros one by one in the importing template.
The other advantage is that the second template is also edited as "quite 
natural" HTML in its own right (more or less).

Would there be another way to do this with FreeMarker? (Of course, the 
syntax would be substantially different, but something following the 
same principles.)


Best wishes,

Bruno.


[1] http://genshi.edgewall.org/
[2] 
http://richardbarabe.wordpress.com/2009/03/19/freemarker-a-brief-example/



------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.