Last active
February 16, 2018 14:36
-
-
Save kjbenk/89d05d337c9d523c9e9070d56a3c3e18 to your computer and use it in GitHub Desktop.
WordPress: Post Permalink using primary category
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Alters the default post permalink structure to be: | |
* | |
* `/{primary-category}/{post-slug}/` | |
*/ | |
/** | |
* The Primary_Category_Post_URL class. | |
*/ | |
class Primary_Category_Post_URL { | |
/** | |
* The permalink structure. | |
* | |
* @var string | |
*/ | |
public $permalink_structure = '/%primary_category%/%postname%/'; | |
/** | |
* Existing instance. | |
* | |
* @var array | |
*/ | |
protected static $instance; | |
/** | |
* Get class instance. | |
* | |
* @return object | |
*/ | |
public static function instance() { | |
if ( ! isset( static::$instance ) ) { | |
static::$instance = new static(); | |
static::$instance->setup(); | |
} | |
return static::$instance; | |
} | |
/** | |
* Setup the singleton. | |
*/ | |
public function setup() { | |
// Set the main permalink structures. | |
if ( function_exists( 'wpcom_vip_load_permastruct' ) ) { | |
wpcom_vip_load_permastruct( $this->permalink_structure ); | |
} else { | |
add_filter( 'init', function() { | |
global $wp_rewrite; | |
$wp_rewrite->set_permalink_structure( $this->permalink_structure ); | |
} ); | |
} | |
// Add rewrite tags. | |
add_action( 'init', [ $this, 'add_rewrite_tags' ] ); | |
// Update post permalinks. | |
add_filter( 'post_link', [ $this, 'custom_permalink' ], 10, 2 ); | |
add_filter( 'post_type_link', [ $this, 'custom_permalink' ], 10, 2 ); | |
// Filter the post rewrite rules to account for our custom permalink. | |
add_filter( 'post_rewrite_rules', [ $this, 'generate_post_rewrite_rules' ] ); | |
// Add the primary category field. | |
add_action( 'fm_post_post', [ $this, 'add_fields' ] ); | |
} | |
/** | |
* Add the custom rewrite tags. | |
*/ | |
public function add_rewrite_tags() { | |
add_rewrite_tag( '%primary_category%', '([^/]+)' ); | |
} | |
/** | |
* Replace the wildcard url structure with the correct content | |
* | |
* @param string $url The current URL. | |
* @param \WP_Post $post The post object. | |
* @return string $url The new URL. | |
*/ | |
public function custom_permalink( $url, $post ) { | |
/** | |
* Filter the array of applicable post types. | |
* | |
* @param array $post_types The array of applicable post types. | |
* @return array $post_types The array of applicable post types. | |
*/ | |
$applicable_post_types = apply_filters( | |
'custom_permalink_applicable_post_types', | |
[ 'post' ] | |
); | |
if ( $post instanceof \WP_Post && in_array( $post->post_type, $applicable_post_types, true ) ) { | |
$primary_category_id = get_post_meta( $post->ID, 'primary_category', true ); | |
if ( ! empty( $primary_category_id ) ) { | |
$primary_category = get_term( $primary_category_id ); | |
if ( ! empty( $primary_category->slug ) ) { | |
$url = str_replace( '%primary_category%', $primary_category->slug, $url ); | |
} | |
} | |
} | |
return $url; | |
} | |
/** | |
* Since we are using a custom permalink structure for this site we wanted to | |
* make sure that its value was correct at all times, which is why we use | |
* `wpcom_vip_load_permastruct( '/%primary_category%/%postname%/' )` in the | |
* `setup()` function. This will then create new rewrite rules where walk_dirs | |
* is true which is something that we do not want to do. | |
* | |
* This function will add the correct post rewrite rules with walk_dirs false, | |
* and filter only runs when the rewrite rules are created or on `flush_rewrite_rules()`. | |
* | |
* @param \WP_Rewrite $post_rewrite Current WP_Rewrite instance, passed by reference. | |
*/ | |
public function generate_post_rewrite_rules( $post_rewrite ) { | |
global $wp_rewrite; | |
return $wp_rewrite->generate_rewrite_rules( $this->permalink_structure, EP_PERMALINK, true, true, false, false ); | |
} | |
/** | |
* Add the Primary Category FM field. | |
*/ | |
public function add_fields() { | |
$fm = new \Fieldmanager_Select( [ | |
'attributes' => array( | |
'style' => 'width: 95%', | |
), | |
'remove_default_meta_boxes' => false, | |
'name' => 'primary_category', | |
'limit' => 1, | |
'first_empty' => true, | |
'description' => __( '(Required) Used as the first level of the post URL.' ), | |
'validation_rules' => 'required', | |
'validation_messages' => __( 'Please select a Primary Category' ), | |
'datasource' => new \Fieldmanager_Datasource_Term( [ | |
'taxonomy' => 'category', | |
'only_save_to_taxonomy' => false, | |
'append_taxonomy' => true, | |
] ), | |
] ); | |
$fm->add_meta_box( __( 'Primary Category' ), [ 'post' ], 'side' ); | |
} | |
} | |
/** | |
* Get the singleton instance. | |
* | |
* @return Primary_Category_Post_URL | |
*/ | |
function primary_category_post_url() { | |
return Primary_Category_Post_URL::instance(); | |
} | |
add_action( 'after_setup_theme', 'primary_category_post_url' ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment