Theme template system

Part 9. Organizing page content in separate template files

Buy the book

These articles are excerpts from the book's manuscript draft. You can read the book here or in an easier-to-read format and finalized by purchasing the finished book.

Table of Contents

This article will introduce the theme template system and give you a glimpse of the WordPress template hierarchy. I will return to the template hierarchy later in future articles. You will get a solid understanding of which file to use and for which purpose. Using this information, you can develop templates for different posts and pages. But in this article, we’ll learn mostly how the inner template system is built to separate different parts of page content to separate files.

About WordPress template hierarchy

You can read about WordPress template hierarchy from here wp hierarchy

The idea is that WordPress has different templates for different pages like single post, page, archive, author, category, etc. If the theme did not implement a template file for the purpose WordPress will look for the next in line. And if WordPress finds no such files, it will use index.php as the last resort to display any content.

To start with our file system lets create a page with some content and define it as a static frontpage for our site. 

  1. Go create a page
  2. Name the new page as WPSmithy
  3. Write some content on the page and publish it
  4. Go to Dashboard / Settings – Reading
  5. Choose “Your homepage displays” – A static page
  6. Select the newly created page (WPSmithy)
  7. Save Changes

Front-page template

According to WordPress theme template hierarchy, WordPress first tries to use a front-page.php to display content for a static front page. So, create a new file, front-page.php, in the theme root folder.

Test your site in a browser. You should get a blank page.

That is because now WordPress is using this empty file for frontpage. We will fix this soon.

Folder structure

I wrote earlier about the folder system. Please read it first, and then return to this article. You better also read the previous article about functions.php, so you can get a solid understanding of the whole idea of splitting code into smaller files that are responsible for only a single task.

At the end of this article, the theme folder system should look like this (view from Sublime Text editor).

View of theme files and folders.

Now lets start by ripping the index.php file into pieces.

Headers for the whole site

The header with navigation and all recurring elements should appear similar on all pages. For this reason, we will take the header part out from index.php and create a new file page-header.php. We will place this file in the _themeparts folder and call for it from every file to display pages or posts.

Cut the header part from our index.php file and paste it in the page-header.php file. Save the file.

The page-header.php file should look like this.

				
					<?php 
/** 
* This is the header part of all of our theme pages and posts.
* 
* version: 1.0
* date: 09.03.2022
*/
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
	<meta charset="<?php bloginfo( 'charset' ); ?>" >
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<link rel="preconnect" href="https://fonts.googleapis.com">
	<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>

	<?php wp_head(); ?>
</head>
<?php 
/**
 * this version is still under construction. This file produce the header 
 * but the contents are hard coded into this file. 
 * Later we remove the contents and replace them with dynamic content.
 */
?>
<body>
	<a class="skiplink" href="#main">Jump right to the content</a>
	<div class="top-bar">
		<div class="limited-width top-bar-content">
			<a href="mailto:info@wpsmithy.com">info@wpsmithy.com</a>
		</div>
	</div>
	<header class="page-header">
		<div class="limited-width">
			<div class="header-content">
				<div class="header-logo">
					<img decoding="async" class="lazyload" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-src="_imgs/wpsmithy-logo-blackbg.png" alt="WP Smithy company logo"><noscript><img decoding="async" class="lazyload" src="_imgs/wpsmithy-logo-blackbg.png" alt="WP Smithy company logo"></noscript>
				</div>	
				<nav class="site-nav">
					<ul>
						<li><a href="#" class="nav-link">page 1</a></li>
						<li><a href="#" class="nav-link">page 2</a></li>
						<li><a href="#" class="nav-link">page 3</a></li>
					</ul>
				</nav>
			</div><!-- .header-content -->
		</div><!-- .limited-width -->
	</header>
				
			

And how do we use this file? By calling it from each of the WordPress template hierarchy files.

Now, we created a file for a static front page. Open the file in code editor and call for the page-header.php. To do this, we use a WordPress function get_template_part('folder/templatefile');

calling template parts using get_template_part() function

We instruct the function to fetch file contents from the file we give as a parameter to the function. Notice that if the name of the template file is page-header.php, the parameter for the function is only page-header.

Leave the file extension .php away.

				
					<?php 
/**
 * load the page-header.php part from _themeparts folder 
 */
	get_template_part('_themeparts/page-header'); 
?>
				
			

Test your site again in browser and you will see a page with only the header visible. No other content at all.

Page displaying only header.

Page content for front-page

