Sep 22, 2009
Building a WordPress Static Homepage with Dynamic Elements
One of the nice features of WordPress is the ability to create static homepages. While most blogs use the standard configuration, where users scroll vertically from the most recent to older blog posts, it often makes sense to use a static homepage instead — especially if you are looking to create a more professional looking site, or are using WordPress as a Content Management System. I recently tackled a project where we needed to create a static homepage with the following features
- The homepage needed to look “homepagey” (i.e. not “bloggy”)
- Client needed room for a short introductory text, which could be edited/updated on the fly without disrupting the homepage layout
- The homepage needed to highlight the many features on the site, so that users could quickly scan the page, see what the site had to offer, and quickly find the latest update in each area.
This quick tutorial will share some code for reproducing something that meets all or some of those criteria. You don’t need to know much code to complete this tutorial, but a little helps. Once you create and implement your homepage template, you will need to use CSS to add styles and adjust the layout.
The Basics of Creating a Homepage Template
This is pretty well-documented elsewhere, but here’s what you need to know on the most basic level. If you are using a prefab theme, find that theme’s page.php file. Now take that file and make a copy called homepage.php (or really, whatever you like). Next, add the five lines below to the very top of the page (before the header and sidebar calls):
< ?php /* Template Name: Home Page */ ?> |
Now, when you edit or create the page you want to use as Home, you can choose the Home Page template and set it as the static homepage for your site in Settings >> Reading. But this won’t get you far. As is, this template just replicates the behavior of any page on your site. That’s not very exciting. Instead, let’s try adding some dynamic content to the template.
Note on custom theme_excerpt() function used below
Before you get all crazy and just copy-paste from the homepage code below, note that I am using a custom function to generate post excerpts. To use that function you must first create a file called functions.php and add the following code:
< ?php function theme_excerpt($num) { global $more; $more = 1; $link = get_permalink(); $limit = $num+1; $excerpt = explode(' ', strip_tags(get_the_content()), $limit); array_pop($excerpt); $excerpt = implode(" ",$excerpt).'...'; $excerpt = preg_replace('`\[[^\]]*\]`','',$excerpt); echo '<p>'.$excerpt.''; $more = 0; } ?> |
This will get you a more flexible excerpt function than the default WordPress one, the_excerpt(). I think I stole this from the Feed Me Seymour theme. You can call the function with theme_excerpt(n) where n is the number of words in the excerpt.
I’m going to break this up into sections, so if you are copy-pasting, you will need to copy all the sections below or pick and choose carefully, otherwise you might end up with some unclosed tags.
Preserving the Page text
Most of the text in a dynamic homepage is generated from feeds, posts, and database queries (i.e. not by adding it manually to the page called Home in your WordPress page list). In some cases, your Home page could be totally blank when accessed from the default page editor. However, you may want to give yourself the option of manually adding and updating text somewhere on your homepage. In the example below, we keep the WordPress page text intact by calling The Loop.
< ?php /* Template Name: Home Page */ ?> <!-- get the header and sidebar... though sometimes you might want to leave the sidebar out of a Home template. It's here just for the sake of illustration--> < ?php get_header(); ?> < ?php get_sidebar(); ?> <div id="content"> <!-- Homepage text from the page editor using 'The Loop'--> < ?php if (have_posts()) : while (have_posts()) : the_post(); ?> <div class="post" id="main-entry"><div id="in-border"> <div class="entry"> < ?php the_content(); ?> </div> < ?php endwhile; endif; ?> </div></div> </div> |
An Internal Category Feed
Below we have the latest one post from the ‘News’ category. You can repeat this with other categories as needed. This is especially useful if you use the Category Visibility plug-in or some other means to hide/show certain category posts in certain areas of your site. In a recent project, for example, we created additional page templates for displaying posts in certain categories (Calendar Events, Timeline Events, Lesson Plans), but excluded them from the blog loop.
<!-- An internal feed.-->
<!-- The latest one post from the 'News' category -->
<!-- You can repeat this with other categories as needed. -->
<li>
<h2>News</h2>
< ?php $my_query = new WP_Query('category_name=news&showposts=1'); while ($my_query->have_posts()) : $my_query->the_post(); $do_not_duplicate = $post->ID; ?>
<!-- Link to the 'News' category -->
<div class="post">
<div id="link-contain">
<p class="contread"><a href="<?php echo get_bloginfo('url'); ?>/news">All News »</a></p>
</div>
<h3>Latest News</h3>
<!-- The post title -->
<h3><a href="<?php the_permalink() ?>" rel="bookmark" title="Permanent Link to < ?php the_title(); ?>">< ?php the_title(); ?></a></h3>
<div class="entry">
<!-- The post excerpt using custom function from theme/function.php -->
< ?php echo theme_excerpt(30); ?>
</div>
</div>
< ?php endwhile; ?>
</li> |
An External Feed
This code uses the WordPress core functionality that brings feeds into your Dashboard. I’m just pulling the title and link here, but you can do more. This is especially useful if your site incorporates another platform besides WordPress. In the example below, I use a feed from the Omeka platform (omeka.org), which I had tucked into my root directory, masquerading as a native section of the site.
<!-- An External Feed -->
<!-- This is especially useful if your site incorporates another platform besides WordPress.-->
<li>
<h2>Collections & Exhibits </h2>
<div class="post" id="omeka-feed">
<div id="link-contain"><p class="contread"><a href="<?php echo get_bloginfo('url'); ?>/omeka">View the Archive »</a></p></div>
<div class="entry">
<!-- This code uses the WordPress core functionality that brings feeds into your Dashboard-->
<!-- I'm just pulling the title and link here, but you can do more-->
< ?php
require_once (ABSPATH . WPINC . '/rss.php');
$rss = @fetch_rss('http://www.myurl.org/omeka/items/browse?output=rss2');
if ( isset($rss->items) && 0 != count($rss->items) ) {
?>
<h3>Latest Additions</h3>
<ul>
< ?php
$rss->items = array_slice($rss->items, 0,7);
foreach ($rss->items as $item ) {
?>
<li>
<a href="<?php echo wp_filter_kses($item['link']);?>">
< ?php echo wp_specialchars($item['title']); ?>
</a>
</li>
< ?php } ?>
</ul>
< ?php } ?>
</div>
</div>
< ?php endwhile; ?>
</li> |
A Special Plugin Feed (Simple:Press)
Lots of plugins generate their own feed. Here we have an internal feed from the Simple:Press forum plugin (simplepressforum.com). Such plug-ins generally use custom functions, such as the one below, the rules for which are defined in the plug-in documentation.
<!-- An internal feed from the Simple:Press forum plugin (simplepressforum.com)-->
<li>
<h2>Discussions</h2>
<div class="post" id="forum-posts">
<div id="link-contain"><p class="contread"><a href="<?php echo get_bloginfo('url'); ?>/forum">View Forums »</a></p></div>
<div class="entry">
<h3>Latest Topics</h3>
<ul>
< ?php sf_recent_posts_tag(3, false, true, true, true, 0, false); ?>
</ul>
</div>
</div>
</li> |
Listing all Pages
Normally, you should list all your pages in the header navigation, but in this case I had too many pages to list there, some of which didn’t belong in the navigation. I listed only the pages that were not part of the header navigation or the footer (About, Contact) in this section. You can find more info about wp_list_pages() here.
<!-- List all parent pages and first level of child pages --> <li> <h2>More</h2> <div class="post" id="more-list"> <ul> <h3>< ?php wp_list_pages('title_li=&depth=2exclude=1,2,3,4,5,6') ;?></h3> </ul> </div> </li> |
If you are copy-pasting, don’t forget to add the footer to end your page
< ?php get_footer(); ?> |
Of course, there are plenty more tricks out there. Frankly, these aren’t that special, but they seem fundamental. If this helps you, let us know in the comments.

Great Article. I never thought of some of the things mentioned here.