Skip to content

Partials

Greg Bowler edited this page Jan 30, 2023 · 11 revisions

In any multi-page web application, page documents will inevitably share chunks of HTML, such as the <head> and any <nav>, or <footer> elements that are present on all pages. This is done by extending a "partial" document. Partials can extend other partials, leading to a simple yet powerful page templating.

Like with HTML components, a special directory is used for storing partial views. In WebEngine applications, this defaults to page/_partial.

Extending a partial

Any page's content can be "injected" into a partial view by using INI syntax in a comment at the top of the HTML. For example:

page/index.html:

<!--
extends=base-page
-->
<h2>Welcome!</h2>
<p>I made this website all myself!</p>

In the comment, the partial view base-page is chosen. This loads the HTML from page/_partial/base-page.html and injects the current page's HTML into a an element specified with the data-partial attribute.

page/_partial/base-page.html:

<!doctype html>
<html>
<head>
	<meta charset="utf-8" />
	<title data-bind:test="title">My website</title>
</head>
<body>
	<header>
		<h1>My website!</h1>
	</header>
	<main data-partial>
		The page content will go in here.
	</main>
	<footer>
		<p>Thank you for visiting!</p>
	</footer>
</body>
</html>

In the above example, the <main> element is used to contain the HTML content of the page/index.html file.

If there are more than one elements with the data-partial attribute, an exception of type PartialInjectionMultiplePointException will be thrown.

Pre-binding using template variables

Using INI syntax in the top comment of a partial view, variables can be added to a section named [vars]. Any variables set here will be bound to the extended partial page automatically. This is useful for setting things like the <title> element of a base template from within the different pages that extend it.

The base template, main-template.html:

Note the <title> and <h1> elements are referencing the site-heading bind key.

<!doctype html>
<html>
<head>
	<meta charset="utf-8" />
	<title>My website :: {{site-heading ?? Home}}</title>
</head>
<body>
	<h1 data-bind:text="site-heading">My website!</h1>
	<main data-partial></main>

	<footer>
		<p>Thanks for visiting</p>
	</footer>
</body>
</html>

An extending page, about.html:

<!--
extends=main-template

[vars]
site-title=About me
-->
<p>This is my about me page on my amazing website!</p>
<p>It's a bit short at the moment.</p>

Once extended, the site-title bind key will be set, which is present as a bind placeholder in the <title> element, and as a bind attribute on the <h1> element of the base template.

Output HTML:

<!doctype html>
<html>
<head>
	<meta charset="utf-8">
	<title>My website :: About me</title>
</head>
<body>
	<h1>About me</h1>
	<main>
		<p>This is my about me page on my amazing website!</p>
		<p>It's a bit short at the moment.</p>
	</main>

	<footer>
		<p>Thanks for visiting</p>
	</footer>
</body>
</html>

Take note of the injected <title> value and the updated <h1> text.


This is the last page of the main documentation section.

Further reading: Constructing DomTemplate objects