This is the second post of my new blog series about WordPress development patterns. If you’d like to read about caching complex queries in WordPress check out my previous post.

The featured posts problem

Almost all WordPress themes with a homepage template will have a hero slider on top, a featured articles section below, and at the end of the page a grid of last blog posts. This is a common design pattern and for sure it has its own benefits otherwise it wasn’t so common, right?

In order to select which content is featured in the slider and in the featured articles section, there are several common strategies used by theme developers:

  • Assign special categories to the posts (or pages) like “Slide” and “Featured” so that a query could pick them and show them on the slider and the featured sections respectively.
  • Have a theme options page where you have some kind of drag-n-drop interface to select which posts will be featured, saved as a WordPress option.
  • As in the previous bullet, but by adding a customizer section to enable the user to pick up the featured posts (similar to what was done on the Twenty Seventeen default theme, on the customizer theme options section).
  • Register a custom post type to manage the featured content.

I’ve already used almost all these strategies in my theme development work but I always felt it was too much overhead or very complex to manage by the end user (a.k.a. the client).

The begin of a cleaner strategy

The idea I’m sharing in this post came to me when I was creating a theme options page to manage the featured content of a slider for a multilingual website. I was already using the CMB2 plugin to manage the custom fields on my theme and I thought I should be using this same plugin to enable the featured posts selection, on my custom theme options page.

To get started, I found out a CMB2 extension to enable a posts drag-n-drop interface (similar to the ACF relationship field type): CMB2 Attached Posts. I manage to inject this field type into a CMB2 theme options page and it all seemed perfect. But no…

Turns out the CMB2 Attached Posts extension has a bug and when you have more than one of this field type on the same page it has conflicts:

cmb2 plugin attached posts search bug

(Don’t get me wrong! CMB2 is a great plugin and I’m very grateful to all the plugin developers! Great work!)

So, without the possibility of using CMB2 and without the energy to dive in the WordPress Settings Spaghetti API again, I start to think into a new way of doing this.

And then I though,

A featured content slider is the same as a WordPress menu!

A WordPress menu is a set of existent posts, on an editorial order… and so is a slider or a featured content section! And with a bonus, the WordPress menus page comes with a drag-n-drop interface, supported by the WordPress core team!

Using menus to manage featured content

To start, I created two new menu locations to manage the slider and featured content:

/**
 * Register navigation
 */
function my_theme_navigation() {
	register_nav_menus( array(
		'main' => 'My Traditional Main Menu',
		'slider' => 'My featured content slider', // Used to select the featured pages on the home slider
		'featured' => 'My featured content grid', // Used to select the featured pages
		'footer' => 'My footer menu',
	));
}
add_action( 'after_setup_theme', 'my_theme_navigation' );

Then, I wrote an helper function my_theme_get_featured_posts to get the post IDs of the featured content, for the needed theme location. (Full gist)

Finally, I used the my_theme_get_featured_posts function to get the post IDs and loop through then to render the slider html (or the featured content section) on the front-page.php template.