WordPress:
Custom Post Types and Taxonomies

Code Snippets

Chapter 2: Creating a plugin for Custom Post Types and Taxonomies

2.1 - Creating a basic plugin

In plugins/posttypes.php:


<?php
/**
 * Plugin Name: Custom Post Types and Taxonomies
 * Plugin URI: http://yoursite.com
 * Description: A simple plugin that adds custom post types and taxonomies
 * Version: 0.1
 * Author: Your Name
 * Author URI: http://yoursite.com
 * License: GPL2
 */

/*  Copyright YEAR  YOUR_NAME  (email : your@email.com)

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License, version 2, as 
    published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
                

Chapter 3: Creating Custom Post Types

3.1 - Creating a basic Custom Post Type

In plugins/posttypes.php:


function my_custom_posttypes() {
    $args = array(
      'public' => true,
      'label'  => 'Testimonials'
    );
    register_post_type( 'testimonial', $args );
}
add_action( 'init', 'my_custom_posttypes' );
                

3.3 - Building out an advanced Custom Post Type

In plugins/posttypes.php:


function my_custom_posttypes() {
    
    $labels = array(
        'name'               => 'Testimonials',
        'singular_name'      => 'Testimonial',
        'menu_name'          => 'Testimonials',
        'name_admin_bar'     => 'Testimonial',
        'add_new'            => 'Add New',
        'add_new_item'       => 'Add New Testimonial',
        'new_item'           => 'New Testimonial',
        'edit_item'          => 'Edit Testimonial',
        'view_item'          => 'View Testimonial',
        'all_items'          => 'All Testimonials',
        'search_items'       => 'Search Testimonials',
        'parent_item_colon'  => 'Parent Testimonials:',
        'not_found'          => 'No testimonials found.',
        'not_found_in_trash' => 'No testimonials found in Trash.',
    );
    
    $args = array(
        'labels'             => $labels,
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'menu_icon'          => 'dashicons-id-alt',
        'query_var'          => true,
        'rewrite'            => array( 'slug' => 'testimonials' ),
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => 5,
        'supports'           => array( 'title', 'editor', 'thumbnail' )
    );
    register_post_type( 'testimonial', $args );
}
add_action( 'init', 'my_custom_posttypes' );

// Flush rewrite rules to add "review" as a permalink slug
function my_rewrite_flush() {
    my_custom_posttypes();
    flush_rewrite_rules();
}
register_activation_hook( __FILE__, 'my_rewrite_flush' );
                

3.5 - Solution: Create a Custom Post Type for Reviews

In plugins/posttypes.php:


    $labels = array(
        'name'               => 'Reviews',
        'singular_name'      => 'Review',
        'menu_name'          => 'Reviews',
        'name_admin_bar'     => 'Review',
        'add_new'            => 'Add New',
        'add_new_item'       => 'Add New Review',
        'new_item'           => 'New Review',
        'edit_item'          => 'Edit Review',
        'view_item'          => 'View Review',
        'all_items'          => 'All Reviews',
        'search_items'       => 'Search Reviews',
        'parent_item_colon'  => 'Parent Reviews:',
        'not_found'          => 'No reviews found.',
        'not_found_in_trash' => 'No reviews found in Trash.',
    );
    
    $args = array(
        'labels'             => $labels,
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'rewrite'            => array( 'slug' => 'reviews' ),
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => 5,
        'menu_icon'          => 'dashicons-star-half',
        'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' ),
        'taxonomies'         => array( 'category', 'post_tag' )
    );
    register_post_type( 'review', $args );
                

Chapter 4: Creating Custom Taxonomies

4.1 - Creating basic custom taxonomies

In plugins/posttypes.php:


// Custom Taxonomies
function my_custom_taxonomies() {
	register_taxonomy(
		'Type of Product/Service',
		'review',
		array(
			'label' => __( 'Type of Product/Service' ),
			'rewrite' => array( 'slug' => 'product-type' ),
			'hierarchical' => true,
		)
	);
        
        register_taxonomy(
		'Price Range',
		'review',
		array(
			'label' => __( 'Price Range' ),
			'rewrite' => array( 'slug' => 'price' ),
			'hierarchical' => true,
		)
	);
        
        register_taxonomy(
		'Mood',
		'review',
		array(
			'label' => __( 'Mood' ),
			'rewrite' => array( 'slug' => 'mood' ),
			'hierarchical' => false,
		)
	);
}

add_action( 'init', 'my_custom_taxonomies' );
                

4.3 - Building out advanced Custom Taxonomies

In plugins/posttypes.php:


// Custom Taxonomies
function my_custom_taxonomies() {
	
    // Type of Product/Service taxonomy
    $labels = array(
        'name'              => 'Type of Products/Services',
        'singular_name'     => 'Type of Product/Service',
        'search_items'      => 'Search Types of Products/Services',
        'all_items'         => 'All Types of Products/Services',
        'parent_item'       => 'Parent Type of Product/Service',
        'parent_item_colon' => 'Parent Type of Product/Service:',
        'edit_item'         => 'Edit Type of Product/Service',
        'update_item'       => 'Update Type of Product/Service',
        'add_new_item'      => 'Add New Type of Product/Service',
        'new_item_name'     => 'New Type of Product/Service Name',
        'menu_name'         => 'Type of Product/Service',
    );

    $args = array(
        'hierarchical'      => true,
        'labels'            => $labels,
        'show_ui'           => true,
        'show_admin_column' => true,
        'query_var'         => true,
        'rewrite'           => array( 'slug' => 'product-types' ),
    );

    register_taxonomy( 'product-type', array( 'review' ), $args );

    // Mood taxonomy (non-hierarchical)
    $labels = array(
        'name'                       => 'Moods',
        'singular_name'              => 'Mood',
        'search_items'               => 'Search Moods',
        'popular_items'              => 'Popular Moods',
        'all_items'                  => 'All Moods',
        'parent_item'                => null,
        'parent_item_colon'          => null,
        'edit_item'                  => 'Edit Mood',
        'update_item'                => 'Update Mood',
        'add_new_item'               => 'Add New Mood',
        'new_item_name'              => 'New Mood Name',
        'separate_items_with_commas' => 'Separate moods with commas',
        'add_or_remove_items'        => 'Add or remove moods',
        'choose_from_most_used'      => 'Choose from the most used moods',
        'not_found'                  => 'No moods found.',
        'menu_name'                  => 'Moods',
    );

    $args = array(
        'hierarchical'          => false,
        'labels'                => $labels,
        'show_ui'               => true,
        'show_admin_column'     => true,
        'update_count_callback' => '_update_post_term_count',
        'query_var'             => true,
        'rewrite'               => array( 'slug' => 'moods' ),
    );

    register_taxonomy( 'mood', array( 'review', 'post' ), $args );
}

add_action( 'init', 'my_custom_taxonomies' );
                

4.5 - Solution: Create a Custom Taxonomy for Rating

In plugins/posttypes.php:


// Price Range taxonomy
    $labels = array(
        'name'              => 'Price Ranges',
        'singular_name'     => 'Price Range',
        'search_items'      => 'Search Price Ranges',
        'all_items'         => 'All Price Ranges',
        'parent_item'       => 'Parent Price Range',
        'parent_item_colon' => 'Parent Price Range:',
        'edit_item'         => 'Edit Price Range',
        'update_item'       => 'Update Price Range',
        'add_new_item'      => 'Add New Price Range',
        'new_item_name'     => 'New Price Range Name',
        'menu_name'         => 'Price Range',
    );

    $args = array(
        'hierarchical'      => true,
        'labels'            => $labels,
        'show_ui'           => true,
        'show_admin_column' => true,
        'query_var'         => true,
        'rewrite'           => array( 'slug' => 'prices' ),
    );

    register_taxonomy( 'price', array( 'review' ), $args );
                

Chapter 5: Creating Custom Post Type Templates

5.2 - Creating a single post template for a Custom Post Type

In childtheme/style.css:


/*
 Theme Name:   Your Child Theme
 Description:  hild theme for displaying custom post types and taxonomies
 Author:       Your Name
 Author URI:   http://yoursite.com
 Template:     [parenttheme] (folder name for parent theme)
 Version:      1.0.0
*/

