Concepts for Custom Theme Development

If you’re new to WordPress development, there’s a couple techniques that will be incredibly useful when building themes for a specific company or purpose. Most WordPress themes available are built for general use, but when adapting it for a specific site it’s usually necessary to hardcode at least a few specific elements rather than make everything dynamic.

For example, it might make sense to hardcode the menu if it requires a lot of custom styling. It might make sense to query for specific pieces of known content. Certain pages may have a lot of art direction or targeted styles that would be incredibly difficult to build a custom UI for.

If you’ve already built a few custom themes, it’s likely know a many of these tips already- but hopefully there’s a few gems that will be useful for your toolkit.

Links

Let’s say you’d like to hardcode a menu or links to specific pages on the site. Instead of using relative links, use the WordPress function home_url. Example:

<?php echo home_url( 'contact' ); ?>

This will construct links based off the base URL, which can be helpful if your site structure ever changes.

Images

Image sources should also be coded using a dynamic file path.

<img src="<?php echo get_template_directory_uri(); ?>/images/example.jpg" alt="Example"?>

This will build a path based on the root of your theme directory.

CSS and Javascript

Although it’s possible to include in CSS and JS from header.php or footer.php, the WordPress way is to enqueue these.

wp_enqueue_style(
	'prefix-css-example',
	get_template_directory_uri() . '/css/example.css',
	array(),
	'1.0.0'
);

This will help prevent script conflicts and make it possible to minify or concat scripts and styles using other plugins.

If you need to load a specific script or style only on one page of the site, the enqueue can also be done as a conditional:

if ( is_front_page() ) :
	wp_enqueue_style(
		'prefix-css-example',
		get_template_directory_uri() . '/css/example.css',
		array(),
		'1.0.0'
	);
endif;

This will help with page speed and load times.

Templates

It’s likely you’ll need custom markup for various pages, categories, and content types. This is where an understanding of template hierarchy is useful.

As an example, let’s say you need custom markup for the “about” page. There’s a couple ways you could do this with WordPress templating. Assuming the slug for the page is “about”, the most direct way is to create a a new template with the file name “page-about.php”. That will now override the standard “page.php” template.

The other option is to create a custom page template that can be selected and set when editing that page. Instructions for building and setting page templates is in the codex.

This article in the WordPress codex also explains how to name file templates for specific posts, custom post types, taxonomy terms, author pages, and any other specific content you might have.

Conditionals

Sometimes you won’t want to completely override a template, but simply output something based on a condition (i.e. is a specific category, is a specific page). To find out how to do that, read the WordPress codex on conditional tags.

if ( is_page( 'about' ) ):
	// Do Something
endif;

Targeted Styling

Hopefully your theme uses the body class function on the body tag:

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

If so, you’ll notice that every page of your site has a unique class which can be used for styling. Want to change the background color of #content for one specific page? Example:

.page-id-101 #content { background: #bada55; }

A number of body classes are included for styling targeting specific posts, categories, and post types.

Includes

If there’s a specific piece of markup that needs to be used on a number of different templates, don’t repeat it, include it! Example:

<?php get_template_part( 'partials/product', 'guarantee' ); ?>

This will include the file partials/product-guarantee.php from the theme’s directory.

Custom Queries

At some point you’ll want to include a specific content (posts, pages, custom post types) on a specific template (the home page for example).

As an example, for one site I built recently we needed to display four specific products (from WooCommerce), in a specific order, on the home page and at the bottom of a number of other templates. Here’s how that was done:

<?php
$args = array(
	'posts_per_page' => 4,
	'post_type' => 'product',
	'post__in' => array( 2284, 2315, 17472, 17301 ), // Post IDs
	'orderby' => 'post__in'
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
	while ( $query->have_posts() ) : $query->the_post();
		wc_get_template_part( 'content', 'product' );
	endwhile;
endif;
wp_reset_query();
?>

These queries can get quite complex depending on what data you’re trying to pull, but I suggest reading up on the possibilities in the codex: https://codex.wordpress.org/Class_Reference/WP_Query.

Starter theme

If you want to build a theme using best practices, I recommend starting with the Underscores theme (or at least reading through their codebase). This is an open-source project with 87 contributors and top-notch theme developers.

Build Tools

If you’re interested in using Grunt build tools for SASS/LESS, minification, concat, and more- I’d recommend reading one of my tutorials on that subject.

About Devin

I'm a WordPress developer based in Austin, Texas. I run a little theme shop called DevPress and work for a startup called Nano. Find me on twitter @devinsays.

3 Responses

  1. I’d recommend home_url() (where the site lives) instead of site_url() (where the WP install lives) because this might break some URLs if WP is installed in a different directory.

Leave a Reply