Amber Weinberg: Freelance Web Developer specializing in semantic WordPress, Mobile, CSS and HTML5 Development

The Blog

How To Build A WordPress CMS Theme – Part 5: Coding The Homepage

Posted on 06/08/11 in blog, development about , , , ,

Whew, here we are again! We’ve got a long way to go today, so let’s skip the fluff and get right down to the coding!

Last week we finished up the header code, and this week we’ll be coding the homepage. In case you’re just joining us, here are the previous tutorials:

Remember you can see the demo of the WordPress version here, and see the regular HTML/CSS site here. You can also download everything in Part 4 . Ready? Let’s go!

Chapter 16: Coding the Homepage

Let’s first take a look at our homepage HTML. If you look at the site, you’ll see we have a main image and some text up top, and some image buttons beneath that. Nothing too difficult:

	<div id="featured">
		<h2>Our Story</h2>
		<p>Sophie discovered her passion for creating cakes after an exhaustive search throughout Toronto and Ottawa for her own wedding cake ended in disappointment. "Everyone was trying to convince me to settle for the cake of the week, but the cake is a centerpiece none of them were expressing what I wanted to say ..."</p>
		<p><a href="about.html">Read More</a></p>
	</div> <!-- END Featured Section -->
 
	<div id="links">
		<ul>
			<li><a href="about.html"><img src="images/artist.jpg" alt="artist" width="221" height="175" /><span>the artist</span></a></li>
			<li><a href="gallery.html"><img src="images/cakes.jpg" alt="cakes" width="221" height="175" /><span>cakes</span></a></li>
			<li><a href="about.html"><img src="images/experience.jpg" alt="experience" width="224" height="175" /><span>the experience</span></a></li>
			<li><a href="http://sophiebifieldcakecompany.wordpress.com"><img src="images/blog.jpg" alt="blog" width="222" height="175" /><span>blog</span></a></li>
		</ul>
	</div><!-- END Links -->

Now in WordPress, it should always be your goal to make everything as editable as possible for your client. Let’s get started with the PHP and functions and see how we can do this. Open up index.php.

First, we’ll need to wrap the loop around our content, so it can eventually be controlled dynamically:

	<?php get_header(); ?>
 
	<?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?>
			<div id="featured">
		<h2>Our Story</h2>
		<p>Sophie discovered her passion for creating cakes after an exhaustive search throughout Toronto and Ottawa for her own wedding cake ended in disappointment. "Everyone was trying to convince me to settle for the cake of the week, but the cake is a centerpiece none of them were expressing what I wanted to say ..."</p>
		<p><a href="about.html">Read More</a></p>
	</div> <!-- END Featured Section -->
 
	<div id="links">
		<ul>
			<li><a href="about.html"><img src="images/artist.jpg" alt="artist" width="221" height="175" /><span>the artist</span></a></li>
			<li><a href="gallery.html"><img src="images/cakes.jpg" alt="cakes" width="221" height="175" /><span>cakes</span></a></li>
			<li><a href="about.html"><img src="images/experience.jpg" alt="experience" width="224" height="175" /><span>the experience</span></a></li>
			<li><a href="http://sophiebifieldcakecompany.wordpress.com"><img src="images/blog.jpg" alt="blog" width="222" height="175" /><span>blog</span></a></li>
		</ul>
	</div><!-- END Links -->
	<?php endwhile; ?>
 
<?php get_footer(); ?>

Now, since there’s multiple areas of content, how do we decide how to split it up for the client? What’s usually best, is to put the main chuck of content (our featured section) into the WYSIWYG, and the rest into custom fields or even custom post types.

Let’s move the main content area inside of the featured div into the WordPress’s admin. Create a page called ‘Home’ and drop the content there. Save the page and come back to index.php.

Now add in the_content() where you removed the h2 and paragraph tags:

	<?php get_header(); ?>
 
	<?php if ( have_posts() ) while ( have_posts() ) : the_post(); ?>
 
             <div id="featured">
                  <?php the_content(); ?>
	     </div> <!-- END Featured Section -->
 
	<div id="links">
		<ul>
			<li><a href="about.html"><img src="images/artist.jpg" alt="artist" width="221" height="175" /><span>the artist</span></a></li>
			<li><a href="gallery.html"><img src="images/cakes.jpg" alt="cakes" width="221" height="175" /><span>cakes</span></a></li>
			<li><a href="about.html"><img src="images/experience.jpg" alt="experience" width="224" height="175" /><span>the experience</span></a></li>
			<li><a href="http://sophiebifieldcakecompany.wordpress.com"><img src="images/blog.jpg" alt="blog" width="222" height="175" /><span>blog</span></a></li>
		</ul>
	</div><!-- END Links -->
	<?php endwhile; ?>
 
