Build A WordPress Theme From Scratch With Bootstrap
In the last few months I’ve spent a load of time building WordPress themes with Bootstrap. If you needed to you could easily build a whole themes from scratch in less than a day with it – that’s the beauty of front-end frameworks. Working with front-end frameworks really does take WordPress theme development to a new level. You can make some amazing things in a short period of time.
Building a WordPress theme from scratch might be quite daunting, but trust me it’s really not. You only need a handful of different files. Most of the files are actually just html with some very basic WP specific php code and some styles. Getting things up and running with Bootstrap adds a few steps before you get started but it’s really nothing overly complicated so don’t worry. I’ll walk you through the whole thing, beginning to end.
Downloading Bootstrap
I’ve previously gone over the absolute minimum requirements for a theme before. You just need 2 files – style.css
and index.php
. To make it a Bootstrap powered theme you need a couple more files – the Bootstrap files.
The easiest way for you to get Bootstrap is to go and download it from the official Github page, or clone and fork it if you want. I recommend you download it from the customize page with all the boxes ticked, that way everything will be compiled into just 4 files (with 2 being the glyphicon halfling images).
If you download if from the homepage then you end up with multiple separate css files which you need to import separately, with it fully compiled it makes it a little bit easier.
You can also include the fully compiled versions of the files from a CDN if you wish.
Just so you know we will be using the full Bootstrap for development (all the css and js) but when it comes time to finish the theme I’ll walk you through removing any unused code to speed up your theme and slim down your code.
Preparing The Theme Folder
When you open up your Bootstrap zip it will look something like this.
You want to copy the css, js and img folder into your theme folder (any empty folder will do but it’s worth noting that if you include numbers in the folder name it may not show in the WP dashboard).
Once you’ve copied over those folders you will want to create 3 more files – functions.php
, index.php
and style.css
. Put them all in the folder along with Bootstrap. Your folder structure should look like this.
Setting up the theme
The first thing you need to do when creating any WordPress theme is add the required comment block to the top of the style.css
file.
A WordPress Style.css with Bootstrap Imported
This code tells WordPress that the files in this folder make a theme called My Bootstrap Theme, it’s version 0.1 of the theme and I’m the author. I’ve also imported the bootstrap.min.css
file – the minified version of Bootstrap’s stylesheet – which includes the responsive stylesheet.
/* Theme Name: My Bootstrap Theme Author: William Patton Author URI: http://www.pattonwebz.com/ Version: 0.1 */ @import url("css/bootstrap.min.css");
The WordPress Index.php File
The markup in the index.php
file is very basic, it shows the site title and has a basic loop but that’s it.
Paste this into the index file.
<!DOCTYPE html> <!--[if IE 7]> <html class="ie ie7" <?php language_attributes(); ?>> <![endif]--> <!--[if IE 8]> <html class="ie ie8" <?php language_attributes(); ?>> <![endif]--> <!--[if !(IE 7) | !(IE 8) ]><!--> <html <?php language_attributes(); ?>> <!--<![endif]--> <html> <head> <meta charset="<?php bloginfo( 'charset' ); ?>" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"> <title><?php wp_title(''); ?></title> <link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>" /> <?php wp_head(); ?> </head> <body <?php body_class(); ?>> <header> <div> <h1 id="site-title"><?php echo get_bloginfo('name') ?></h1> </div> </header> <section id="content"> <?php if ( have_posts() ) : ?> <?php /* Start the Loop */ ?> <?php while ( have_posts() ) : the_post(); ?> <h2><?php the_title(); ?></h2> <?pho the_content(); ?> <?php endwhile; ?> <?php endif; ?> </section> <?php wp_footer(); ?> </body> </html>
<!DOCTYPE html>
.You need to have a viewport width defined too in your head section. That’s done like this:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
.Our Basic Functions File
Now all we need to do is add a couple of php functions to get our style and script included. Not surprisingly we add them to the functions.php
file.
We just need 2 functions, one to add our stylesheet and one to add our Javascript. Technically both of these could be done in a single functions but I think it’s better practice to have one for styles and a separate one for javascript. Functions in WordPress tend to be created then hooked into other places. So we add the action (our function) to the appropriate hook. You can see an awesome list of hooks available compiled by Adam Brown on his site.
function enqueue_my_scripts() { wp_enqueue_script( 'jquery', '//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js', '1.9.1', true); // Bootstrap relies on we need the jquery library wp_enqueue_script( 'bootstrap-js', get_template_directory_uri() . '/js/bootstrap.min.js', array('jquery'), true); // all the Bootstrap javascript goodness } add_action('wp_enqueue_scripts', 'enqueue_my_scripts');
The above code creates a function which queues up the jQuery library and our Bootstrap JavaScript file. We also tell it that the bootstrap.min.js
depends on jQuery being loaded first, so it won’t load if jQuery doesn’t. The true directive at the end there tells WordPress we want them to be added in the footer to prevent pageload issues.
function enqueue_my_styles() { wp_enqueue_style( 'bootstrap-style', get_template_directory_uri() . '/css/bootstrap.min.css'); wp_enqueue_style( 'my-bootstrap-style', get_template_directory_uri() . '/style.css'); } add_action('wp_enqueue_scripts', 'enqueue_my_styles');
This code does almost exactly the same as the function to include the javascript, only this time we are doing it with stylesheets. We only have one stylesheet to include from Bootstrap and one of our own.
Functions.php
The complete functions.php
file just wraps those 2 functions in php tags. Together it all looks like this:
<?php function enqueue_my_scripts() { wp_enqueue_script( 'jquery', '//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js', array('jquery'), '1.9.1', true); // we need the jqyery library for the Bootstrap plugins wp_enqueue_script( 'bootstrap-js', 'js/bootstrap.min.js', array('jquery'), true); // all the Bootstrap javascript plugin goodness } add_action('wp_enqueue_scripts', 'enqueue_my_scripts'); function enqueue_my_styles() { wp_enqueue_style( 'bootstrap-style', get_template_directory_uri() . '/css/bootstrap.min.css'); wp_enqueue_style( 'my-bootstrap-style', get_template_directory_uri() . '/style.css'); } add_action('wp_enqueue_scripts', 'enqueue_my_styles'); ?>
Once you’ve done that you’re finished. You have a Bootstrap powered WordPress theme. It doesn’t look like much yet because we haven’t applied any of the Bootstrap styles to the markup but I’ll cover that in the next post.
Using Bootstrap Style In Your Theme
Eventually this theme will bulk up and become a completely functional styled theme. We’ll use the affix plugin to make some awesome floating social share buttons with Jetpack and we’ll make a responsive nav menu with a custom navwalker class – which adds glyphicons to menu items.
Next time I will add some Bootstrap markup and make the theme look like a proper webpage.
You have a small error in the index.php code , one of the <?php (at the end of it) is <?pho . Easy to find but doing this tutorial and seeing blank instead of ..something .. makes you think something you did was wrong .
Cheers,
George
Ahh George, thanks for the heads up, I hadn’t noticed any errors in the code recently. Last time I tested everything was a few months ago and it all worked fine. It’s been a few weeks since I last updated code in the post so that means that I introduced the error then it’s not been working for that amount of time… hardly the best impression to give people who are looking for help. I will run through the tutorial today and fix any problems then confirm everything works as expected again.
And thanks again for pointing it out, I’m actually pretty surprised that nobody else has left a comment telling me it’s broken or asking for help and I’m assuming it’s because of the same reason you give – because they think they did something wrong when in fact it was my fault 🙁
So it sounds like you eventually got it all working like you need it but if you still have any issues with anything to do with this (or Bootstrap in general) just give me a shout, I’m always happy to help 🙂
Hello William
This is very great, but the @import should not be used due to page speed
How can we include (support) bootstrap for our custom themes?
Can I just copy over all files form bootstrap to my css file?
(Sorry i am a very bloody beginner….)
Hey Daniel,
Very good point about
@import
being an issue in terms of page speed. You could just copy the contents of thebootstrap.css
file into your main stylesheet but the better option is including Bootstrap via thewp_enqueue_style();
function. Here’s the page in the WP Codex that explains thewp_enqueue_style()
function: http://codex.wordpress.org/Function_Reference/wp_enqueue_styleYou’ll need to add lines similar to this in your theme setup function:
Have a look in functions.php for lines that look like those that include your main
style.css
file and add it to the same function.And if you modify the register call for the main
style.css
file to set Bootstrap as a dependency of it then Bootstrap styles will always be included first (so you can do CSS overrides in thestyle.css
file easily).Let me know how you get on and feel free to give me a shout via the contact form on the site.
heh… thats cool 🙂
not only awesome instructions but also quiet fast!!
you should open a beginner-support agency 🙂
I am building a ultra-minimlistic theme according to your instructions here.
(functions.php, style.css, index.php and a 404.php – nothing more)
I added though a menu support so i can use the WP menu
Maybe I will widgetize it a bit too 🙂
Its already running 🙂
(very very minimal now)
For the rest I use wp-types plugin, for the construction….
🙂
thank you again for this instructions here.
You’re very welcome Daniel 🙂
I looked at your site and see an error notice at the moment though relating to an enqueue not being added at the right spot. The fix for that would be to add the enqueue inside a function. If you used this guide to start the theme then the function you want to add it too will be called ‘enqueue_my_styles()’.
Setting Bootstrap as a dependency in the code from this post would make that function into this:
Hello William
😀 yes I was screwing a bit…
Thank you!!
(I see now the difference)
just learned some new things here 😀
Thanks!!
very interesting how load time goes down with just this slight change, from approx 1.8 sec to 1.08 sec (Gmetrix)
I guess I (though the very minimal theme) do things still wrong, but maybe its also the wp-types plugin…
somehow I get 500 msec waiting time on the main site url…
weird. could a renamed wp-content folder be the issue?
Its manually renamed, with define values in the config.php file—
😀
thanks again!!
Renaming that folder should cause much, if any, slowdown so it’s something else that’s taking up that 500ms. To be honest 500ms response time isn’t all that bad compaired to the average time. Faster than about 60% of sites tested from the US. I use this site to check response speed: https://www.200please.com and your site scores well.
Since your theme is so minimal I can only assume that the 500ms is caused by either the plugins or by slow/badly configured hosting.
I’d be interested to hear if you ever figure out how to improve your response time and what you found caused it.
Hey William
Just wanted to let you know here that speed issues are 80% caused by the wp-types plugins
There are few @import calls,
not declared header expire,
and mainly, using Gtmetrix and your suggested tool above, non detectable huge waiting times (not detectable == it does not tell what it is that makes the “wait time”)
I assume because of not fully minified css, and some js parsing issue too, mostly related to those plugins
Fact is, enabling those plugins increases load time form 1.06 up to sometimes 3.0 sec (not felt, though)
It varies each time you test the site.
This only by activating the plugins…
So definitely not solvable from a “cutover perspective” 🙂
Your help was very great.
And your “theme” is definitely not the issue for the speed 🙂 🙂
Tnx
I have found a error if you try to load a carousel with the functions used in this tut.
TypeError: $(...).carousel is not a function
Stack-overflow members helped me solve it:
The correct enqueueing would be:
function enqueue_my_scripts() {
wp_enqueue_script( 'jquery', '//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js', array('jquery'), '1.9.1', false); // adding in header
wp_enqueue_script( 'bootstrap-js', get_template_directory_uri().'/js/bootstrap.min.js', array('jquery'), true); // addition of 'get_template_directory_uri()'
}
then the carousel works 🙂