Tuesday, June 30, 2015

Organizing the Templates

Now that we have implemented the key template files (outside of commenting), we have introduced a significant amount of repetition; repetition is bad.  A simple fix is to move the common top and bottom of the HTML files into header.php and footer.php and then include them into each file.

header.php
<html>
  <head>
    <title>Barebones</title>
    <?php wp_head() ?>
  </head>
  <body>

footer.php
<?php wp_footer() ?>
  </body>
</html>    

And then into each of the other files we add the following to the top (replacing the header.php content):

<?php get_header(); ?>

and the following to the bottom (replacing the footer.php content):

<?php get_footer(); ?>

Adding Search

WordPress includes a search feature that is easy to implement.  On front-page.php add the following:

front-page.php
<?php get_search_form(); ?>

With this in place, the search results page is defaulting to index.php which does not work. We will start with copying page.php to search.php. We then will make some refinements.

search.php
<html>
  <head>
    <title>Barebones</title>
    <?php wp_head() ?>
  </head>
  <body>
    <?php wp_nav_menu(array('theme_location' => 'header-menu')); ?>
    <?php if (function_exists('yoast_breadcrumb')) {
      yoast_breadcrumb();
     }?>
    <?php get_search_form(); ?>
    <?php if (have_posts()) : ?>
      <?php while (have_posts()) : the_post(); ?>
        <p><b><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></b></p>
      <?php endwhile; ?>
    <?php else : ?>
      <p>No matches.</p>
    <?php endif; ?>
    <?php wp_footer() ?>
  </body>
</html>

Pinning Down Posts

Now that we have the infrastructure for the home page and the hierarchy of sub-pages, we need to explore content that is organized by time, i.e., posts, for ideas like press release archives.

First, we need to update the default category for posts and change its name from Uncategorized to something more useful, e.g., Press Releases, by using admin > Posts > Categories.

Then we create a couple of posts by using admin > Posts > All Posts.

Finally, we can go into admin > Appearance .> Menus to add the archive screen for the Press Releases category to the menu.

At this point, however, navigating to the category archive does not result in the desired result as it is picking up the index.php file for the template.  Looking at the template hierarchy again we see that we need to create archive.php by simply copying over page.php:  https://developer.wordpress.org/themes/basics/template-hierarchy/.

The problem now, however, is that the screen is not geared towards a list of posts.  A better layout would a list of as follows:

Post Title (linked to full post)
Post Date
Beginning part of the post.

To implement this, we update archive.php as follows:

archive.php
<html>
  <head>
    <title>Barebones</title>
    <?php wp_head() ?>
  </head>
  <body>
    <?php wp_nav_menu(array('theme_location' => 'header-menu')); ?>
    <?php if (function_exists('yoast_breadcrumb')) {
      yoast_breadcrumb();
     }?>
    <?php while (have_posts()) : the_post(); ?>
      <p><b><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></b><br />
      <i><?php the_time('F j, Y'); ?></i><br />
      <?php the_content('', false); ?></p>
    <?php endwhile; ?>
    <?php wp_footer() ?>
  </body>
</html>

Now that we have the archive, the link to the full post brings up our index.php for the template.  To fix this, we copy page.php to single.php and update as follows:

single.php
<html>
  <head>
    <title>Barebones</title>
    <?php wp_head() ?>
  </head>
  <body>
    <?php wp_nav_menu(array('theme_location' => 'header-menu')); ?>
    <?php if (function_exists('yoast_breadcrumb')) {
      yoast_breadcrumb();
    }?>
    <?php while (have_posts()) : the_post(); ?>
      <p><b><?php the_title(); ?></b><br />
      <i><?php the_time('F j, Y'); ?></i><br /></p>
      <?php the_content(); ?>
    <?php endwhile; ?>
    <?php wp_footer() ?>
  </body>
</html>

Finally, in order to get the breadcrumbs to work for post pages change admin > SEO > Advanced > Taxonomy to... > Posts to Category.

Refining the Templates

Now that we have added the breadcrumbs, we might be thinking that we do not need it on the home page, just on the sub-pages. As a matter of fact, we likely are thinking that the home page need a completely different structure than the sub-pages.  Looking back at the template hierarchy we can address this easily: https://developer.wordpress.org/themes/basics/template-hierarchy/.

We start by copying index.php to three new files:

  • front-page.php
  • page.php
  • 404.php

On front-page.php, we can delete the breadcrumb block.

On 404.php, we can delete the breadcrumb and "The Loop" block, i.e., the code looping on posts and add a bit about the page not being found.

Because we are not currently using, posts, search, or commenting the index.php file is no longer in use. For completeness, we can change the content of index.php to look like the 404.php file as a catch all.

Monday, June 29, 2015

Menuing

With out three page structure, we need to a way to navigate from the home page to the pages A and B. Luckily, WordPress provides a navigation menus feature that makes this easy: https://codex.wordpress.org/Navigation_Menus.

The first step is to add to functions.php:

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

note: The weird double-underscore is use for language, e.g., Spanish, translation if enabled.

Then we add the following just below the body tag in index.php.

index.php
<?php wp_nav_menu(array('theme_location' => 'header-menu')); ?>

Now as we update the menu in admin > Appearance > Menus, we can see the changes reflected on all of the pages.

Setting Up Permalinks

A quick visit to admin > Settings > Permalinks (e.g., setting it to Post name) will give one nice looking URLs.

Setting Up Breadcrumbs

This is essentially the "menu" for navigating back up the hierarchy of pages.

