Individual templates for pages
There are many ways to organize templates – you can re-use existing ones or you can use one template at a time.
Re-using sub-templates
To avoid repeating lots of code, you can put different building blocks of your website together in templates. You can re-use different parts to make template building less redundant.
Templates can include other templates. This allows you to define page elements like HTML-head metadata or headers and footers in one central file. The following code shows how include parts of a page into one page, so that HTML-head metadata and a footer are defined in a separate file:
First of all, we create a new include-htmlhead.vm file and add some meta info and static resource imports:
include-htmlhead.vm
<meta name="Description" content="$page.description">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="${theme.baseUrl}/css/main.css" rel="stylesheet" media="all" type="text/css">
<title>$page.title - Company Name</title>
Secondly, we create a new include-footer.vm file for defining the content of a footer. As content, we simply create a link to the homepage of the TEST space:
include-footer.vm
<footer>
<a href="$link.to.space("TEST")">Link_to_TEST_Space</a>
</footer>
Finally, we can include the newly created files in our page.vm file
Modified default.vm
<!DOCTYPE html>
<html>
<head>
<title>$page.title</title>
$include.template("include-htmlhead.vm")
</head>
<body>
$page.content
$include.template("include-footer.vm")
</body>
</html>
Using a main layout with include templates depending on page properties
This is what we do on the k15t.com website. To avoid repeating the same HTML boilerplate over and over again, you can use one template – page.vm – as the main layout for other pages. Elements like header, navigation, styles and metadata will be coded only once and populated using content/page properties.
page.vm
<!DOCTYPE html>
<html lang="en">
<head>
<title>$page.title</title>
</head>
<body>
<header>
<span class="title">K15t Software</span>
</header>
<main>
#if ($isError)
$include.template("templates/common/error.vm")
#else
#if($isBlogOverview)
$include.template("templates/blog/overview.vm")
#elseif($page.properties.contentTemplate)
$include.template($page.properties.contentTemplate.asText)
#elseif($isPage)
$include.template("templates/content.vm")
#end
#end
</main>
</body>
</html>
As you can see above in the code, we use $page.properties.contentTemplate
to decide what template to include. This requires a page property macro with a table, which contains a row with contentTemplate filled in. The table can be used as key-value storage you can access in your velocity files.
This typically looks like this, if correctly implemented:
Of course you can also store other data there.
As you can see in the elseif($isPage)
block, we include a generic content.vm which will output the page title and the $page.content
if no contentTemplate is present.
content.vm
<article>
<header>
<h1>$page.title</h1>
<span class="author-info">Written by $page.creator.username</span>
</header>
$page.content
</article>
Related recipes
The error template can be used to display errors, while the blog overview is used to show a list of articles if the blog setting is enabled.