Here is some code I’ve cooked up based on some code I’ve already been working on. My original code works okay, however I haven’t tested this code because I haven’t seen your code. Here is what you need to do:
-
on your post type definition, set the
rewrite
argument to false -
Put the following code after your post type code:
//Create Permalink for news posts function wpse136458_create_permalink( $permalink, $post, $leavename, $sample ) { $rewritecode = array( '%year%', '%monthnum%', '%day%', '%hour%', '%minute%', '%second%', $leavename? '' : '%postname%', '%post_id%', '%category%', '%author%', $leavename? '' : '%pagename%', '%category-news%' //Add custom permalink tags here ); if ( '' != $permalink && !in_array($post->post_status, array('draft', 'pending', 'auto-draft')) ) { $unixtime = strtotime($post->post_date); $category = ''; if ( strpos($permalink, '%category%') !== false ) { $cats = get_the_category($post->ID); if ( $cats ) { usort($cats, '_usort_terms_by_ID'); // order by ID $category = $cats[0]->slug; if ( $parent = $cats[0]->parent ) $category = get_category_parents($parent, false, "https://wordpress.stackexchange.com/", true) . $category; } // show default category in permalinks, without // having to assign it explicitly if ( empty($category) ) { $default_category = get_category( get_option( 'default_category' ) ); $category = is_wp_error( $default_category ) ? '' : $default_category->slug; } } $author=""; if ( strpos($permalink, '%author%') !== false ) { $authordata = get_userdata($post->post_author); $author = $authordata->user_nicename; } $date = explode(" ",date('Y m d H i s', $unixtime)); $cat_news=""; if ( strpos($permalink, '%category-news%') !== false ) { $news_terms = wp_get_object_terms( $post->ID, 'category-news' ); if( $news_terms ) { $cat_news = $news_terms[0]->slug; } } //Enter permalink manipulations here $rewritereplace = array( $date[0], $date[1], $date[2], $date[3], $date[4], $date[5], $post->post_name, $post->ID, $category, $author, $post->post_name, $cat_news //Add custom tag replacements here ); $permalink = str_replace($rewritecode, $rewritereplace, $permalink); } return $permalink; } add_filter( 'post_type_link', 'wpse136458_create_permalink', 10, 4 ); //Helper functions function struct_to_query( $struct, $post_type_slug ) { global $wp_rewrite ; $querycode = array_merge( $wp_rewrite->queryreplace, array( 'paged=', 'feed=' ) ); $tagcode = array_merge( $wp_rewrite->rewritecode, array( '%paged%', '%feed%' ) ); $num_toks = preg_match_all('/%.+?%/', $struct, $toks); $tokens = $toks[0]; $query_result = str_replace( $tagcode, $querycode, $tokens ); $query_string = ''; foreach( $query_result as $index => $value ) $query_string .= '&' . $value . '$matches[' . (string)( (int) $index + 1 ). ']'; return 'index.php?post_type=" . $post_type_slug . $query_string; } function struct_to_regex( $struct ) { global $wp_rewrite ; $regexcode = array_merge( $wp_rewrite->rewritereplace, array( "([0-9]{1,})', '(feed|rdf|rss|rss2|atom)' ) ); $tagcode = array_merge( $wp_rewrite->rewritecode, array( '%paged%', '%feed%' ) ); return rtrim( str_replace( $tagcode, $regexcode, $struct ), "https://wordpress.stackexchange.com/" ) . '?/?$'; } function wpse136458_tax_regex( $taxonomy ) { $terms = get_terms( $taxonomy, array( 'hide_empty' => false ) ); $slugs = wp_list_pluck( $terms, 'slug' ); return '(' . implode( '|', $slugs) . ')'; } //Creates the complex rewrite rules function wpse136458_rewrite_api() { add_rewrite_tag( '%category-news%', wpse136458_tax_regex( 'category-news' ) ); $structs = array( '/news/%category-news%/%year/%monthnum%/%day%/page/%paged%/', '/news/%category-news%/%year/%monthnum%/%day%/feed/%feed%/', '/news/%category-news%/%year/%monthnum%/%day%/%feed%/', '/news/%category-news%/%year/%monthnum%/%day%/', '/news/%category-news%/%year/%monthnum%/page/%paged%/', '/news/%category-news%/%year/%monthnum%/feed/%feed%/', '/news/%category-news%/%year/%monthnum%/%feed%/', '/news/%category-news%/%year/%monthnum%/', '/news/%category-news%/%year/page/%paged%/', '/news/%category-news%/%year/feed/%feed%/', '/news/%category-news%/%year/%feed%/', '/news/%category-news%/%year/', '/news/%category-news%/page/%paged%/', '/news/%category-news%/feed/%feed%/', '/news/%category-news%/%feed%/', '/news/%category-news%/%postname%/', '/news/%category-news%/', '/news/%year/%monthnum%/%day%/page/%paged%/', '/news/%year/%monthnum%/%day%/feed/%feed%/', '/news/%year/%monthnum%/%day%/%feed%/', '/news/%year/%monthnum%/%day%/', '/news/%year/%monthnum%/page/%paged%/', '/news/%year/%monthnum%/feed/%feed%/', '/news/%year/%monthnum%/%feed%/', '/news/%year/%monthnum%/', '/news/%year/page/%paged%/', '/news/%year/feed/%feed%/', '/news/%year/%feed%/', '/news/%year/', '/news/page/%paged%/', '/news/feed/%feed%/', '/news/%feed%/', '/news/', ); foreach( $structs as $struct ) { add_rewrite_rule( struct_to_regex( $struct ), struct_to_query( $struct, 'news' ), 'top' ); } //This creates permalinks for news posts add_permastruct( 'news', 'news/%category-news%/%postname%/', array( 'walk_dirs' => false, 'endpoints'=>false ) ); } add_action( 'init', 'wpse136458_rewrite_api' ); //Flush rewrite rules when adding, removing or deleting terms // Taxonomy created add_action( 'created_category-news', 'flush_rewrite_rules' ); // Taxonomy edited add_action( 'edited_category-news', 'flush_rewrite_rules' ); // Taxonomy Deleted add_action( 'delete_category-news', 'flush_rewrite_rules' );
I’ll post an in depth explanation after work. Let me know if it works for you
EDIT: Okay, here is the basic rundown: wpse136458_rewrite_api
is the heart of how this works. It basically creates an array of permalink structures made from rewrite tags that follow the rules you specified, then creates the rewrite rules from those structures, using the helper functions struct_to_query
(creates the query string) and struct_to_regex
(creates the regex). The first line of the function, which I just added, creates a rewrite tag for your category-news
taxonomy and the last line that calls add_permastruct
creates a permastruct that WP uses for specific news
posts.
wpse136458_create_permalink
is a callback to the post-type_link
filter that takes that news
permalink and fills it in with the right data, like the category and the postname