steve.fm

A work in progress

Using Bootstrap Navigation in WordPress

The navigation bar of a website, or nav bar for short, is typically a collection of links displayed across the top of a site.

Both Bootstrap and WordPress have opinionated ways for structuring the navigation of a site. There are definite benefits to using WordPress’s menu manager and functions to display the menu items you set up in the Admin panel. Because the functions provided by WordPress output to a different format than Bootstrap, there are a few options to proceed.

  1. We could manually create the navigation bar and its items.
  2. We could build our own styles based on the output of the menu manager’s functions.
  3. We could use a third-party plugin to translate the menu manager’s output into a Bootstrap-friendly format.

The first and second options, while attractive now, probably won’t be best long-term. First — While my site only has a few items now, I’ll save time when I need to add items later if I build a dynamically generated menu. Second — Rolling my own styles only feels like it will save time. Even though I’m planning to modify the Bootstrap nav bar, I’ll probably end up replicating most, if not all, of its responsive functionality in both CSS and Javascript.

After doing some research, it seems like there’s a plugin for WordPress that does exactly what I want: [https://wordpress.org/plugins/my-bootstrap-menu/]. When getting up to speed quickly, I find that it’s typically best to try before you buy, and buy before you build. If I followed my own advice on this project, I’d probably be using Medium, but I don’t just want to write — I want to build.

Once I have a menu in place, the My Bootstrap Menu plugin will let me use it and will automatically style it. To get a menu to show up in WordPress admin, I’ll have to register it within my functions.php file.

add_action( 'init', 'register_my_menu' );
function register_header_menu() {
        register_nav_menu('header-menu',__( 'Header Menu' ));
}

Now that I’ve built it in the admin, I’ll add it to my header.php file by using the wp_nav_menu() function.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="Steve Carroll">

    <title>
        <?php echo get_bloginfo('name'); ?> &mdash;
        <?php echo get_bloginfo('description'); ?>
    </title>

    <script src="https://use.typekit.net/uqh7odo.js"></script>
    <script>try{Typekit.load({ async: true });}catch(e){}</script>

    <?php wp_head(); ?>
</head>
<body>
    
    <div class="page-header">
        <div class="container">
            <div class="row">
                <div class="col-sm-offset-2 col-md-offset-2 col-sm-10">
                    <h2><?php echo get_bloginfo('name') ?> <br>
                    <small><?php echo get_bloginfo('description') ?></small></h2>
                </div>
            </div>
        </div>
    </div>

    <?php wp_nav_menu( array( 'theme_location' => 'header-menu' ) ); ?>
    
    <div class="container">

It’s not Bootstrap themed yet, but it’s there. Now I’ll update the settings in the My Bootstrap Menu plugin to recognize that menu and convert it to Bootstrap’s navigation format.

It was that easy…

It is, however, not exactly how I want. I’d like the Home link to be aligned with my blog’s title and the content. Ideally, I’d also like the Caverly link to be right-aligned, but I can deal with everything left-aligned for now.

How’d we get there?

I added the following to my stevefm.less file:

.navbar-inner .navbar-collapse {
    .row;
    > div {
        .make-md-column(7);
        .make-sm-column(9);
        .make-sm-column-offset(2);
    }
}

Looking at the source code that My Bootstrap Menu generated for WordPress, I was able to apply some of Bootstrap’s mixins to the menu structure so it would align correctly. Basically, I made the generated elements behave like a .container class with a .row and .col-* classes depending on the screen size.

Read more about Building Steve.fm

Tinkering

If this is my first post on tinkering, I should get a medal. If not, well… that’s to be expected.

I tend to enjoy messing with things until I get them right.

Currently, I’m stuck in a bit of a hard spot. I want to get a few things squared away before my next post, but I might just post this one describing where I’m stuck now with the site, and we’ll see how we work it out.

The site has three priorities right now, as I see it:

  1. Get navigation up and running.
  2. Figure out good typefaces at appropriate sizes for the body text, headings, and code… maybe the navigation while we’re at it.
  3. Update the style of the code samples to be a little less “Bootstrap-y”, maybe with some syntax highlighting.

Right now, the blog looks more-or-less like this

Read more about Building Steve.fm

Displaying Dates for Every Post

Early on, I noticed a problem where the date was displaying for some of my posts and not others.

I did some quick Googling and found out there’s actually a WordPress Codex page for that the_date() function that recommends using a different function if you want to return the date for multiple posts made on the same day. While some people might just want to display the date for the top post and let others assume that all the posts following are from the same date, I want the date to be on every post.

In case you’re curious, I’m going to update the metadata section in my content.php file to use the get_the_date() function instead:

        <div class="blog-post-metadata">
            <?php the_author(); ?> <br>
            <?php echo get_the_date(); ?>
        </div>

I can also imagine a world where I make a post heading that contains the date for all posts within that date… and where I remove the author information tag as well. It doesn’t make much sense to display the author long-term for a site where I plan on being the only author. The name of the blog should give some indication.

Read more about Building Steve.fm

Customizing the Post Layout

When I first launched the blog, I didn’t care much how content was laid out, I just wanted to make sure things were displaying. Now that i’ve got this worked out, I want to get my posts set up a little nicer.

Ideally, I’ll have the post metadata on the lefthand side of the post, de-emphasized, and the post content to the right of it.

When the site gets scaled down to smaller devices, I want the metadata to shift below the post, rather than being before it. On left-to-right layouts, this tends to be an issue because typically the contpent that comes first left-to-right will be on the top for mobile devices. Bootstrap has a solution to this problem.

In Bootstrap’s responsive grid layouts, they have the option to push or pull columns for different size classes. What this means is that you can basically shift the contents when the devices get larger than a certain size. The actual order of blog post elements is:

  1. Title
  2. Content
  3. Metadata

So I’ll start off by structuring my content.php file with that in mind:

<!-- Title Row -->
<div class="row">
    <div class="col-sm-offset-2 col-md-offset-2 col-sm-8 col-md-6">
        <h2 class="blog-post-title"><?php the_title(); ?></h2>
    </div>
</div>

<!-- Content & Metadata Row -->
<div class="row">

    <!-- Content Column -->
    <div class="col-sm-8 col-md-6">
        <div class="blog-post">
            <?php the_content(); ?>
        </div>
    </div>

    <!-- Metadata Column -->
    <div class="col-sm-2 col-md-2">
        <div class="blog-post-metadata">
            <?php the_author(); ?> <br>
            <?php echo get_the_date(); ?>
        </div>
    </div>
</div>

<hr>

Larger Devices

Smaller Devices

While it’s not quite what we want for larger devices, it works well for smaller ones. Before we go into pushing and pulling, it helps to have a basic understanding about how Bootstrap’s grid system works.

Bootstrap grids are basically divided up into twelve columns. Twelve makes a lot of sense because it’s a relatively small and manageable number that’s evenly divisible by a lot of other numbers:

  • 1
  • 2
  • 3
  • 4
  • 6
  • 12

Those numbers can then be combined to make other combinations of numbers, leaving you with a lot of possibilities for how you arrange your grid. In fact, you don’t even have to get to twelve if you don’t want to. You can see in the code above, the content takes up 8 columns on small devices, but only 6 columns on medium-sized devices.

Once you specify the number of columns to use for an element, it will use that number of columns for all larger devices until you specify it again. For example, I’ve specified 8 columns on small — if I had not specified anything for medium, it would use 8 columns for medium, large, and extra large devices. For any devices smaller than “small”, the column would span the entire width of the device.

Now that we’ve got that under our belts, pushing and pulling should make a little more sense. Let’s say I have an element (A) that’s using 8 columns, then an element (B) that’s using 2 columns.

You can see that element A is using columns 1-8 and element B is using columns 9-10. To get element B into element A’s spot, I’ll have to pull it 8 columns. Because I have two different values at two different sizes, I’ll have to specify for each size class.

The code will look like this for the metadata column:

<!-- Metadata Column -->	
<div class="col-sm-2 col-md-2 col-md-pull-6 col-sm-pull-8">
    <div class="blog-post-metadata">
        <?php the_author(); ?> <br>
        <?php the_date(); ?>
    </div>
</div>

Yikes! To get this to display the way it’s supposed to, I also need to push my other content over:

<!-- Content Column -->
<div class="col-sm-8 col-md-6 col-md-push-2 col-sm-push-2">
    <div class="blog-post">
        <?php the_content(); ?>
    </div>
</div>

Read more about Building Steve.fm

Fixing Style Bugs

I had a few instances where some tricky bugs were showing up on my site. One was that when images were being loaded from Ulysses, they were displaying as gigantic images, far outside of the width I had set my posts. This made things looks pretty weird.

I fixed this by adding the properties from the responsive image class into my style.less file, which I renamed stevefm.less for clarity. In Less, I’m able to add all the properties of one class to another simply by putting it inside the other class, like so:

.blog-post img {
    .img-responsive;
}

In standard CSS, it would look more like this:

.blog-post img {
    display: block;
    max-width: 100%;
    height: auto;
}

See how Less saves time?

The second bug I ran into was that my blog style was starting to creep into my admin style. This might be tricky to see, but my serif typeface, Garamond, was creeping into everything!

I fixed this by changing the add_action() tag parameter in my functions.php — which is basically the name of the action that the function gets added to. What I didn’t know was that 'init' was also used on the Admin side! The functions.php file now looks like this:

<?php 
    add_action('wp_enqueue_scripts', 'add_theme_styles');
    add_action('wp_enqueue_styles', 'add_theme_scripts');

    function add_theme_styles() {
        wp_enqueue_style('stevefm', get_stylesheet_directory_uri().'/stylesheets/stevefm.less');
   }

    function add_theme_scripts() {
        wp_enqueue_script('jquery.min', get_stylesheet_directory_uri().'/bower_components/jquery/dist/jquery.min.js');
        wp_enqueue_script('bootstrap.min', get_stylesheet_directory_uri().'/bower_components/bootstrap/dist/js/bootstrap.min.js');
   }
 ?>
Read more about Building Steve.fm

Customizing Bootstrap

While it’s certainly not a bad look, I’d prefer to not use Bootstrap out of the box. Instead, I’ll be modifying some of the core Bootstrap components and adding some of my own styles to make it more my own.

The first thing I’m going to do is create my own custom variables file called stevefm-variables.less and import it right after I import Bootstrap in my style.less file. That way, I can safely overwrite Bootstrap’s variables with my own values.

Because I want to use a custom typeface from Adobe TypeKit, I’ll have to add their embed tag to my header.php within my <head> tags. I’ll put it just before the wp_head(); function.

I’ll also update the header to have my site’s name and description. The updated header file looks like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="Steve Carroll">

    <title>
        <?php echo get_bloginfo('name'); ?> &mdash;
        <?php echo get_bloginfo('description'); ?>
    </title>

    <script src="https://use.typekit.net/uqh7odo.js"></script>
    <script>try{Typekit.load({ async: true });}catch(e){}</script>

    <?php wp_head(); ?>
</head>
<body>
    
    <div class="jumbotron">
        <div class="container">
            <h1><?php echo get_bloginfo('name') ?></h1>
            <p><small><?php echo get_bloginfo('description') ?></small></p>
        </div>
    </div>

    <div class="container">

While I’m in the process of updating my formatting, I’m also going to take a minute to update the format of my posts in content.php. Right now, the text spans widely across large screens, such as laptops and desktop computers, which makes it difficult to read. I’ll use Bootstrap’s grid formatting with .col-* and .row to achieve the formatting I want at various sizes.

content.php

<div class="row">
    <div class="col-sm-8 col-md-6">
        <div class="blog-post">
            <h2 class="blog-post-title"><?php the_title(); ?></h2>
            
            <?php the_content(); ?>
            <p class="blog-post-metadata">&mdash;<?php the_author(); ?> <?php the_date(); ?></p>
            <hr>
        </div>
    </div>
</div>

I’ll also get rid of that text in my footer.php that says “this is the footer,” since I know it’s working correctly now.

And last but not least, my style.less now looks like this:

@import '../bower_components/bootstrap/less/bootstrap.less';
@import "stevefm-variables.less";


.blog-post-title {
    .h2;
    // margin-bottom: 0;
}

.blog-post-metadata {
    .small;
}

It’s all coming together!

Read more about Building Steve.fm

Deploying Local WordPress to a Server

Early on in registering my site with my hosting provider, I had an issue where the domain wouldn’t map over right away. Normally, this wouldn’t be a big deal, but since I had a chunk of time to really dig into building a WordPress site, I didn’t want to waste any of it waiting.

To get up an running quickly, I installed MAMP: Macintosh, Apache, MySQL, PHP. MAMP basically runs an Apache server on my Mac that has a MySQL database and support for the PHP programming language, which WordPress is built with. That way, I would be able to start building while my domain was busy mapping over to my new host from Tumblr.

Now that I have a site with a few posts, I figure it’s time to get it on the internet and continue working on it in the open.

Exporting the Database

Since I’ve already got WordPress installed on my host, I’m hoping this process will be fairly simple. This is a step I think I can actually skip. While I have test posts loaded into my local site, I don’t need the database since I’ll be publishing them using Ulysses. I will need to upload the other files, however.

Transferring Files via FTP

I’m going to use an app for the Mac called Transit. It’s built by a small team of Mac developers that make great software, and I try to support then whenever I can. Their products are always very thoughtful and functional — two keys to a great application.

Looks like I can just click and drag files over into the right directories and I’m done!

Publishing from Ulysses

As I mentioned in an earlier post, I use Ulysses for nearly all of my writing that involves a computer — As soon as they made the announcement that they were releasing an update where I could publish to WordPress, I decided to drop my Tumblr site and move everything to WordPress right away. It’s been a fun adventure so far… All I have to do to publish is click a share icon, enter my credentials, and let the magic happen.

Read more about Building Steve.fm

Adding Bootstrap

I’m going to take a shortcut for my site and install Bootstrap with Bower into my wp-content folder. I’ll update my style.less file to include the bootstrap.less and enqueue JQuery along with the necessary Bootstrap scripts in my functions.php file.

When I updated my style.less file to import the core Bootstrap file and loaded up my page, it didn’t load the styles as I was expecting. After searching around for about an hour, I realized that I had been updating the wrong file… doh!

style.less

@import '../bower_components/bootstrap/less/bootstrap.less';

functions.php

<?php 
    add_action('init', 'theme_enqueue_styles');
    add_action('init', 'theme_enqueue_scripts');

    function theme_enqueue_styles() {
        wp_enqueue_style('style', get_stylesheet_directory_uri().'/stylesheets/style.less');
   }

    function theme_enqueue_scripts() {
        wp_enqueue_script('jquery.min', get_stylesheet_directory_uri().'/bower_components/jquery/dist/jquery.min.js');
        wp_enqueue_script('bootstrap.min', get_stylesheet_directory_uri().'/bower_components/bootstrap/dist/js/bootstrap.min.js');
   }
 ?>

footer.php

        This is the footer
    </div>

    <?php wp_footer(); ?>
    
</body>
</html>

With the Bootstrap styles loaded, my site looks like this:

Read more about Building Steve.fm

Getting Set Up with Less and Some Basic Styles

I’m a big believer that strong typography can make a big difference between a great experience reading what someone has written and a subpar experience. It’s not something most people tend to notice, but when it’s done right, the typeface selection makes reading the site a lot easier.

Before I select the typeface for my site, I want to get it prepared with some basic styles. To do that, I’ll get it set up for the way I normally work.

I like to develop styles with a CSS pre-processor, like Less or Sass, that simplifies the process of writing CSS — Which has a nasty habit of making you repeat properties over and over, when it would be so much easier to just declare variables or functions, and creating stylesheets that are easier to navigate.

WordPress seems to have a great plugin for processing Less, and since it’s baked in to the current stable release of Bootstrap, so Less will be my choice. Who knows, maybe I’ll do a conversion to Sass at some point in the future and the newest version of Bootstrap in the future?

Installing WP Less

Installing WP Less could not have been easier. I just followed their instructions on the installation page in the WordPress Plugin Directory.

  1. Search for the plugin name (WP-LESS)
  2. Click on the install button
  3. Activate it

Once you activate it, they tell you to use the wp_enqueue_style() function to load in your *.less files.

Loading .less Files

To get started, I’ll create a style.less file in the same folder as my other files with the following:

body {
    font-family: 'Lucida Grande', 'Helvetica Neue', Arial, san-serif;
    padding: 50px;
    padding-top: 150px;
}

Now that this file has been created wit some very basic changes to typography and layout, I’ll need to add it. I’ll create a new file called functions.php that will load my stylesheet file using the wp_enqueue_style(). I’ll also need to include the <?php wp_head(); ?> function in my header.php file to make sure it works correctly:

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="Steve Carroll">

    <!-- Load our styles -->
    <?php wp_head(); ?>

Our new functions.php file should look like this:

<?php 
    add_action('init', 'theme_enqueue_styles');

    function theme_enqueue_styles() {
        wp_enqueue_style('style', get_stylesheet_directory_uri().'/stylesheets/style.less');
   }
 ?>

The first parameter we’ve included in this function is name name of our file. The second is for the directory where it’s kept. Since it’s in the same folder as our style.css file, we can use another function that automatically returns the directory it’s in,get_stylesheet_directory_url(). PHP uses dot-syntax to join strings together, so we can use a dot between the stylesheet directory function and our stylesheet directory to specify exactly where our style.less file will be kept.

It’s coming along!

Read more about Building Steve.fm

Dynamic Post Content

Because I don’t have my content.php file set up to load content, if I were to add a few posts to my WordPress site like you might do for other templates, those posts wouldn’t display on my site.

WordPress has a feature that they call “the loop” that lets you iterate over records in a collection. What this basically means is that if you have a bunch of posts, you can display those posts one-by-one. You can even use a template in the body of a loop to make sure that each post gets formatted as it should. With my blog as it currently is, that means the title goes at the top, the content of my post goes in the middle, and the metadata of my post goes at the end.

I’m going to create a loop on my index.php page that loads posts from my blog according to the content.php template I’ve already created.

<?php get_header(); ?>

<!-- Display each post until there are no more posts -->
<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
    <?php get_template_part('content'); ?>
<?php endwhile; else: ?>
    <p><?php _e('Sorry, no posts!'); ?></p>
<?php endif; ?>

<?php get_footer(); ?>

Since I’ve added three posts to my site to test, my content.php template should load three times. It won’t yet be dynamic at this point because I haven’t told it to pull any of the values from the posts it’s pulling — only to pull as many times as there are posts.

The function that loops through my posts does a few things. First, it checks to see if there are any posts. Then, it displays the first post it finds. After that, as long as there are more posts to display, it will continue to display them. Once there are no more posts, it stops trying to display them. If it turned out there were never any posts to display in the first place, it would display a message to my site’s visitors that lets them know there are no posts available for their selection.

Why is this important?

Primarily, it’s important because we keep bringing up the word “post”. My posts are an instance of the wp_post class in WordPress. Every post I make on my site has the same properties available as the wp_post class, although the values may be different. This means that I can use the Class Reference for WPPost that WordPress provides to figure out how to display information from my posts.

One of the many concepts I have learned through trying new things over and over again is that figuring how to get to the answer is as important as getting the answer. I’m sure it won’t be long until I have my post content showing up.

My content.php file looks like this currently:

<div class="blog-post">
    <h2 class="blog-post-title">My Clever Title</h2>
        <p>This is the content of the post. Not very fancy, but it's loaded.</p>
        <p class="blog-post-metadata">Steve Carroll &mdash; 9:42pm on September 3, 2016</p>
        <hr>
</div>

From this, I have decided that I want to load the title from my posts, as well as the content, author, and date/time it was created. I’m not sure why, but while in the loop instead of individual pages, the properties must be prefixed by “the” instead of “post”. I’ve updated my content.php to access these properties from my posts.

<div class="blog-post">
    <h2 class="blog-post-title"><?php the_title(); ?></h2>
    <p><?php the_content(); ?></p>
    <p class="blog-post-metadata"><?php the_author(); ?> &mdash; <?php the_date(); ?></p>
    <hr>
</div>

And there you have it!

At this point, I’ve got a basic homepage set up where all my posts will be loaded to the page with new posts positioned at the top. I’ll probably want to handle pagination or some lazy loading at some point in the future, but I don’t have enough written yet to really justify that. So it makes sense at this point to start working on getting everything to look a bit better.

Read more about Building Steve.fm