Blog

Custom Conditional Tags, Custom Post Types and Custom Field Display for WordPress Genesis Childtheme

I recently had a client ask for  a website that allowed “window shopping”. They wanted users to be able to view products, inventory, and prices, but did not want to allow actual transactions. I considered setting them up with an e-commerce system with disabled shop features. But they adamantly assured me that they would never desire full e-commerce resources. So why burden their website with a bulky plugin?

I decided to go with custom post types.

When their website was almost complete – including custom post types, a taxonomy for those post types, custom fields for price and inventory, and code in place to display and style the custom fields on the front end – I realized that one thing was missing.

There was not succinct way that I could find to use conditional tags to display custom fields within only the custom post type article entry. But during my perusing, I synthesized a solution.

I can’t trace my steps back and cite completely. I can say that I spent a lot of time on Justin Tadlock’s blog, Josh Pollock’s blog, and the WordPress Support Forum.

And here’s what I want to share – there’s a really easy-to-enhance snippet that you can use to create a brand new, custom conditional tag for your website. Using your custom conditional tag, you can call custom field data to display wherever you want within a loop or on a page. In conjunction with pre-existing WordPress conditional tags, a custom conditional tag offers a lot of flexibility. If you want to jump to the custom conditional tag, go ahead!

If you want to warm up to it by seeing how I setup the rest of the system, scroll on. I will cover:

  • Custom Post Types
  • Custom Taxonomies
  • Custom Fields
  • Conditional Tags

Custom Post Types

Creating Custom Post Types is a breeze. Really. Below you can see the code that I used to register my product post types. Your intuition is probably enough to interpret a majority of the lines. But if you’re interested in further detail than I’ve offered, hop over to Justin Tadlock’s exhaustive and organized article about Custom Post Types and, of course, the Codex.

One thing to notice is that the Taxonomies Arg contains “‘portfolio-category'”. That’s a Custom Taxonomy that will be created in the next section of this article. It would be possible to enter multiple arguments separated by commas in order to use many custom taxonomies ( like categories and tags ) on the same content.

/* CREATE CUSTOM POST TYPE
---------------------------------------------- */

add_action( 'init', 'create_custom_post_type' );
function create_custom_post_type() {

$labels = array(
	'name' => __( 'Products' ),
	'singular_name' => __( 'Product' ),
	'all_items' => __('All Products'),
	'add_new' => _x('Add new Product', 'Products'),
	'add_new_item' => __('Add new Product'),
	'edit_item' => __('Edit Product'),
	'new_item' => __('New Product'),
	'view_item' => __('View Products'),
	'search_items' => __('Search in Products'),
	'not_found' => __('No Products found'),
	'not_found_in_trash' => __('No Products found in trash'),
	'parent_item_colon' => ''
	);

$args = array(
	'hierarchical' => true,
	'labels' => $labels,
	'public' => true,
	'has_archive' => true,
	'menu_position' => 5,
	'rewrite' => array('slug' => 'products'),
	'taxonomies' => array( 'portfolio-category' ),
	'supports' => array( 'title', 'editor', 'thumbnail' , 'custom-fields', 'excerpt', 'comments', 'custom-fields', 'revisions', 'page-attributes', 'genesis-cpt-archives-settings' )
	);

register_post_type( 'products', $args);
}

Custom Taxonomy

My application required that I generate some sort of navigation system for the “window shop”, so I used the following code to generate a Product-Category Taxonomy. Justins article and Codex ( linked above ) contain more information about custom taxonomies.

Do note, to register multiple taxonomies, you can simply repeat the register_taxonomy command within the create_portfolio_tax function.

/* REGISTER CUSTOM TAXONOMY
---------------------------------------------- */

add_action( 'init', 'create_portfolio_tax' );
function create_portfolio_tax() {
register_taxonomy(
	'product-category',
	'products',
		array(
		'label' => __( 'Category' ),
		'hierarchical' => true
		)
	);
}

Custom Fields

For my project, I used Advanced Custom Fields to create, regulate, and integrate custom fields. The reasons I opted for a plugin included that

  • the client might come back later and ask me to add a new product descriptor – like product weight – and I would like to be able to add that on the fly with just a touch of new code
  • I am aware that creating custom fields to display in templates is relatively easy, but after all that, you still have to create custom meta boxes for the admin if you want it to look nice, which includes creating rules to govern upon which admin post pages the custom meta boxes display. ACFields has all that in the bag.

So – ACFields came out ahead on the cost benefit analysis for me. If you have a different, fast, stable solution, share it with me!

Display Custom Fields Using the New Conditional Tag

I’m showing you the snippet I used to display the Custom Fields, without the Custom Conditional Tag to help illustrate why this is a useful tool.

You can see below, I’m using echo and printf to create divs and display the content for my Custom Fields – price and units_available.

I implemented this on a Genesis child theme, which is why you’re seeing a function rather than a PHP statement. The Genesis hook genesis_entry_header allows us to inject a piece of code directly below the Header of all Article elements on the website.

Now all of my Product Post Types have their cost and inventory available to view! Unfortunately, every other Article element on the website has price and inventory, too, even though they’re not products. This is where the Custom Conditional Tag comes into vogue.

/* ADD CUSTOM DETAILS UNDER TITLE
Using Genesis Hooks
Using Advanced Custom Fields to create fields.
---------------------------------------------- */

