Sample Custom Post Type

<?php
/**
 * Testimonials
 *
 * @package      CoreFunctionality
 * @author       Bill Erickson
 * @since        1.0.0
 * @license      GPL-2.0+
**/

class EA_CPT_Testimonial {

	/**
	 * Instance of the class.
	 *
	 * @since 1.0.0
	 *
	 * @var object
	 */
	private static $instance;

	/**
	 * Class Instance.
	 *
	 * @since 1.0.0
	 *
	 * @return EA_CPT_Testimonial
	 */
	public static function instance() {
		if ( ! isset( self::$instance ) && ! ( self::$instance instanceof EA_CPT_Testimonial ) ) {
			self::$instance = new EA_CPT_Testimonial();

			// Actions
			add_action( 'init',              array( self::$instance, 'register_tax'      )    );
			add_action( 'init',              array( self::$instance, 'register_cpt'      )    );
			add_action( 'gettext',           array( self::$instance, 'title_placeholder' )    );
			add_action( 'pre_get_posts',     array( self::$instance, 'testimonial_query' )    );
			add_action( 'template_redirect', array( self::$instance, 'redirect_single'   )    );

			// Column Filters
			add_filter( 'manage_edit-testimonial_columns',        array( self::$instance, 'testimonial_columns' )        );

			// Column Actions
			add_action( 'manage_testimonial_pages_custom_column', array( self::$instance, 'custom_columns'      ), 10, 2 );
			add_action( 'manage_testimonial_posts_custom_column', array( self::$instance, 'custom_columns'      ), 10, 2 );
		}
		return self::$instance;
	}
	
	/**
	 * Register the taxonomies
	 *
	 * @since 1.2.0
	 */
	function register_tax() {

		$labels = array(
			'name'                       => 'FOO',
			'singular_name'              => 'FOO',
			'search_items'               => 'Search FOOs',
			'popular_items'              => 'Popular FOOs',
			'all_items'                  => 'All FOOs',
			'parent_item'                => 'Parent FOO',
			'parent_item_colon'          => 'Parent FOO:',
			'edit_item'                  => 'Edit FOO',
			'update_item'                => 'Update FOO',
			'add_new_item'               => 'Add New FOO',
			'new_item_name'              => 'New FOO',
			'separate_items_with_commas' => 'Separate FOOs with commas',
			'add_or_remove_items'        => 'Add or remove FOOs',
			'choose_from_most_used'      => 'Choose from most used FOOs',
			'menu_name'                  => 'FOOs',
		);

		$args = array(
			'labels'            => $labels,
			'public'            => true,
			'show_in_nav_menus' => true,
			'show_ui'           => true,
			'show_in_rest'      => true,
			'show_tagcloud'     => false,
			'hierarchical'      => false,
			'rewrite'           => array( 'slug' => 'cpt-slug/foo', 'with_front' => false ),
			'query_var'         => true,
			'show_admin_column' => false,
			// 'meta_box_cb'    => false,
		);

		register_taxonomy( 'foo', array( 'testimonials' ), $args );
	}

	/**
	 * Register the custom post type
	 *
	 * @since 1.2.0
	 */
	function register_cpt() {

		$labels = array(
			'name'               => 'Testimonials',
			'singular_name'      => 'Testimonial',
			'add_new'            => 'Add New',
			'add_new_item'       => 'Add New Testimonial',
			'edit_item'          => 'Edit Testimonial',
			'new_item'           => 'New Testimonial',
			'view_item'          => 'View Testimonial',
			'search_items'       => 'Search Testimonials',
			'not_found'          => 'No Testimonials found',
			'not_found_in_trash' => 'No Testimonials found in Trash',
			'parent_item_colon'  => 'Parent Testimonial:',
			'menu_name'          => 'Testimonials',
		);

		$args = array(
			'labels'              => $labels,
			'hierarchical'        => false,
			'supports'            => array( 'title', 'editor', 'thumbnail' ),
			'public'              => true,
			'show_ui'             => true,
			'show_in_menu'        => true,
			'show_in_rest'        => true,
			'show_in_nav_menus'   => true,
			'publicly_queryable'  => true,
			'exclude_from_search' => false,
			'has_archive'         => true,
			'query_var'           => true,
			'can_export'          => true,
			'rewrite'             => array( 'slug' => 'testimonials', 'with_front' => false ),
			'menu_icon'           => 'dashicons-groups', // https://developer.wordpress.org/resource/dashicons/
		);

		register_post_type( 'testimonial', $args );

	}

	/**
	 * Change the default title placeholder text
	 *
	 * @since 1.2.0
	 * @global array $post
	 * @param string $translation
	 * @return string Customized translation for title
	 */
	function title_placeholder( $translation ) {

		global $post;
		if ( isset( $post ) && 'testimonial' == $post->post_type && 'Enter title here' == $translation ) {
			$translation = 'Enter Name Here';
		}
		return $translation;

	}

	/**
	 * Customize the Testimonials Query
	 *
	 * @since 1.2.0
	 * @param object $query
	 */
	function testimonial_query( $query ) {
		if( $query->is_main_query() && !is_admin() && $query->is_post_type_archive( 'testimonial' ) ) {
			$query->set( 'posts_per_page', 20 );
		}
	}

	/**
	 * Redirect Single Testimonials
	 *
	 * @since 1.2.0
	 */
	function redirect_single() {
		if( is_singular( 'testimonial' ) ) {
			wp_redirect( get_post_type_archive_link( 'testimonial' ) );
			exit;
		}
	}

	/**
	 * Testimonials custom columns
	 *
	 * @since 1.2.0
	 * @param array $columns
	 */
	function testimonial_columns( $columns ) {

		$columns = array(
			'cb'                  => '<input type="checkbox" />',
			'thumbnail'           => 'Thumbnail',
			'title'               => 'Name',
			'date'                => 'Date',
		);

		return $columns;
	}

	/**
	 * Cases for the custom columns
	 *
	 * @since 1.2.0
	 * @param array $column
	 * @param int $post_id
	 * @global array $post
	 */
	function custom_columns( $column, $post_id ) {

		global $post;

		switch ( $column ) {
			case 'thumbnail':
				the_post_thumbnail( 'thumbnail' );
				break;
		}
	}

}

/**
 * The function provides access to the class methods.
 *
 * Use this function like you would a global variable, except without needing
 * to declare the global.
 *
 * @since 1.0.0
 *
 * @return object
 */
function ea_cpt_testimonial() {
	return EA_CPT_Testimonial::instance();
}
ea_cpt_testimonial();
Bill Erickson

Bill Erickson is a freelance WordPress developer and a contributing developer to the Genesis framework. For the past 14 years he has worked with attorneys, publishers, corporations, and non-profits, building custom websites tailored to their needs and goals.

Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk