3.3 Wire-framing with templates
3.3.1 Drawing a first wire-frame
3.3.1.1 Introduction
The first thing we want to address in this project is the overall behaviour of the web application: "Which pages link to where, what will be on which pages, how end-users will interact." In web-designer and information-architect circles this work is often tackled through so called wire-frames.
In Kauri we foster this approach and throw in our
to help speed up the process and to keep these prototyping steps as a basis for future work.
Indeed rather then throwing these design-time files away, we will extend them during next phases and foresee an active role for them in the actual implementation.
3.3.1.1.1 Templating
During the wire framing phases itself these techniques allow you to benefit from envisioned reuse. An early opinion on visual consistency, slight variants and reuse of graphical elements can be captured in the templating language right away: making the creation of the wireframe snappier and taking considerably more active steps towards further functional development.
3.3.1.1.2 Page naming & auto-routing
Likewise, a nowadays common sensitivity for the URIs (and which parts it is composed off) is easily layed down in the folder and file names picked up by our 'pages' routing-support.
Both of these are already activated in the generated project. If you haven't started your project yet, do so now
[linux] $ kauri.sh run -s module-source-location.properties -p prototype [windows] > kauri.bat run -s module-source-location.properties -p prototype
This keeps your project running, and (through the -s option) hooked to the source-files as you edit them: simply refreshing in the browser will show the effects of any changes immediately.
3.3.1.2 Which pages do we want?
And how will they be addressable (and indexed by search engines)?
It really doesn't matter if the sense for "cool URIs" comes from an opportunistic SEO drive or a more fundamental vision or REST awareness.
3.3.1.2.1 User Stories
Being a web-site in the works our 'myblog' project will have the archetypical "home/index" page serving as an entry point (that was easy). We want it to show the first x lines/paragraphes of the last 3 entries in the blog, each having a permalink pointer behind the title, and behind a 'read more>>' link.
That should lead to an entry-detail page that shows the full contents of the blog-entry (and some meta-data as author, tags/categories/keywords, publication/creation date-time. Browsing through these entry-detail pages will be done through previous-next links on the page.
The tags should be listed on the home page, and provide links to overview-pages that will list all entries associated to that tag. The list here will look like the list on the home page. In fact both (all) lists of entries should be sorted on publication-date (descending) and have some paging ability (ie. be cut off to say length 20, and provide a link to 'older entries')
We foresee (of course) a management interface to add new entries, and control old ones (edit, unpublish, remove).
3.3.1.2.2 URIs
Based on this minimalistic analysis we get the following list of template-pages we need to provide
|
NAME |
@URI_TEMPLATE |
|---|---|
|
=Description |
|
|
home |
@ / |
|
= entry-point, links to tags, older entries and details of listed entry |
|
|
entry |
@ /entry/{pubdate_key}/{title_for_seo} |
|
= detail for specific blog entry, links to previous, next |
|
|
tag |
@ /tag/{name}?page.before=YYYY-MM-DDTHH:MM:SSZ&page.size=20 |
|
= list of entries with that tag |
|
|
admin-list |
@ /manage?page.before=YYYY-MM-DDTHH:MM:SSZ&page.size=20 |
|
= list of entries with options to remove/edit/unpublish/ |
|
|
entry-form |
@ /manage/new |
|
= form to create new or update existing entry |
Note the usage of the {name} placeholders in the URI-paths. These indicate
the ROLE or semantics of that part of the path. This notation
comes from the
By using these literally (i.e. with the { and } characters in there!) as the names for the folders and files on disk the 'pages' router in Kauri will automatically promote these pathnames-on-disk into active uri-templates. It will thus match patterns rather then actual literals, and provide the recognized parts to the template logic as ready variables.
So in our case since the uri-template: /entry/{pubdate_key}/{title} will match a family of request-URIs like: /entry/2010-08-04T07:01:00/about-page-routing. To obtain this we simply provide the following in our project:
[myblog]/src/main/kauri
+-- pages
+-- entry
+-- {pubdate_key} # Yes, your folder name holds the { and } characters
+-- {title}..xml # Yes, your file-name holds two periods.
About the double-period notation: the contract is this: the
second extension is removed from the actual uri-template. This trick allows to
provide an extension to your file that makes it recognizable to your development
tools (an xml template file to be opened in your xml editor) without having it
ripple through in the URI-scheme. Check out the
In the {title}..xml template we will be able to use the matched names as variables. So for the sample request URI we mentioned above we will get something like:
|
variable |
value |
|---|---|
|
pubdate_key |
'2010-08-04T07:01:00' |
|
title |
'about-page-routing' |
3.3.1.2.3 Benefits
Recognizing these 'uri-templates' upfront reduces the work to be done: Only single template-pages need to be developed, not a set of individual individual (copy-pasted and then ill-synced) sample instance pages

More benefit to this approach is in the fields documentation and project-management: Marking {roles} in the paths/names of these templates communicates in a natural way (ie. built-into the project source code) more of the design-time insight to the further development process.
3.3.1.3 What is on these Templates?
So, we are ready to lay out the 'paths' and create the distinct templates, but not without some more consideration for elegance and efficiency to actually fill them up.
The previous section described how recognized templates can be captured using the built-in uri-templating: a simple mechanism to catch all same-looking pages into one {role}-named template. The next analysis effort is in recognizing the recurring zones, bits and pieces in these templates.
Like in the previous section, this will result in
- further work-optimization during the wire-framing (avoiding copy-paste)
- higher visual consistency across the site
- unambiguous communication of which pieces are intentionally looking alike.
Looking at our my-blog sample we see the different pages should have a lot in common. The diagram below graphically represents the important relations between these templates:
- <<inherit>> relations show how the templates implementing end-user facing page-impressions should all derive from one common layout
- <<includes>> relations show bits of html snippets that should be reused in different pages
- <<linksTo>> relations show how one page will link to another

To capture this Kauri's templating language naturally provides the t:inherit (reusable general layouts) and t:insert (reusable snippets) statements.
See the reference, starting of at the
3.3.1.4 Do It Yourself
With the above thinking done, we can fully list the template files we need to create: (we shortened some names for convenience)
main-module/src/main/kauri/
|-- pages
| |-- entry
| | `-- {key}
| | `-- {title}..xml
| |-- index.html.xml
| |-- manage
| | `-- {key}..xml
| |-- manage..xml
| `-- tag
| `-- {tag}..xml
`-- templates
|-- layout
| |-- footer.xml
| |-- header.xml
| `-- layout.xml
`-- snippet
`-- entry-list.xml
We separate the 'pages' from the 'templates'. The pages are the
ones that are end-user-facing. They get a URI assigned to them which makes them
publicly accessible.
Even if those too just use the template language, we keep them separate from the
strictly internal templates that help out managing the reusable layout and
recurring snippets.
Don't delete or change any of the generated files yet.
Just create the missing ones, and fill those with some basic XML that makes them
avoid errors:
<?xml version="1.0"?> <html xmlns:t="http://kauriproject.org/template"> TODO -- preferably enhanced with some idea of what this particular page should show </html>
As we go along these files will be further enhanced and more details of templating and routing will be touched upon. For now we'll just show the basic principles that make up the essence of the wire-framing job:
- Learn how the layout inheritance works (and introducing header and footer)
- Learn how template inclusion works
- Putting down the links between the various pages.
- Show how the matched part of uri-templates is made available in the templating.
3.3.1.4.1 Inherit and extend a common layout
This first part is really easy because it is already in use by the generated templates: pages/index.html.xml declares an inheritance on templates/layout/layout.xml. It does so in the first line:
<html t:inherit="module:/templates/layout/layout.xml" xmlns:t="http://kauriproject.org/template">
This layout.xml template declares the general layout structure and
leaves room for so called 'blocks' that can be overridden in the templates that
inherit from this template. These just provide blocks with matching names that
will replace the ones from the parent.
You can see how the layout.xml declares the blocks named title and
content. And how the matching blocks in the index.html.xml page
actually replace those.
To satisfy the various <<inherit>> relations in the diagram above we just apply the same layout to all the actual end-user-facing pages. This is what you do:
- add the above inheritance declaration (t:inherit="module:/templates/layout/layout.xml") to the root element of all the templates in the pages directory (not to the ones in templates)
- then move the earlier TODO text into a <t:block name="content"> ... </t.block>
Don't worry too much about the path starting with the
pseudo-protocol: module:/ for pointing to the layout-master-template.
It is explained in our section about
For now it suffices to know that these absolute references a reresolved against
the root of the kauri-resources of your module. (in your module source files
that means, relative to [module]/src/main/kauri)
You can simply use relative paths as well for the t:inherit
attribute. But depending on their position the reference to
template/layout/layout.xml would need to be prefixed with one or more ../
In this case the 'absolute' version is more appropriate.
As a sample, here is how pages/entry/{key}/{title}..xml should look for now:
<?xml version="1.0"?>
<html t:inherit="module:/templates/layout/layout.xml" xmlns:t="http://kauriproject.org/template">
<t:init>
<t:variable name="page_title" value="TODO: should become the title of the entry"/>
</t:init>
<t:block name="title">${page_title}</t:block>
<t:block name="content">
<h1>${page_title}</h1>
TODO entry detail page
</t:block>
</html>
Notice how we also override the title block and how the ${...} syntax is used as a placeholder for expression evaluation during template execution. This allows to define the page_title once and inject its value
- both in the header/title of the page
- and in the h1 element in the content-body.
More details about inheriting templates (like why use
<t:init>) is in the
3.3.1.4.2 Include re-useable template-snippets
Next we realize the <<includes>> relations from the diagram above. Just drop in a <t:include> with appropriate src attribute: i.e. pointing to the template-file you want to include.
For the layout.xml page we push out the header/footer sections to different XML files.
<?xml version="1.0"?>
<html xmlns:t="http://kauriproject.org/template">
<head>
<title><t:block name="title">[title]</t:block></title>
<link rel="stylesheet" type="text/css" href="${publicUri('service:/main/static/css/main.css')}"/>
<script type="text/javascript" src="${publicUri('service:/main/static/js/basic.js')}"/>
<t:block name="extraHeaders"/>
</head>
<body>
<t:block name="header"><t:include src="header.xml" /></t:block>
<t:block name="content"/>
<t:block name="footer"><t:include src="footer.xml" /></t:block>
</body>
</html>
Being a master-layout page it is wise to wrap the include statements into separate blocks so inheriting pages can choose to override in any way.
A similar include should be used for reusing the list of entries on the index, tag-overview and management pages. On those pages you can just leave a:
<t:include src="/templates/snippet/entry-list.xml" />
somewhere in the content-block (i.e. <t:block name="content">)
The snippet-file itself can then look like this for now:
<?xml version="1.0"?>
<div xmlns:t="http://kauriproject.org/template">
<!-- we will need to think about injecting title and data for this list to produce -->
<h2>TODO injected title</h2>
<ul class="entry-list" >
<t:variable name="permalink" value="${publicUri('service:/main/entry/some-key/some-title')}" />
<li>
<a href="${permalink}" >TODO some-entry-title</a><br />
TODO some entry summary<br />
<a href="${permalink}" >read more >></a>
</li>
</ul>
</div>
You should see this dummy list now included on the various pages where you added the <t:include> directive.
3.3.1.4.3 Linking your pages in a module-reuse-world
Marked in the above sample we introduce an unfamiliar way to link up the pages in your design.
${publicUri('service:/main/entry/some-key/some-title')}
What is going on? Well two things in fact.
The first observation is that we can't simply use relative links in this entry-list page. Since it will be embedded inside different pages we cannot be sure that the base path of those will always be the same, and thus that we can pin down the correct relative path towards the detail pages. In our example the usage inside the manage..xml template would suggest a relative permalink to "entry/**" while the inclusion in tag/{tag}..xml would need "../entry/**" to work properly.
By switching to an absolute reference "/entry/**" we can easily service both usage scenario's. Only we can't be sure about / being the actual public URI that points to the root of the service we are building. Therefor we ask the framework (who does now about this configuration aspect at run-time) explicitly to translate our URI into a public reference with the publicUri function.
People familiar with other component based web app frameworks should not be too surprised about this.
The actual mount-point for the various public services in your
module is covered in the
Which services your module is providing is declared in the spring-bean xml files
inside src/main/kauri/spring/** using the export-restservice tag
described in the
In short: you can ignore this only:
- if you are sure from the usage context of the template that relative URI's will work
- if you are sure from the usage context of the module that / will surely be your entry-point.
"Being sure" about these aspects translates into documenting it and describing it as known limitations of your template and/or module.
This should allow you to put down the various <<linksTo>> relations foreseen in the analysis diagram.
3.3.1.4.4 Grab the matched part of a uri-template
Finally we are ready to abuse the dynamic parts introduced by the uri-template technique. By creating the template at pages/tag/{tag}..xml we are sure to match any /tag/my-topic. Now here is how we can use the actual matched {tag} in our template:
<?xml version="1.0"?>
<html t:inherit="/templates/layout/layout.xml" xmlns:t="http://kauriproject.org/template">
<t:init>
<t:variable name="tag" value="${request.attributes.tag}"/>
<t:variable name="page_title" value="Entries for topic ${tag}"/>
</t:init>
<t:block name="title">$page_title</t:block>
<t:block name="content">
<h1>${page_title}</h1>
<t:include src="/templates/snippet/entry-list.xml" />
</t:block>
</html>
The internal routing and matching will make the matched {tag} part from the uri-template available as a request-attribute with the matching name.
3.3.1.5 Conclusion
Kauri offers more then the simple-read-static-files support from your average file-system or bare bones web-server. By using the built-in pages-router and the template language the initial design phases of new projects (the so called wire-framing) can both
- be more efficient itself as well as
- be of higher quality for later follow up.
The resulting work shows more visible traces of recognized recurring visual elements and uri-patterns.
Since all of this runs in 'source' mode no project builds or service restarts are required. The typical fast round-trip of the designer-cycle template-save-and-test-in-browser is maintained.
Finally the wire-framing work doesn't need to be thrown away and redone in a more dynamic language. The same files can be extended and kept live (and thus up to date) as development continues. This is especially important in environments where development of one part is in parallel with the analysis and design work on new sections and modules.
Previous