Cornerstone: All Content Types Aboard!

Queries are blind when it comes to custom content types
By Sol in Lab

My main goal today was including all content items (regardless of post type) for display on the front end.  This would return content type functionality to what it was prior to WordPress 3.0.  Custom post types are now 1st-class citizens in WordPress, each with their own place in the post_type column of the wp_posts table.  They’ve been promoted to the big show and are no longer relagated to the wp_postmeta table with all the other secondary post data.

For my purposes, custom content types (Cornerstone’s extension of WordPress’ own post types) should generally not interfere with the retrieval of content, but serve primarily to indicate the types of metadata a content item can/should contain.  Since I’ve decided to synchronize custom content types with WordPress’ custom post types for better compatibility, we now have a small issue since the default posts query (e.g. used on the home page, etc.) only retrieves content items with “post” as the post type, so items with other content types are left in the dust and not retrieved.  Isn’t that just how it always is?  You get a leg up in the world, only to be pushed back down.  I say equality for all content types!

To rectify this and allow all content items regardless of content type to be retrieved in default post queries, I’ve hooked into the pre_get_posts action to modify the query before any posts are retrieved.

add_action('pre_get_posts', $this->m('pre_get_posts'), 20);
//Calls internal method

When the pre_get_posts action is fired, Cornerstone’s pre_get_posts method:

  • Checks to make sure the query is a standard post query
  • Retrieves all custom content types and adds them to the post_type query variable
/**
 * Modifies query parameters to include custom content types
 * @param WP_Query $q Reference to WP_Query object being used to perform posts query
 * @see WP_Query for reference
 */
function pre_get_posts($q) {
	$qv =& $q->query_vars;
	$pt =& $qv['post_type'];

	/* Do not continue processing if:
	 * > In admin section
	 * > Single object requested
	 * > More than one post type is already specified
	 * > Post type other than 'post' is supplied
	 */
	if ( is_admin()
	|| is_singular()
	|| ( is_array($pt)
		&& ( count($pt) > 1
			|| 'post' != $pt[0] )
		)
	|| !in_array($pt, array('post', null))
	) {
		return false;
	}
	$default_types = $this->get_default_post_types();
	$custom_types = array_diff(array_keys($this->get_types()), $default_types);
	if ( !count($custom_types) )
		return false;
	//Wrap post type in array
	if ( empty($pt) || is_null($pt) )
		$pt = array('post');
	if ( !is_array($pt) )
		$pt = array($pt);
	//Add custom types to query
	foreach ( $custom_types as $type ) {
		$pt[] = $type;
	}
}

With the additional content types added to the query, all content items are now retrieved in standard post queries (ultimately, each custom content type will have the option to define whether it is included in standard queries or not).  All is now right with the world and I can sleep soundly knowing that custom content types are getting a fair shake.

Next

Work on content types continues as permalinks for content with custom post types need to have the ability use the section-name/post-name permalink structure enabled by Cornstone (by default it’s post-type/post-name).  Once that’s sorted, I’m heading back to the admin section to work on the edit form for items with custom post types.