@import url("../[parenttheme]/style.css");
                

5.3 - Adding custom taxonomies to a template

In childtheme/content-review.php:


<div class="taxonomies">
    <div class="product-type">
        <?php echo get_the_term_list( $post->ID, 'product-type', 'Type of product: ', ', ', '' ); ?> 
    </div>
    <div class="price-range">
        <?php echo get_the_term_list( $post->ID, 'price', 'Price Range: ', ', ', '' ); ?> 
    </div>
    <div class="mood">
        <?php echo get_the_term_list( $post->ID, 'mood', 'The mood this puts me in: ', ', ', '' ); ?> 
    </div>
</div>
                

In childtneme/style.css:


.taxonomies {
    font-family: 'Lato';
    font-size: 90%;
    margin-bottom: 2rem;
}

.taxonomies a {
    font-weight: 600;
}
                

5.5 - Creating a taxonomy archive template

In childtheme/content.php:


<?php 
if ( is_post_type_archive('review') ) { ?>
    <div class="taxonomies">
        <div class="product-type">
            <?php echo get_the_term_list( $post->ID, 'product-type', 'Type of product: ', ', ', '' ); ?> 
        </div>
        <div class="price-range">
            <?php echo get_the_term_list( $post->ID, 'price', 'Price Range: ', ', ', '' ); ?> 
        </div>
        <div class="mood">
            <?php echo get_the_term_list( $post->ID, 'mood', 'The mood this puts me in: ', ', ', '' ); ?> 
        </div>
    </div>
<?php } ?>
                

Chapter 6: Working with Custom Post Types and Taxonomies

6.1 - Including Custom Post Types in the front page and search results

In childtheme/functions.php:


function my_add_reviews( $query ) {
    if ( ! is_admin() && $query->is_main_query() {
        if ($query->is_home() || $query->is_search() ) {
        $query->set( 'post_type', array( 'post', 'review' ) );
        }
    }
}

add_action( 'pre_get_posts', 'my_add_reviews' );
                

6.2 - Creating custom loops for Custom Post Types

In childtheme/testimonials.php:


<?php
/* 
 * Display 3 random testimonials
 */

$args = array( 
    'post_type' => 'testimonial', 
    'posts_per_page' => 3,
    'orderby' => 'rand'
);

$testimonials = new WP_Query( $args );
echo '<aside id="testimonials" class="clear">';
while ( $testimonials->have_posts() ) : $testimonials->the_post();
    echo '<div class="testimonial">';
    echo '<figure class="testimonial-thumb">';
    the_post_thumbnail('medium');
    echo '</figure>';
    echo '<h1 class="entry-title">' . get_the_title() . '</h1>';
    echo '<div class="entry-content">';
    the_content();
    echo '</div>';
    echo '</div>';
endwhile;
echo '</aside>';
                

In childtheme/style.css:


#testimonials {
    background: #fff;
    padding: 4rem 0;
}

.testimonial {
    width: 33.333333%;
    float: left;
    padding: 0 4rem;
}

.testimonial-thumb img {
    display: block;
    margin: 0 auto 2rem;
}

.testimonial h1 {
    text-align: center;
}