Welcome to the third and final entry in the “Building an Assemble.io Blog” series. In Building an Assemble.io Blog: Part 1, I covered the basics including installation, layouts, adding entries, and displaying a posts list. In Building an Assemble.io Blog: Part 2, I abstracted common elements of the template into partials, added support for non-markdown pages, and added a home page featuring the latest blog entry.
This entry covers static blog assets, integrates Bootstrap styles into the blog, and adds Disqus comments for user feedback and interactivity.
Notes: The code in this tutorial is hosted on GitHub at https://github.com/webercoder/assembleio-blog. This post begins at the example-7 tag. Feel free to follow along if you’d like, or make you own!
Static Assets
All blogs have static assets such as images, scripts, and stylesheets that need to be deployed alongside the blog engine. Grunt can be configured to handle and deploy these assets.
Let’s start by adding a favicon to the site. I’ve picked this single color rubix cube icon for now. First make the static resources directory and add the favicon to it:
% mkdir src/static
% mv ~/location/of/favicon.ico src/static
Let’s configure Grunt to copy resources from our static folder to the build folder. We’ll be using grunt-contrib-copy for this task. First install the package:
% npm install --save-dev grunt-contrib-copy
Pop open our Gruntfile.js
and add the copy
code:
module.exports = function(grunt) {
'use strict';
grunt.initConfig({
// Tasks here
assemble: {
options: {
layout: 'default.hbs',
layoutdir: './src/layouts/',
partials: './src/layouts/partials/**/*.hbs',
helpers: './src/helpers/**/*.js'
},
blog: {
files: [{
cwd: './src/content',
dest: './build/',
expand: true,
src: ['**/*.md', '**/*.hbs']
}]
}
},
copy: {
'static-assets': {
files: [{
expand: true,
src: [
'./**/*'
],
dest: 'build/',
filter: 'isFile',
cwd: 'src/static/'
}]
}
}
});
// Load plugins for the above tasks
grunt.loadNpmTasks('assemble');
grunt.loadNpmTasks('grunt-contrib-copy');
// The default task or other custom tasks
grunt.registerTask('default', ['assemble', 'copy']);
};
I’ve added the copy
block, grunt.loadNpmTasks('grunt-contrib-copy')
, and registered
copy
to run as part of the default grunt.registerTask
call. The copy block will
copy everything in the src/static
folder into build/
.
Now run grunt
and load the site in your browser (/build/index.html
). You should see the favicon in
your address bar or somewhere around the page title.
Update: Sadly the favicon will not appear if
you are browsing the site from a subdirectory, as I advised above. Browsers automatically
load favicon’s from the website’s root directory, and since favicon.ico
is not in
the root above but in /build
, the browser will not retrieve it. We can get creative
with the Assemble relative linking and add a <link>
element to our header, or
you can load the blog from the root of your web server. I will update the blog to
use the first option in the future.
Git Checkpoint: The code above is available on the tag example-8 in the example Git repository.
Basic Styling
The visual design of the example blog is as barebones as it gets. Using Bootstrap we can add a clean new look to the site in minutes rather than days. In this post, I’ll cover how to integrate Bootstrap into this static publishing engine.
Note: Bootstrap uses a 12-column grid to simplify creating a layout. I won’t be covering this in detail, however. If you would like to know more, check out the official Bootstrap documenation.
First download Bootstrap from Bootstrap’s website
and place bootstrap.min.css
in to src/static/css
.
Next change src/layouts/partials/header.hbs
to look like this:
When linking to bootstrap.min.css
, I’ve used the {{relative page.dest ...}}
handlebar tag to create a relative link from the current page location. Doing this
keeps our code portable so it can be run under any directory.
Additionally, the new tags inside the body define a Bootstrap navbar and a container.
The navbar is very basic, containing only a single link to the home page. <div class="container">
is required by Bootstrap for styling purposes and is closed off in src/layouts/partials/footer.hbs
:
Next add a row and column to the page template, src/layouts/page.hbs
. This will
add our content to Bootstrap’s grid, allowing the content to flow as Bootstrap’s
authors designed.
You can later add other columns inside the row
as long as all the col-*-n classes
add up to 12. For example, we could do a two column layout using the following code:
In the snippet above the second column will be 2x the width of the first column.
Finally, add similar classes to src/layouts/page.hbs
:
With all that saved, run grunt
and then browser to the build
directory like before.
Looks much nicer! If you would like to know more about Bootstrap, start with their
Getting Started guide.
Git Checkpoint: The code above is available on the tag example-9 in the example Git repository.
Disqus Comments
As a static publishing engine, writing our own database-powered commenting system defeats the purpose. You could do something fancy like creating a JAWS Stack with AWS services or baking your own server side solution; or you can use Disqus. We’ll go with the latter for simplicity.
First signup for a Disqus account on disqus.com. At the time
of writing, you can register a new site with Disqus by clicking the top-right gear
to expose a menu, and clicking “Add Disqus to Site.” Fill in the required
information and click submit. Finally grab the universal code and add it to src/layouts/partials/footer.hbs
between a new Boostrap row and column:
After running grunt
once again, go to the site and view a blog entry. Comments
should be live!
Git Checkpoint: The code above is available on the tag example-10 in the example Git repository.
Conclusion
In this entry, we fleshed out our blog with static assets, Bootstrap styles, and a turn-key commenting system.
I hope you enjoyed the series! Feel free contact me if you have questions.