2.2 Adding pages

Our site has a basic layout now, but we still can't really call it a site because there's no content yet. Let's start by making an About page.

Wagon generators

We could simply create a new file, app/views/pages/about.liquid, but I'm going to take this opportunity to show you another handy Wagon feature: wagon generate. wagon generate is a time-saving command that generates boilerplate for LocomotiveCMS pages, content types, and snippets.

Open a command line, navigate to the site's project directory, and run the following command.

$ bundle exec wagon generate page about
Do you prefer a HAML template ? no
    create  app/views/pages/about.liquid

As you can see, I again opted for regular HTML-style Liquid templates. Wagon then created a file: app/views/pages/about.liquid. Let's check it out.

title: About

# true if the page is included in the menu
listed: true

# true if the page is published
published: true

# position among sibling pages
# position: 1

# sets a redirection to the given url (301)
# redirect_url: "<url to a page or to a remote url>"

# content type that this page is templatizing
# content_type: "<slug of one of the content types>"

# editable_elements:
#   'some_block/some_slug': "<text>"
#   'some_block/some_slug': "<relative path to the file under the public/samples folder>"
{% extends parent %}

{% block main %}

  <p>Hello world</p>

{% endblock %}

The wagon generate command fills the created file with some common header options that you can comment in or out to suit your needs. It also makes a "Hello World" body. Regarding the YAML header, you've already met title and published, but that still leaves quite a few unknowns. Let's look at three of them.

  • listed: LocomotiveCMS has a cool feature, {% nav %}, that automatically generates site navigation. listed is a boolean flag indicating whether or not this page should appear in the site's navigation. Keep this value as true.
  • position: An integer representing what position this page holds in the navigation mentioned above. Lower numbers are listed before higher numbers. Uncomment this option and keep the value at 1.
  • redirect_url: setting this value will cause this page to redirect to the specified URL. Imagine that in the future, I decide to put the contents of the About page onto the homepage instead. I could delete the page and visitors to this URL would be met with a 404 error. Or, I could leave this file empty, except for one line in the YAML header: redirect_url: "/". Doing so would redirect all visitors to the home page. But we won't be using this for our page, so let's delete it.

What about content_type and editable_elements? We're not ready for these just yet, so just leave them commented out and we'll come back to these later.

Page inheritance

Onto the body of the page, where the first line introduces an important new concept.

{% extends parent %}

In LocomotiveCMS, all pages are part of an inherticance tree. The parent of any page under app/views/pages is app/views/pages/index.liquid. The parent of any page under the app/views/pages/foo/ directory is app/views/pages/foo.liquid.

When a page extends a parent page, it inherits the body of the parent page. Turn on the Wagon web server and open your browser to http://localhost:3333/about. You should see this.


Despite not having any of index.liquid's content, this page looks very similar to index.liquid. The only differences are the places where we used the page.title variable. That's because, as mentioned above, extending a parent means inheriting the body of the parent. Extending a page is the equivalent of copying the parent page's body and pasting it into this page's body; the page keeps its YAML header values but otherwise looks like the parent.

If that's all there was to inheritance, it wouldn't be very useful. That's where blocks come in. Blocks allow children to overwrite portions of a parent page. Let's try it out.

Open app/views/pages/index.liquid and enclose "Coming soon." with a block tag like so.

{% block 'main' %}
    Coming Soon.
{% endblock %}

This creates a new block called main. If you look in the about.liquid file, you'll see that "Hello world" is also inside a block called main. Because about.liquid extends index.liquid, index.liquid's main block will be overwritten. If you compare the two pages in your web browser, you'll see something like below.

Home page About page

We've inherited from the home page and overridden the main block with new content.

What happens if a child doesn't override a parent's block? See for yourself by changing about.liquid's block name from main to test and preview the site in your browser. If the child doesn't specify a block, the parent's block is used. Ok, change about.liquid's block name back to main.

Let's make our site a little less fake by using some real content. Replace about.liquid's main block with the code below.

{% block 'main' %}

        Thank you for visiting Wisdom for Wanderers! This blog aims to introduce readers to cool things to see, eat, and do all over the world. And along the way, I'll share some handy travel tips that can make wandering the globe easier and more fun than ever. The blog tends to focus on sights and places a little off the tourist trail, so unadventurous beware.

        I hope you enjoy the site and bon voyage!

{% endblock %}

Fixing the menu

Our About page is looking pretty good, but as of yet, there's no way to get there aside from typing in the URL manually. Let's add the About page to the menu.

We could continue adding <li> tags to index.liquid's navigation bar, but why not save some time by using the {% nav %} tag I told you about earlier?

In index.liquid, just after the Home link's closing </li>, add the following line:

{% nav "site", no_wrapper: true, active_class: "active" %}

I'm going to break down this line, but for a full explanation of the nav tag, see the nav reference page. The nav tag prints a list of page links, and the first argument specifies which pages go in the list. The options are site, parent, and page. Choosing site, gets all child pages of app/views/pages/index.liquid, parent gets children of the parent page, and page gets all children of this page.

This is the site-wide navigation bar, so I chose site. The next argument, no_wrapper indicates that we don't want these links to be wrapped in <nav> and <ul> tags, which makes sense for this situation. The final argument specifies the CSS class name added to an <li> tag when its link is the current page. I specified active, since that's the class name used in Bootstrap.

Let's see what this looks like.

Our new navigation menu

Looks nice. Now, when we create new pages, they will be added to the navigation menu automatically.

404 Page

While we are on the topic of pages, surely you've noticed the 404.liquid file sitting in the app/views/pages directory. This is a special page that will show when visitors try to visit a non-existent page. Take a look at the contents.

title: Page not found
published: true
{% extends index %}

{% block 'main' %}

<div class="jumbotron">
  <h1>Arrggggh, page not found</h1>

{% endblock %}

This time, instead of extending parent, the page extends index. In this situation, 404.liquid can't specify parent, because it's a special page outside of the LocomotiveCMS inheritance tree and it doesn't have a parent. However, the extend tag can be used to extend any page, not just the page's parent. In this situation, the page is extending index, but any page slug can be used here. This feature further increases the flexibility of LocomotiveCMS templates.

Let's take a look at this page by pointing our browser to a bogus URL.

The 404 page

Sure enough, we are shown the 404.liquid page and, thanks to the template inheritance, the site title, navigation and the page title are shown.

This page works, but the jumbotron doesn't look right with our title and menu. And the pirate-esque "Arrggggh" doesn't really match our site. Update the content of 404.liquid's main block to match the code below:

    It looks like you wandered a little too far! The page you are looking for does not exist.

Take another look at the preview in your browser. Nothing special, but it's good enough for now. Let's finish up.

Finishing up

Mission complete: we added a new page to our site, added it to the navigation menu, and modified the 404 page for bonus points. Let's save our work.

$ git add app/views/pages/index.liquid
$ git add app/views/pages/about.liquid
$ git add app/views/pages/404.liquid
$ git commit -m "Added an about page, updated the site navigation, and modified the 404 text."

Ok, stay tuned for the next lesson where we'll cover using assets like images, CSS, JavaScript, and custom fonts.

Next: assets
© 2023 LocomotiveCMS Terms of use Privacy Policy
Back to top