<?php get_footer(); ?>

If you save the page and try to check it in the browser – nothing happens. That’s because right now, WordPress doesn’t know what page to grab content from. We have to tell WordPress with a query, to take the content from our newly created Home page.

Note: Some people prefer to do “templates” in WordPress, especially for the homepage. This consists of a separate PHP page with a special tag. You’d then create a page, choose that template in the sidebar, and then go to Settings > Reading to set that page as the homepage. That’s a lot of unnecessary work for both you and client, which is why I suggest doing it the way I do below.

Here’s the query telling WordPress to pull the content from the page called “Home”:

	<?php get_header(); ?>
 
	<?php query_posts('pagename=Home'); if ( have_posts() ) while ( have_posts() ) : the_post(); ?>
 
             <div id="featured">
                  <?php the_content(); ?>
	     </div> <!-- END Featured Section -->
 
	<div id="links">
		<ul>
			<li><a href="about.html"><img src="images/artist.jpg" alt="artist" width="221" height="175" /><span>the artist</span></a></li>
			<li><a href="gallery.html"><img src="images/cakes.jpg" alt="cakes" width="221" height="175" /><span>cakes</span></a></li>
			<li><a href="about.html"><img src="images/experience.jpg" alt="experience" width="224" height="175" /><span>the experience</span></a></li>
			<li><a href="http://sophiebifieldcakecompany.wordpress.com"><img src="images/blog.jpg" alt="blog" width="222" height="175" /><span>blog</span></a></li>
		</ul>
	</div><!-- END Links -->
	<?php endwhile; ?>
 
<?php get_footer(); ?>

Refresh the page and look! The featured content should be showing up now!

Let’s look at the four image links below. There are several ways we could code these for the client, and depending on how technical minded your client is or how often they want to change content, should help you decide which way to go with these. For the sake of the tutorial, let’s say our clients know basic HTML and are planning on changing these links weekly. In that case, it’s best to just drop them in as a custom field.

When doing custom fields, you should try to automate as much as you can for the client. In our example above, we don’t need the client to enter the div, ul, or li tags, we just need him to enter the link, the image they want to use, and the title.

So copy and paste each link into a separate custom field, and name each custom field “Link”. You can have as many custom fields as you’d like with the same name. You’ll also need to change the image path to match yours. Also be sure to add the custom fields in the order you want to links appear.

Now we can delete the links from our code and replace it with the get_post_meta function that will echo out our custom fields:

<?php get_header(); ?>
 
	<?php query_posts('pagename=Home'); if ( have_posts() ) while ( have_posts() ) : the_post(); ?>
	    <div id="featured">
	       <?php the_content(); ?>
		</div> <!-- END Featured Section -->
 
		<div id="links">
			<ul>
				<li><?php echo get_post_meta($post->ID, 'Link', true);?></li>
			</ul>
		</div><!-- END Links -->
	<?php endwhile; ?>
 
<?php get_footer(); ?>

Save the page and refresh in your browser…where’d all of our links go??? It should only display one at this point.

When using multiple custom fields with the same name, you can’t just echo the get_post_meta function like you’d normally do. Instead, you need to replace that with a foreach that will also surround each link with a li tag:

<?php get_header(); ?>
 
	<?php query_posts('pagename=Home'); if ( have_posts() ) while ( have_posts() ) : the_post(); ?>
	    <div id="featured">
	       <?php the_content(); ?>
		</div> <!-- END Featured Section -->
 
		<div id="links">
			<ul>
				<?php $link = get_post_meta($post->ID, 'Link', false); ?>
				<?php foreach($link as $link) { echo '<li>'.$link.'</li>'; } ?>
			</ul>
		</div><!-- END Links -->
	<?php endwhile; ?>
<?php get_footer(); ?>

And BOOM! How easy is that? Compare it to the original HTML site and it looks just the same, but is now controllable by the client.

Next Week

We move on to coding the footer! Please let me know if you have any questions or issues regarding this week’s post in the comments below. See ya next week!

About the author
Amber Weinberg specializes in clean and semantic XHTML, CSS and WordPress development. She has over 10 years of coding experience and is pretty cool to work with. Amber is available for freelance work, so why not hire her for your next project?

