How-to: Manually Select Posts on Frontpage Using Sticky Posts

Quite often companies would like their front page to display blog items but only the ones they specifically choose. There are a few different ways to go about doing this in WordPress which I will touch on first, however one of the best ways is to ask them to make the posts sticky and create a special template for the front page that only shows sticky posts and then another template for the blog that ignores the sticky status.

A Few Other Solutions and Why I’m Not a Fan

The key to achieving the desired result is basically to single out the posts that need to be on the front page in such a way that they can be filtered in a page template. Perhaps the first way of doing this people think of is categories and tags.

Using a special “frontpage” tag works perfectly until someone inadvertently tags a post about the old Microsoft Frontpage application with “frontpage” and it shows up on the frontpage. While the example may seem far fetched, the risk for inadvertent tagging is obvious.

Getting around this by using a dedicated category is a more secure way but draws attention to the other negative aspect of both these methods: It shows for the user. As a general rule, I like tweaks like this to be invisible to the end site user which rules out using both categories and tags.

The Solution: Sticky Posts!

Let’s get on with the solution that actually works fine and is logical to most webmasters. The idea is the following:

  • Whenever a post should appear on the frontpage, mark it as sticky.

However, this brings an interesting problem to the blog listing. Because the sticky posts will appear at the top of the blog listing the solution to the first problem will create a second one. Don’t worry, WordPress has a function you can pass to the query to solve this. Let’s get started.

Frontpage Template

The code that I use for the front page template is basically a standard WordPress loop, making sure to include the template naming comment at the top.

What is a little bit special is that I create a new custom query using the WP_Query function, passing the post__in option and having that equal posts that are sticky. This is done through the following bit of code: ‘post__in’ => get_option(‘sticky_posts’);

Note that the have_posts() etc. functions change to have $query in front instead of $this.

<?php /*
Template Name: Frontpage
*/ ?>
<?php get_header(); ?>

		<?php $query = new WP_Query(array( // Creating a custom Query
			'post__in'  => get_option( 'sticky_posts' ) // Only including posts that are sticky
		)); ?>

		<?php if($query->have_posts()) : ?><?php while($query->have_posts()) : $query->the_post(); ?>

			<?php get_template_part('content',get_post_format()); ?>

		<?php endwhile; ?>

		<?php else : ?>

			<h1>No Content Could Be Found</h1>

			<p>No content could be found for your query.</p>

		<?php endif; ?>

	<?php get_sidebar(); ?>

<?php get_footer(); ?>

You can use the code here yourself if you like, however the best is to modify your own template so that you don’t miss out on any special tags or features.

Template For Blog Page

For the blog page, you don’t need to be working on a special page template as WordPress will automatically use the index.php file if applicable. In the code example below I am only including the start of the loop:

<?php $query = new WP_Query(array(
					'ignore_sticky_posts' => 1
				)); ?>

				<?php if($query->have_posts()) : ?><?php while($query->have_posts()) : $query->the_post(); ?>

For the index page, I choose to go the same route by creating another custom query. The importance is that you pass the option ‘ignore_sticky_posts’ => 1 to the query. With this enabled (set to 1), all sticky posts will appear sorted by post dates and have their stickiness ignored on the blog page.

Conclusion

This is my favorite way of doing this even though it has one major flaw of itself. If the blog in question plans to also utilize the sticky posts feature, you would have to go with one of the other workarounds for this such as setting a custom field value and checking for that on the front page.