modifying php templates for custom post types

By default WordPress does not show custom fields on the front-end and to do so requires some theming. In this series we have looked at a number of tools, both plugins and themes, for creating the theme templates for Custom Post Types in order to show their custom fields. In this post we will instead look at the old fashioned way of handling this without a builder, by modifying the theme’s PHP templates directly to create the single for the Book Custom Post Type.

There are several reasons why you might want to go this way, including:

  • You don’t want to use a builder for performance reasons.
  • Having a builder installed just for one template seems like overkill.
  • You have no budget and cannot afford a theme template builder.
  • You want to learn.

Video Version

Project Setup

For whatever reason, you are moving into the realm of the power user or developer and there are some things you need to make this happen. The first, and perhaps most important, is curiosity and patience. You need to be willing to do a lot of trial and error and not get frustrated.

For this example, I’m using the free Kadence theme. Kadence is a new, popular theme that is page builder friendly and works well with Gutenberg.

kadence theme on wordpress org

Because we’ll be modifying theme files it is important to use a child theme. These days many popular themes have already put together a child theme for you. I Googled “kadence child theme” and the first result was a page on the Kadence website that told how to make a child theme along with a download of a child theme for Kadence. I downloaded the example child theme to use for this project.

kadence child theme download

I’m working on my local desktop machine where I’m running Laragon for local WordPress development sites. You will need access to the files on your website for this project so a local site is easiest, but you can also use an online staging site if you have FTP access to edit the files. Don’t try to edit the files from within WordPress because if you make a mistake you may lock yourself out from your site.

On my development site I have a number of demo posts created.

demo post content

I also created a Custom Post Type called Books, added some custom fields to it, and entered a number of book records.

book records

Each book record has two custom fields: one for the author’s photo and one for a link to the author’s website. If you are unfamiliar with how to create Custom Post Types and add custom fields, the first post in this series shows you how to do that.

book custom fields

I’ve gone ahead and used the Customizer to make the archive and single book layout look as close as possible to how I want them to be. A cool thing about the Kadence theme is that it lets you apply the Customizer options to the archive and single for Custom Post Types, just as it does for your posts and blog.

Here is a single book record on the front-end. As you can see, the featured image is huge and the custom fields don’t show. There is no option for a two column layout with the featured image and custom fields on the left and the title, post meta and content on the right.

default single book

Down the Rabbit Hole – Finding Which File to Edit

WordPress has a system of rules for picking which theme template will be used for which content. This is called the Template Hierarchy. If you look at the diagram, for the single, WordPress is going to pick “single.php” and if you want to make it specific to the book Custom Post Type then it would be “single-book.php”.

wordpress template hierarchy

These days things are not so cut and dried. That is because theme authors have divided up templates into reusable parts to be more efficient. This means that there area lot of conditional includes and functions that bring in content, so you need to be a bit of a detective and follow the breadcrumb trail. If we look at the Kadence theme directory we see that there is a “single.php” file!

kadence theme directory

If we look at the contents of “single.php” file we see that in between a “get_header()” and “get_footer()” functions, it calls a function for the single. We could just replace this file with our own and put our code here, but there is a lot that the theme does downstream from here that we would miss or have to manually recreate. It is better to make as few changes as possible to get the job done.

contents of single php file

We can do a search through the Kadence theme files for this and then follow what that calls, but there is another option which is easier. If you want to know what theme template files are being used the you can install the Show Current Template plugin from the WordPress plugin directory.

show current template on wordpress org

Now with this installed we can go to any page and in the admin toolbar we will see what templates and functions were used. Ouch. That’s a long list. I do see reference to a template-parts directory so I go and check that out.

includes in rendering book single

That does not have any files in it, just subdirectories.

template parts directory

However, below that I find some files for the post single.

content sub directory

Let’s take a look at this “single.php” file first. The “single.php” file loads the “single-entry.php”.

single php file

This file looks to output the featured image, meta, and content, along with other content. Great, that’s what we need. So, here is the plan, I’m going to copy the single.php file over into the child theme and in it we will test for the book Custom Post type. We will also copy over the single-entry.php file, but we will rename that to single-entry-book.php. If we find that we are loading a book page then we will direct to our new book version of the file which we will modify.

single entry file

Working with the Child Theme

We have been looking at the Kadence theme files, but remember we have a child theme active. Here is what the child theme directory looks like. There is not much there: two place holder files and a screenshot.

child theme directory

Now, there is some magic about child themes and that is that we only need to copy over the files that we want to edit and our files in the child theme directory are used instead of the ones in the parent theme. We do need to replicate the folder structure for any files we copy over however. So, I want to copy over the two files with the same directory structure.

two files with directory structure

Now I want to edit the single.php to use the single-entry-book.php file if the post type is “book”. Here is the original version:

orginal version of include

I noticed that the WordPress function “get_post_type()” was already being used, so I changed that one line into an IF / ELSE condition where I checked for the book Custom Post Type. Here is the version with the conditional added:

