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 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>
HTML/XML
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>
HTML/XML
Finally, we can include the newly created files in our
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>
HTML/XML
Using a main layout with include templates depending on page properties
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>
XML
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 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>
XML
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.