Now that we have the header working, we need to display the page’s contents. This time we create a new file in the _themeparts folder. Name the file as frontpage-content.php

Again, go to the index.php, cut away the page’s content, and paste it into the newly created file. Save the file. It should look like this.

				
					<?php
	if ( have_posts() ) : 
	while( have_posts() ) : the_post();
?>


<div class="hero">
	<h1><?php the_title(); ?><br><?php echo get_bloginfo('description'); ?></h1>
</div>

<main id="main" class="limited-width">
	
	<?php
		the_content();
	?>

</main>

<?php
	endwhile;
	endif;
?>
				
			

Edit the front-page.php file again and make it call for the content. Add this code into the file.

				
					<?php 
/**
 * load the frontpage-content.php part from _themeparts folder 
 */
	get_template_part('_themeparts/frontpage-content'); 
?>
				
			

Test your site on browser and you’ll see some improvement. Now, the page has a header and content. Great, now add the footer, and we are (almost) done.

Footer for all pages and posts

I think you have already gotten the idea. Think about it, what should you do?

Go create a new file in _themeparts -folder. Name the file as page-footer.php.

Do like we did with the header part. Then, open index.php and cut away the footer part of the code (the only code there should be left), and paste it into our new file.

				
					<?php 

/**
 * this version is still under construction. This file produce the header 
 * but the contents are hard coded into this file. 
 * Later we remove the contents and replace them with dynamic content.
 */
 ?>

	<footer class="page-footer">
		<div class="limited-width">
			<div class="footer-content">
				<div class="footer-section">
					<h2>Site links</h2>
					<ul>
						<li><a href="#" class="footer-menu-link">link 1</a></li>
						<li><a href="#" class="footer-menu-link">link 2</a></li>
						<li><a href="#" class="footer-menu-link">link 3</a></li>
						<li><a href="#" class="footer-menu-link">link 4</a></li>
					</ul>
				</div>
				<div class="footer-section">
					<h2>section 2</h2>
					<p>These footer sections will be "widgetizeds" i.e. User can place a Gutenberg Block into the section area to create a footer for his or her liking.</p>
				</div>
				<div class="footer-section">
					<h2>section 3</h2>
					<p>This is the third content block in footer. No content is mandatory so it is a free design that the end user can do.</p>
				</div>
			</div><!-- .footer-content -->
		</div><!-- .limited-width -->
	</footer>
	<div class="bottom-line">
		<p>@ 2022 WP Smithy</p>
	</div>
	
<?php 
/**
 * Prints scripts or data before the closing body tag on the front end.
 */
	wp_footer();
?>
</body>
</html>
				
			

Again make front-page.php use this footer and add the code into it.
This is the final code for the whole front-page.php file. For simplicity sake I have shortened the code into one php block and removed all comments.

				
					<?php 

	get_template_part('_themeparts/page-header'); 

	get_template_part('_themeparts/frontpage-content'); 

	get_template_part('_themeparts/page-footer'); 
?>
				
			

Test your site and you should have a complete working front-page.

What about the index.php file?

Now that we we have removed all code from index.php, any other page than front-page should be blank. Let’s fix it.

Test it first. Go create a new article. Name it as you wish and publish it. After you have published it, try to review it. The post is displayed blank. Only a white page, and why?

Because according to WordPress template hierarchy it tries to use a template file for posts but can’t find any, so as a last resort, it uses index.php – which is empty.

Fix index.php file

Create a new file in _themeparts folder and name it index-content.php. Let’s make it display post contents and title of course. I will explain the code better in a later article. Add this code to the file and save it.

				
					<?php
	if ( have_posts() ) : 
	while( have_posts() ) : the_post();
?>

<main id="main" class="limited-width">

	<h1><?php the_title(); ?></h1>
	
	<?php
		the_content();
	?>

</main>

<?php
	endwhile;
	endif;
?>
				
			

And then edit the index.php file itself. The code should look like this.

				
					<?php 

	get_template_part('_themeparts/page-header'); 

	get_template_part('_themeparts/index-content'); 

	get_template_part('_themeparts/page-footer'); 
?>
				
			

Why all these separate content files?

You may wonder why to bother with all these different files. Believe me, when the theme evolves and time passes, and you get more and more feature requests, it is much easier to maintain the code. You can create your page templates for marketing purposes and campaigns, and so on. The code is easier to understand, edit and debug if needed.

And now you know the system. This is how we will continue from now on.

Picture of Kari Selovuo

Kari Selovuo

Leave a Reply

Your email address will not be published. Required fields are marked *