conditional version of include

Looking on the front-end at a single book post nothing has changed. That is what we’d expect because we only renamed the single-entry.php file and didn’t make any changes yet. However, there is another possibility and that is that we are working in the wrong place with the wrong files. I like to verify, step at a time, that changes are working as expected. I see in the output template list that our renamed file was included, so that is one bit of verification.

verifying new template being used 1

Just to make double-certain, I added a bit of PHP code to the renamed file to confirm it is being used. The “echo” command writes out the variable, in this case the result from the get_post_type() function.

verifying new template being used 2

And this is what I see on the front-end, so it is working.

verifying new template being used 3

I can removed that test now. I recall that in the Customizer there are options for featured image placement and size for the book Custom Post Type, so I set those.

customizer featured image options for book single

Looking at the code, the place I want to modify is all within the “article” tag. This is the content area. I’m going to use some simple CSS grid options to create my two columns. To do that you declare a high level element as the “grid container” and then you can declare child elements are the grid columns. So, I add a class to the article tag. Here is the original version. Note that it is outputting some classes.

original article tag

I add a class to the list that I will hang my CSS off of. I give it a prefix of my initials so its clear to me I added it.

modified article tag

Now to add the columns and put the fields into the each column. In the screenshot below you can see the underlined classes I added for CSS layout and styling. There are also now two divs that have classes that I’ll use for the columns.

adding columns to content area

Now I go to the Customizer and add the CSS. The first bit declares the top article element as the grid container. The next bit with the media query says if the browser width is at leaset than 400px then show the two divs side by side. If not, then stack them. The final bit centers the image in its column.

.dcm-book-single {
	display:grid;
}
@media (min-width:400px) {
	.dcm-book-single {
		grid-template-columns:20% 80%;
	}
}
.dcm-book-feature-image {
	display:block;
  margin: 25px auto;	
}

Here is what it is looking like so far.

grid columns working

Now, the whole point of this was to show the custom fields, so let’s add them in below the featured image.

custom fields showing

Now I add some CSS to center the author’s photo and the text in the button. Everything looks good.

custom fields final

Final Tasks: Making the Child Theme Whole

We have been pretty good at making the minimum number of changes necessary. We have also kept the theme styles and Customizer options working. Nevertheless, we are basically hacking the theme and there are a few additional steps we can take to make our child theme “whole”.

The first thing we can do is move the CSS from the Customizer to the child theme’s stylesheet. That will keep all of the pieces together in one place. I copied and then deleted the CSS in the Customizer. I then opened the “styles.css” file in the child theme directory and add it there. While there I modified the description to let people know what it does.

child theme stylesheet

I noticed even after saving that the changes weren’t showing, so I looked in the child theme’s “functions.php” file and saw that the command to load it was commented out with an instruction to uncomment it, which I did.

stylesheet loading enabled

While in the child theme’s directory, I edited the theme thumbnail also.

child theme image modified

Finally, I zipped up a copy of the child theme directory to save in case I needed this again later.

Discussion and Conclusions

As you can see, creating the single template by modifying the PHP and adding CSS is a lot more effort than using a theme builder plugin. You need to know some HTML, CSS, and PHP. Yes, now we know why the theme template functionality of page builders is so popular. It is faster and easier.

Some people are happy to jump in and modify a child theme and after you do it a few times you know the general routine. However, there is no standardized way of including theme files or theme code beyond some basics required by WordPress. Before writing this post I checked out several themes and Kadence was the easiest I saw to modify. In other words, you are going to need to do some exploration to choose a theme you understand and find where to modify a theme as they are each different.

We could have just copied the “single.php” file in the root of the Kadence theme directory to a “single-book.php” file, delete everything out, and then added our code there. If we took that route we would have then taken responsibility for the code, styles, and output. By making our changes as small as possible we leveraged the theme’s code and styles so that it continued to do the heavy lifting.

One take-away I hope you remember is about child themes. You saw how we only needed to modify and copy over, preserving the folder structure, the files we wanted to modify or add. That is a pretty cool feature of child themes and it means that the theme author can update the parent theme to add new features and there is little likelihood that our additions would break. Still, it is a good idea to be mindful that your child theme depends on the parent. Also, depending on what changes you made, you may want to keep an eye on new versions of the parent theme in case they impact your child theme.

I don’t expect a lot of people to drop page builders and do it by hand. In several of the earlier posts in this series I mentioned the “old fashioned way of creating PHP templates by hand” and felt that it was a good idea to provide a feel for what that was like. I hope you found this post interesting. Please share your thoughts in the comments.

Some of the links in the post above are “affiliate links.” This means if you click on the link and purchase the item, I will receive an affiliate commission. You will still pay the same amount so there is no extra cost to you. I am disclosing this in accordance with the Federal Trade Commission’s 16 CFR, Part 255: “Guides Concerning the Use of Endorsements and Testimonials in Advertising.”

Similar Posts

Add your first comment to this post