ClarkWP Word Pressings - commentaries and general tutorials.

An Abstract (and brief) Look Into WP Theme Development

Introduction

This article is first and foremost written to give insight on what comprises a WordPress Theme. Though I will be touching on many things needed this is not intended to be a how to on theme development. It is more so an insider look at the processes involved and the code needed to achieve various functionalities within the themes themselves.

What We Will Be Covering

For this article, we will be using a theme I am currently developing as a case study. We will be covering the basics of the theme as well as some of the more advanced features such as custom shortcodes, custom post types and various functions used throughout the theme.

Theme Basics

First off, if you don’t want a primer into themes, please skip to the next section.

The following are the basic constants when developing WordPress Themes, the core items and methods to turn what otherwise would be plain static HTML into a dynamic template file in a WordPress Theme.

The most important thing to understand about WordPress Themes is that they are modular. When talking WordPress, that means that parts of the templates are broken down into modules that are called in template files rather than hard coding them into every file. So, what does that look like? Lets take this extremely basic example static HTML5 page and break it down into WordPress modules.

Disclaimer: I did this all freestyle, so it may or may not work, it is a hypothetical, not to be taken literal as a working theme!

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <title>Example HTML Page</title>
    <meta name="viewport" content="width=device-width" />
    <link href="style.css" />
    </head>
    <body>
    <div id="wrapper">
    <section id="content" class="container" role="main">
      <article>
        <header>
          <h1>Example Article</h1>
        </header>
   <p>Lorem ipsum dolor sit amet...</p>
      </article>
    </section>
    </div>
    <footer>
      <p>Some footer content here</p>
    </footer>
    </body>
    </html>

Okay, that is all well and good, but what files do we need to create? Glad you asked! Here are the absolute baseline template pieces we will need to make our hypothetical theme(for our purposes):

  • header.php
  • page.php
  • footer.php
  • style.css

Note the names of these files, it the names are just as vital as the templates themselves. If you misname a template part, it could potentially break your theme.

Now here is how we break apart our initial HTML into the appropriate files.

header.php

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8" />
    <title>Example HTML Page</title>
    <meta name="viewport" content="width=device-width" />
    <?php wp_head();
      //We add this line so we can hook into
      it in our functions.php file, we also remove the stylesheet call
      because that will be handled with functions.php as well. ?>
    </head>
    <body>
    <div id="wrapper">
    <section id="content" class="container" role="main">

We will leave page.php empty for now, because that gets a little more complex. Let’s just go ahead and worry about our footer.php file which will look like this:

footer.php

    </section>
    </div>
    <footer>
      <p>Some footer content here</p>
    </footer>
    <?php wp_footer(); // Again this is used for hooking later on ?>
    </body>
    </html>

Now for our page.php file.

page.php

<!-- Start the loop -->
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
  <!-- Append the ID and class to the article element -->
  <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
    <header>
      <!-- Display the title of the page/post -->
      <h1><?php the_title(); ?></h1>
    </header>
    <!-- If there is a featured image, show it -->
    <?php if ( has_post_thumbnail() ) { the_post_thumbnail(); } ?>
    <!-- Display the content -->
    <?php the_content(); ?>
    <!-- I like to add a link to edit the post to improve usability -->
    <?php edit_post_link(); ?>
  </article>
<!-- Show the comments template if user is logged in -->
<?php if ( ! post_password_required() ) comments_template('', true); ?>
<!-- End the loop -->
<?php endwhile; endif; ?>

Okay, so I said you’d be getting your feet wet but I went ahead and shoved you in. As far as the loop goes, if there is content, loop through it, and display it on-screen. If you really want to get in-depth refer to the WordPress Codex article on the The WordPress Loop.

There are, however, a few lines I need to point out because they relate to how our content is displayed.

  • the_title(); – Gets the Title of a given page or post
  • the_content(); – Pulls the page content
  • edit_post_link(); – I like throwing this in there so there is an edit link available to editors and admins
  • if ( has_post_thumbnail() ) { the_post_thumbnail(); } – Get the featured image

Now that we have our base pages in place, we need to focus on functions.php and we can wrap up this little intro to WordPress themes.

Our functions.php file for all intents and purposes will be extremely bare, there are usually more than a few functions contained within the functions.php file to make the theme tick, but I won’t be getting into those here, that is something for a later chapter in this article. For this file, we are just going to enqueue our stylesheet to get our page back to what it was before.

To enqueue a script or stylesheet is essentially just a fancy way of telling WordPress to add our scripts and styles into the correct file at the correct time. In this case, the header.php file.
Note: you can set flags to have the function enqueue script files in the footer.

