Sample Custom Post Type

<?php
/**
 * Shop CPT
 *
 * @package      Cultivate
 * @author       CultivateWP
 * @since        1.0.0
 * @license      GPL-2.0+
 **/

/**
 * Shop CPT
 */
class BE_CPT_Shop {

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

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

			add_action( 'init', array( self::$instance, 'register_tax' ), 4 );
			add_action( 'init', array( self::$instance, 'register_cpt' ) );
			add_action( 'template_redirect', array( self::$instance, 'redirect_single' ) );
		}
		return self::$instance;
	}

	/**
	 * Register the taxonomies
	 */
	public function register_tax() {

		$taxonomies = [
			'shop_category' => [
				'singular_name' => 'Shop Category',
				'plural_name'   => 'Shop Categories',
				'post_type'     => [ 'shop' ],
			],
		];

		foreach ( $taxonomies as $tax => $args ) {
			$singular_name = ! empty( $args['singular_name'] ) ? $args['singular_name'] : ucwords( str_replace( '_', ' ', $tax ) );
			$plural_name   = ! empty( $args['plural_name'] ) ? $args['plural_name'] : $singular_name . 's';
			$hierarchical  = isset( $args['hierarchical'] ) ? $args['hierarchical'] : true;
			$rewrite       = ! empty( $args['rewrite'] ) ? $args['rewrite'] : [ 'slug' => str_replace( '_', '-', $tax ), 'with_front' => false ];
			$admin_column  = isset( $args['show_admin_column'] ) ? $args['show_admin_column'] : true;
			$post_type     = ! empty( $args['post_type'] ) ? $args['post_type'] : [ 'post' ];

			$labels = [
				'name'                       => $plural_name,
				'singular_name'              => $singular_name,
				'search_items'               => 'Search ' . $plural_name,
				'popular_items'              => 'Popular ' . $plural_name,
				'all_items'                  => 'All ' . $plural_name,
				'parent_item'                => 'Parent ' . $singular_name,
				'parent_item_colon'          => 'Parent ' . $singular_name . ':',
				'edit_item'                  => 'Edit ' . $singular_name,
				'view_item'                  => 'View ' . $singular_name,
				'update_item'                => 'Update ' . $singular_name,
				'add_new_item'               => 'Add New ' . $singular_name,
				'new_item_name'              => 'New ' . $singular_name . ' Name',
				'separate_items_with_commas' => 'Separate ' . $plural_name . ' with commas',
				'add_or_remove_items'        => 'Add or remove ' . $plural_name,
			];

			$args = [
				'labels'            => $labels,
				'public'            => true,
				'show_in_nav_menus' => true,
				'show_ui'           => true,
				'show_in_rest'      => true,
				'show_tagcloud'     => false,
				'hierarchical'      => $hierarchical,
				'rewrite'           => $rewrite,
				'query_var'         => true,
				'show_admin_column' => $admin_column,
			];

			register_taxonomy( $tax, $post_type, $args );
		}
	}

	/**
	 * Register the custom post type
	 */
	public function register_cpt() {

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

		$args = array(
			'labels'              => $labels,
			'hierarchical'        => false,
			'supports'            => array( 'title', 'thumbnail', 'genesis-cpt-archives-settings' ),
			'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' => 'shop', 'with_front' => false ),
			'menu_icon'           => 'dashicons-cart',
		);

		register_post_type( 'shop', $args );

	}

	/**
	 * Redirect Single Testimonials
	 *
	 * @since 1.2.0
	 */
	public function redirect_single() {
		if ( is_singular( 'shop' ) ) {
			$url = get_post_meta( get_the_ID(), 'be_shop_url', true );
			if ( empty( $url ) ) {
				$url = get_post_type_archive_link( 'shop' );
			}
			wp_redirect( esc_url( $url ) );
			exit;
		}
	}
}

/**
 * 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 be_cpt_shop() {
	return BE_CPT_Shop::instance();
}
be_cpt_shop();
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