Skip to content

Instantly share code, notes, and snippets.

@thefuxia
Last active August 4, 2017 21:09
Show Gist options
  • Save thefuxia/6034374 to your computer and use it in GitHub Desktop.
Save thefuxia/6034374 to your computer and use it in GitHub Desktop.
CPT with tax slug
<?php # -*- coding: utf-8 -*-
namespace CPTPermalinkDemo;
/**
* Plugin Name: Custom post type with taxonomy permalink
* Description:
* Plugin URI:
* Version: 2013.07.19
* Author: Thomas Scholz
* Author URI: http://toscho.de
* Licence: MIT
* License URI: http://opensource.org/licenses/MIT
* Textdomain:
* Domain Path: /languages
* Network:
*/
\add_action( 'init', array ( __NAMESPACE__ . '\Controller', 'init' ) );
class Controller {
protected $post_type = 'product';
protected $taxonomy = 'color';
public static function init()
{
static $instance = NULL;
if ( NULL === $instance )
$instance = new self;
return $instance;
}
protected function __construct()
{
$permalink = new Permalink( $this->post_type, $this->taxonomy );
\add_filter( 'post_type_link', array ( $permalink, 'filter_permalink' ), 10, 2 );
$post_type = new Post_Type( $this->post_type, $this->taxonomy );
$taxonomy = new Taxonomy( $this->taxonomy, $this->post_type );
}
}
class Post_Type
{
protected $taxonomy;
public function __construct( $post_type, $taxonomy )
{
$this->taxonomy = $taxonomy;
\register_post_type( $post_type, $this->get_args( $post_type ) );
}
protected function get_args( $post_type )
{
$u = \ucfirst( $post_type );
$l = \mb_strtolower( $post_type );
return array (
'can_export' => TRUE,
'description' => '',
'exclude_from_search' => FALSE,
'has_archive' => TRUE,
'hierarchical' => FALSE,
'labels' => array (
'add_new' => 'Add new',
'add_new_item' => "Add new $l",
'all_items' => "All {$l}s",
'edit_item' => "Edit $l",
'name' => $u . 's',
'name_admin_bar' => $u,
'new_item' => "New $l",
'not_found' => "No {$l}s found.",
'not_found_in_trash' => "No {$l}s in trash.",
'parent_item_colon' => "Parent $l:",
'search_items' => "Search {$l}s",
'singular_name' => $u,
'view_item' => "View $l"
),
//'map_meta_cap' => TRUE,
'menu_icon' => null,
'menu_position' => null,
'permalink_epmask' => EP_PERMALINK,
'public' => TRUE,
'publicly_queryable' => TRUE,
'query_var' => $l,
// Use a translated slug in pretty permalinks
'rewrite' => array (
//'slug' => $l,
'slug' => "%$this->taxonomy%",
'with_front' => FALSE
),
'show_in_nav_menus' => TRUE,
'show_in_menu' => TRUE,
'show_in_admin_bar' => TRUE,
'show_ui' => TRUE,
'supports' => array(
'author',
'comments',
'editor',
'excerpt',
'revisions',
'thumbnail',
'title',
),
);
}
}
@thefuxia
Copy link
Author

Unfortunately, GitHub cannot save the rest of the file as a Gist, so I had to put it into a comment.

class Taxonomy
{
    public function __construct( $taxonomy, $post_type )
    {
        \register_taxonomy( $taxonomy, array( $post_type ), $this->get_args( $taxonomy ) );
    }

    protected function get_args( $taxonomy )
    {
        $u = \ucfirst( $taxonomy );
        $l = \mb_strtolower( $taxonomy );
        return array(
            'hierarchical'          => TRUE,
            'public'                => TRUE,
            'query_var'             => $taxonomy,
            'rewrite'               => TRUE,
            'labels'                => array(
                'name'                       => $u . 's',
                'singular_name'              => $u,
                'search_items'               => "Search {$l}s",
                'popular_items'              => "Popular {$l}s",
                'all_items'                  => "All {$l}s",
                'parent_item'                => "Parent {$l}",
                'parent_item_colon'          => "Parent {$l}:",
                'edit_item'                  => "Edit $l",
                'view_item'                  => "View $l",
                'update_item'                => "Update $l",
                'add_new_item'               => "Add new $l",
                'new_item_name'              => "New $l name",
                'separate_items_with_commas' => "Separate {$l}s with commas",
                'add_or_remove_items'        => "Add or remove {$l}s",
                'choose_from_most_used'      => "Choose from the most used {$l}s",
            ),
            // make sure the oldest taxonomy will be used for the slug
            'sort'                  => TRUE,
            'show_admin_column'     => TRUE,
            'show_in_nav_menus'     => TRUE,
            'show_tagcloud'         => FALSE,
            'show_ui'               => TRUE,
            'update_count_callback' => '',
        );
    }
}

class Permalink
{
    protected $post_type;
    protected $taxonomy;

    public function __construct( $post_type, $taxonomy )
    {
        $this->post_type = $post_type;
        $this->taxonomy  = $taxonomy;
    }

    /**
     * Parse post link and replace the placeholder.
     *
     * @param   string $link
     * @param   object $post
     * @return  string
     */
    public function filter_permalink( $link, $post )
    {
        static $cache = array (); // Don't repeat yourself.

        if ( isset ( $cache[ $post->ID ] ) )
            return $cache[ $post->ID ];

        if ( $this->post_type !== $post->post_type )
        {
            echo "$this->post_type !== $post->post_type";
            $cache[ $post->ID ] = $link;
            return $link;
        }

        $cache[ $post->ID ] = $this->get_link_replacement( $link, $post );

        return $cache[ $post->ID ];
    }

    protected function get_link_replacement( $link, $post )
    {
        $term         = $this->get_post_term( $post->ID );
        $place_holder = "%$this->taxonomy%";

        if ( ! $term ) // insert a fallback value
            return \str_replace( $place_holder, $this->post_type, $link );

        return \str_replace( $place_holder, $term, $link );
    }

    /**
     * Get the slug of first assigned tag.
     *
     * Solution by Christopher Davis.
     * @link http://wordpress.stackexchange.com/a/72712
     *
     * @see   init()
     * @param int $id          Post ID
     * @return boolean|string  FALSE if no tags are found, the slug otherwise.
     */
    protected function get_post_term( $id )
    {
        $args = array ( 'orderby' => 'term_order' );
        $tags = \wp_get_object_terms( $id, $this->taxonomy, $args );

        if ( ! $tags )
            return FALSE;

        return \current( (array) $tags )->slug;
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment