As the web continues to mature and the demand for the efficiency of content delivery increases, more and more slim and trim CMSs are coming into the fray. Developers (front-end and back-end) are branching away from the heavy-hitters like WordPress and Drupal, and into the likes of more streamlined, tailor-made solutions. Bolt CMS is one of these CMSs, and prides itself on being a dream for designers, developers, and content editors alike.
On the front-end side of things, Bolt uses the increasingly popular Twig templating language, allowing front-end devs to quickly and neatly generate templates the way they want, and how they want. On the back-end side of things, custom types and fields give us the freedom to organise things the way we want. Bolt is also built upon Silex with Symfony components, making it stable, powerful, open source, and free. Twig, Silex, and Symfony are all under the Sensio Labs umbrella, so you’re guaranteed one will never leave the other in the dust. It’s a great combination!
Bolt has a really nicely laid out documentation on their site, as well as a Stack Overflow tag with an increasing number of posts. Other ways to raise points or get support include the GitHub issue tracker. Read up on the community page for more info.
Building With Bolt
In this article, we’re going to take a look at the following key points which should set us up nicely for building our first project with Bolt:
- Requirements, setup and installation
- Main configuration and theme set up
- Splitting up files into templates
- Introducing and creating content types
- Retrieving content from database records
From now on, I recommend you keep the docs open in your browser, because we’ll reference it a lot. Alright, let’s dig in!
Requirements, Setup & Installation
Bolt requires the following in order to run:
- PHP 5.3.3 or higher
- Access to SQLite, MySQL, or PostgreSQL
- Apache with
mod_rewrite
or Nginx
The PHP installation also has a few more requirements, but you can read up on those here. For the admin panel to run efficiently and optimally, modern browsers are recommended. Of course, this is just for the admin side of things. The front-end will be served on the various browsers according to the way you build it.
There are three ways to install Bolt. I’m going to use option 1, the command line way. Let’s open up terminal and from there on, run the following commands:
curl -O http://bolt.cm/distribution/bolt-latest.tar.gz
tar -xzf bolt-latest.tar.gz --strip-components=1
From here on, make sure the correct files and directories have the correct permissions. Do this by running the following:
chmod -R 777 files/ app/database/ app/cache/ app/config/ theme/ extensions/
A Quick Note About 777 Permissions
777 is the number of the beast, and we should all be aware of this. You should be aware of why Bolt requires 777 on certain directories:
- It’s required on the
/files/
directory, because Bolt needs to write to this directory when uploading media through the admin. - It’s required by the
app/cache/
directory, because Bolt automatically caches and retrieves cached material from this directory. - The
app/database/
permissions are totally optional, and completely unnecessary unless using SQLite. If you are using SQLite, Bolt will need to write to this directory to update the sqlite file. - The
app/config/
andtheme/
permissions are also optional, and only required if users would like to edit the theme and configuration files through the bolt admin. - The
extensions/
directory is also optional, and only required if you’ll be uploading extensions via the Bolt admin.
You should be totally aware of the implications of using 777 permissions, and try to configure your server to avoid having to do so. Moving on.
Continuing With Setup
Out of the box, Bolt works just fine with SQLite (a file-based database). We’re going to configure it to work with MySQL though, which is probably a more likely scenario in a production website. Let’s set that up quickly. Since we’re in the terminal already, let’s cd
into the app/config
directory. Bolt gives us the default config.yml.dist
file to start with, which is ready to roll with SQLite. Let’s copy that and rename it to config.yml
so we can use MySQL, and open that up in an editor.
We edit the database section in accordance with the Bolt docs, but make sure to put your own values in:
database:
driver: mysql
username: root
password: password
databasename: bolt
host: localhost
port: 3306
Point your virtual host to the root directory of the project (for the easiest way to do this, see Homestead Improved) and visit the desired URL in the browser. You should now be presented with the Bolt start up page, prompting you to create the first user. Go ahead and do that. Now, you can log into the admin panel and also view the front end! Awesome, let’s move onto content types – the heart of Bolt.
Main Configuration and Theme Setup
By default, Bolt will load with the base-2014
theme. This is great for snooping around and getting started, but it’s very likely that you’ll want to create your own theme, and build from scratch. First of all, open up the project in your editor of choice. Navigate to the theme
directory, and create a new directory called my-theme
(you can call it whatever you want, really). Now, we want to change that theme on our back end.
Remember that configuration file we edited before we first loaded our project? Well, it’s now accessible through the admin. Go to Configuration > Main configuration
, and it’ll load up the file. There’s a whole host of configuration options here, but we’ll stick to just three for now:
- Edit the
sitename
to your site name. - Edit the
payoff
to your site’s tagline - Edit the
theme
to the newly created theme (my-theme
in my case)
After that, save the configuration file. Now go ahead and create an index.twig
file inside your theme, and just input some boilerplate code like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My Website</title>
<link rel="stylesheet" href="http://bootswatch.com/superhero/bootstrap.min.css">
</head>
<body>
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Site Title</a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a href="#">Lorem</a></li>
<li><a href="#">Ipsum</a></li>
<li><a href="#">Dolor</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container -->
</nav>
<main>
<div class="container">
<div class="jumbotron">
<h1>Hello, world!</h1>
<p>Welcome to my first bolt site.</p>
</div>
</div>
</main>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
</body>
</html>
Notice that I’ve included a bootstrap template so that we have some aesthetics going on. You’ll probably want to link to your own CSS files, and don’t worry, I’ll show you how to do that soon. Hit refresh on the front-end window, and voila, your brand new site is waiting to be filled with delicious templates and content! But with many pages in the mix, it’s a hugely unsustainable and terrible practice to copy and paste entire chunks of reusable template code into new files, over and over again. Let’s get into templating a little bit.
Splitting Up Files Into Templates
As with any modern day website, particularly CMSs, we want to call upon different template files as needed. If you head on over to the “building templates” section of the docs, you’ll get some valuable information to help you out. Based on Bolt’s recommended file structure, and our current template, we can easily extract two main parts from our existing index.twig
file:
_header.twig
_footer.twig
Now, our main index file should look like this:
{% include '_header.twig' %}
<main>
<div class="container">
<div class="jumbotron">
<h1>Hello, world!</h1>
<p>Welcome to my first bolt site.</p>
</div>
</div>
</main>
{% include '_footer.twig' %}
The relevant parts have been extracted into their respective files, but I won’t include them here to overstate the obvious. Now that we’ve touched on the basics of templating, let’s move on to content types and records, i.e. content creation, storage, and retrieval.
Introducing and Creating Content Types
We’re talking about a CMS here, so naturally, we’re going to be pulling some kind of content and records from a database. Let’s assume that we’re building a little business website, and we want to have three static pages and one testimonials page with multiple testimonial entires. So we’re looking at this sort of navigation:
- home
- about
- testimonials
- single testimonial
- ...
- contact
Let’s roll with this idea for the remainder of this article, so that we have something to build on. This brings us to the next main feature, and perhaps the main feature, of Bolt CMS – Content types and records. They concatenate the two words in the docs, because that’s how we reference them in the code, so from now on we’ll be calling them “contenttypes”.
So what exactly is a contenttype? Here’s a little excerpt from the Bolt docs:
All content in Bolt is stored in the database in a logical and flexible fashion. In general…you have an idea what kind of content you’re going to be managing. All of these different types of content are called Contenttypes in Bolt, and you can add as many different contenttypes as you need.
Apart from a couple required “Fields” that are used internally, we’re pretty much free to define how the Contenttype is structured. In the case of our static pages, we might want to include title
, teaser
, image
, and body
fields. In the case of our testimonials, we’ll probably want something like name
, position
, body
, and date
. Let’s examine this a bit more.
If we head over to our admin dashboard, you’ll notice that under the Content section, there are three different types of content that we can enter:
- Pages
- Entries
- Showcases
These are actually contenttypes, and are all defined inside our contenttypes.yml
file. Bolt makes it easy for us, and we can access this file directly through the admin (Configuration > Contenttypes
). After studying the current contents of this file, let’s go ahead and delete everything except the pages
content type. Our file should now look like this:
# Pages - used for the static pages like about, contact, etc.
pages:
name: Pages
singular_name: Page
fields:
title:
type: text
class: large
group: content
slug:
type: slug
uses: title
image:
type: image
teaser:
type: html
height: 150px
body:
type: html
height: 300px
template:
type: templateselect
filter: '*.twig'
taxonomy: [ chapters ]
recordsperpage: 100
When you save that, you should notice that you no longer have access to the entries
and showcases
contenttypes. Let’s try to create our own for testimonials before we add any content. Head over to the “defining contenttypes” section in the docs, and let’s read through a bit. We’ll definitely want a name
and singular_name
, and our fields will be as we mentioned above. Let’s add our testimonial contenttype:
# Testimonials
testimonials:
name: Testimonials
singular_name: Testimonial
fields:
name:
type: text
class: large
position:
type: text
body:
type: textarea
height: 150px
Save, and now you might get an alert to go and update your database. Follow the instructions, refresh, and now we can add a testimonial. Let’s quickly create a new testimonial, add some dummy data to it, and save it. We’ve just created our first contenttype, added a new entry, and stored it in the database. We’re not quite there yet, though. You’re probably wondering how to access and display these records. Well, let’s look at that in the next section.
Retrieving Content From Database Records
We’re going to backtrack just a little bit here, because we ignored a couple of important features. By default, Bolt looks for a record.twig
template file to output the “record”, or the contenttype entry. If we preview that testimonial we just created, we’ll get an error thrown at us telling us that Bolt tried to use record.twig
, and it doesn’t exist. Let’s create that and throw in some dummy content:
{% include '_header.twig' %}
<main>
<div class="container">
<div class="page-header">
<h1>Record!</h1>
<p>This is a generic record.</p>
</div>
<div class="page-content">
<h2>Record Stuff Here</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sint eum tempore optio corporis aspernatur tempora temporibus vero maxime consectetur dolorum dolore vel numquam aut iure, esse, repudiandae nemo animi, vitae.</p>
</div>
</div>
</main>
{% include '_footer.twig' %}
Now if we hit refresh on our preview, we’ll see that we’ve generated the generic record page with dummy data. This brings us to point number two, though. It’s highly unlikely that the template for a testimonial will be the same as the template for a static page, so let’s fix that. Back in the defining contenttypes docs, we’ll see a few other things of interest:
record_template
– the template to display a single record of a contenttypelisting_template
– the template to display the collection of records of a contenttype
As we already know, by default, record_template
will use the record.twig
template file by default. For listing_template
, it’ll search for the listing.twig
file by default. We can, however, override these in our configuration of our contenttype. Let’s update it like this:
# Testimonials
testimonials:
name: Testimonials
singular_name: Testimonial
fields:
name:
type: text
class: large
position:
type: text
body:
type: textarea
height: 150px
listing_template: testimonials.twig
record_template: testimonial.twig
Now, let’s create the respective testimonials.twig
and testimonial.twig
files. Here are the two files I created:
testimonials.twig
{% include '_header.twig' %}
<main>
<div class="container">
<div class="page-header">
<h1>Testimonials!</h1>
<p>All the testimonials be here.</p>
</div>
<div class="page-content">
<p>All testimonials...</p>
</div>
</div>
</main>
{% include '_footer.twig' %}
testimonial.twig
{% include '_header.twig' %}
<main>
<div class="container">
<div class="page-header">
<h1>Testimonial!</h1>
<p>This is a testimonial.</p>
</div>
<div class="page-content">
<p>Testimonial content...</p>
</div>
</div>
</main>
{% include '_footer.twig' %}
Now, we can access the overview page in the browser like via /testimonials
, and our first record via /testimonial/1
(which is the default slug structure for records). Let’s focus on the single testimonial for now, and retrieve the data. Inside a single record page, we have access to the record
values. To increase code readability, we can access it by the record name, in our case testimonial
. If we go ahead and enter {{ dump(testimonial) }}
in our record template, we’ll see the entire record dumped on our screen.
So how do we access parts of it? With Twig templating, we can access the various values by simple dot-notation. In other words, if we wanted the “name” of the person who wrote the testimonial (as defined in our contenttype configuration), we’d access it like this:
{{ testimonial.name }}
With that in mind, let’s configure our template to pull in the content:
{% include '_header.twig' %}
<main>
<div class="container">
<div class="page-header">
<h1>{{ testimonial.name }} | <small>{{ testimonial.position }}</small></h1>
<time>{{ testimonial.datecreated|date("jS F, Y") }}</time>
</div>
<div class="page-content">
{{ testimonial.body }}
</div>
</div>
</main>
{% include '_footer.twig' %}
Now, creating more testimonials and viewing them should be a breeze. Let’s now head to our testimonials.twig
template, and try to retrieve all testimonials. Just as we were able to before, we can access the “records” by name. We can call upon records
, or in this case, testimonials
. Go ahead and dump that out onto your page, and you’ll see them all.
Twig templating offer neat ways to iterate over arrays, along with some filters. I won’t get into too much detail here, but you’ve seen the first filter in action above when we formatted the date. I’ll use another filter to truncate the testimonial body to 100 characters. Our testimonials template should now look like this:
{% include '_header.twig' %}
<main>
<div class="container">
<div class="page-header">
<h1>Testimonials</h1>
<p>All the testimonials for this great company be here.</p>
</div>
<div class="page-content">
{% for testimonial in testimonials %}
<div class="testimonial">
<h3>{{ testimonial.name }} | <small>{{ testimonial.position }}</small></h3>
<p>{{ testimonial.body|excerpt(100) }}</p>
</div>
{% endfor %}
</div>
</div>
</main>
{% include '_footer.twig' %}
And there you go! Navigate over to /testimonials
, and you’ll see the looped, formatted output. Go ahead now and populate your about page and contact page, and try to output the records in the generic record.twig
template file. If you feel like you want a specific template for pages, create a page.twig
file and go from there the same way as above. You’re now properly on your way to building up your site just the way you want.
A Note On Images & Media
One thing we haven’t touched on at all here is how Bolt handles media uploads. If you’re coming from a WordPress background, you’re most likely interested in the way WordPress handles media, with its robust, and (personally speaking) easy to use media library. Bolt is a constant work in progress, and there’s no doubt that there’s some room for improvement here. But once you get accustomed to the file management system, it becomes a bit easier.
In Bolt terminology, images are kept “on the stack”. This just means that there’s a stack of images that you manually uploaded. If you take a look at the directory structure, you’ll see the files
directory. Here is where uploads are stored. When you upload a file in the admin, it’ll store it in a sub-directory referencing the year and month of the upload. Now, if you have a regular HTML field in your contenttype, and you’re trying to get an image in there, you might be a bit confused at this point. There’s no actual button to upload the image! Why is this?
By default, Bolt disables the image button from the WYSIWYG editor. Lucky for us, that’s easily accessible from the main configuration file. Inside the admin, head to settings -> configuration -> main configuration
, and scroll down to the WYSIWYG section. There, you can change the images setting to true. Back in your record editor, you can now insert images the way you’d expect.
Where To Go From Here
There’s a whole lot more to Bolt than what we’ve seen, and that’s what makes it beautiful to work with. It’s feature rich, but only when you want it to be. It remains lightweight and fast throughout development and production, and just feels natural and easy to use. From here on, I recommend reading through the documentation. It’s really well written and easy to follow, and it answers a lot of your questions. My two top choice sections in the docs to boost your knowledge and workflow would be content fetching and template tags. After that, you’re looking at pagination, search, extending Bolt, and the works.
Thanks for reading, and I hope this article gave you some great insight into building with Bolt CMS. If you’re a WordPress or Drupal developer, I highly encourage you to open your mind to new platforms like Bolt. You will not be disappointed at all!
Frequently Asked Questions (FAQs) about Using BoltCMS to Build a Small Business Website
What are the key features of BoltCMS that make it suitable for building a small business website?
BoltCMS is a simple, flexible, and powerful Content Management System (CMS) that is perfect for small businesses. It offers a user-friendly interface, making it easy for non-technical users to manage their website content. BoltCMS supports various content types, including pages, blog posts, and custom types, allowing businesses to create a diverse range of content. It also has a robust template system, enabling businesses to customize their website’s look and feel. Moreover, BoltCMS is built on modern technologies like Symfony and Twig, ensuring a secure and efficient website.
How easy is it to install and set up BoltCMS?
Installing and setting up BoltCMS is straightforward. It requires a server with PHP and a database (SQLite, MySQL, or PostgreSQL). The installation process involves downloading the BoltCMS package, uploading it to your server, and running the installation script. After installation, you can access the BoltCMS dashboard to configure your website settings and start creating content.
Can I customize the design of my BoltCMS website?
Yes, BoltCMS offers extensive customization options. It uses the Twig templating engine, which allows you to create custom templates for different content types. You can also modify the CSS and JavaScript files to change the website’s appearance and behavior. Additionally, BoltCMS supports themes, which you can use to quickly change your website’s design.
How secure is a website built with BoltCMS?
BoltCMS is built on the Symfony framework, which follows best security practices. It includes features like CSRF protection, XSS prevention, and SQL injection prevention. Moreover, BoltCMS regularly releases updates to fix any security vulnerabilities.
Does BoltCMS support SEO?
Yes, BoltCMS has built-in SEO features. It generates SEO-friendly URLs and includes fields for meta tags. You can also install SEO plugins to further optimize your website for search engines.
Can I add a blog to my BoltCMS website?
Yes, BoltCMS supports multiple content types, including blog posts. You can easily create a blog section on your website and manage your blog posts from the BoltCMS dashboard.
Does BoltCMS offer any plugins or extensions?
Yes, BoltCMS has a marketplace where you can find various plugins and extensions. These can add new features to your website, like contact forms, social media integration, and more.
Can I migrate my existing website to BoltCMS?
Yes, it’s possible to migrate your existing website to BoltCMS. The process involves exporting your current website’s content, importing it into BoltCMS, and setting up your BoltCMS website to match your old website’s structure and design.
How does BoltCMS handle media files?
BoltCMS includes a file manager that allows you to upload and manage media files. You can easily add images, videos, and other media to your content.
Can I use BoltCMS to create a multilingual website?
Yes, BoltCMS supports multilingual websites. You can create content in multiple languages and set up language switchers on your website.
I'm a web designer & developer from Trinidad & Tobago, with a degree in Mechanical Engineering. I love the logical side of the web, and I'm an artist/painter at heart. I endorse progressive web techniques, and try to learn something every day. I try to impart my knowledge as much as possible on my personal blog, callmenick.com. I love food, I surf every weekend, and I have an amazing creative partnership with fellow mischief maker Elena. Together, we run SAYSM.