{"id":155245,"date":"2016-06-07T14:00:58","date_gmt":"2016-06-07T14:00:58","guid":{"rendered":"https:\/\/premium.wpmudev.org\/blog\/?p=155245"},"modified":"2017-10-15T07:34:48","modified_gmt":"2017-10-15T07:34:48","slug":"wordpress-development-intermediate-theme-development-in-detail","status":"publish","type":"post","link":"https:\/\/wpmudev.com\/blog\/wordpress-development-intermediate-theme-development-in-detail\/","title":{"rendered":"WordPress Development for Intermediate Users: Theme Development in Detail"},"content":{"rendered":"<p>Interested in taking your WordPress game to a whole new level? Want to further develop your PHP skills and add more complex and exciting functionality to your themes and plugins?<\/p>\n<p>Welcome to our latest series, WordPress Development for Intermediate users. This series follows on from our popular <a href=\"https:\/\/wpmudev.com\/blog\/wordpress-development-beginners-getting-started\/\" target=\"_blank\">WordPress Development for Beginners<\/a> tutorials, which introduced you to the fundamentals of developing websites with WordPress,\u00a0how to get started coding with PHP, and building themes and plugins.<\/p>\n<p>In this seven-week series, we step things up a notch to\u00a0really test your skills. You&#8217;ll learn how to:<\/p>\n<ul>\n<li>Develop a\u00a0WordPress theme with include files, template parts, template tags,\u00a0plus action and filter hooks<\/li>\n<li>Add Customizer functionality to your theme<\/li>\n<li>Develop plugins using best practice for coding<\/li>\n<li>Add complex, custom queries and loops to your themes and plugins<\/li>\n<li>Create and work with custom post types<\/li>\n<li>Work with metadata, including post metadata (or custom fields) and other metadata e.g. author metadata, and<\/li>\n<li>Translate your code and get it ready for release<\/li>\n<\/ul>\n<p>When you&#8217;ve worked through this series and applied what you&#8217;ve learned, you&#8217;ll come out the other end a competent WordPress developer, ready to create your own themes and plugins and distribute them to other users or even sell sites built on them to clients.<\/p>\n<p><em>Note: It\u2019s important that you have a working knowledge of PHP as this is the foundational language of WordPress and I&#8217;ll be referring to code snippets throughout this series.<\/em><\/p>\n<p>Let&#8217;s get started.<\/p>\n<p><strong>Missed a tutorial in our WordPress Development for Intermediate Users series? You can catch up on all seven posts here:<\/strong><\/p>\n<ul>\n<li><a href=\"https:\/\/wpmudev.com\/blog\/wordpress-development-intermediate-theme-development-in-detail\/\" target=\"_blank\">WordPress Development for Intermediate Users: Theme Development in Detail<\/a><\/li>\n<li><a href=\"https:\/\/wpmudev.com\/blog\/wordpress-development-for-intermediate-users-making-your-themes-customizer-ready\/\" target=\"_blank\">WordPress Development for Intermediate Users: Making Your Themes Customizer-Ready<\/a><\/li>\n<li><a href=\"https:\/\/wpmudev.com\/blog\/wordpress-development-intermediate-building-plugins\/\" target=\"_blank\">WordPress Development for Intermediate Users: Building Plugins<\/a><\/li>\n<li><a href=\"https:\/\/wpmudev.com\/blog\/wordpress-development-for-intermediate-users-custom-post-types-and-taxonomies\/\" target=\"_blank\">WordPress Development for Intermediate Users: Custom Post Types and Taxonomies<\/a><\/li>\n<li><a href=\"https:\/\/wpmudev.com\/blog\/wordpress-development-intermediate-users-queries-loops\/\" target=\"_blank\">WordPress Development for Intermediate Users: Queries and Loops<\/a><\/li>\n<li><a href=\"https:\/\/wpmudev.com\/blog\/wordpress-development-intermediate-users-custom-fields-metadata\/\" target=\"_blank\">WordPress Development for Intermediate Users: Custom Fields and Metadata<\/a><\/li>\n<li><a href=\"https:\/\/wpmudev.com\/blog\/wordpress-development-intermediate-users-internationalization\/\" target=\"_blank\">WordPress Development for Intermediate Users: Internationalization<\/a><\/li>\n<\/ul>\n<a class=\"general_big_button\" href=\"https:\/\/wpmudev.com\/academy\/\"><span class=\"text\">That&#8217;s right, tons of WordPress knowledge, peer review, instructor feedback and certification, for free for WPMU DEV members<\/span><span class=\"button-a-b\">Start Learning<\/span><\/a>\n<p><!--more--><\/p>\n<h3>Before You\u00a0Begin<\/h3>\n<p>This course assumes you have coded for WordPress before and that you have a basic understanding of how themes and plugins work. If you haven&#8217;t developed for WordPress before, or you&#8217;d like a\u00a0refresher, I\u00a0strongly\u00a0recommend you read through\u00a0<a href=\"https:\/\/wpmudev.com\/blog\/wordpress-development-beginners-getting-started\/\" target=\"_blank\">WordPress Development for Beginners<\/a>, which will give you everything you need to know before you start this series.<\/p>\n<p>You&#8217;ll also need access to a few things so that you can follow along and work alongside me. These are:<\/p>\n<ul>\n<li>A development WordPress installation. I recommend working on your local machine<\/li>\n<li>A code editor with FTP access if you&#8217;re working remotely (which you will be doing eventually)<\/li>\n<li>If your code editor doesn&#8217;t have FTP access, an FTP client<\/li>\n<\/ul>\n<p>I deliberately haven&#8217;t given you links to help you find all these things \u2013 I&#8217;m assuming that you&#8217;re already at the level where you know about this kind of stuff\u00a0and can find them yourself.<\/p>\n<p>For this tutorial in this series as well as the next tutorials, we&#8217;ll be working with a demo theme that I&#8217;ve created, which you can find on <a href=\"https:\/\/github.com\/rachelmccollin\/wpmudev-intermediate-WordPress-development\" target=\"_blank\">Github<\/a>. I&#8217;ve also created a <a href=\"http:\/\/rachelmccollin.co.uk\/wpmudev-intermediate\/\" target=\"_blank\">demo site<\/a> that I&#8217;ll be updating as we work through the series. Here&#8217;s how it looks right now:<\/p>\n<div  class=\"wpdui-pic-regular  \"> <img loading=\"lazy\" decoding=\"async\" class=\"attachment-735x735 size-735x735\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2016\/05\/starting-demo-site.png\" alt=\"demo site\" width=\"735\" height=\"508\" \/> <\/div>\n<p>As we work through the different topics in this part of the course, I&#8217;ll show you how to apply what you&#8217;ve learned to the demo theme. So if you want to follow along, download it before you start and install and activate it on your development site.<\/p>\n<p>Take a look at the starting theme so you can see how it&#8217;s structured. It includes template files, widgets and a menu \u2013 all covered in our beginner development series. It also includes some basic styling \u2013 I&#8217;m not claiming that it&#8217;s beautiful, and you might want to improve on it!<\/p>\n<h3>What We&#8217;ll Cover in This\u00a0Tutorial<\/h3>\n<p>In this first tutorial,\u00a0we&#8217;re going to dive straight into theme development. This tutorial will build on what you learned\u00a0if you studied the following modules in our WordPress Development for Beginners course:<\/p>\n<ul>\n<li><a href=\"https:\/\/wpmudev.com\/blog\/theme-development\/\" target=\"_blank\">Building Themes<\/a><\/li>\n<li><a href=\"https:\/\/wpmudev.com\/blog\/wordpress-development-beginners-widgets-menus\/\" target=\"_blank\">Widgets and Menus<\/a><\/li>\n<\/ul>\n<p>So, I&#8217;m not going to show you how to create a basic theme or how to register a widget area or a menu. If you don&#8217;t know how to do these things, go back to that series and check it out!<\/p>\n<p>Instead, we&#8217;re going to look at more advanced aspects of theme development, specifically:<\/p>\n<ul>\n<li>Approaches to theme development<\/li>\n<li>Structuring your theme \u2013 the template hierarchy<\/li>\n<li>Using\u00a0template parts<\/li>\n<li>Adding template tags for styling<\/li>\n<li>Adding functionality in the functions\u00a0file<\/li>\n<li>Adding hooks to your theme<\/li>\n<\/ul>\n<p>But before we start coding\u00a0that, let&#8217;s take\u00a0a look at some of the approaches available for theme development.<\/p>\n<h3>Approaches to WordPress Theme Development<\/h3>\n<p>Before you start to develop your own themes, it&#8217;s worth considering how you&#8217;re going to go about it. Let&#8217;s take a look at some of the possible approaches.<\/p>\n<h4>Approach 1: Coding from Scratch<\/h4>\n<p>Writing a theme from scratch isn&#8217;t something I&#8217;d recommend. It means starting with a blank PHP file (or files) and then adding all of the code you need to create a theme. You might decide to do this the very first time you build a theme but you certainly shouldn&#8217;t do it for subsequent themes. After all, there will be a lot of shared code that you can re-use.<\/p>\n<p>So, whatever approach you use for your first theme, don&#8217;t code your next theme from scratch \u2013 either edit your first theme, or use your first theme to create a starter\u00a0theme.<\/p>\n<h4>Approach 2: Adapting Static HTML<\/h4>\n<p>This has traditionally been the method that people use to learn WordPress, and it&#8217;s a good approach if you&#8217;ve already created static sites and are comfortable\u00a0with coding HTML. Alternatively, if you&#8217;ve created a prototype for the site you&#8217;re building using static HTML, this might be the approach you use.<\/p>\n<p>If you&#8217;re starting with static HTML, you&#8217;ll need to do a few things to convert your markup to a theme, including:<\/p>\n<ul>\n<li>Changing your <em>index.html<\/em> file to <em>index.php<\/em><\/li>\n<li>Splitting it into template parts \u2013 separating out the header, footer and sidebar into different files<\/li>\n<li>Adding a loop instead of static content<\/li>\n<li>Adding any relevant template tags (more of which shortly)<\/li>\n<li>Editing\u00a0information\u00a0in the <code>&lt;head&gt;<\/code> and elsewhere on the page, such as site name and page description. Use functions such as <code>get_bloginfo()<\/code> to fetch this from the database instead of manually coding it into your theme<\/li>\n<li>Replacing a hard-coded navigation menu with one that uses the WordPress menus interface<\/li>\n<li>Replacing static content in the sidebar and footer with widget areas, where relevant<\/li>\n<li>Adding extra template files as well as <em>index.php<\/em>\u00a0\u2013 more of which shortly<\/li>\n<\/ul>\n<p>You&#8217;ll have learned about a lot of this in our beginner WordPress development course.<\/p>\n<p>For a detailed walkthrough that teaches\u00a0you how to create a theme from static HTML, you might find my book, <a href=\"http:\/\/www.amazon.com\/gp\/product\/1849514224\/ref=as_li_tf_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1849514224&amp;linkCode=as2&amp;tag=racmcc-20\" target=\"_blank\">WordPress Theme Development: Beginner&#8217;s Guide<\/a>, helpful.<\/p>\n<div  class=\"wpdui-pic-large   \" >\n<figure class=\"wp-caption aligncenter\" data-caption=\"true\"><img loading=\"lazy\" decoding=\"async\" class=\"attachment-1364x1364 size-1364x1364\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2016\/05\/underscores-wide.png\" alt=\"Underscores is a starter theme that can speed up your WordPress theme development\" width=\"1364\" height=\"401\" \/><figcaption class=\"wp-caption-text\">Underscores is a starter theme that can speed up your WordPress theme development<\/figcaption><\/figure>\n<\/div>\n<h4>Approach 3: Using a Starter Theme<\/h4>\n<p>Another approach is to take a third-party starter theme such as <a href=\"http:\/\/underscores.me\" target=\"_blank\">underscores<\/a> and use that as the basis for your code. This will give you all the WordPress essentials such as a loop, and save a lot of work.<\/p>\n<p>Alternatively, you can use your own starter theme, that you create when you develop your first theme. Strip out all of the code that won&#8217;t apply to other themes, such as colors, fonts or bespoke layout and functions, and use that to kick things off when you develop your next theme.<\/p>\n<p>Make sure your starter theme is coded using <a href=\"http:\/\/code.tutsplus.com\/tutorials\/dry-wordpress-theme-development--cms-22117\" target=\"_blank\">DRY principles<\/a> and that it&#8217;s responsive (or even better, mobile-first) and includes accessibility features.<\/p>\n<p>If you have extra functionality that you add to a lot of your themes but not all of them, you could keep include files for each of these and then add them to a theme when you need to. I&#8217;ll show you how to do this later on in\u00a0this part of the course.<\/p>\n<h4>Approach 4: Creating a Child Theme<\/h4>\n<p>Another way to code your themes is by using an existing theme as a parent theme and then creating a child theme of that for each project. I work in a way that combines this and the starter theme approach: I&#8217;ve created my own custom framework\u00a0theme, which I use as a parent theme for every new site I build, and a starter child theme with just a few basics in it. I then add to and edit that\u00a0child theme for each project.<\/p>\n<p>Using a child theme means you can keep all of the code you use again and again in your parent theme, saving you time and server space. If you need to override anything, just create a template file with the same name in your child theme, and WordPress will use that instead of the one from the parent theme.<\/p>\n<p>You might also use a third party theme as your parent theme, such as a <a href=\"https:\/\/wpmudev.com\/blog\/choosing-a-wordpress-theme-framework-the-ultimate-guide\/\" target=\"_blank\">framework theme<\/a>. Many frameworks come with child themes you can use\u00a0out of the box, but there&#8217;s nothing to stop you coding your own.<\/p>\n<div  class=\"wpdui-pic-regular  \">\n<figure class=\"wp-caption aligncenter\" data-caption=\"true\"><img loading=\"lazy\" decoding=\"async\" class=\"attachment-735x735 size-735x735\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2016\/05\/cherry-framework.png\" alt=\"cherry framework website\" width=\"735\" height=\"458\" \/><figcaption class=\"wp-caption-text\">A theme framework like Cherry is one way to approach developing your own child themes<\/figcaption><\/figure>\n<\/div>\n<h4>Approach 5: Customizing an Existing Theme<\/h4>\n<p>A popular approach when people are first starting out is to take an existing theme (such as the default theme, currently Twenty Sixteen) and customize that to meet your own needs. This can be a good way to get started as it lets you pore through the theme&#8217;s code to see how everything works and can be a great way to learn. However there are some caveats:<\/p>\n<ul>\n<li>If you want to benefit from updates to the theme, use a child theme instead of directly editing the theme<\/li>\n<li>You may find yourself stripping out a lot of functionality and styling and adding your own<\/li>\n<li>Only use a theme that is similar to what you want to achieve<\/li>\n<li>Only use a well-coded theme \u2013 check out its reviews in the WordPress Theme Directory<\/li>\n<\/ul>\n<p>In short, if you&#8217;re using a third party theme as a way to learn and plan to tear it apart to create your own, and you&#8217;re not worried about updates, then go ahead. But if you&#8217;re going to change so much that it&#8217;s unrecognizable, a starter theme may be better. If you want to keep a lot of the styling and functionality from the theme, use a child theme to make your own tweaks.<\/p>\n<h3>Theme Structure: The Theme Template Hierarchy<\/h3>\n<p>Your theme will need to include certain template files, which are the files WordPress uses to display content depending on what page a visitor is looking at. There are four main types of file in your theme:<\/p>\n<ul>\n<li>Template files &#8211; <em>index.php<\/em>, <em>page.php<\/em> and more<\/li>\n<li>A\u00a0stylesheet &#8211; <em>style.css<\/em><\/li>\n<li>Template parts &#8211; <em>header.php<\/em>, <em>sidebar.php<\/em>, <em>footer.php<\/em> and any other template parts you create, such as a <em>loop.php<\/em> file<\/li>\n<li>Functions files &#8211; <em>functions.php<\/em> and any include files<\/li>\n<\/ul>\n<p>The minimum number of files is two: <em>index.php<\/em> and <em>style.css<\/em>. Theoretically, you could build a theme with just these two files, but I wouldn&#8217;t recommend it. Separating out things like the header and footer and creating different template files for static pages, archive pages and single posts, for example, will make your life easier. And using include files can make\u00a0your code more efficient.<\/p>\n<p>Our\u00a0starting theme includes the following files:<\/p>\n<ul>\n<li><em>index.php<\/em><\/li>\n<li><em>style.css<\/em><\/li>\n<li><em>functions.php<\/em><\/li>\n<li><em>header.php<\/em><\/li>\n<li><em>sidebar.php<\/em><\/li>\n<li><em>footer.php<\/em><\/li>\n<\/ul>\n<p>This is\u00a0one template file, one stylesheet, one functions file and three template parts. I&#8217;ll explain what each of\u00a0these are in turn.<\/p>\n<h4>Template Files<\/h4>\n<p>The first file WordPress goes to when displaying content is the relevant template file. It will pick this according to what content is being displayed, using the template hierarchy.<\/p>\n<div  class=\"wpdui-pic-regular  \">\n<figure class=\"wp-caption aligncenter\" data-caption=\"true\"><img loading=\"lazy\" decoding=\"async\" class=\"attachment-735x735 size-735x735\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2016\/05\/wp-hierarchy.png\" alt=\"wphierarchy.com - visual guide to the template hierarchy\" width=\"735\" height=\"453\" \/><figcaption class=\"wp-caption-text\">wphierarchy.com is a great interactive guide to the theme template hierarchy<\/figcaption><\/figure>\n<\/div>\n<p>So, for example, if a visitor is reading a single post from your blog, WordPress will work through this list of files and use the first one it finds from this list to display content:<\/p>\n<ol>\n<li><em>single-post.php<\/em> (for single posts, not pages or custom post types)<\/li>\n<li><em>single.php<\/em> (for single posts or custom post types, not pages)<\/li>\n<li><em>singular.php<\/em> (for single posts, custom post types or pages)<\/li>\n<li><em>index.php<\/em> (for anything that doesn&#8217;t have a more specific\u00a0template part)<\/li>\n<\/ol>\n<p>And if your user navigates to an archive page, for example the archive for the &#8220;Featured&#8221; category, WordPress will work through these template files:<\/p>\n<ol>\n<li><em>category-featured.php<\/em> (just for that category)<\/li>\n<li><em>category-XX.php<\/em> (where XX is the ID of the &#8216;featured&#8217; category)<\/li>\n<li><em>category.php<\/em> (for all category archives)<\/li>\n<li><em>archive.php<\/em> (for all archives including categories, taxonomy terms, authors and tags)<\/li>\n<li><em>index.php<\/em><\/li>\n<\/ol>\n<p>So as long as your theme has an <em>index.php<\/em> file, there will always be a file available to display content. But you need to make sure it accounts for all content types, including single posts and pages, archives and search pages, as well as the 404 page. It can be easier to create template files specifically for each of these.<\/p>\n<p>Let&#8217;s add a couple more template files to our starter theme to customize the way the theme displays single posts and pages. The easiest way to do this is by copying the <em>index.php<\/em> file. First, let&#8217;s do this for pages.<\/p>\n<ol>\n<li>Make a copy of <em>index.php<\/em> and call it <em>page.php<\/em>.<\/li>\n<li>Find the following line:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"page-edits.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=page-edits.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Edit it so it reads as follows:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"page-new-code.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=page-new-code.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Save your new file.<\/li>\n<\/ol>\n<p>This doesn&#8217;t change much\u00a0when people are viewing the site, but it does leave out some code that isn&#8217;t necessary. The conditional statement you removed checks if we&#8217;re on a page, something that isn&#8217;t necessary as WordPress will only use this template file if we&#8217;re on a page.\u00a0\u00a0It also changes the\u00a0<code>h2<\/code>\u00a0tag to\u00a0<code>h1<\/code>.<\/p>\n<p>Now that you&#8217;ve done this, you can edit the <em>index.php<\/em>\u00a0file to amend that check for the front page.<\/p>\n<ol>\n<li>Open index.php.<\/li>\n<li>Find this code:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"index-to-edit.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=index-to-edit.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Edit it so it reads like this:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"index-new-code.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=index-new-code.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Save the file.<\/li>\n<\/ol>\n<p>This removes the check for the front page from the loop.<\/p>\n<p>Now let&#8217;s create a file for single posts.<\/p>\n<ol>\n<li>Make a copy of <em>index.php<\/em> and call it <em>single.php<\/em><\/li>\n<li>Find these lines:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"single-to-edit.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=single-to-edit.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Edit them so they read as follows:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"single-new-code.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=single-new-code.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Save the file.<\/li>\n<\/ol>\n<p>This removes the check for being on the front page, as a single blog post won&#8217;t be the front page. It also changes the <code>h2<\/code> tag to <code>h1<\/code>.<\/p>\n<p>Finally, let&#8217;s create a fourth template for archives.<\/p>\n<ol>\n<li>Make a copy of <em>index.php<\/em> and call it <em>archive<\/em> php.<\/li>\n<li>Find this line:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"archive-line-to-find.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=archive-line-to-find.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Underneath it, add these lines:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"archive-new-code.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=archive-new-code.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Save the file.<\/li>\n<\/ol>\n<h4>The Stylesheet<\/h4>\n<p>Every theme must contain a stylesheet, because that tells WordPress about the theme, as well as providing styling for your site.<\/p>\n<p>Your stylesheet needs to contain commented out text at the top telling WordPress all about it. In the theme we&#8217;ll be using, the stylesheet starts with the following:<\/p>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"stylesheet-opening.css\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=stylesheet-opening.css\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<h4>Template Parts<\/h4>\n<p>If you&#8217;re creating lots of template files, each with its own loop, header, footer etc., you may be worrying about all the repeated code. The good news is you don&#8217;t need to repeat any code. You can use template parts to code certain parts of your theme just once and then include that code in your template files. Examples include:<\/p>\n<ul>\n<li>The header &#8211; <em>header.php<\/em><\/li>\n<li>The sidebar &#8211; <em>sidebar.php<\/em><\/li>\n<li>The footer &#8211; <em>footer.php<\/em><\/li>\n<li>A generic loop &#8211; <em>loop.php<\/em><\/li>\n<li>A more specific\u00a0loop &#8211; <em>loop-page.php<\/em>, for example<\/li>\n<\/ul>\n<p>Let&#8217;s use a template part for the loop in our theme.<\/p>\n<ol>\n<li>Open the <em>index.php<\/em> file.<\/li>\n<li>Find this code:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"loop-code.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=loop-code.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Copy that code.<\/li>\n<li>Create a new file in your theme called <em>loop.php<\/em>.<\/li>\n<li>Open your new file and paste the code into it. Save the file.<\/li>\n<li>Go back to <em>index.php<\/em> and delete the code you just copied.<\/li>\n<li>In its place, add this:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"loop-include.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=loop-include.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Save your file.<\/li>\n<li>Now delete the code above from the <em>archive.php<\/em> file and replace it with the same <code>get_template_part()<\/code> function as you&#8217;ve used in <em>loop.php<\/em>. Save the <em>archive.php<\/em> file.<\/li>\n<\/ol>\n<p>Now, instead of having the loop coded into two template files you&#8217;ve got it in one file. If you need to edit it you only have to do so once.<\/p>\n<p>Let&#8217;s do the same for the loop for single posts and pages.<\/p>\n<ol>\n<li>Create a new file in your theme called <em>loop-single.php<\/em>.<\/li>\n<li>Open the <em>page.php<\/em> file.<\/li>\n<li>Find this code:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"loop-single.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=loop-single.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Copy it into your new include file and delete it from page.php.<\/li>\n<li>In <em>page.php<\/em>, replace it with this:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"include-single-loop.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=include-single-loop.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Save your files.<\/li>\n<li>Now repeat the above for <em>single.php<\/em>, removing the loop and replacing it with the function.<\/li>\n<\/ol>\n<p>Again this uses the <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/get_template_part\/\" target=\"_blank\"><code>get_template_part()<\/code><\/a> function, but this time it has two parameters: &#8220;loop&#8221; and &#8220;single.&#8221; If WordPress can&#8217;t find a <em>loop-single.php<\/em> file, it will fall back to using <em>loop.php<\/em>.<\/p>\n<h4>Functionality Files<\/h4>\n<p>If you want to add functions to your theme, you should use <a href=\"https:\/\/wpmudev.com\/blog\/functions-file\/\" target=\"_blank\"><em>functions.php<\/em><\/a>. This is where you&#8217;d do things like registering widgets and menus. If your theme starts to contain a lot of functionality and you want to separate it out, you can use an include file. We&#8217;ll do this in the next post in this series, where we&#8217;ll add an include file for Customizer functionality.<\/p>\n<p>To include a file, you add something like this\u00a0to your <em>functions.php<\/em> file:<\/p>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"include.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=include.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>This includes a file on the <em>includes<\/em> folder in your theme, called <em>customizer.php<\/em>. The code from that file is run as if it were coded into the <em>functions.php<\/em> file at the point where you placed the include function.<\/p>\n<p>Our theme already has a file called <em>functions.php<\/em> which contains the functions for registering menus and widgets. Let&#8217;s add some theme support to it.<\/p>\n<ol>\n<li>Open <em>functions.php<\/em><\/li>\n<li>At the bottom, add these lines:<br \/>\n<div class=\"gist\" data-gist=\"1c9db3673e9a82cdfb72\" data-gist-file=\"theme support - full function.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/1c9db3673e9a82cdfb72.js?file=theme+support+-+full+function.php\">Loading gist 1c9db3673e9a82cdfb72<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Save your file.<\/li>\n<\/ol>\n<p>You&#8217;ll now find that when you add posts to your site, you can set featured images and specify post formats. For more on using <em>functions.php<\/em> for theme support, see our <a href=\"https:\/\/wpmudev.com\/blog\/functions-file\/\" target=\"_blank\">ultimate guide to the theme functions file<\/a>.<\/p>\n<h4>Challenge: Adding More Template Files<\/h4>\n<p>Now that you&#8217;ve added some files to your theme, try adding some more without my guidance. Add the following files:<\/p>\n<ul>\n<li><em>404.php<\/em> &#8211; for error pages<\/li>\n<li><em>search.php<\/em> &#8211; for search results<\/li>\n<\/ul>\n<p>You might want to use a copy of <em>archive.php<\/em> for the search template, and a copy of any of your files for 404 pages, but replacing the loop with an error notice. Even better, you could include a list of the most recent posts and\/or a search box in your search page \u2013 something we&#8217;ll do later on in this course.<\/p>\n<p>If you get stuck, take a look at the finished part 1 theme from the <a href=\"https:\/\/github.com\/rachelmccollin\/wpmudev-intermediate-WordPress-development\" target=\"_blank\">source files<\/a> for this series.<\/p>\n<h3>Adding Template Tags to Your Theme<\/h3>\n<p>The next step is to add some <a href=\"https:\/\/codex.wordpress.org\/Template_Tags\" target=\"_blank\">template tags<\/a> to your theme. Here&#8217;s how the WordPress Codex defines template tags:<\/p>\n<blockquote><p>Template tags are used within your blog&#8217;s\u00a0<a title=\"Templates\" href=\"https:\/\/codex.wordpress.org\/Templates\" target=\"_blank\">Templates<\/a>\u00a0to display information dynamically or otherwise customize your blog, providing the tools to make it as individual and interesting as you are.<\/p><\/blockquote>\n<p>Template tags are a kind of function, but instead of using them in a functions file or a plugin, you use them in your template files to generate content such as:<\/p>\n<ul>\n<li>Fetching content from template parts with <code>get_header()<\/code>, <code>get_sidebar()<\/code>, <code>get_footer()<\/code> and <code>get_template part()<\/code>.<\/li>\n<li>Displaying\u00a0information\u00a0about the site such as its title, home url or description using <code>bloginfo()<\/code>.<\/li>\n<li>Outputting post content and metadata with tags like <code>the_content()<\/code>, <code>the _title()<\/code> and <code>the_permalink()<\/code>.<\/li>\n<li>Displaying information about a post&#8217;s author with tags like <code>get_the_author()<\/code> and <code>get_the_author_link()<\/code>.<\/li>\n<li>Outputting information about the post as an ID or class for styling purposes with tags like <code>body_class()<\/code>.<\/li>\n<\/ul>\n<p>Note that some tags have a <code>get_<\/code> at the beginning of them while others don&#8217;t. If you use a tag that begins with <code>get_<\/code>, all WordPress does is fetch that information \u2013 it doesn&#8217;t output it. So to output what you&#8217;ve fetched, you use <code>echo<\/code> before it. For example,\u00a0<code>echo get_the_author_link()<\/code> echoes out the link to the author&#8217;s profile. This gives you more control over exactly how content is output. If you just used <code>the_author_link()<\/code>, WordPress would output this in a predefined way. Sometimes that works for you, but sometimes it doesn&#8217;t and you want to add your own markup around a template tag with <code>get_<\/code> at the beginning.<\/p>\n<p>The theme we&#8217;re working with already has some template tags added. Work through the template files and see if you can find them. You should find the following:<\/p>\n<ul>\n<li>In <em>header.php<\/em>:\u00a0<code>bloginfo('url')<\/code>,\u00a0<code>bloginfo('name')<\/code> and\u00a0<code>bloginfo( 'description' )<\/code>.<\/li>\n<li>In <em>index.php<\/em>, <em>archive.php<\/em>, <em>single.php<\/em> and <em>page.php<\/em>: <code>get_template_part()<\/code>, which you added earlier.<\/li>\n<li>In <em>loop.php<\/em> and <em>loop-single.php<\/em>: <code>the_permalink()<\/code>,\u00a0<code>the_title_attribute()<\/code>,\u00a0<code>the_title()<\/code> and\u00a0<code>the_content()<\/code>.<\/li>\n<\/ul>\n<p>So you can see you&#8217;ve already been working with template tags. Let&#8217;s add some more, specifically to help with styling.<\/p>\n<h4>Adding Template Tags for Styling<\/h4>\n<p>WordPress gives you three\u00a0incredibly useful template tags that you can add to your <code>&lt;body&gt;<\/code> element and to your loop to enable more fine-grained styling of your posts, pages and archives. These are:<\/p>\n<ul>\n<li><code class=\"inline\">body_class()<\/code>, which you add to the\u00a0<code class=\"inline\">body<\/code>\u00a0tag in a theme&#8217;s <em>header.php<\/em>\u00a0file: it\u00a0adds classes\u00a0to the\u00a0<code class=\"inline\">body<\/code>\u00a0element according to the type of page being viewed<\/li>\n<li><code>the_ID()<\/code>, which you can use to add the post ID to a post in the loop<\/li>\n<li><code class=\"inline\">post_class()<\/code>, which works in a similar way to <code>body_class()<\/code> but is used with posts in the loop<\/li>\n<\/ul>\n<p>Let&#8217;s add them to our theme.<\/p>\n<ol>\n<li>Open the <em>header.php<\/em> file.<\/li>\n<li>Find the opening <code>&lt;body&gt;<\/code> tag, which is on its own line.<\/li>\n<li>Edit it so it reads like this:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"body_class.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=body_class.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Save and close the file.<\/li>\n<li>Open the <em>loop.php<\/em> file.<\/li>\n<li>Find the\u00a0opening <code>&lt;article&gt;<\/code> tag which will be on its own line.<\/li>\n<li>Edit it so it reads:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"post_class.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=post_class.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Save and close the file.<\/li>\n<li>Repeat steps 5-8 for the <em>loop.php<\/em> file.<\/li>\n<\/ol>\n<p>You&#8217;ll now find that your <code>&lt;body&gt;<\/code> element has a number of classes assigned to it, depending on what kind of content is being viewed. And your <code>&lt;article&gt;<\/code> elements each have an ID which is the post ID and a number of classes relevant to the kind of post it is.<\/p>\n<p>Let&#8217;s take a look at the code that&#8217;s generated for the home page of the site. Save your theme and go to your site&#8217;s home page in your browser. Inspect the code. Here&#8217;s mine:<\/p>\n<div class=\"image-grid cgrid-row\">\n<div class=\"cgrid-col cgrid-col-span-full\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-155301\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2016\/05\/body-class.jpg\" alt=\"inspecting code on my site's home page\" width=\"735\" height=\"512\" \/><\/div>\n<\/div>\n<p>This is the code that&#8217;s output:<\/p>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"body_class_home.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=body_class_home.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>Now let&#8217;s take a look at another page. Navigate to a single post and see what&#8217;s output for the <code>body<\/code>:<\/p>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"body_class_single.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=body_class_single.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>As you can see, WordPress generates different classes because we&#8217;re on a single post.\u00a0Now take a look at the code that&#8217;s generated for the <code>&lt;article&gt;<\/code> tag on that single post page:<\/p>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"post_class.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=post_class.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div>\n<p>The <code>article<\/code> has a number of classes which indicate the post ID, its post type, status, category and more, as well as an ID equivalent to the post&#8217;s ID. You can then use this to style your posts according to category or post type, or even individually by targeting the post ID. So if you were running a news site for example, with each category having its own color, you could style all posts in that category using the appropriate color on the main listing page.<\/p>\n<h3>Adding Filter and Action Hooks to Your Theme<\/h3>\n<p>The next thing you can add to your theme to make it even more powerful are hooks. These let you either amend the content you already have in your theme or add new content, without editing the template files themselves. So if you wanted to write a plugin that inserts content somewhere in your pages, you could do this easily. In fact, we&#8217;ll do this later on in the course.<\/p>\n<p>It&#8217;s also a really useful technique if you&#8217;re developing a theme that you intend to use as a parent theme. In your child theme&#8217;s functions files, you can create functions that insert extra content as required into the parent theme (or amend existing content) without creating duplicate\u00a0template files in your child theme. All <a href=\"https:\/\/wpmudev.com\/blog\/choosing-a-wordpress-theme-framework-the-ultimate-guide\/\" target=\"_blank\">theme frameworks<\/a> have a large number of hooks so you can do this.<\/p>\n<p>If you want to understand how hooks work, and the difference between action and filter hooks, you need to study part 5 of our <a href=\"https:\/\/wpmudev.com\/blog\/wordpress-development-beginners-building-plugins\/\" target=\"_blank\">WordPress Development for Beginners<\/a>\u00a0series, which shows you how to use hooks in your plugins. So in other words, you should already know this!<\/p>\n<p>There are two kinds of hooks: action hooks and filter hooks:<\/p>\n<ul>\n<li>Action hooks are empty &#8211; they&#8217;re a spot in your theme or plugin where you or another developer can insert some code by attaching a function to that hook.<\/li>\n<li>Filter hooks surround existing code or content &#8211; wrap a filter hook around existing content to make it possible to override that content by attaching a function to that hook. This replaces the contents of the filter with the contents of the function.<\/li>\n<\/ul>\n<p>Here, we&#8217;ll be doing something\u00a0a bit different: Instead of writing\u00a0a function to hook to an existing hook, we&#8217;ll be creating that hook in our theme.<\/p>\n<h4>Adding Action Hooks<\/h4>\n<p>To create an action hook in your theme you use the <code>do_action()<\/code> function. This has one parameter: the unique name of the hook.<\/p>\n<p>So let&#8217;s use this to\u00a0add some action hooks.<\/p>\n<ol>\n<li>Open the <em>header.php<\/em> file.<\/li>\n<li>Immediately above the <code>&lt;header&gt;<\/code> tag, add this line:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"do_action_before_header.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=do_action_before_header.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Now immediately below the closing header tag which reads <code>&lt;\/header&gt;<\/code>, add this line:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"do_action_after_header.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=do_action_after_header.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Save and close the file.<\/li>\n<\/ol>\n<p>You&#8217;ve just added two action hooks to your header. You could use these to add extra content there in your theme&#8217;s (or a child theme&#8217;s) functions file or via a plugin. Now let&#8217;s add some more.<\/p>\n<ol>\n<li>Open the <em>index.php<\/em> file.<\/li>\n<li>Find the <code>&lt;div class=\"content\"&gt;<\/code> line and add\u00a0this immediately below it:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"do_action_before_content.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=do_action_before_content.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Now immediately before the closing <code>&lt;\/content&gt;<\/code> tag, add this:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"do_action_after_content.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=do_action_after_content.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Save and close the file.<\/li>\n<li>Repeat steps 1-4 for <em>single.php<\/em> and <em>page.php<\/em>.<\/li>\n<\/ol>\n<p>You&#8217;ll have noticed that you&#8217;ve added the same hook three times in three different files. If you wanted to, you could change the structure of your files, maybe moving the opening markup from <em>index.php<\/em>, <em>page.php<\/em> and <em>single.php<\/em> into <em>header.php<\/em>, and the closing markup into <em>sidebar.php<\/em>. If you want to try this, please go ahead, but be careful that you don&#8217;t miss anything out.<\/p>\n<p>The advantage of using the hook, even though\u00a0we&#8217;ve had to add it three times, is that if we wanted to add extra code before or after the content, we only have to do it once, via a function that we then attach to that hook. The function\u00a0would run regardless of which of the three template files WordPress is currently using. And if you only want to hook new content to one of your template files, you could use a conditional tag to check what kind of content is being viewed. Again you&#8217;ll learn this later in the course.<\/p>\n<p>Next let&#8217;s add a hook to each of the sidebar and footer. I&#8217;m not going to give you detailed instructions here, instead I&#8217;ll let you work it out for yourself. If you get stuck, check the <a href=\"https:\/\/github.com\/rachelmccollin\/wpmudev-intermediate-WordPress-development\" target=\"_blank\">source code<\/a> for this part of the course. In that source code I&#8217;ve included both the starter theme and the finished theme.<\/p>\n<p>So, add these hooks:<\/p>\n<ul>\n<li><code>wpmu_before_sidebar<\/code> before the sidebar widget area (making sure you put it outside the conditional tag for active widgets.<\/li>\n<li><code>wpmu_after_sidebar<\/code> after the sidebar widget area.<\/li>\n<li><code>wpmu_before_footer<\/code> before the footer.<\/li>\n<li><code>wpmu_after_footer<\/code> after the footer.<\/li>\n<\/ul>\n<p>You&#8217;ll need to edit two files: <em>sidebar.php<\/em> and <em>footer.php<\/em>. Make sure your hooks are inside the <code>&lt;aside class=\"sidebar\"&gt;<\/code> and <code>footer<\/code> elements.<\/p>\n<h4>Adding Filter Hooks<\/h4>\n<p>Filter hooks let users override\u00a0existing code. A useful place to do this is in the header, where the site title and description are. By doing this you give users the option to replace these with a logo, for example.<\/p>\n<p>So let&#8217;s do it!<\/p>\n<ol>\n<li>Open the <em>header.php<\/em> file and find this code:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"header_before_filter.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=header_before_filter.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><\/li>\n<li>Edit it so it reads:<br \/>\n<div class=\"gist\" data-gist=\"abcb5a4b406e4b32577823d641096012\" data-gist-file=\"header_filter.php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/abcb5a4b406e4b32577823d641096012.js?file=header_filter.php\">Loading gist abcb5a4b406e4b32577823d641096012<\/a><div class=\"gist-consent-notice\" style=\"display:none\"><p>Please <a href=\"javascript:Cookiebot.renew()\">update your cookie preferences<\/a> to enable preference cookies to view this gist.<\/p><\/div><\/div><br \/>\nDon&#8217;t forget to change all the instances of <code>bloginfo()<\/code> to <code>get_bloginfo()<\/code>, because of the echo that surrounds the whole thing. And make sure you&#8217;ve got all the syntax right &#8211; PHP is very unforgiving when it comes to semicolons!<\/li>\n<li>Save the file.<\/li>\n<\/ol>\n<p>This doesn&#8217;t make any different to what&#8217;s displayed in the header yet, but if someone using a child theme or writing a plugin should want to change this specific aspect of the header in future, they won&#8217;t have to create a duplicate of the whole <em>header.php<\/em> file. All they need to do is write a function which they attach to that filter hook using <code>add_filter()<\/code>. We&#8217;ll take a look at doing that later in the course.<\/p>\n<h3>Theme Building is Fun!<\/h3>\n<p>Now that you&#8217;ve completed this part of the course you&#8217;ll know a lot more about theme building, and you&#8217;ll have the beginnings of your\u00a0own theme with some powerful features that you can use to develop the theme further and add content to your site.<\/p>\n<p>I haven&#8217;t included CSS in this series as it&#8217;s about WordPress, not CSS. But if you want to add or change the CSS in the theme&#8217;s stylesheet please go ahead \u2013 I&#8217;d love to see how you style my basic starter theme and make it look better!<\/p>\n<p>If there are any items that you&#8217;ve struggled with when it comes to adding the code to your theme, or you want to see how I&#8217;ve done it, check out the files for the part 1 completed theme in the <a href=\"https:\/\/github.com\/rachelmccollin\/wpmudev-intermediate-WordPress-development\" target=\"_blank\">source files for this series<\/a>. I strongly recommend doing this before posting questions below, as the best way to learn theme building is by interrogating the code.<\/p>\n<p>In the next tutorial in this series, we&#8217;ll continue working with this theme and we&#8217;ll add theme Customizer functionality to it.<\/p>\n<a class=\"general_big_button\" href=\"https:\/\/wpmudev.com\/academy\/\"><span class=\"text\">That&#8217;s right, tons of WordPress knowledge, peer review, instructor feedback and certification, for free for WPMU DEV members<\/span><span class=\"button-a-b\">Start Learning<\/span><\/a>\n","protected":false},"excerpt":{"rendered":"<p>Interested in taking your WordPress game to a whole new level? Want to further develop your PHP skills and add more complex and exciting functionality to your themes and plugins? Welcome to our latest series, WordPress Development for Intermediate users. This series follows on from our popular WordPress Development for Beginners tutorials, which introduced you [&hellip;]<\/p>\n","protected":false},"author":347011,"featured_media":156231,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"blog_reading_time":"","wds_primary_category":0,"wds_primary_tutorials_categories":0,"footnotes":""},"categories":[263],"tags":[],"tutorials_categories":[],"class_list":["post-155245","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials"],"_links":{"self":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/155245","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/users\/347011"}],"replies":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/comments?post=155245"}],"version-history":[{"count":34,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/155245\/revisions"}],"predecessor-version":[{"id":160087,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/155245\/revisions\/160087"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media\/156231"}],"wp:attachment":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media?parent=155245"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/categories?post=155245"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tags?post=155245"},{"taxonomy":"tutorials_categories","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tutorials_categories?post=155245"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}