Technical Overviews

Editing page templates

Editing Page Templates

This tutorial will introduce you to the apostrophe-pages and apostrophe-templates modules. It will also cover the basics of editing page templates in Nunjucks, and show you how to add a hero section to the Home page.

But first, two quick questions we should answer... what the heck is an Apostrophe module? And what's this app.js file all about?

About app.js

app.js is Apostrophe's main configuration file. This is the file that fires up Apostrophe with a given configuration, and is where you can specify what modules you want to be present in your project. As you add them, you also configure them by providing options via an object.

Some modules are always a part of Apostrophe whether you configure them or not. You will create more to meet the needs of your project.

lib/modules: modules in Apostrophe

Apostrophe is a modular content management system. Each meaningful component is broken into its own module, which can then be interacted with or subclassed (extended) by other modules in the system. Under the hood, modules are powered by moog and moog-require, but you don't have to understand that right away to build a great website.

The lib/modules folder of your project is where modules created for your own project live. And it is also where you can "implicitly subclass" (i.e. configure or improve upon) Apostrophe's own modules, whether part of the apostrophe npm module's core or packaged in separate npm modules.

We've already seen two modules that are extended in your test project's lib/modules folder, apostrophe-assets and apostrophe-pages. apostrophe-assets gets some custom LESS CSS files, while apostrophe-pages contains page templates.

Apostrophe modules and npm modules are not the same thing. One npm module might package several Apostrophe modules that are maintained together as a "bundle." You'll see this later when you install the apostrophe-blog npm module.

Modifying page templates

Now that we know what a module is, let's take a look in the apostrophe-pages module directory of your project (lib/modules/apostrophe-pages). Here you'll find a /views directory containing our .html template files. Within the /pages subdirectory you'll find our existing Home page template, home.html. Right now, our site only has this template so let's add a new one.

Adding a New Page Template

Let's add a default template for new pages.

The first step is to add configuration for the apostrophe-pages module in app.js:

// This configures our default page template
'apostrophe-pages': {
types: [
name: 'default',
label: 'Default'
name: 'home',
label: 'Home'

If you are not using nodemon, you will need to restart the node app when you make most code changes. In the terminal window, press control-C, then type: node app.js

This is because every node application is a webserver in its own right. Unlike PHP applications, node apps "stay alive" indefinitely, handling many page requests asynchronously for better performance. Later, in production, we'll use a more robust webserver as a "frontend proxy" to help handle the load.

If you find this annoying in development, there's a simple fix: use nodemon. A reasonable nodemon configuration is provided with projects generated by apostrophe-cli.

Creating and Extending Page Templates

We've configured the two page types we want for our site. But if you try to add a new page now via the "Page Menu" (lower left corner) and give it the "default" page type, you'll get an error.

Apostrophe is looking for the template file lib/modules/apostrophe-pages/views/pages/default.html. So open up your editor and create that file.

Now let's take a look at how to add content to the page.

With an empty default.html, we don't get much; not even a page title. But we can get quite a bit for free just by extending a layout template.

Nunjucks allows you to extend another template, with the option of overriding blocks to update or change the template. For example:

{% extends "layout.html" %}

Projects created with our CLI from the apostrophe-boilerplate project ship with a simple layout.html file in the top-level views/ folder, where templates are found if they are not present in a specific module. If you peek in layout.html, you'll find several examples of "blocks" you can override, notably main:

{% block beforeMain %}
We recommend you use the beforeMain block for global page components
like headers or navigation.
{% endblock %}
{% block main %}
Usually, your page templates in the apostrophe-pages module will override
this block. It is safe to assume this is where your page-specific content
should go.
{% endblock %}
{% block afterMain %}
This would be a great place to put a global footer.
{% endblock %}

Blocks are another great Nunjucks feature; they are defined in files you extend, and you can override them in your page template just by using the block keyword.

So using these blocks on your pages means everything output by your page template will be inserted into the layout in the appropriate spot.

There is also a title block which you can extend to set the page title, although the default layout.html makes a good guess based on the current piece or page.

Even layout.html extends another file. For a typical page load, it extends outerLayout.html, which lives in the lib/modules/apostrophe-templates/views folder. That file extends the outerLayoutBase.html file that ships with Apostrophe. Most of the time you won't need to look there, but it does contain additional blocks you can override, notably extraHead which is perfect for adding link elements to the head element and so on.

Using blocks to override parts of the layout

Now that we've extended layout.html in default.html, we can override the beforeMain block. Let's add a hero section to the top of the page:

{% block beforeMain %}
<div class="block hero">
<div class="inner">
<div class="hero-text">
<h4>Welcome to my first Apostrophe site!</h4>
{% endblock %}

Because we extended the layout, we can avoid duplicating a lot of markup.

Including, importing and extending files from many modules

Sometimes you'll want to write Nunjucks macros, include files, or extensible layouts that are used by many different Apostrophe modules. For convenience, you can put these "global" templates in the top-level views/ folder of your project. Any template not found in the current module will be located there as a "fallback." In older projects, this won't work unless you enable it. See app.js in the apostrophe-boilerplate project.

But what about editable content? Good question! That's the next topic.