add_action( 'genesis_entry_content', 'products_details_markup' );
function products_details_markup() {
		echo '<div class="product-stats">';
			echo '<div class="product-price">';
				printf( the_field('price') );
			echo '</div>';
			echo '<div class="units-available">';
				printf( the_field('units_available') );
			echo '</div>';
		echo '</div>';
	}

Conditional Tags

Finally – My Product Post Type is ready. My taxonomy is ready. My Custom Fields are ready and are displaying in all the right places, as well as many wrong places. I want to call my Custom Field Data to display beneath the title of only ( and every ) Custom Post Type Post.

At first, I started out using conditional tags from the WP Codex to try to regulate my product markup. In not too long, I had four different arguments, many of which were complex arguments, forming my if-statement. And there were still display issues.

I went on a hunt for a simple solution. I didn’t found a perfect piece of code until I noted a comment on the WP Support forms noting that the category-template.php file in /wp-includes contained the core functions for registering conditional tags.

I found the has_term conditional tag in category-template.php and modified it to create a new Conditional Tag: has_product.

/* CREATE has_custom CONDITIONAL FUNCTION FOR POST TYPES
Allows has_custom to be used as conditional tag. Checkout
category-template.php 'function has_term' as of WP 3.9.1
to expand or modify this function.
---------------------------------------------- */

function has_product( $taxonomy = 'product-category' ) {
	$post = get_post($post);

	if ( !$post )
		return false;

	$r = is_object_in_term( $post-&gt;ID, $taxonomy );
	if ( is_wp_error( $r ) )
		return false;

	return $r;
	}

Now, I can use has_product in my if statement to restrict the products markup information from displaying on content that is not a Product Post Type, like so.

/* ADD CUSTOM DETAILS UNDER TITLE
Using Genesis Hooks
Using has_custom Conditional Function
Using Advanced Custom Fields to create fields.
---------------------------------------------- */

add_action( 'genesis_entry_content', 'products_details_markup' );
function products_details_markup() {
	if ( has_product() ) {
		echo '<div class="product-stats">';
			echo '<div class="product-price">';
				printf( the_field('price') );
			echo '</div>';
			echo '<div class="units-available">';
				printf( the_field('units_available') );
			echo '</div>';
		echo '</div>';
	}
}

The Whole Package; Plugin-ified

I packaged it up as a plugin for my website. You can use the entire code below to create your own plugin.

<?php
/*
Plugin Name: Simple Custom Post Type Plugin
Plugin URI: /
Description: Entire batch of snippets required to register a Custom Post Type, Custom Taxonomy, and Custom Conditional Tag.  
Author: James Ryven Valeii
Version: 1.0
Author URI: 
License: GPL2
*/

/* REGISTER CUSTOM TAXONOMY 
 ---------------------------------------------- */

add_action( 'init', 'create_portfolio_tax' );
function create_portfolio_tax() {
    register_taxonomy(
        'product-category',
        'products',
        array(
            'label' => __( 'Category' ),
            'hierarchical' => true
        )
    );
}

/* CREATE CUSTOM POST TYPE
 ---------------------------------------------- */

add_action( 'init', 'create_custom_post_type' );
function create_custom_post_type() {
 
   $labels = array(
    'name' => __( 'Products' ),
    'singular_name' => __( 'Product' ),
    'all_items' => __('All Products'),
    'add_new' => _x('Add new Product', 'Products'),
    'add_new_item' => __('Add new Product'),
    'edit_item' => __('Edit Product'),
    'new_item' => __('New Product'),
    'view_item' => __('View Products'),
    'search_items' => __('Search in Products'),
    'not_found' =>  __('No Products found'),
    'not_found_in_trash' => __('No Products found in trash'), 
    'parent_item_colon' => ''
    );
 
    $args = array(
    'hierarchical' => true,
    'labels' => $labels,
    'public' => true,
    'has_archive' => true,
    'menu_position' => 5,
    'rewrite' => array('slug' => 'products'),
	'taxonomies' => array( 'portfolio-category', 'portfolio-tag' ),
    'supports'  => array( 'title', 'editor', 'thumbnail' , 'custom-fields', 'excerpt', 'comments', 'custom-fields', 'revisions', 'page-attributes', 'genesis-cpt-archives-settings' )       
    );
 
  register_post_type( 'products', $args);
}

/* CREATE has_custom CONDITIONAL FUNCTION FOR POST TYPES
   Allows has_custom to be used as conditional tag. Checkout 
   category-template.php 'function has_term' as of WP 3.9.1
   to expand or modify this function.
 ---------------------------------------------- */
 
function has_product( $taxonomy = 'product-category' ) {
	$post = get_post($post);

	if ( !$post )
		return false;

	$r = is_object_in_term( $post->ID, $taxonomy );
	if ( is_wp_error( $r ) )
		return false;

	return $r;
}

/* ADD CUSTOM DETAILS UNDER TITLE
   Using Genesis Hooks
   Using has_custom Conditional Function
   Using Advanced Custom Fields to create fields.
 ---------------------------------------------- */
 
add_action( 'genesis_entry_content', 'products_details_markup' );
function products_details_markup() {
	if ( has_product() ) {
		echo '<div class="product-stats">';
			echo '<div class="product-price">';
				printf( the_field('price') );
			echo '</div>';
			echo '<div class="units-available">';
				printf( the_field('units_available') );
			echo '</div>';
		echo '</div>';
	}
}

?>

What’s Next

Our Work

Check out some recent work we’re proud of.

Our Blog

Read our latest ideas about tech, features, messaging, and more.

Get in Touch

Want to discuss a project? Hit us up, we’d love to chat!