Here we use our first Wordpress Plugin; the one that we are using is called WordPress SEO  Use admin > Plugins to get this done and insert the following in index.php where one wants the breadcrumb to appear, e.g., just below the navigation menu.

index.php
<?php if (function_exists('yoast_breadcrumb')) {
  yoast_breadcrumb();
}?>

note: This plug-in serves a number other SEO purposes that we will address in a later post.

Adding in Third-Party CSS and JavaScript Libraries

Because we are going to want to use third-party CSS and JavaScript libraries, we need to learn how to accomplish this in Wordpress.

As an example, we are going to load the Bootstrap library: http://getbootstrap.com/. The first step is to get the files into the template folder, e.g., wp-content/themes/barbones.  In my case, I used a tool called bower to get the files downloaded: http://bower.io/.

We do this by simply updating index.php as follows:

index.php
<html>
  <head>
    <title>Barebones</title>
    <link rel="stylesheet" href="<?php echo bloginfo("template_url"); ?>/bower_components/bootstrap/dist/css/bootstrap.min.css">
    <link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>">
  </head>
  <body>
    <?php while (have_posts()) : the_post(); ?>
      <?php the_content(); ?>
    <?php endwhile; ?>
    <script src="<?php echo bloginfo("template_url"); ?>/bower_components/jquery/dist/jquery.min.js"></script>
    <script src="<?php echo bloginfo("template_url"); ?>/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
  </body>
</html>

note: The locations of one's bootstrap files will differ depending on how one download them.

A Better Way

While the above method is super clean, it does not play well with Wordpress and other plugins, e.g., any JavaScript or CSS that they need will not be inserted.  The most obvious example of this is the lack of the WordPress toolbar when logged in.

The proper way then involves registration and enqueueing both JavaScript and CSS resources; e.g., the following explains script registration: https://codex.wordpress.org/Function_Reference/wp_register_script.

The first step is to create and update the functions.php file with the following as the example of using bootstrap:

functions.php
<?php
  function add_theme_scripts() {
    wp_register_style('bootstrap',
      get_template_directory_uri() .
      '/bower_components/bootstrap/dist/css/bootstrap.min.css',
      array(), '20150629', 'all');
    wp_register_style('style', get_stylesheet_uri(),
      array(), '20150629', 'all');
    wp_register_script('bootstrap',
      get_template_directory_uri() .
      '/bower_components/bootstrap/dist/js/bootstrap.min.js',
      array('jquery'), '20150629', true);
    wp_enqueue_style('bootstrap');
    wp_enqueue_style('style');
    wp_enqueue_script('bootstrap');
  }
  add_action('wp_enqueue_scripts', 'add_theme_scripts');
// REMOVED CLOSING TAG PER WP CODING STANDARDS

note: As to removing the closing tag: https://make.wordpress.org/core/handbook/coding-standards/php/#remove-trailing-spaces.

Then we need to update index.php as follows:

index.php
<html>
  <head>
    <title>Barebones</title>
    <?php wp_head() ?>
  </head>
  <body>
    <?php while (have_posts()) : the_post(); ?>
      <?php the_content(); ?>
    <?php endwhile; ?>
    <?php wp_footer() ?>
  </body>
</html>

A Minimally Useful Theme

Now we are going to make the theme minimally useful by updating the index.php and the style.css files.

index.js
<html>
  <head>
    <title>Barebones</title>
    <link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>">
  </head>
  <body>
    <?php while (have_posts()) : the_post(); ?>
      <?php the_content(); ?>
    <?php endwhile; ?>
  </body>
</html>

style.css
body {
  background-color: yellow;
}

The first thing one will notice is that the stylesheet is now being applied (however hideous).  In order to see the posts (actually can be either posts or pages) showing on the screen, we need to add some content.  Since we are focused on creating a home page and a hierarchy of sub pages, we will create the following pages with some random content, e.g., "hello from page A", etc.
  • home
  • A
  • B
note: We will treat pages A and B as top level pages instead of setting home as their parent to give us clean URLs later.

When viewing a page, i.e., selecting view from admin,  one will now see the content displayed on the screen.

Finally, we will go ahead and set the home page to load as what loads when the site is loaded without any query string (i.e., the home page of the site). Use admin > settings > reading > Front page displays to set this.

Sunday, June 28, 2015

Bootstrapping a Theme

This series of posts explores the basics of creating WordPress themes for one's use; as opposed to creating one for redistribution.  The distinction is important as we will only focus on developing it for a particular use and thus greatly simplify the effort.

This particular use will to have:
  • Static Home Page
  • Hierarchy of Sub Pages
  • Search
  • Press Releases
  • Mega Menu
  • Breadcrumbs
This effort also is focused on giving one maximal control over the site (HTML, CSS, and JavaScript) with minimal use of programming (WordPress and PHP).

The starting point to understanding theme development is the template hierarchy: https://developer.wordpress.org/themes/basics/template-hierarchy/.  Rather than building out a bunch of template files to start with; we will start slowly and introduce them one at a time.

Bootstrapping a Theme

Create a new folder for your theme, e.g., barebones, in the WordPress folder: wp-content/themes.

Populate this new folder with two files:

index.php
<html>
  <head>
    <title>Barebones</title>
  </head>
  <body>
    <p>Hello Barebones</p>
  </body>
</html>
An empty style.css file.

At this point we have a theme that we can activate.  This theme, however, is not terrible useful at all that it does is display the text Hello Barebones regardless of the query string.