32 Awesome Comments

  1. Megan says:

    I’m curious to know what changes were made to the functions.php file to support this. Is that coming in a future post?

    • @Megan there’s be no changes at all to functions.php file. Although, you might want to keep in mind that I did start off from my hijinks files template :)

      • Megan says:

        I see now. A note to other WordPress newbies, Custom Links are hidden by default when editing a Page. It can be enabled by selecting the ‘Screen Options’ pull down box in the upper right corner and checking the ‘Custom Fields’ checkbox.

  2. David B. says:

    This needs to be a video series. Reading these so far have been good, but watching them would probably make this one hell of a comprehensible tutorial on theme building.

  3. JohnjrFisher says:

    Great job so far Amber, and congrats to you and your husband :D

  4. Hey Amber, working through this and getting hung up when I try to add the value to the custom fields section. I’m adding this chunk of code:

    <a href="/?page_id=5″> <img src="/images/artist.jpg” alt=”artist” width=”221″ height=”175″ />the artist

    and it all is coming up on the homepage, but the link and the image wont work correctly. Getting this error:

    Access forbidden!

    You don’t have permission to access the requested object. It is either read-protected or not readable by the server.
    If you think this is a server error, please contact the webmaster.
    Error 403
    localhost
    9/13/2011 2:21:50 PM
    Apache/2.2.14 (Win32) DAV/2 mod_ssl/2.2.14 OpenSSL/0.9.8l mod_autoindex_color PHP/5.3.1 mod_apreq2-20090110/2.7.1 mod_perl/2.0.4 Perl/v5.10.1

    Am I doing something wrong or is this just a problem with my local host environment? When I use absolute URLs everything works peachy.

    Thanks and great tutorials, seriously helping me out a ton!!

  5. Leonie says:

    Hi Amber,

    Great posts!
    Just a question the relative urls in the custom content don’t work for me (eg. /images/artist.jpg). Since wordpress prefers us to use absolute urls like before the image call, is there a way around this?
    Would love a post on creating custom admin content areas! Do you already have one??

    Thanks so much!
    Leonie

    • Relative URLs work, you just need to make sure you include the real path, which isn’t images/image.jpg, but wp-content/themes/your-theme/images/image.jpg or you could use the function bloginfo(‘template_url’) to dynamically call that URL

  6. Meredith Burke says:

    Hi Amber, these are great lessons. I have a question about how you handle the “home” link in the site menu. Obviously if you put the WYSIWG-created “Home” page in the menu, it won’t go to the actual index…it goes to the page with the text content for the index. Do you put a custom URL for the index in the menu instead? Thanks.

    • Nope, it actually automatically create a custom home link for you already, it’s always the top link under pages. If you also have a page called “Home” (which I always do), it will show two “home” links, the top one will be the one that actually goes to the homepage – you’ll have to manually update it though if you move the site.

  7. Kevin says:

    Hi Amanda, this may be out of the scope of the tutorials. Is there a way to add a jquery tabs in the sidebar that will show recent posts in one tab and archives in another. Or can you direct me to a decent tutorial that will show how to create my own tabs? I can create the tabs – it’s the custom implementation of WordPress that I have trouble with.
    Thanks

    • It’s Amber… :)

      All you need to do is just drop in WordPress’s functions for those in each tab section. For archives, you’d use wp_get_archives, for recent posts you’d need to run another query. Check out the WordPress Codex, it’s very helpful.

  8. Kevin says:

    Sorry about the name (administering dope slap)

  9. Bas says:

    Amber i get stucked with this part:

    Here’s the query telling WordPress to pull the content from the page called “Home”:

    When i add it nothing happens when i refresh the page. I thought i must be a typo, but after pasting the code from your site, still nothing happens.

    I just update tot the latest WordPress, but i don’t think that have anything to do with it.

    Can you help me out?

  10. Bas says:

    page id instead does work. But it is still strange it doesn’t work.

  11. Ivanna says:

    Hello Amber,
    I have followed your tutorial and have two problem with part 5 – coding the homepage.
    First I put the “featured” div starting with and ending with Read More between ….the_post(); ?> and

    At this point, I do not see Read More. Even if path syntax is wrong, I think I should still see the text Read More.

    Next, I load the links into custom fields but all I see are the alt tag and the image title (span). Perhaps the syntax is wrong so now I try all possible permutations including (‘template_url’), (‘url’) and (‘url_directory’). None of these work.

    If I add links, they are seen but the image is not seen. The images are in /my_theme/images.

    In the custom fields I use name of Link and value of <img src="/images/contact.png” />. All I see are four black dots where pictures should be.

    I have read and tried your instructions over and over but it is still the same. What am I doing wrong?

    thank you

  12. Ivanna says:

    thank you for replying.
    I did not create a Read More link. I just pasted from your article. Even so, the words Read More are not there.

    I do not know about the custom fields, I just follow the instructions. do I just use html syntax?

    thank you

  13. Daquan Wright says:

    Hey Amber, for some reason I’m super confused about how to get the sidebar on just the blog page (not sure how relevant it is to this specific part of the tutorial, but that’s what I’m on with my own blog at the moment).

    Could you point out how to enable the sidebar on just the blog page (similar to your own website), please?

  14. Steven says:

    This may be a dumb question, but if the “home” template is in index.php how do you display the posts for a “blog” page?

Leave a Reply