How to build a wordpress theme in 5 steps

This tutorial is more like a personal reference of my own to quickly get myself on tracks while building a new WordPress theme.

So if you need more details on building up your own theme, then you will have to follow the guildelines on WordPress.org.

There is also a nice infographic highlighting the anatomy of a wordpress theme on Yoast. Today we will focus on the following steps :

  1. Setting up the new theme folders and files
  2. Filling in code
  3. Adding Templates
  4. Adding widgets
  5. Configuration details

Before Building a WordPress theme

To make things as clear as possible, let’s template a typical brochure website.

Generally this type of website will have the following content :

  1. a nice homepage
  2. a blog home page (option)
  3. an article page (or services page)
  4. a contact page

Other pages will replicate the layout of one of the above pages. You may also only need 1 or 2 unique layout to be used among all pages.

For my clients, I used to design at least 3 different layouts. The layouts can however be modified easily for each website.

Once you defined the pages you need, you will work on the following :

  1. Integrating the graphical chart using HTML5, CSS3, JS, (Jquery, Bootstrap…) outside of WordPress
  2. Organizing the theme folder and files on WordPress
  3. Add any functionnalities

We will of course skip to step 2 which is the scope of this tutorial.

It is time to dive into coding for WordPress.

1. Skeleton WordPress theme

Start by creating a new folder within : wp-content/themes/

Then add the following files and folders into it :

wp-content/themes/YourTheme/functions.php

wp-content/themes/YourTheme/style.css

wp-content/themes/YourTheme/index.php

wp-content/themes/YourTheme/front-page.php (static page – does not include blog posts)

wp-content/themes/YourTheme/home.php (index page of blog posts)

wp-content/themes/YourTheme/single.php (a blog post)

wp-content/themes/YourTheme/page.php (a default template for a page)

wp-content/themes/YourTheme/404.php

wp-content/themes/YourTheme/footer.php

wp-content/themes/YourTheme/header.php

wp-content/themes/YourTheme/sidebar.php

 

For now the files are empty. We will fill them next.

And also prepare the following folders to add any static files :

wp-content/themes/YourTheme/css

wp-content/themes/YourTheme/js

wp-content/themes/YourTheme/images

wp-content/themes/YourTheme/icons

Then finally add another folder where sit the template files for specific content :

wp-content/themes/YourTheme/template-parts

This way you can customize the design as expected.

We will end with the creation of a screenshot of your theme under :

wp-content/themes/YourTheme/screenshot.png

2. Filling default data

The stylesheet includes all the details of the theme within comments :

/*
Theme Name: Your Theme
Theme URI: http://yourwebsite.com/themes/yourtheme
Author: the company team
Author URI: http://yourwebsite.com/
Description: Include details of your theme here
Version: 1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: whatever tags, here
Text Domain: yourtheme

This theme, like WordPress, is licensed under the GPL.
Use it to make something cool, have fun, and share what you've learned with others.
*/

When building a WordPress theme or any other project, it’s of great habit to follow standards, let’s review the files we’ve seen with default content in them :


<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo( 'charset' ); ?>" />
<title><?php wp_title(); ?></title>
<link rel="profile" href="yourprofileurl." />
<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>" />
<?php if ( is_singular() && get_option( 'thread_comments' ) ) wp_enqueue_script( 'comment-reply' ); ?>
<?php wp_head(); //beware here it adds default head tags from wordpress ?>
</head>

In addition to the basic content of the header.php, you will generally include a menu as follow :

If you need more information on implementing a menu with WordPress, take a look at our article on menu customization.

To fill the files you can just extract some code from the latest default themes on WordPress, for instance : TwentySixteen.


<?php wp_footer(); ?>

</body>

</html>

You may add widgets and other menus to the footer, here we keep things simple.

Now let’s fill our main default template file under index.php :


<?php get_header(); // We load the header file ?>

<!-- skip the following line - this is just an example -->


<div class="container">
<?php if ( have_posts() ) : ?>
<?php if ( is_home() && ! is_front_page() ) : ?>


<header>

<h1><?php single_post_title(); ?></h1>

</header>


<?php endif; ?>
<?php // Start the loop.

 while ( have_posts() ) : the_post(); 
/* 
* Include the Post-Format-specific template for the content. 
* If you want to override this in a child theme, then include a file 
* called content-___.php (where ___ is the Post Format name) and that will be used instead. */ 

get_template_part( 'template-parts/content', get_post_format() ); 

// End the loop. 
endwhile; 

// Previous/next page navigation. 

