Building a WordPress Theme
Not too difficult
A little harder
#*&%@#!
why build a theme?
• better understanding of how WordPress works
• self-sufficiency to fix or change theme aspects
• empowerment ( yourself, a career )
• move beyond the WordPress dashboard
• world domination…results may vary
World 1-1
Templates
template terminology
• template files - files that control how your site content is
displayed
• template tags - WordPress functions that grab content from
the database (get_header, get_sidebar(‘someparameter’))
• page templates - type of template that is only applied to
pages in your theme
• files to display your data - WordPress template files (php)
• files for theme information and styles - style.css
• files to add/remove functionality (functions.php)
• other files used can include javascript, images, svg, sass/less
and more!
theme files
index.phpstyle.css
Required Theme Files
create a folder, place these two files and you’ll soon have your theme
style.css
• file header - provides details about theme in the form of
comments
• can house css styles for your site
style.css
/*
Theme Name: Twenty Fifteen
Theme URI: https://wordpress.org/themes/twentyfifteen/
Author: the WordPress team
Author URI: https://wordpress.org/
Description: Our 2015 default theme is clean, blog-focused, and designed for clarity. Twenty Fifteen's simple,
straightforward typography is readable on a wide variety of screen sizes, and suitable for multiple languages.
Version: 1.1
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: black, blue, gray, pink, purple, white, yellow, dark, light, two-columns, left-sidebar,featured-images,
microformats, post-formats
Text Domain: twentyfifteen`
*/
Dashboard - Theme Details
style.css
/*
Theme Name: Twenty Fifteen
*/
// begin theme styles
index.php
https://gist.github.com/philiparthurmoore/b1f47c15d3eb2c573924
<!DOCTYPE html>
<html>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<title><?php wp_title( '|', true, 'right' ); ?></title>
<link rel="stylesheet" href="<?php echo esc_url( get_stylesheet_uri() ); ?>" type="text/css" />
<?php wp_head(); ?>
</head>
<body>
<h1><?php bloginfo( 'name' ); ?></h1>
<h2><?php bloginfo( 'description' ); ?></h2>
index.php
https://gist.github.com/philiparthurmoore/b1f47c15d3eb2c573924
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<h3><?php the_title(); ?></h3>
<?php the_content(); ?>
<?php endwhile; ?>
<?php if ( get_next_posts_link() ) { next_posts_link(); } ?>
<?php if ( get_previous_posts_link() ) { previous_posts_link(); } ?>
<?php else: ?>
<p>No posts found. :(</p>
<?php endif; ?>
index.php
https://gist.github.com/philiparthurmoore/b1f47c15d3eb2c573924
<?php wp_footer(); ?>
</body>
</html>
most themes include these files
header.php index.php sidebar.php footer.php
header.php
<!DOCTYPE html>
<html>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<title><?php wp_title( '|', true, 'right' ); ?></title>
<link rel="stylesheet" href="<?php echo esc_url( get_stylesheet_uri() ); ?>" type="text/css" />
<?php wp_head(); ?>
</head>
<body>
<h1><?php bloginfo( 'name' ); ?></h1>
<h2><?php bloginfo( 'description' ); ?></h2>
footer.php
<?php wp_footer(); ?>
</body>
</html>
sidebar.php
<?php if ( is_active_sidebar( 'sidebar-1' ) ) : ?>
<div id="primary-sidebar" class="primary-sidebar widget-area" role="complementary">
<?php dynamic_sidebar( 'sidebar-1' ); ?>
</div><!-- #primary-sidebar -->
<?php endif; ?>
working index.php
<?php get_header() ?>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<h3><?php the_title(); ?></h3>
<?php the_content(); ?>
<?php endwhile; ?>
<?php if ( get_next_posts_link() ) { next_posts_link(); } ?>
<?php if ( get_previous_posts_link() ) { previous_posts_link(); } ?>
<?php else: ?>
<p>No posts found. :(</p>
<?php endif; ?>
<?php get_sidebar() ?>
<?php get_footer() ?>
page reference
content
header.php
sidebar.php
footer.php
the loop
• used to display posts, page content, comments, custom post
types, custom fields
• when you read about certain functions that list only working
in the loop, this is where it goes
• https://codex.wordpress.org/The_Loop
Blog Archive
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<h2><?php the_title(); ?></h2>
<?php the_post_thumbnail(); ?>
<?php the_excerpt(); ?>
<?php endwhile; else: ?>
<?php _e('Sorry, no posts matched your criteria.'); ?>
<?php endif; ?>
Individual Post
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<h1><?php the_title(); ?></h1>
<?php the_content(); ?>
<?php endwhile; else: ?>
<?php _e('Sorry, no pages matched your criteria.'); ?>
<?php endif; ?>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<h1><?php the_title(); ?></h1>
<?php the_content(); ?>
<?php endwhile; else: ?>
<?php _e('Sorry, no pages matched your criteria.'); ?>
<?php endif; ?>
Template Tags
World 2-1
template tags
• a piece of php code that tells WordPress “do” or “get” something
• they separate the theme into smaller, more understandable,
sections.
• some tags can only be used in specific areas
• values can be passed through tags to display specific content
working index.php
<?php get_header() ?>
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php the_title(‘<h3>’, ‘</h3>’); ?>
<?php the_content(); ?>
<?php endwhile; ?>
<?php if ( get_next_posts_link() ) { next_posts_link(); } ?>
<?php if ( get_previous_posts_link() ) { previous_posts_link(); } ?>
<?php else: ?>
<p>No posts found. :(</p>
<?php endif; ?>
<?php get_sidebar() ?>
<?php get_footer() ?>
General
collect them all: https://codex.wordpress.org/Template_Tags
get_header()
get_footer()
get_sidebar()
Author
wp_list_authors()
the_author()
the_author_link()
Bookmark
wp_list_bookmarks()
get_bookmark()
Category Comment
Link
the_permalink()
home_url()
site_url()
Post
the_content()
the_excerpt()
the_title()
Post Thumbnail
the_post_thumbnail()
has_post_thumbnail()
Navigation
wp_nav_menu()
template tag categories
comment_author()
comment_date()
get_avatar()
the_category()
the_tags()
the_terms()
Conditionals
conditionals
if ( is_user_logged_in() ) {
echo 'Welcome, registered user!';
} else {
echo 'Welcome, visitor!';
}
https://developer.wordpress.org/themes/basics/conditional-tags/
if ( is_front_page() ) {
// do something
}
Template Hierarchy
World 3-1
• Query strings (data from page links) determine which
template or set of templates to display page content
• Templates are selected in the order determined by the
template hierarchy
• If a template file cannot be matched, index.php will be used
query string - http://example.com/
template flow
front-page.php home.php page.php index.php
query string - http://example.com/blog/category/luigi/
template flow
category-luigi.php category-6.php category.php
archive.php index.php
template hierarchy
http://wphierarchy.com/ - Rami Abraham, Michelle Schulp
expanded theme
header.php index.php sidebar.php footer.php
404.php single.php page.php
page templates
• only apply to pages
• used to change the look and feel of a page
• can be applied to a single page, page section or class of
pages
• custom pages with template names give users control by
enabling template switching
page template flow
$custom.php
page-$slug.php page-id.php page.php
page query
Custom Page Template
/**
* Template Name: Two Columns Template
*
* Description: A page template that provides a key component of WordPress as
* a CMS by meeting the need for a carefully crafted introductory page.
*
* @package WordPress
* @subpackage Twenty_Fifteen
* @since Twenty Fifteen 1.0
*/
Theme Folder Structure
World 4-1
folder setup
• main theme template files are in the root directory
• no required folders in themes at this time
• page-templates folder, languages folder are auto
recognized
archive.php
comments.php
image.php
content.php
index.php page.php
header.php
sidebar.php
screenshot.png search.php
single.php style.css
footer.php
css inc images languages
page-
templates
Twenty Fifteen Theme Structure
404.php author-bio.php
content-*.php
functions.php
rtl.css
Functions and Hooks
World 5-1
functions file
• adds/removes features and functionality to your theme
• acts like a plugin
• automatically loaded for both admin and external pages
• “put it in your functions file” location
• enqueuing stylesheets and scripts
• enable theme features, including: sidebars, post formats,
custom headers/backgrounds
• enable options for the theme customizer
• define functions for your theme to use
• and more
functions.php
if ( ! function_exists( 'themename_setup' ) ) :
function themename_setup() {
register_nav_menus( array(
'primary' => __( 'Primary Menu', 'theme_name' ),
'secondary' => __( 'Secondary Menu', 'theme_name' )
) );
add_theme_support( 'post-thumbnails' );
}

endif;
add_action( 'after_setup_theme', 'themename_setup' );
header.php
<!DOCTYPE html>
<html>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<title><?php wp_title( '|', true, 'right' ); ?></title>
<link rel="stylesheet" href="<?php echo esc_url( get_stylesheet_uri() ); ?>" type="text/css" />
<?php wp_head(); ?>
</head>
<body>
<h1><?php bloginfo( 'name' ); ?></h1>
<h2><?php bloginfo( 'description' ); ?></h2>
functions.php
function twentyfifteen_scripts() {
// Load our main stylesheet.
// hooks into wp_head();
wp_enqueue_style( 'twentyfifteen-style', get_stylesheet_uri() );
// hooks into wp_footer();
wp_enqueue_script( 'twentyfifteen-script', get_template_directory_uri() . '/js/functions.js',
array( 'jquery' ), '20150330', true );
}
add_action( 'wp_enqueue_scripts', 'twentyfifteen_scripts' );
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>">
<title><?php wp_title( '|', true, 'right' ); ?></title>
<?php wp_head(); ?>
</head>
<?php wp_footer(); ?>
</body>
</html>
// header.php
// footer.php
hooks
power of hooks
• two types: actions and filters
• part of the plugin api
• gives the ability to customize, extend, and enhance
WordPress
• used heavily throughout WordPress, plugins and themes
filters
http://codex.wordpress.org/Plugin_API/Filter_Reference
filter hook info
• Use when you want to manipulate data coming from the
database to the browser, or vice versa
• Change the content by adjusting what is outputted
• Filtered content is always returned
http://codex.wordpress.org/Plugin_API/Filter_Reference
filter hooks
add_filter( 'the_content', 'theme_add_call_number' );
function theme_add_call_number ( $content ) {
if ( is_page() ) {
$content .= '<div>Call for more info! - 555-555-5555</div>';
}
return $content;
}
// functions.php
actions
http://codex.wordpress.org/Plugin_API/Action_Reference
action hook info
• when queries are ran, actions (hooks in general) are
executed during the WordPress page creation life cycle.
• we can hook into when these are ran and run our own
functions
http://codex.wordpress.org/Plugin_API/Action_Reference
action hooks
<body>
<?php do_action ( ‘themename_before_header' ); ?>
add_action( 'themename_before_header', ‘themename_page_alert’, 5 );
function themename_page_alert() {
if ( is_front_page() ) {
echo ‘<div>Alert! We have an important message!</div>’;
}
}
// header.php
// functions.php
Local Development Crash Course
Warp Level
MAMP
or Wamp, Xampp, DesktopServer, etc
Using MAMP
• Download and install the software

- https://www.mamp.info/en/downloads/
• Setup your document root 

- where your sites will be stored
• Start the Mamp Server, create database
• Install WordPress, connect database
• Profit $$$$
https://codex.wordpress.org/Installing_WordPress_Locally_on_Your_Mac_With_MAMP
startutorial.com
“First, solve the problem. Then, write the code.”
Justin Tucker
@certainstrings certainstrings.com
resources
• developer.wordpress.org/themes/basics
• developer.wordpress.org
• wordpress.tv
• teamtreehouse.com
• pippinsplugins.com
• tommcfarlin.com
slides: bit.ly/wp-theme-building

Builing a WordPress Theme

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
    why build atheme? • better understanding of how WordPress works • self-sufficiency to fix or change theme aspects • empowerment ( yourself, a career ) • move beyond the WordPress dashboard • world domination…results may vary
  • 6.
  • 7.
    template terminology • templatefiles - files that control how your site content is displayed • template tags - WordPress functions that grab content from the database (get_header, get_sidebar(‘someparameter’)) • page templates - type of template that is only applied to pages in your theme
  • 8.
    • files todisplay your data - WordPress template files (php) • files for theme information and styles - style.css • files to add/remove functionality (functions.php) • other files used can include javascript, images, svg, sass/less and more! theme files
  • 9.
    index.phpstyle.css Required Theme Files createa folder, place these two files and you’ll soon have your theme
  • 10.
    style.css • file header- provides details about theme in the form of comments • can house css styles for your site
  • 11.
    style.css /* Theme Name: TwentyFifteen Theme URI: https://wordpress.org/themes/twentyfifteen/ Author: the WordPress team Author URI: https://wordpress.org/ Description: Our 2015 default theme is clean, blog-focused, and designed for clarity. Twenty Fifteen's simple, straightforward typography is readable on a wide variety of screen sizes, and suitable for multiple languages. Version: 1.1 License: GNU General Public License v2 or later License URI: http://www.gnu.org/licenses/gpl-2.0.html Tags: black, blue, gray, pink, purple, white, yellow, dark, light, two-columns, left-sidebar,featured-images, microformats, post-formats Text Domain: twentyfifteen` */
  • 12.
  • 13.
    style.css /* Theme Name: TwentyFifteen */ // begin theme styles
  • 14.
    index.php https://gist.github.com/philiparthurmoore/b1f47c15d3eb2c573924 <!DOCTYPE html> <html> <head> <meta charset="<?phpbloginfo( 'charset' ); ?>"> <title><?php wp_title( '|', true, 'right' ); ?></title> <link rel="stylesheet" href="<?php echo esc_url( get_stylesheet_uri() ); ?>" type="text/css" /> <?php wp_head(); ?> </head> <body> <h1><?php bloginfo( 'name' ); ?></h1> <h2><?php bloginfo( 'description' ); ?></h2>
  • 15.
    index.php https://gist.github.com/philiparthurmoore/b1f47c15d3eb2c573924 <?php if (have_posts() ) : while ( have_posts() ) : the_post(); ?> <h3><?php the_title(); ?></h3> <?php the_content(); ?> <?php endwhile; ?> <?php if ( get_next_posts_link() ) { next_posts_link(); } ?> <?php if ( get_previous_posts_link() ) { previous_posts_link(); } ?> <?php else: ?> <p>No posts found. :(</p> <?php endif; ?>
  • 16.
  • 17.
    most themes includethese files header.php index.php sidebar.php footer.php
  • 18.
    header.php <!DOCTYPE html> <html> <head> <meta charset="<?phpbloginfo( 'charset' ); ?>"> <title><?php wp_title( '|', true, 'right' ); ?></title> <link rel="stylesheet" href="<?php echo esc_url( get_stylesheet_uri() ); ?>" type="text/css" /> <?php wp_head(); ?> </head> <body> <h1><?php bloginfo( 'name' ); ?></h1> <h2><?php bloginfo( 'description' ); ?></h2>
  • 19.
  • 20.
    sidebar.php <?php if (is_active_sidebar( 'sidebar-1' ) ) : ?> <div id="primary-sidebar" class="primary-sidebar widget-area" role="complementary"> <?php dynamic_sidebar( 'sidebar-1' ); ?> </div><!-- #primary-sidebar --> <?php endif; ?>
  • 21.
    working index.php <?php get_header()?> <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <h3><?php the_title(); ?></h3> <?php the_content(); ?> <?php endwhile; ?> <?php if ( get_next_posts_link() ) { next_posts_link(); } ?> <?php if ( get_previous_posts_link() ) { previous_posts_link(); } ?> <?php else: ?> <p>No posts found. :(</p> <?php endif; ?> <?php get_sidebar() ?> <?php get_footer() ?>
  • 22.
  • 23.
  • 24.
    • used todisplay posts, page content, comments, custom post types, custom fields • when you read about certain functions that list only working in the loop, this is where it goes • https://codex.wordpress.org/The_Loop
  • 25.
    Blog Archive <?php if( have_posts() ) : while ( have_posts() ) : the_post(); ?> <h2><?php the_title(); ?></h2> <?php the_post_thumbnail(); ?> <?php the_excerpt(); ?> <?php endwhile; else: ?> <?php _e('Sorry, no posts matched your criteria.'); ?> <?php endif; ?>
  • 26.
    Individual Post <?php if( have_posts() ) : while ( have_posts() ) : the_post(); ?> <h1><?php the_title(); ?></h1> <?php the_content(); ?> <?php endwhile; else: ?> <?php _e('Sorry, no pages matched your criteria.'); ?> <?php endif; ?>
  • 27.
    <?php if (have_posts() ) : while ( have_posts() ) : the_post(); ?> <h1><?php the_title(); ?></h1> <?php the_content(); ?> <?php endwhile; else: ?> <?php _e('Sorry, no pages matched your criteria.'); ?> <?php endif; ?>
  • 28.
  • 29.
    template tags • apiece of php code that tells WordPress “do” or “get” something • they separate the theme into smaller, more understandable, sections. • some tags can only be used in specific areas • values can be passed through tags to display specific content
  • 30.
    working index.php <?php get_header()?> <?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?> <?php the_title(‘<h3>’, ‘</h3>’); ?> <?php the_content(); ?> <?php endwhile; ?> <?php if ( get_next_posts_link() ) { next_posts_link(); } ?> <?php if ( get_previous_posts_link() ) { previous_posts_link(); } ?> <?php else: ?> <p>No posts found. :(</p> <?php endif; ?> <?php get_sidebar() ?> <?php get_footer() ?>
  • 31.
    General collect them all:https://codex.wordpress.org/Template_Tags get_header() get_footer() get_sidebar() Author wp_list_authors() the_author() the_author_link() Bookmark wp_list_bookmarks() get_bookmark() Category Comment Link the_permalink() home_url() site_url() Post the_content() the_excerpt() the_title() Post Thumbnail the_post_thumbnail() has_post_thumbnail() Navigation wp_nav_menu() template tag categories comment_author() comment_date() get_avatar() the_category() the_tags() the_terms()
  • 32.
  • 33.
    conditionals if ( is_user_logged_in()) { echo 'Welcome, registered user!'; } else { echo 'Welcome, visitor!'; } https://developer.wordpress.org/themes/basics/conditional-tags/ if ( is_front_page() ) { // do something }
  • 34.
  • 35.
    • Query strings(data from page links) determine which template or set of templates to display page content • Templates are selected in the order determined by the template hierarchy • If a template file cannot be matched, index.php will be used
  • 36.
    query string -http://example.com/ template flow front-page.php home.php page.php index.php
  • 37.
    query string -http://example.com/blog/category/luigi/ template flow category-luigi.php category-6.php category.php archive.php index.php
  • 38.
    template hierarchy http://wphierarchy.com/ -Rami Abraham, Michelle Schulp
  • 39.
    expanded theme header.php index.phpsidebar.php footer.php 404.php single.php page.php
  • 40.
    page templates • onlyapply to pages • used to change the look and feel of a page • can be applied to a single page, page section or class of pages • custom pages with template names give users control by enabling template switching
  • 41.
    page template flow $custom.php page-$slug.phppage-id.php page.php page query
  • 42.
    Custom Page Template /** *Template Name: Two Columns Template * * Description: A page template that provides a key component of WordPress as * a CMS by meeting the need for a carefully crafted introductory page. * * @package WordPress * @subpackage Twenty_Fifteen * @since Twenty Fifteen 1.0 */
  • 43.
  • 44.
    folder setup • maintheme template files are in the root directory • no required folders in themes at this time • page-templates folder, languages folder are auto recognized
  • 45.
    archive.php comments.php image.php content.php index.php page.php header.php sidebar.php screenshot.png search.php single.phpstyle.css footer.php css inc images languages page- templates Twenty Fifteen Theme Structure 404.php author-bio.php content-*.php functions.php rtl.css
  • 46.
  • 47.
    functions file • adds/removesfeatures and functionality to your theme • acts like a plugin • automatically loaded for both admin and external pages • “put it in your functions file” location
  • 48.
    • enqueuing stylesheetsand scripts • enable theme features, including: sidebars, post formats, custom headers/backgrounds • enable options for the theme customizer • define functions for your theme to use • and more
  • 49.
    functions.php if ( !function_exists( 'themename_setup' ) ) : function themename_setup() { register_nav_menus( array( 'primary' => __( 'Primary Menu', 'theme_name' ), 'secondary' => __( 'Secondary Menu', 'theme_name' ) ) ); add_theme_support( 'post-thumbnails' ); }
 endif; add_action( 'after_setup_theme', 'themename_setup' );
  • 50.
    header.php <!DOCTYPE html> <html> <head> <meta charset="<?phpbloginfo( 'charset' ); ?>"> <title><?php wp_title( '|', true, 'right' ); ?></title> <link rel="stylesheet" href="<?php echo esc_url( get_stylesheet_uri() ); ?>" type="text/css" /> <?php wp_head(); ?> </head> <body> <h1><?php bloginfo( 'name' ); ?></h1> <h2><?php bloginfo( 'description' ); ?></h2>
  • 51.
    functions.php function twentyfifteen_scripts() { //Load our main stylesheet. // hooks into wp_head(); wp_enqueue_style( 'twentyfifteen-style', get_stylesheet_uri() ); // hooks into wp_footer(); wp_enqueue_script( 'twentyfifteen-script', get_template_directory_uri() . '/js/functions.js', array( 'jquery' ), '20150330', true ); } add_action( 'wp_enqueue_scripts', 'twentyfifteen_scripts' );
  • 52.
    <head> <meta charset="<?php bloginfo('charset' ); ?>"> <title><?php wp_title( '|', true, 'right' ); ?></title> <?php wp_head(); ?> </head> <?php wp_footer(); ?> </body> </html> // header.php // footer.php
  • 53.
  • 54.
    power of hooks •two types: actions and filters • part of the plugin api • gives the ability to customize, extend, and enhance WordPress • used heavily throughout WordPress, plugins and themes
  • 55.
  • 56.
    filter hook info •Use when you want to manipulate data coming from the database to the browser, or vice versa • Change the content by adjusting what is outputted • Filtered content is always returned http://codex.wordpress.org/Plugin_API/Filter_Reference
  • 57.
    filter hooks add_filter( 'the_content','theme_add_call_number' ); function theme_add_call_number ( $content ) { if ( is_page() ) { $content .= '<div>Call for more info! - 555-555-5555</div>'; } return $content; } // functions.php
  • 58.
  • 59.
    action hook info •when queries are ran, actions (hooks in general) are executed during the WordPress page creation life cycle. • we can hook into when these are ran and run our own functions http://codex.wordpress.org/Plugin_API/Action_Reference
  • 60.
    action hooks <body> <?php do_action( ‘themename_before_header' ); ?> add_action( 'themename_before_header', ‘themename_page_alert’, 5 ); function themename_page_alert() { if ( is_front_page() ) { echo ‘<div>Alert! We have an important message!</div>’; } } // header.php // functions.php
  • 61.
    Local Development CrashCourse Warp Level
  • 62.
    MAMP or Wamp, Xampp,DesktopServer, etc
  • 63.
    Using MAMP • Downloadand install the software
 - https://www.mamp.info/en/downloads/ • Setup your document root 
 - where your sites will be stored • Start the Mamp Server, create database • Install WordPress, connect database • Profit $$$$ https://codex.wordpress.org/Installing_WordPress_Locally_on_Your_Mac_With_MAMP
  • 64.
    startutorial.com “First, solve theproblem. Then, write the code.”
  • 65.
    Justin Tucker @certainstrings certainstrings.com resources •developer.wordpress.org/themes/basics • developer.wordpress.org • wordpress.tv • teamtreehouse.com • pippinsplugins.com • tommcfarlin.com slides: bit.ly/wp-theme-building