How to Create a WordPress Theme with Twitter Bootstrap

Bootstrap can be adapted towards a wide range of applications, for example, content management. WordPress’s complex but easy-to-use theme structure is a great platform for taking advantage of this. Since our primary focus will be on the versatility of Bootstrap as a framework, this tutorial may assume you’ve already some basic knowledge of theming for WordPress.


View Demo | Download Source Files


The markup for this demo’s purposes will be based off an example from Bootstrap’s official site. From this single file, we’ll now want to separate the markup into a WordPress-compatible template structure. We’ll need at the very least to incorporate our Bootstrap layout into header.php, index.php, sidebar.php, and footer.php.

Here’s how header.php looks at its most basic:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Bootstrap, from Twitter</title>
    <link rel="pingback" href="<?php bloginfo('pingback_url'); ?>" />
    <link href="<?php bloginfo('template_url'); ?>/css/bootstrap.min.css" rel="stylesheet">
    <link href="<?php bloginfo('template_url'); ?>/css/bootstrap-responsive.min.css" rel="stylesheet">

    <?php wp_head(); ?>
  </head>

  <body <?php body_class(); ?>>

    <div class="navbar navbar-inverse navbar-fixed-top">
      <div class="navbar-inner">
        <div class="container-fluid">
          <button type="button" class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="brand" href="<?php echo get_option('home'); ?>/"><?php bloginfo('name'); ?></a>
          <div class="nav-collapse collapse">
            <p class="navbar-text pull-right">
              Logged in as <a href="#" class="navbar-link">Username</a>
            </p>
            <ul class="nav">
              <li class="active"><a href="<?php echo get_option('home'); ?>/">Home</a></li>
              <li><a href="#about">About</a></li>
              <li><a href="#contact">Contact</a></li>
            </ul>
          </div><!--/.nav-collapse -->
        </div>
      </div>
    </div>

    <div class="container-fluid">
      <div class="row-fluid">

	<?php get_sidebar(); ?>

        <div class="span9">

Note where the PHP calls to the wp_head + sidebar data. Note where we’ve included the site title + home link with bloginfo(‘name’); and echo get_option(‘home’); respectively. Also called is the wp_head data right before the body opens.

More importantly, see that get_sidebar(); call? That’s our reference to sidebar.php:

<div id="sidebar" class="span3">
    <div class="well sidebar-nav">
        <ul class="nav nav-list">
            <?php dynamic_sidebar( $index ); ?> 
        </ul>
    </div>
</div>

The dynamic_sidebar function calls your WordPress widgets if you have any setup. From there, we continue into index.php:

<?php get_header(); ?>

<div class="hero-unit">
<h1>Hello, world!</h1>
<p>This mini-site demonstrates integration of all necessary WordPress template elements into the Bootstrap framework. Below this hero unit are a few of the most recent posts, which will fill out dynamically in span4-classed divs. A post template is also included and can be viewed by selecting one of the entries.</p>
</div>

<div class="row-fluid">
	<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
          <div class="span4" <?php post_class() ?> id="post-<?php the_ID(); ?>">
              <h2><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h2>
              <?php include (TEMPLATEPATH . '/inc/meta.php' ); ?>
              <div class="entry">
                <?php the_excerpt(); ?>
              </div>
              <div class="postmetadata">
                <?php the_tags('Tags: ', ', ', '<br />'); ?>
                Posted in <?php the_category(', ') ?> | 
                <?php comments_popup_link('No Comments &#187;', '1 Comment &#187;', '% Comments &#187;'); ?>
              </div>
          <p><a class="btn" href="<?php the_permalink() ?>">Read More &raquo;</a></p>
        </div><!--/span-->

	<?php endwhile; ?>
	<?php include (TEMPLATEPATH . '/inc/nav.php' ); ?>
	<?php else : ?>
	  <h2>Not Found</h2>
	<?php endif; ?>
</div><!--/row-->

<?php get_footer(); ?>

Contained here are our calls to the header and footer data. Inside those two tags is what will make up the main content area. For the homepage, we have a hero unit and a quick setup for displaying recent posts. Each post is wrapped in the span4 class to tile dynamically within the row-fluid div. The title, excerpt, and meta-data makes up each tile.

After this, we’ll end with footer.php:

        </div><!--/span-->
      </div><!--/row-->

      <hr>

      <footer>
      	&copy;<?php echo date("Y"); echo " "; bloginfo('name'); ?>
      </footer>

    </div><!--/.fluid-container-->

    <script src="js/bootstrap.min.js"></script>
    <?php wp_footer(); ?>

  </body>
</html>

The most important element is the wp-footer function to close out the body. Voila, Bootstrap is now integrated as a WordPress theme. To flesh out the rest of the theme’s files, we’ve used the blank template provided by DigWP.com here. If you’re going with theirs, all you need to do is remove the get_sidebar calling your single.php + page.php files.

Check out the demo and try out the source files in your own WordPress site!


View Demo | Download Source Files


About Michael Milstead

Michael is a front-end developer who has enjoyed building websites for the past seven years.

2 Comments

  • AtomicSmash says:

    That’s a really simple and clean. Tried to explain to a colleague how easy it would be to inegrate Bootstrap into WordPress, this proves it!

    Cheers!

  • Theo says:

    Hi Michael,

    thanks for this. Was thinking of looking into this myself but am glad I discovered your tutorial.

    BTW did you notice that the Bootstrap responsive style sheet results in ugly results when you resize to medium sized screens. Elements on the sidebar (search, headings) show inside the content section (probably easiest solution is media query for medium sized screens with a min-width for the sidebar).

Leave a Reply

What is 10 + 8 ?
Please leave these two fields as-is:
IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)
Start planning your project today. Get Started