the_posts_pagination( array( 'prev_text'          => __( 'Previous page', 'yourtheme' ), 'next_text'          => __( 'Next page', 'yourtheme' ), 'before_page_number' => '<span class="meta-nav screen-reader-text">' . __( 'Page', 'yourtheme' ) . ' </span>', ) );

// If no content, include the "No posts found" template.
else : 
     get_template_part( 'template-parts/content', 'none' );
endif; ?>
</div>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Note : we’ve included the displayed text with the notation __( to allow translations, for more information, please refer to the article on using Poedit with Wordpress.

Similar to the index page, you can set up a front-page.php and a home.php page using the same type of code with slight changes according to your needs.

Now we need to treat an article page a little differently :


<?php get_header(); ?>


<div class="container">
   <?php // Start the loop. while ( have_posts() ) : the_post(); // Include the single post content template. get_template_part( 'template-parts/content', 'single' ); // If comments are open or we have at least one comment, load up the comment template. if ( comments_open() || get_comments_number() ) { comments_template(); } if ( is_singular( 'attachment' ) ) { // Parent post navigation. the_post_navigation( array( 'prev_text' => _x( '<span class="meta-nav">Published in</span>
                                                          <span class="post-title">%title</span>', 
                                                         'Parent post link', 'yourtheme' ),
				) );
			} elseif ( is_singular( 'post' ) ) 
                        {
				// Previous/next post navigation.
				the_post_navigation( array(
					'next_text' => '<span class="meta-nav" aria-hidden="true">' . __( 'Next', 'yourtheme' ) . '</span> ' .
						'<span class="screen-reader-text">' . __( 'Next post:', 'yourtheme' ) . '</span> ' .
						'<span class="post-title">%title</span>',
					'prev_text' => '<span class="meta-nav" aria-hidden="true">' . __( 'Previous', 'yourtheme' ) . '</span> ' .
						'<span class="screen-reader-text">' . __( 'Previous post:', 'yourtheme' ) . '</span> ' .
						'<span class="post-title">%title</span>',
				) );
			}

			// End of the loop.
		endwhile;
		?>

	</div>




	<?php get_sidebar( 'content-bottom' ); ?>

<?php get_sidebar(); ?>
<?php get_footer(); ?>

Most of the code is taken from the latest wordpress Theme : TwentySixteen.

I assume you know how to deal with html/css within your code. For more details about each function, you can refer to WordPress documentation or directly ask here by letting us a comment.

3. Templating with WordPress

Rather than calling the get_template_part( ‘template-parts/content’, ‘single’ ) function or any other template, you could simply put the following code instead :


<?php the_title();

if (have_posts()) {
  while (have_posts()) {
    the_post();
    the_content(); 
  }
} ?>

But for a more precise layout, you can use the template under the folder and name it  template-parts/content-single.php 


<?php

<article>

<header>
	<?php the_title( '

<h1 class="entry-title">', '</h1>

' ); ?>
</header>


<!-- .entry-header -->
	<?php yourtheme_excerpt(); ?>
	<?php yourtheme_post_thumbnail(); ?>


<div class="entry-content">
		<?php the_content(); wp_link_pages( array( 'before' => '


<div class="page-links"><span class="page-links-title">' . __( 'Pages:', 'yourtheme' ) . '</span>',
				'after'       => '</div>



',
				'link_before' => '<span>',
				'link_after'  => '</span>',
				'pagelink'    => '<span class="screen-reader-text">' . __( 'Page', 'yourtheme' ) . ' </span>%',
				'separator'   => '<span class="screen-reader-text">, </span>',
			) );

		?>
	</div>



<!-- .entry-content -->

	


<footer>
		<?php yourtheme_entry_meta(); ?>
		<?php
			edit_post_link(
				sprintf(
					/* translators: %s: Name of current post */
					__( 'Edit<span class="screen-reader-text"> "%s"</span>', 'yourtheme' ),
					get_the_title()
				),
				'<span class="edit-link">',
				'</span>'
			);
		?>
	</footer>



<!-- .entry-footer -->
</article>



<!-- #post-## -->

?>

All template files are constructed the same way so we will skip theme except for the default one under content.php :




<article>
	

<header>
		<?php if ( is_sticky() && is_home() && ! is_paged() ) : ?>
			<span class="sticky-post"><?php _e( 'Featured', 'yourtheme' ); ?></span>
		<?php endif; ?>

		<?php the_title( sprintf( '

<h2 class="entry-title"><a href="%s" rel="bookmark">', esc_url( get_permalink() ) ), '</a></h2>


' ); ?>
	</header>


<!-- .entry-header -->

	<?php yourtheme_excerpt(); ?>

	<?php yourtheme_post_thumbnail(); ?>

	

<div class="entry-content">
		<?php
			/* translators: %s: Name of current post */
			the_content( sprintf(
				__( 'Continue reading<span class="screen-reader-text"> "%s"</span>', 'yourtheme' ),
				get_the_title()
			) );

			wp_link_pages( array(
				'before'      => '

<div class="page-links"><span class="page-links-title">' . __( 'Pages:', 'yourtheme' ) . '</span>',
				'after'       => '</div>


',
				'link_before' => '<span>',
				'link_after'  => '</span>',
				'pagelink'    => '<span class="screen-reader-text">' . __( 'Page', 'yourtheme' ) . ' </span>%',
				'separator'   => '<span class="screen-reader-text">, </span>',
			) );
		?>
	</div>


<!-- .entry-content -->

	

<footer>
		<?php yourtheme_entry_meta(); ?>
		<?php
			edit_post_link(
				sprintf(
					/* translators: %s: Name of current post */
					__( 'Edit<span class="screen-reader-text"> "%s"</span>', 'yourtheme' ),
					get_the_title()
				),
				'<span class="edit-link">',
				'</span>'
			);
		?>
	</footer>


<!-- .entry-footer -->
</article>


<!-- #post-## -->

For more templates and more precisely to build your own custom templates you can use the following code :


<pre><?php /* Template Name: Example */ ?>

The content of the file will sit under the filename : example.php

You may check WordPress documentation for more details.

4. Sidebars & widgets

WordPress recommands the use of widgets for a better structure organization and a way to achieve this is by using sidebars.

While reading the different template files, you may have notice the sidebar call like this one : get_sidebar()

Let’s review what is this file dealing with :


<?php if ( is_active_sidebar( 'sidebar-1' )  ) : ?>


<aside>

<?php dynamic_sidebar( 'sidebar-1' ); ?>

</aside>


<!-- .sidebar .widget-area -->

<?php endif; ?>

The above example of a sidebar refers to widget called sidebar-1. A widget can be manipulated through the administrative interface of WordPress.

We are almost done with our theme, you could actually launch it now and it will be fine, but if you need to define a few widgets and other useful options, we need to fill up our functions.php file.

5. Configuration options

As we set up a sidebar under a specific name, we need to register it along wih WordPress and this is done through the following file we created earlier :


function yourtheme_widgets_init() {

function yourtheme_widgets_init() {

register_sidebar( array( 'name'          => __( 'Sidebar', 'yourtheme' ),

'id'            => 'sidebar-1',

'description'   => __( 'Add widgets here to appear in your sidebar.', 'yourtheme' ),

'before_widget' => '
<section>',

'after_widget'  => '</section>

',

'before_title'  => '
<h2>', 'after_title'   => '</h2>

', ) );

}

add_action( 'widgets_init', 'yourtheme_widgets_init' );

To follow the standards, beware of the name of the functions (use your theme name as prefix).

And do not forget the add_action call below the function declaration.

Now optionally you will enqueue scripts and styles within the same file as follow :


function yourtheme_scripts() {
	// Add custom fonts, used in the main stylesheet.
	wp_enqueue_style( 'yourtheme-fonts', yourtheme_fonts_url(), array(), null );

	// Add Genericons, used in the main stylesheet.
	wp_enqueue_style( 'genericons', get_template_directory_uri() . '/genericons/genericons.css', array(), '3.4.1' );

	// Theme stylesheet.
	wp_enqueue_style( 'yourtheme-style', get_stylesheet_uri() );

	// Load the html5 shiv.
	wp_enqueue_script( 'yourtheme-html5', get_template_directory_uri() . '/js/html5.js', array(), '3.7.3' );
	wp_script_add_data( 'yourtheme-html5', 'conditional', 'lt IE 9' );

}
add_action( 'wp_enqueue_scripts', 'yourtheme_scripts' );

I invite you to read the documentation on WordPress for more details or just check the code inside the latest default theme of WordPress.

That’s it for this short and quick tutorial.

As mentioned at the beginning, these lines are more of a reference so you can build your theme structure rapidly, one alternative is to rely on an existing theme such as TwentySixteen and remove the code you don’t need and add your own layout.

I hope you enjoyed these lines, have a nice trip.

Leave a Reply

Want more information?

Related links will be displayed here in this section for you to pick up another good spot to get more details about Web marketing and Search Engine Optimization. There will be some sites which we selected to ease the work of any webmaster or/and web marketer on the Internet.

%d bloggers like this: