Building a Custom WordPress Website from Scratch

We all know WordPress has grown to a mature content management system these days. There are several great WordPress themes you can use to build a professional corporate website. You are not limited to creating a magazine or blog site if you choose WordPress as your CMS.

Wordpress websiteA few days ago I launched my company’s website at finalwebsites.nl and that website was one of my first WordPress websites that used all of the common WordPress features like widgets, shortcodes and custom post types. Don’t get me wrong, I used them all before (like for this blog), but in the past I created complicated sidebars without the use of widgets.

Remember, this series of articles is not on using or modifying an existing theme. These tutorial are designed for those with some HTML, CSS and PHP experience who used WordPress to build websites before. You should be familiar with common WordPress concepts and functions.

This WordPress tutorial series is about:

  1. Building a custom WordPress website from scratch – How to setup a theme and which template parts are important.
  2. Dynamic sidebars and widget logic – The default WordPress widgets are often to limited in their functions. This article is about using your own widgets and other solutions.
  3. Using custom post types to build an FAQ – Learn how to create a custom post type and how to build a simple FAQ page.
  4. WordPress plugins for regular websites – You need plugins for every WordPress site, this article is an update on my previous WordPress plugin list.
  5. Optimize your WordPress website – The first tutorials in the series are about building a website and the last one is about how to make your WordPress website better.

Build your WordPress theme from scratch

In most of my previous projects I used a child theme structure to create a WordPress website more quickly. This time I started my theme with my “own” empty files.

Create a new directory inside the themes directory with a name of your choice, than create your first file called style.css and add this comment:

/*
Theme Name: mythemename
Theme URI: https://www.web-development-blog.com/
Description: A custom theme for my website
Author: Olaf
Version: 1.0
*/

This information is used by WordPress to recognize your theme. Let’s continue with the header.php file. This theme file is very simple because it doesn’t have a lot of PHP code.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:og="http://opengraphprotocol.org/schema/" <?php language_attributes(); ?>>
<head profile="http://gmpg.org/xfn/11">
<meta http-equiv="Content-Type" content="<?php bloginfo('html_type'); ?>; charset=<?php bloginfo('charset'); ?>" />
<title><?php wp_title(''); ?></title>
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />
<?php wp_head(); ?>
</head>
<body>
	<div id="container">
		<div id="header">
			<a id="logo" href="<?php echo home_url(); ?>">
				<img src="<?php bloginfo('template_directory'); ?>/images/logo.png" alt="Logo <?php bloginfo('name'); ?>" />
			</a>
			<?php wp_nav_menu( array( 'container_class' => 'topnavigation', 'theme_location' => 'primary' ) ); ?>
		</div>

I used common WordPress functions for the standard values, paths and the navigation menu. The WordPress function “wp_head” will add all the other header elements. Notice the outer DIV element which stays open in the header file. We close that DIV element inside the footer.php file.

<div id="footer">		
			&copy; <?php bloginfo('name'); ?>
		</div>
	</div>
<?php wp_footer(); ?>
</body>
</html>

The file for the footer is often very simple. The function “wp_footer()” is very important, because this function is by WordPress to include other codes if needed. Let’s create also the sidebar.php file.

<div id="sidebar">
	<ul>
		<?php
		if ( ! dynamic_sidebar( 'primary-widget-area' ) ) { ?>
		<li id="search" class="widget-container widget_search">
			<?php get_search_form(); ?>
		</li>
		<?php } ?>
	</ul>
</div>

If the sidebar doesn’t exists or if the sidebar doesn’t contains a widget, a search form will show up. If you like, you can remove that one as well. Create also the file functions.php and add the following PHP code to get the navigation and the widget area working, we will add more PHP code later in this series.

<?php
register_nav_menus( array(
	'primary' => __( 'Primary Navigation', 'mythemename' ),
) );
register_sidebar(
	array(
		'name' => 'Primary Widget Area',
		'id' => 'primary-widget-area',
		'description' => 'The primary widget area',
		'before_widget' => '<div id="%1$s" class="smallcol %2$s">',
		'after_widget' => '<div class="smallcolfooter"></div></div>',
		'before_title' => '<h3 class="widget-title">',
		'after_title' => '</h3>'
	)
);

In theory you can run a WordPress website with the index.php file only, but this is not very clean and not flexible. Place the “WordPress loop” in your index.php file and include the functions for header, footer and sidebar. While doing this you should have this code in your index.php file:

 <?php get_header(); ?>
	<div id="content">
		<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
		<div class="post">
			<h2><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h2>				
			<?php the_excerpt(); ?>
		</div>
		<?php endwhile; ?>
		<?php endif; ?>
	</div>
	<?php get_sidebar(); ?>
<?php get_footer(); ?>

When your first theme-set is complete you can activate the theme from the WordPress admin panel. Create also a custom menu and use “Primary Navigation” as the theme location. Test your theme, you should see a list of posts from the post section.

More theme files for your WordPress website

How many theme files you need depends on the structure of your website. A custom homepage is always a good idea. But first we copy the index.php file and call it page.php. There are only a few things you need to change: replace the H2 tag with an H1 tag, remove the link from the title and replace the function “the_excerpt()” with “the_content()”. The theme file for the custom homepage is based on the page.php file and we call it page-home.php. If we create later a page with the slug “home”, WordPress will pick up that theme automatically. We use the following code that shows the content for the homepage and also the latest 5 blog posts.

<?php get_header(); ?>
	<div id="content">
		<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
		<div class="post">				
			<?php the_content(); ?>
		</div>
		<?php endwhile; ?>
		<?php endif; ?>
		<div id="latest">
			<?php
			$args = array('post_type' => 'post', 'posts_per_page' => 5, 'orderby' => 'post_date', 'order' => 'DESC' );
			$the_query = new WP_Query( $args );
			echo '
			<h2>Latest blog posts</h2>
			<ul>';
			if ( $the_query->have_posts() ) {
				while ( $the_query->have_posts() ) {
					$the_query->the_post();
					echo .= '
				<li>
					<a href="'.get_permalink().'">'.get_the_title().'</a><br />
					'.get_the_excerpt().'
				</li>';
				}
			} else {
				echo '
				<li>Sorry, no posts right now.</li>';
			}
			wp_reset_postdata();
			echo '
			</ul>';
			?>
		</div>
	</div>
	<?php get_sidebar(); ?>
<?php get_footer(); ?>

I don’t use a H1 element or the “get_the_title()” function for the homepage theme, because I like to call the page “Home” (to recognize that page between the others). I put the H1 element with a real header or title into the content field. The next theme file is the one we use for the posts. Copy the page.php file and save it under the name single.php and use this code.

<?php get_header(); ?>
	<div id="content">
		<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
		<div class="post">
			<h1 class="posttitle"><?php the_title(); ?></h1>				
			<?php the_content(); ?>
		</div>
		<?php comments_template(); ?>
		<?php endwhile; ?>
		<?php endif; ?>
	</div>
	<?php get_sidebar(); ?>
<?php get_footer(); ?>

This theme file looks the same as the file for the page theme, except the function “comments_template()”. This WordPress function will provide the comment list and also the comment form. You can change the look using CSS or you can create a comments.php file with several other comment functions. For the last option you should check the WordPress codex for more information.

The last theme file I create for this tutorial is the file we need for the category archives. It looks (again) a lot like the index.php file except that there is some category information, like the category name and the description. Create a file named category.php and add this code.

<?php get_header(); ?>
	<div id="content">
		<h1 class="posttitle"><?php single_cat_title(); ?></h1>
		<?php echo category_description(); ?>
		<?php if (have_posts()) : while (have_posts()) : the_post(); ?>
		<div class="post">
			<h2><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h2>			
			<?php the_excerpt(); ?>
		</div>
		<?php endwhile; ?>
		<div class="page-nav">
			<?php previous_posts_link('? Previous') ?>
			<?php next_posts_link('Next ?') ?>
		</div>
		<?php endif; ?>
	</div>
	<?php get_sidebar(); ?>
<?php get_footer(); ?>

Below the while loop there are some simple navigation links, your need them to provide access to previous articles.

This was my tutorial about building a custom WordPress theme. I think it’s very easy to create the files and I’m sure it’s much more work create the style sheet for your WordPress website. The next tutorial is about how to create custom widgets for dynamic sidebars, stay tuned.

Published in: WordPress Development