functions.php

<?php
function enqueue_scripts()
{
  // Add our style.css file to header.php
  wp_enqueue_style('stylesheet',  get_stylesheet_uri() );
}
// Hook into the wp_enqueue_scripts action
add_action('wp_enqueue_scripts', 'enqueue_scripts');
?>

That code will search for the style sheet and output it to our header.php file wherever we decided to place the wp_head() tag.

The last thing that you absolutely HAVE to have in a theme is a special comment section in the header of your style.css that tells WordPress that this is an actual theme.

/*
Theme Name:  My cool theme
Theme URI:  http://mythemesite.com/
Author:  Your name here
Author URI:  http://yourwebsite.com/
Description: A really cool simple theme that barely functions.
Version:  1.0
License:  GNU General Public License
License URI:  https://www.gnu.org/licenses/gpl.html
*/

That about wraps up the WordPress theme dev primer, now we can get into some more advanced stuff and see what is possible when creating themes.

A Quick Note About The Theme

If you want to get a real good idea of the features you can view the documentation here, which is pretty in depth, and teaches you how to do literally everything that the theme can do.

I should also link to the front end of the site so you can see what the theme looks like, you may be viewing an early version just FYI, so the content may or may not be complete.

Features

There are tons of features we can implement when creating themes. There are also a few things in the theme dev community that are not quite “standards” but are pretty common. Things like sliders and custom shortcodes and page templates to name a few.

For this theme, I didn’t overload it with features, rather I chose some fundamental features that would allow the user to complete common tasks quickly and with the least possible effort, some these features include the following:

Responsive Design

Responsive design is coding your sites to react and adapt to various screen sizes, sometimes not just smaller screen sizes either.  Responsive design for all sites in my opinion is a must in today’s world so if you are thinking about this field make sure you understand at least some core principles of responsive design. The only thing that I didn’t add yet, but have it on the list for the first maintenance release is making it retina ready.

Drag and Drop Page Builder

This is really an essential selling point of the theme, instead of having to mess with using some pretty complicated HTML to build multi-column layouts, users are able to visually create responsive multi-column layouts that run 100% on widgets. It is important to note, I also developed a responsive grid system that uses shortcodes for more advanced users who want to go even further with their layouts.
Page Builder

Theme Customizer

Instead of using some bulky confusing theme options framework, I decided to use the WordPress Settings API and put all of the major customization options in the WordPress Theme Customizer. Check out the documentation for a full list of customizable features.
Theme Customizer

Sidebar Layout

Usually, sidebars are included in page templates but page templates are not as flexible as I would like for this purpose. So, I wrote a function to add the ability to choose where your sidebars display and if you want to show them at all. There are also post type specific sidebars, so you can really customize your pages.

This is what it looks like on the “Add New Page” page:
Sidebar Layout

Functions

These are a few functions that I implemented to make life a little easier. Some of them quite simple, some of them a little more intensive.

Enable Shortcodes in Widgets

By default, if you type a shortcode in a widget area, it will return whatever you typed. Not necessarily the desired functionality, so to combat this flaw, we can force the widget area to parse shortcodes like the content area.

/* Enable Shortcodes in Text Widgets */
add_filter('widget_text', 'do_shortcode');

Kill Extra Breaks and Empty Paragraphs in Shortcodes

WordPress is great, but it tends to over think code in the post area, and users don’t help by adding indiscriminate hard returns and spaces. Thinking these are desired,, WordPress converts them into random <br> & <p> tags in the content of shortcodes, very undesirable. This can ruin the look of your page, so here is code I add to remedy this:

/* Clean up Shortcodes*/
function clean_shortcodes($content){
  $array = array (
    '<p>[' => '[',
    ']</p>' => ']',
    ']<br />' => ']'
  );
  $content = strtr($content, $array);
  return $content;
}
add_filter('the_content', 'clean_shortcodes');

Custom JQuery – The whole shebang

I thought it would be a fun bonus to include my entire scripts.js. I will give you a brief walk through to help you understand what is going.

The code includes the following features:

  • Smooth Scrolling to Anchors: This feature allows you to add a hashtagged ID in a link to match an ID of content and when the link is clicked it automatically scrolls to the given content ID.
  • Mobile Nav Toggle: A simple little feature the slides the Mobile navigation menu up or down when tapped on a device or clicked on screen.
  • Enable Sticky Navigation: Sticky navigation is a nice addition for usability. Essentially what this function does is forces the navigation bar to “stick” to the top of the screen when you scroll down past it. It also un-sticks it when you scroll up past it.
  • Accordion Content: An accordion style content display is a great way to show content. When you click on the item title it hides or shows content based on if the content is currently hidden or is being shown.
// Basic Scripts
// Author: Kenny Scott
// License: GNU General Public License 3+
jQuery(function ($) {

  // Smooth Scrolling to Anchors
  $("a.scroll, a#top-btn").click(function (event) {
    // Prevent the anchor tag from working the way it normally does
    event.preventDefault();
    $('html,body').animate({
      // Animate the scroll to the top of the page
      scrollTop: $(this.hash).offset().top
    }, 1000, 'easeInOutQuad');
  });

  // Mobile Nav Toggle
  $('button#mobile-menu').on('click', function () {
   // When the user taps, animate the menu sliding down
    $('#mobile-navigation .menu').slideToggle(300, 'easeInOutQuad');
  })

  // Enable Sticky Navigation
 // Get the offset of the nav element
  var fixedNavTop = $('.top-fixed, .below-logo-fixed').offset().top;
  var fixedNav = function () {
    var scrollTop = $(window).scrollTop();
   //If user scrolls past navbar, add the fixed-nav class
    if (scrollTop > fixedNavTop) {
      $('.top-fixed, .below-logo-fixed').addClass('fixed-nav');
   // If we arent past the navbar, remove the fixed-nav class
    } else {
      $('.top-fixed, .below-logo-fixed').removeClass('fixed-nav');
    }
  };

  // Accordion Content
  $("h5.accordion-title").click(function () {
    if ($(this).parents('.accordion').length >= 1) {
      var accordion = $(this).parents('.accordion');
      // If the accordion is open, close it
      if ($(this).hasClass('active')) {
        $(accordion).find('h5.accordion-title').removeClass('active');
        $(accordion).find(".accordion-content").slideUp();
      } else {
        $(accordion).find('h5.accordion-title').removeClass('active');
        $(accordion).find(".accordion-content").slideUp();
        $(this).addClass('active');
        // Open or close the item
        $(this).next(".accordion-content").slideToggle();
      }
    } else {
      if ($(this).hasClass('active')) {
       // Close the item
        $(this).removeClass("active");
      } else {
        // Open the item
        $(this).addClass("active");
      }
    }
    return false;
  });
  $("h5.accordion-title").click(function () {
    if (!$(this).parents('.accordion').length >= 1) {
     // Close or open the item
      $(this).next(".accordion-content").slideToggle();
    }
  });

  // Bind the fixedNav function to the scroll event
  $(window).scroll(function () {
    fixedNav();
  });

});

Shortcodes

Shortcodes are fantastic, they take a lot of pain out of throwing in features to a theme, but you can go a little to crazy with them. I only threw in about 10 in this theme, here are a couple gold medal status shortcodes:

Safe Mailto

This little beauty will obfuscate your email address if you want to use it in your pages but prevent data miners from harvesting your email address.
Usage:

  [mailto]your_email@email.com[/mailto]

If you view the source of the page you will get the following:
Safe email output

Responsive Grid

This has got to be the easiest way to manually hook up a nice responsive layout short of using the visual Page Builder.

Usage:

  [row]Content for a single column here [/row]
  [row]
    [column size="half"]Column 1 content[/column]
    [column size="half" position="last"]Column 2 content[/column]
  [/row]
  [row]
    [column size="third"]Column 1 content[/column]
    [column size="third"]Column 2 content[/column]
    [column size="third" position="last"]Column 3 content[/column]
  [/row]

Multi-site video

This shortcode allows embeds from YouTube, Daily Motion and Vimeo. Just paste the video id in and you are good to go.
Usage:


Other Cool Stuff

This theme utilizes custom post types each with their own custom fields. The custom post types I created for this theme are:

  • Services
  • Portfolio
  • Staff Members
  • Service Areas

Of these custom post types, Service areas uses some pretty hefty PHP and JavaScript. It generates a custom google map and pin based on location that you can click, then generates pins for each individual service area and then generates an image of the location on the map for each single service area page. Trust me, it is long and painful, I spent a couple days on it. You can see it in action here: Service area page

Conclusion

I really hope this at least gave you some smidgen of an idea of the kinds of things that go into a theme. As users we can get caught up in the facade of things so quickly it is sometimes overlooked at how detailed the product really is. The WordPress Theme I created was literally coded from scratch, no frameworks included the total lines of code is 21,729, and this is just a basic theme!

Any questions, please feel free to abuse the comments section below!

Advertisements

2 thoughts on “An Abstract (and brief) Look Into WP Theme Development”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s