{"id":171351,"date":"2018-03-29T13:00:17","date_gmt":"2018-03-29T13:00:17","guid":{"rendered":"https:\/\/premium.wpmudev.org\/blog\/?p=171351"},"modified":"2022-04-01T02:40:07","modified_gmt":"2022-04-01T02:40:07","slug":"html-to-wordpress-theme-tutorial-step-1-converting-your-html-to-php","status":"publish","type":"post","link":"https:\/\/wpmudev.com\/blog\/html-to-wordpress-theme-tutorial-step-1-converting-your-html-to-php\/","title":{"rendered":"HTML to WordPress Theme Tutorial: Step 1 &#8211; Converting Your HTML to PHP"},"content":{"rendered":"<p>For many of us, our first experience of coding for WordPress is when we write our first theme.<\/p>\n<p>After all, every WordPress site needs a theme, and if you want something bespoke then it makes sense to code it yourself.<\/p>\n<p>When I started out with WordPress in 2010, I&#8217;d never worked with a content management system (CMS) before. But I&#8217;d coded plenty of HTML and CSS, either within large sites that used HTML for content as part of a CMS, or for small client sites I built from scratch.<\/p>\n<p>I spent weeks weighing up the pros and cons of different CMSes I could use for client sites (remember, this was before WordPress became the dominant force it is today) and decided on WordPress for two reasons. The first was the awesome community of users and developers that we&#8217;re all a part of. And the second was the fact that with some HTML experience, it&#8217;s not that hard to create a WordPress theme.<\/p>\n<p>Continue reading, or jump ahead using these links:<\/p>\n<ul>\n<li><a href=\"#need\">What You\u2019ll Need<\/a><\/li>\n<li><a href=\"#code\">The Starting Code<\/a><\/li>\n<li><a href=\"#theme\">Setting Up Your Theme<\/a><\/li>\n<li><a href=\"#tags\">Adding Template Tags<\/a>\n<ul>\n<li><a href=\"#stylesheet\">Calling the Stylesheet<\/a><\/li>\n<li><a href=\"#classes\">Creating Automatically Generated Classes and IDs<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#loop\">Adding a Loop<\/a><\/li>\n<li><a href=\"#hooks\">Adding Hooks<\/a><\/li>\n<\/ul>\n<p>In this series of three posts, I&#8217;m going to walk you through the process of creating your own WordPress theme from static HTML. We&#8217;ll start with a single HTML file and a CSS stylesheet, and convert those into a WordPress theme with all the bells and whistles that entails.<\/p>\n<p>The posts will work through the process in order:<\/p>\n<ol>\n<li>Creating your <em>index.php<\/em> file, adding in template tags and a loop.<\/li>\n<li>Creating additional template files and template parts such as the header, sidebar and footer files.<\/li>\n<li>Adding functionality, including widgets and a navigation menu, and getting your functions file set up.<\/li>\n<\/ol>\n<p>In this post I&#8217;ll create a single file &#8211; <em>index.php<\/em>. That will be based on the <em>index.html<\/em> file from my static site, but I&#8217;ll remove the content and replace it with template tags and a loop.<\/p>\n<p>So let&#8217;s get started!<\/p>\n<h2 id=\"need\">What You&#8217;ll Need<\/h2>\n<p>To follow along with this series, you&#8217;ll need a few tools:<\/p>\n<ul>\n<li>A development installation of WordPress, preferably on your local machine.<\/li>\n<li>A code editor.<\/li>\n<li>A static site &#8211; if you don&#8217;t have one you&#8217;re working from, you can <a href=\"https:\/\/github.com\/rachelmccollin\/WPMU-DEV-Theme-Development-Series-Files\" target=\"_blank\">download the files I&#8217;m using<\/a>.<\/li>\n<\/ul>\n<p>Make sure you do this work on a development site, not a live site &#8211; you don&#8217;t want the world to see your theme until it&#8217;s ready.<\/p>\n<h2 id=\"code\">The Starting Code<\/h2>\n<p>The starting site has just two files &#8211; our <em>index.html<\/em> and <em>style.css<\/em>. I&#8217;ve deliberately kept things simple, and used a pared down version of my site. Here&#8217;s how it looks:<\/p>\n<div  class=\"wpdui-pic-regular  \"> <img loading=\"lazy\" decoding=\"async\" class=\"attachment-600x600 size-600x600\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2018\/03\/starting-site.png\" alt=\"Our starting home page\" width=\"600\" height=\"383\" \/> <\/div>\n<p>You can find the contents of the <em>index.html<\/em> and <em>style.css<\/em> files on <a href=\"https:\/\/github.com\/rachelmccollin\/WPMU-DEV-Theme-Development-Series-Files\/tree\/master\/Starting%20code\" target=\"_blank\">Github<\/a> &#8211; I&#8217;m not going to show the code here as there&#8217;s a lot!<\/p>\n<p><em>Note: This is a basic set of code designed to help you create your own theme. If you want to use it for live sites, you&#8217;ll probably have to add extra styling etc. to it. It wouldn&#8217;t pass the theme directory requirements. Please just use it for learning, not to power a live site.<\/em><\/p>\n<h2 id=\"theme\">Setting Up Your Theme<\/h2>\n<p>To create your theme, you&#8217;ll need a folder for it in your WordPress installation. Using your code editor or file manager, go to <em>wp-content\/themes<\/em> and create a new folder. Give it whatever name you want. I&#8217;m going to call mine <em>wpmudev-theme-part1<\/em>.<\/p>\n<p>Copy your <em>index.html<\/em> and <em>style.css<\/em> files to that folder. They won&#8217;t do anything yet, but they will soon.<\/p>\n<p>Now you have a folder with two files in it. You&#8217;re getting started!<\/p>\n<p>Right now, WordPress doesn&#8217;t know that you have a theme. Any theme needs just two files: <em>index.php<\/em> and <em>style.css<\/em>. As you&#8217;ll see while following along with this series, you normally need more than that, but the theme will function with just two.<\/p>\n<p>Let&#8217;s start by adding commented out text to your stylesheet. Open your style.css file and add the following:<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"b4442aa88f39d99e5699970792e3a999\" data-gist-file=\"style comments css\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/b4442aa88f39d99e5699970792e3a999.js?file=style+comments+css\">Loading gist b4442aa88f39d99e5699970792e3a999<\/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><\/span><\/p>\n<p>This gives WordPress the information it needs to recognise that this is the theme stylesheet. Feel free to edit the details, adding your own name and URL and changing the name of the theme if you like.<\/p>\n<p>The next thing to do is change the filename of your <em>index.html<\/em> file to <em>index.php<\/em>. You now have the two files that will get your theme working.<\/p>\n<p>However you haven&#8217;t added any PHP yet. To do that we&#8217;ll need to add some template tags and a loop. Let&#8217;s do that.<\/p>\n<h2 id=\"tags\">Adding Template Tags<\/h2>\n<p>A template tag is a special WordPress function that you use in a theme template file. It can do any one of a wide variety of things &#8211; to see the range of template tags on offer, check out the codex.<\/p>\n<p>Here we&#8217;re going to add template tags for two things:<\/p>\n<ul>\n<li>Calling the stylesheet<\/li>\n<li>Automatically generated classes and IDs for CSS<\/li>\n<\/ul>\n<h3 id=\"stylesheet\">Calling the Stylesheet<\/h3>\n<p>Right now if you open up your site with your new theme activated, you&#8217;ll notice that none of your styling is loading. Here&#8217;s how mine looks:<\/p>\n<div  class=\"wpdui-pic-regular  \"> <img loading=\"lazy\" decoding=\"async\" class=\"attachment-600x600 size-600x600\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2018\/03\/code-no-styling.png\" alt=\"My site with no CSS\" width=\"600\" height=\"408\" \/> <\/div>\n<p>Don&#8217;t panic! You just need to add a stylesheet call to the <code>head<\/code> section of your index file.<\/p>\n<p><em>Note: In part three of this series, I&#8217;ll show you how to move this to the theme functions file, which is best practice. For now we&#8217;re just working with two files: the stylesheet and index.php files, so we&#8217;ll stick with those.)<\/em><\/p>\n<p>Open up your <em>index.php<\/em> file. Find this line:<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"fa23ad1d4fb421fb45b7dbec4b1e7bc4\" data-gist-file=\"stylesheet links\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/fa23ad1d4fb421fb45b7dbec4b1e7bc4.js?file=stylesheet+links\">Loading gist fa23ad1d4fb421fb45b7dbec4b1e7bc4<\/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><\/span><\/p>\n<p>Edit it so instead of calling a static file, it uses PHP to load the theme stylesheet:<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"22955ed4e7d7f17ef5e5f3c3762570a7\" data-gist-file=\"stylesheet link new\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/22955ed4e7d7f17ef5e5f3c3762570a7.js?file=stylesheet+link+new\">Loading gist 22955ed4e7d7f17ef5e5f3c3762570a7<\/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><\/span><\/p>\n<p>This uses the\u00a0<code><a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/bloginfo\/\" target=\"_blank\">bloginfo()<\/a><\/code> template tag, a useful tag that fetches all kinds of information about your website from the database. In this case it&#8217;s fetching the url of the theme and then accessing the file in that folder called <em>style.css<\/em>.<\/p>\n<p>Now refresh your home page. You&#8217;ll find that the styles load. Here&#8217;s my page now:<\/p>\n<div  class=\"wpdui-pic-regular  \"> <img loading=\"lazy\" decoding=\"async\" class=\"attachment-600x600 size-600x600\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2018\/03\/stylesheet_working.png\" alt=\"My site with styles working\" width=\"600\" height=\"378\" \/> <\/div>\n<p>You&#8217;ll notice that it looks exactly like your old static site. That doesn&#8217;t mean we&#8217;re done though &#8211; nowhere near! The content is pulling through from static content in that <em>index.php<\/em> file, which we&#8217;ll correct by adding a loop. But first let&#8217;s add some more template tags.<\/p>\n<h3 id=\"classes\">Creating Automatically Generated Classes and IDs<\/h3>\n<p>It&#8217;s really useful to be able to get WordPress to automatically generate CSS classes and IDs for your posts and your <code>&lt;body&gt;<\/code> element. This means you can later use those classes for styling, targeting specific post types, categories and more.<\/p>\n<p>Open your <em>index.php<\/em> file. Find the opening <code>&lt;body&gt;<\/code> tag. It&#8217;ll be sitting on its own line, after the closing <code>&lt;\/head&gt;<\/code> tag.<\/p>\n<p>Edit it so it reads like this:<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"8cd1751d0c132cd6ad40aa6682f1dbf5\" data-gist-file=\"body php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/8cd1751d0c132cd6ad40aa6682f1dbf5.js?file=body+php\">Loading gist 8cd1751d0c132cd6ad40aa6682f1dbf5<\/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><\/span><\/p>\n<p>This uses the <a href=\"https:\/\/developer.wordpress.org\/reference\/functions\/body_class\/\" target=\"_blank\"><code>body_class()<\/code><\/a> template tag, which will detect what kind of page your website visitors are on at any given time and generate CSS classes based on that.<\/p>\n<p>If you refresh your page and inspect the code you&#8217;ll find that WordPress automatically adds some CSS classes for you:<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"7cbafc9d5266642adef21170e05b8c8b\" data-gist-file=\"body generated\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/7cbafc9d5266642adef21170e05b8c8b.js?file=body+generated\">Loading gist 7cbafc9d5266642adef21170e05b8c8b<\/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><\/span><\/p>\n<div>\n<p>These will vary according to the page you&#8217;re on in your site and which type of content it&#8217;s displaying. You can use this to target your CSS at certain content types such as single posts, certain categories or anything you want.<\/p>\n<\/div>\n<div>Now let&#8217;s do this for your individual post. Find this line in your <em>index.php<\/em> file:<\/div>\n<div><\/div>\n<div><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"4776a2e641a86ae9fd3f717420fdbb57\" data-gist-file=\"article before html\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/4776a2e641a86ae9fd3f717420fdbb57.js?file=article+before+html\">Loading gist 4776a2e641a86ae9fd3f717420fdbb57<\/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><\/span><\/div>\n<div><\/div>\n<p>Edit that line so it reads like this:<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"1a2e4d2362ca8070067e61b504119554\" data-gist-file=\"article after php\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/1a2e4d2362ca8070067e61b504119554.js?file=article+after+php\">Loading gist 1a2e4d2362ca8070067e61b504119554<\/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><\/span><\/p>\n<p>This uses two template tags:<\/p>\n<ul>\n<li>The <code><a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/the_ID\" target=\"_blank\">the_ID()<\/a><\/code> tag fetches the post ID and uses that to give the post a unique ID.<\/li>\n<li>The <code><a href=\"https:\/\/codex.wordpress.org\/Function_Reference\/post_class\" target=\"_blank\">post_class()<\/a><\/code> tag works in a similar way to the <code>body_class()<\/code> tag, adding a list of classes to the article element that correspond to the type of post this is. Note that right now this won&#8217;t work properly as you&#8217;re not fetching a post from the database &#8211; but when we add the loop next, it will.<\/li>\n<\/ul>\n<h2 id=\"loop\">Adding a Loop<\/h2>\n<p>Now for the fun bit. Right now, the content of your page is hard-coded in. You want it to be populated from a call to the database, so that the correct content will be displayed whatever page you&#8217;re on.<\/p>\n<p>In your <em>index.php<\/em> file, find the code inside the <code>&lt;article&gt;<\/code> tag (the one you already added the ID and closes to with template tags).<\/p>\n<p>Edit that code so it reads like this:<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"74bd99075818f1fa0bb0f76a829cf008\" data-gist-file=\"loop index\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/74bd99075818f1fa0bb0f76a829cf008.js?file=loop+index\">Loading gist 74bd99075818f1fa0bb0f76a829cf008<\/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><\/span><\/p>\n<div><\/div>\n<p>There&#8217;s a lot of code there &#8211; if you want to understand what&#8217;s going on, check out <a href=\"https:\/\/wpmudev.com\/blog\/the-wordpress-loop-explained\/\" target=\"_blank\">our post explaining the loop<\/a>.<\/p>\n<p>Now if you refresh your home page you&#8217;ll see some very different content &#8211; your posts. If this is a brand new WordPress install you&#8217;ll see the default post that&#8217;s added when you install WordPress:<\/p>\n<div  class=\"wpdui-pic-regular  \"> <img loading=\"lazy\" decoding=\"async\" class=\"attachment-600x600 size-600x600\" src=\"https:\/\/wpmudev.com\/blog\/wp-content\/uploads\/2018\/03\/loop-added.png\" alt=\"My site now has a loop\" width=\"600\" height=\"384\" \/> <\/div>\n<h2 id=\"hooks\">Adding Hooks<\/h2>\n<p>The final step in this first part of our series is to add a couple of important hooks to our code. These are placed in the <code>head<\/code> section and the footer, and they&#8217;re essential for many plugins to work.<\/p>\n<p>In your <code>head<\/code> section, add this before the closing <code>&lt;\/head&gt;<\/code> tag:<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"8ef006c357a310ce1814b58aeadab445\" data-gist-file=\"wp head\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/8ef006c357a310ce1814b58aeadab445.js?file=wp+head\">Loading gist 8ef006c357a310ce1814b58aeadab445<\/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><\/span><\/p>\n<div>\n<p>Now move down to the end of your index.php file. Before the closing <code>&lt;\/body&gt;<\/code> tag, add the <code>wp_footer()<\/code> hook:<\/p>\n<p><span style=\"font-weight: 400;\"><div class=\"gist\" data-gist=\"f2939159ab4aa783731c65b3289baa55\" data-gist-file=\"wp footer\"><a class=\"loading\" href=\"https:\/\/gist.github.com\/f2939159ab4aa783731c65b3289baa55.js?file=wp+footer\">Loading gist f2939159ab4aa783731c65b3289baa55<\/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><\/span><\/p>\n<p>That adds a special hook to the top and bottom of every page in your site &#8211; these are essential for your themes and your site to work properly, so don&#8217;t skip them.<\/p>\n<\/div>\n<p>Now save your file.<\/p>\n<h2>What Comes Next<\/h2>\n<p>You now have the beginnings of a WordPress theme. However there&#8217;s still work to do. In the next part of this series I&#8217;ll walk you through the process of splitting your theme up into multiple template files. You&#8217;ll create separate files for the header, sidebar and footer, an include file of the loop, and a separate file for each of pages and archives.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>For many of us, our first experience of coding for WordPress is when we write our first theme. After all, every WordPress site needs a theme, and if you want something bespoke then it makes sense to code it yourself. When I started out with WordPress in 2010, I&#8217;d never worked with a content management [&hellip;]<\/p>\n","protected":false},"author":347011,"featured_media":171538,"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":[200,174,10550],"tutorials_categories":[],"class_list":["post-171351","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorials","tag-html","tag-php","tag-wordpress-theme"],"_links":{"self":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/171351","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=171351"}],"version-history":[{"count":20,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/171351\/revisions"}],"predecessor-version":[{"id":209647,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/posts\/171351\/revisions\/209647"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media\/171538"}],"wp:attachment":[{"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/media?parent=171351"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/categories?post=171351"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tags?post=171351"},{"taxonomy":"tutorials_categories","embeddable":true,"href":"https:\/\/wpmudev.com\/blog\/wp-json\/wp\/v2\/tutorials_categories?post=171351"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}