One-Pager Made Easy with Bolt

Phillipp
Bolt CMS
Published in
7 min readMar 4, 2016

--

One-Page sites are great when you have little content, want to promote something or if SEO is not a priority.

Personally I am not a big fan of them, but you or your client might be. So let me show you how to build one with Bolt. Don’t worry, it’s actually quite easy and can be done with Bolts core functions.

The Technical Concept

So what do we need? We need different sections with different layouts.

For the sections, we’ll create a new Sections contenttype with just a title, slug and a template select field.

Each section layout will get its own template and template fields. This way we can store exactly the data each section needs, without having thousands of different input fields on our Sections contenttype itself.

Let’s get started, shall we?

I’ll assume you already have a Bolt instance running and skip the installation part. If you haven’t, you can find detailed instructions here.

The Sections Contenttype

This will be the backbone of our One-Page site. It defines the different sections with their template and data. We will also be able to sort the order of our sections.

As mentioned above, the sections just need a title, slug and a template select field. The final contenttype could look like this:

sections:
name: Sections
singular_name: Section
fields:
title:
type: text
class: large
group: content
slug:
type: slug
uses: title
template:
type: templateselect
filter: '*_section.twig'
record_template: hero_section.twig
taxonomy: [ order ]
default_status: published
viewless: true
searchable: false

Most of the settings should be self explanatory. As you can see, we defined hero_section.twig as default template. This is important when the user hasn’t selected a template via the template select. We will create it later.

We have also applied an order taxonomy, so we can define the position of each section.

ORDER ALL THE THINGS (At Least the Sections)

In order to make our sections sortable, we have to apply a taxonomy that has has_sortorder set to true. We have already applied a taxonomy named order to our sections contenttype, but it doesn’t exist yet. So let’s create it.

order:
slug: order
singular_slug: orderfoo
behaves_like: grouping
has_sortorder: true
options: { position: "position" }

The last three settings are the important ones. It must behave like grouping, it must have at least one option, and of course, we want the ability to order the records with this taxonomy (in our case, the sections).

When you now create a new section record, you’ll see a taxonomy tab where you can see your order taxonomy, with the position option. There you can set the position of your section.

That’s it! Now we are able to sort our sections.

Building the Theme/ Templates

Almost everything we need for our setup is in place. We can create sections and we can sort them. Now it’s time to build the theme.

Create a new folder for your theme inside the theme folder. You can name it like you want. I simply used onepage for that.

Now we need an index.twig, a config.yml and our three example sections; hero_section.twig, calltoaction_section.twig and threeentriesfeature_section.twig.

index.twig

This is our main template. It contains our navigation and footer, and of course, it includes our sections. For simplicity, I’ll show you just the code to fetch all sections and how to include their selected template.

{% set default_template = app.config.get('contenttypes/sections')['record_template'] %}

{% setcontent sections = 'sections' %}

{% for section in sections %}
{% if section.template is not empty %}
{% include section.template with {section: section} %}
{% else %}
{% include default_template with {section: section} %}
{% endif %}
{% endfor %}

First we get the default template for our sections contenttype. As you might remember, we set it to hero_section.twig. Then we fetch all our section records, which are already sorted by our sort taxonomy.

Finally we iterate over our section records and either include the selected or default template.

config.yml

This is our theme configuration. There we can give our templates legible names and set template fields.

Template specific fields allow you to define extra fields to use when a template is chosen for a record.

For now we just give our three section layouts a legible name. The template specific fields follow for each section layout.

templateselect:
templates:
- filename: "hero_section.twig"
name: "Hero"
- filename: "calltoaction_section.twig"
name: "Call to Action"
- filename: "threeentriesfeature_section.twig"
name: "3 featured entries"

hero_section.twig

The first of our three section layouts is a simple full-width jumbotron from bootstrap. It only needs a headline and a content field. Insert the following into your config.yml:

templatefields:
hero_section.twig:
headline:
type: text
class: large
content:
type: html
height: 200px

The template itself is quite simple as well:

<section>
<div class="jumbotron" style="margin-bottom: 0px;">
<div class="container">
<h1>{{ section.templatefields.headline }}</h1>
{{ section.templatefields.content }}
</div>
</div>
</section>

Let’s create a new section and select the Hero template or stick with the default one (because it’s the same). You’ll see a Template tab where you can edit the content of your template fields for the Hero template.

calltoaction_section.twig

For this little Call to Action layout I use a bit of CSS from bootsnipp. It has a headline, a content field and some pre-defined styles to choose.

Extend the templatefields entry in your config.yml with the following:

calltoaction_section.twig:
headline:
type: text
class: large
content:
type: html
height: 200px
style:
type: select
values: [ light, dark, bubble, block, mage ]

The template isn’t very special too:

<div class="callout-{{ section.templatefields.style }} text-center fade-in-b">
<div class="container">
<div class="row">
<h1>{{ section.templatefields.headline }}</h1>
{{ section.templatefields.content }}
</div>
</div>
</div>

Should be self explanatory, right?

Now do the same as above. Create a new section and select the Call to Action template. Now you have to save the section and reload the site. Otherwise the template fields for the Call to Action template won’t be loaded. The Template tab looks quite similar to the one from the Hero template but it has a select box for the style.

threeentriesfeature.twig

This one is a bit more complex. The plan is to select 3 records from the entries contenttype which will be shown next to each other.

We need a headline and three select fields where we can select records from the entries contenttype. As with the previous section, add the following to your templatefields entry:

threeentriesfeature_section.twig:
headline:
type: text
class: large
entry_1:
type: select
values: entries/id,title
autocomplete: true
sort: title
entry_2:
type: select
values: entries/id,title
autocomplete: true
sort: title
entry_3:
type: select
values: entries/id,title
autocomplete: true
sort: title

The select fields will only store the id of the selected entry. So we have to fetch the whole records in our template. It couldn’t be simpler as the following:

{% setcontent entry_1 = 'entries/' ~ section.templatefields.entry_1 %}
{% setcontent entry_2 = 'entries/' ~ section.templatefields.entry_2 %}
{% setcontent entry_3 = 'entries/' ~ section.templatefields.entry_3 %}

<section style="padding-bottom: 20px;">
<div class="container">
<div class="row">
<div class="col-md-12">
<h2 class="text-center">{{ section.templatefields.headline }}</h2>
</div>
</div>
<div class="row">
<div class="col-md-4 div-col-sm-12">
<h3 class="text-center">{{ entry_1.title }}</h3>
{{ entry_1.teaser }}
</div>
<div class="col-md-4 div-col-sm-12">
<h3 class="text-center">{{ entry_2.title }}</h3>
{{ entry_2.teaser }}
</div>
<div class="col-md-4 div-col-sm-12">
<h3 class="text-center">{{ entry_3.title }}</h3>
{{ entry_3.teaser }}
</div>
</div>
</div>
</section>

Besides the headline, we also display the title and teaser of each selected entry.

Now do the same as with the previous ones and create a new section with your new template. Your Template tab will look like this:

That’s it! We have built a simple One-Page site with 3 small and reusable section layouts. My examples use CSS classes from bootstrap. When you include it in your index.twig, you’ll get a similar output to this when you have set up each section:

You can also find the complete example on Github.

I hope this has helped you to set up your or your clients One-Page site. This approach can also be used for configurable home or landing pages.

If you have further questions, just ask me on the Bolt Slack Channel (username: phillipp).

--

--