我有一个自定义的帖子类型products
和一个带有slug的自定义分类“产品类别”products
.
My goal: 我正在尝试创建如下URL结构:
产品发布类型存档:products/
产品顶级类别存档:products/product-category
产品类别档案:products/product-category/product-sub-category
产品页面:products/product-category/product-sub-category/product-page
The problem:产品页面似乎只想使用实际类别。所以URL结构看起来像products/uncategorized/product-page
. 类别存档页不会维护cpt库。所以他们的结果是category/sub-category
.
What I\'ve tried: 无数的谷歌搜索,相当多的代码片段(我记得我将在下面介绍)、一些自定义函数和一些插件。没有用。
我有以下代码。
add_action( \'init\', \'products_cpt\', 0);
add_action( \'init\', \'register_taxonomies\', 0 );
//A custom post type for all products
function products_cpt(){
$labels = array(
\'name\' => _x(\'Products\', \'Post Type General Name\'),
\'singular_name\' => _x(\'Product\', \'Post Type Singluar Name\'),
\'menu_name\' => __(\'Products\'),
\'parent_item_colon\' => __(\'Parent Product\'),
\'all_items\' => __(\'All Products\'),
\'view_item\' => __(\'View Product\'),
\'add_new_item\' => __(\'Add New Product\'),
\'add_new\' => __(\'Add New\'),
\'edit_item\' => __(\'Edit Product\'),
\'update_item\' => __(\'Update Product\'),
\'search_items\' => __(\'Search Products\'),
\'not_found\' => __(\'Not Found\'),
\'not_found_in_trash\' => __(\'Not Found in Trash\')
);
$supports = array(
\'title\',
\'editor\',
\'excerpt\',
\'thumbnail\',
\'custom-fields\',
\'revisions\'
);
$args = array(
\'labels\' => $labels,
\'hierarchical\' => true,
\'public\' => true,
\'exclude_from_search\' => false,
\'show_in_admin_bar\' => true,
\'show_in_nav_menus\' => true,
\'publicly_queryable\' => true,
\'query_var\' => true,
\'taxonomies\' => array( \'chemicals\' ),
\'supports\' => $supports,
\'has_archive\' => \'products\'
);
register_post_type(\'products\', $args);
}
function register_taxonomies() {
$taxonomies = array(
\'products\' => array(
\'Product\',
\'Products\'
),
);
foreach($taxonomies as $slug => $name){
create_product_taxonomy($slug,$name[0],$name[1]);
}
}
function create_product_taxonomy($slug, $singular, $plural) {
$labels = array(
\'name\' => _x( $singular.\' Categories\', \'Taxonomy General Name\', \'text_domain\' ),
\'singular_name\' => _x( $singular.\' Category\', \'Taxonomy Singular Name\', \'text_domain\' ),
\'menu_name\' => __( $singular.\' Categories\', \'text_domain\' ),
\'all_items\' => __( \'All \'.$singular.\' Categories\', \'text_domain\' ),
\'parent_item\' => __( \'Parent \'.$singular.\' Category\', \'text_domain\' ),
\'parent_item_colon\' => __( \'Parent \'.$singular.\' Category:\', \'text_domain\' ),
\'new_item_name\' => __( \'New \'.$singular.\' Category Name\', \'text_domain\' ),
\'add_new_item\' => __( \'Add New \'.$singular.\' Category\', \'text_domain\' ),
\'edit_item\' => __( \'Edit \'.$singular.\' Category\', \'text_domain\' ),
\'update_item\' => __( \'Update \'.$singular.\' Category\', \'text_domain\' ),
\'view_item\' => __( \'View \'.$singular.\' Category\', \'text_domain\' ),
\'separate_items_with_commas\' => __( \'Separate \'.$singular.\' Categories with commas\', \'text_domain\' ),
\'add_or_remove_items\' => __( \'Add or remove \'.$singular.\' Categories\', \'text_domain\' ),
\'choose_from_most_used\' => __( \'Choose from the most used \'.$singular.\' Categories\', \'text_domain\' ),
\'popular_items\' => __( \'Popular \'.$singular.\' Categories\', \'text_domain\' ),
\'search_items\' => __( \'Search \'.$singular.\' Categories\', \'text_domain\' ),
\'not_found\' => __( \'Not Found\', \'text_domain\' ),
\'no_terms\' => __( \'No \'.$singular.\' Categories\', \'text_domain\' ),
\'items_list\' => __( $singular.\' Categories list\', \'text_domain\' ),
\'items_list_navigation\' => __( $singular.\' Categories list navigation\', \'text_domain\' ),
);
$args = array(
\'labels\' => $labels,
\'hierarchical\' => true,
\'public\' => true,
\'show_ui\' => true,
\'show_admin_column\' => true,
\'show_in_nav_menus\' => true,
\'show_tagcloud\' => true,
\'has_archive\' => $plural,
\'rewrite\' => array(
\'slug\' => \'products\',
\'with_front\' => true,
\'hierarchical\' => true
)
);
register_taxonomy( $slug, \'products\', $args );
}
首先,我将永久链接设置设置为:
接下来,我尝试添加以下代码,但它只适用于产品页面。产品类别档案仍为404\'d。
add_filter( \'post_type_link\', \'products_post_link\', 1, 3 );
function products_post_link( $post_link, $id = 0 ){
$post = get_post($id);
if ( is_object( $post ) ){
$terms = wp_get_object_terms( $post->ID, \'products_category\' );
$slug_url = \'\';
$last_id = 0;
if( $terms ){
foreach($terms as $term) {
if ($term === reset($terms)){
foreach($terms as $termInner){
if($termInner->term_id == 0){
$slug_url .= $termInner->slug.\'/\';
}
}
}elseif ($term === end($terms)){
foreach($terms as $termInner){
if($termInner->parent == $last_id){
$slug_url .= $termInner->slug;
$last_id = $termInner->term_id;
}
}
}else{
foreach($terms as $termInner){
if($termInner->parent == $last_id){
$slug_url .= $termInner->slug.\'/\';
$last_id = $termInner->term_id;
}
}
}
}
return str_replace( \'%category%\' , $slug_url , $post_link );
}
}
return $post_link;
}
这是CPT init函数的一部分:
\'rewrite\' => array(
\'slug\' => \'products/%category%\',
\'with_front\' => false,
\'hierarchical\' => true,
),
我还尝试了以下方法,不记得发生了什么,但我记得它不起作用:
add_action(\'init\', \'custom_resource_rewrite_rules\');
function custom_resource_rewrite_rules() {
add_rewrite_rule(\'products/([A-Za-z0-9\\-\\_]+)/?\', \'$matches[1]\', \'top\');
}
我还试着玩
term_link
滤器没有bueno。
最后,我尝试了以下插件,也没有成功。
Custom Permalinks
Permalinks Customizer
Custom Post Type Permalinks
有人能解决这个问题吗?我在拔头发。
最合适的回答,由SO网友:J Robz 整理而成
永远之后,我找到了答案!
第一:我们注册自定义帖子类型;自定义分类法:
add_action( \'init\', \'register_sps_products_post_type\' );
function register_sps_products_post_type() {
register_post_type( \'sps-product\',
array(
\'labels\' => array(
\'name\' => \'Products\',
\'menu_name\' => \'Product Manager\',
\'singular_name\' => \'Product\',
\'all_items\' => \'All Products\'
),
\'public\' => true,
\'publicly_queryable\' => true,
\'show_ui\' => true,
\'show_in_menu\' => true,
\'show_in_nav_menus\' => true,
\'supports\' => array( \'title\', \'editor\', \'author\', \'thumbnail\', \'comments\', \'post-formats\', \'revisions\' ),
\'hierarchical\' => false,
\'has_archive\' => \'products\',
\'taxonomies\' => array(\'product-category\'),
\'rewrite\' => array( \'slug\' => \'products/%product_category%\', \'hierarchical\' => true, \'with_front\' => false )
)
);
register_taxonomy( \'product-category\', array( \'sps-product\' ),
array(
\'labels\' => array(
\'name\' => \'Product Categories\',
\'menu_name\' => \'Product Categories\',
\'singular_name\' => \'Product Category\',
\'all_items\' => \'All Categories\'
),
\'public\' => true,
\'hierarchical\' => true,
\'show_ui\' => true,
\'rewrite\' => array( \'slug\' => \'products\', \'hierarchical\' => true, \'with_front\' => false ),
)
);
}
接下来,我们添加了一个新的重写规则,以便Wordpress知道如何解释新的permalink结构:
add_action( \'generate_rewrite_rules\', \'register_product_rewrite_rules\' );
function register_product_rewrite_rules( $wp_rewrite ) {
$new_rules = array(
\'products/([^/]+)/?$\' => \'index.php?product-category=\' . $wp_rewrite->preg_index( 1 ), // \'products/any-character/\'
\'products/([^/]+)/([^/]+)/?$\' => \'index.php?post_type=sps-product&product-category=\' . $wp_rewrite->preg_index( 1 ) . \'&sps-product=\' . $wp_rewrite->preg_index( 2 ), // \'products/any-character/post-slug/\'
\'products/([^/]+)/([^/]+)/page/(\\d{1,})/?$\' => \'index.php?post_type=sps-product&product-category=\' . $wp_rewrite->preg_index( 1 ) . \'&paged=\' . $wp_rewrite->preg_index( 3 ), // match paginated results for a sub-category archive
\'products/([^/]+)/([^/]+)/([^/]+)/?$\' => \'index.php?post_type=sps-product&product-category=\' . $wp_rewrite->preg_index( 2 ) . \'&sps-product=\' . $wp_rewrite->preg_index( 3 ), // \'products/any-character/sub-category/post-slug/\'
\'products/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$\' => \'index.php?post_type=sps-product&product-category=\' . $wp_rewrite->preg_index( 3 ) . \'&sps-product=\' . $wp_rewrite->preg_index( 4 ), // \'products/any-character/sub-category/sub-sub-category/post-slug/\'
);
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
另一方面,下一个函数修复了子类别的问题。问题本身在于,当您尝试加载URL为faq/category/child-category/的页面时,WordPress会尝试加载带有slug“child-category”的帖子,而不是带有slug“child-category”的子类别。
// A hacky way of adding support for flexible custom permalinks
// There is one case in which the rewrite rules from register_kb_rewrite_rules() fail:
// When you visit the archive page for a child section(for example: http://example.com/faq/category/child-category)
// The deal is that in this situation, the URL is parsed as a Knowledgebase post with slug "child-category" from the "category" section
function fix_product_subcategory_query($query) {
if ( isset( $query[\'post_type\'] ) && \'sps-product\' == $query[\'post_type\'] ) {
if ( isset( $query[\'sps-product\'] ) && $query[\'sps-product\'] && isset( $query[\'product-category\'] ) && $query[\'product-category\'] ) {
$query_old = $query;
// Check if this is a paginated result(like search results)
if ( \'page\' == $query[\'product-category\'] ) {
$query[\'paged\'] = $query[\'name\'];
unset( $query[\'product-category\'], $query[\'name\'], $query[\'sps-product\'] );
}
// Make it easier on the DB
$query[\'fields\'] = \'ids\';
$query[\'posts_per_page\'] = 1;
// See if we have results or not
$_query = new WP_Query( $query );
if ( ! $_query->posts ) {
$query = array( \'product-category\' => $query[\'sps-product\'] );
if ( isset( $query_old[\'product-category\'] ) && \'page\' == $query_old[\'product-category\'] ) {
$query[\'paged\'] = $query_old[\'name\'];
}
}
}
}
return $query;
}
add_filter( \'request\', \'fix_product_subcategory_query\', 10 );
此函数让WordPress知道如何在自定义帖子类型重写段塞结构中处理%product\\u category%:
function filter_post_type_link($link, $post)
{
if ($post->post_type != \'sps-product\')
return $link;
if ($cats = get_the_terms($post->ID, \'product-category\'))
{
$link = str_replace(\'%product_category%\', get_taxonomy_parents(array_pop($cats)->term_id, \'product-category\', false, \'/\', true), $link); // see custom function defined below\\
$link = str_replace(\'//\', \'/\', $link);
$link = str_replace(\'http:/\', \'http://\', $link);
}
return $link;
}
add_filter(\'post_type_link\', \'filter_post_type_link\', 10, 2);
基于的自定义函数
get_category_parents
. 它获取分类法的父项:
// my own function to do what get_category_parents does for other taxonomies
function get_taxonomy_parents($id, $taxonomy, $link = false, $separator = \'/\', $nicename = false, $visited = array()) {
$chain = \'\';
$parent = &get_term($id, $taxonomy);
if (is_wp_error($parent)) {
return $parent;
}
if ($nicename)
$name = $parent -> slug;
else
$name = $parent -> name;
if ($parent -> parent && ($parent -> parent != $parent -> term_id) && !in_array($parent -> parent, $visited)) {
$visited[] = $parent -> parent;
$chain .= get_taxonomy_parents($parent -> parent, $taxonomy, $link, $separator, $nicename, $visited);
}
if ($link) {
// nothing, can\'t get this working :(
} else
$chain .= $name . $separator;
return $chain;
}
来源:
SO网友:user1676224
实际上,这是一种可怕的做法。
如果在自定义帖子类型之前/之上注册分类法,则可以使用自定义帖子类型重写规则为分类法添加前缀。
例如:。
if ( ! function_exists( \'type_taxonomy\' ) ) {
// Register Custom Taxonomy
function type_taxonomy() {
$labels = array(
\'name\' => _x( \'Types\', \'Taxonomy General Name\', \'asw\' ),
\'singular_name\' => _x( \'Type\', \'Taxonomy Singular Name\', \'asw\' ),
);
$rewrite = array(
\'slug\' => \'update/type\',
\'with_front\' => false,
\'hierarchical\' => false,
);
$args = array(
\'labels\' => $labels,
\'hierarchical\' => true,
\'public\' => true,
\'show_ui\' => true,
\'show_admin_column\' => true,
\'show_in_nav_menus\' => true,
\'show_tagcloud\' => true,
\'rewrite\' => $rewrite,
\'show_in_rest\' => true,
);
register_taxonomy( \'type\', array( \'updates\' ), $args );
}
add_action( \'init\', \'type_taxonomy\', 0 );
}
if ( ! function_exists(\'updates_post_type\') ) {
// Register Custom Post Type
function updates_post_type() {
$labels = array(
\'name\' => _x( \'Updates\', \'Post Type General Name\', \'asw\' ),
\'singular_name\' => _x( \'Updates\', \'Post Type Singular Name\', \'asw\' ),
);
$rewrite = array(
\'slug\' => \'update\',
\'with_front\' => true,
\'pages\' => true,
\'feeds\' => true,
);
$args = array(
\'label\' => __( \'Updates\', \'asw\' ),
\'description\' => __( \'Posts should include important updates on health, well being and community\', \'asw\' ),
\'labels\' => $labels,
\'supports\' => array( \'title\', \'editor\', \'thumbnail\' ),
\'taxonomies\' => array( \'type\', \'category\', \'post_tag\', \'brands\', \'markets\' ),
\'hierarchical\' => false,
\'public\' => true,
\'show_ui\' => true,
\'show_in_menu\' => true,
\'menu_position\' => 5,
\'menu_icon\' => \'dashicons-heart\',
\'show_in_admin_bar\' => true,
\'show_in_nav_menus\' => true,
\'can_export\' => true,
\'has_archive\' => true,
\'exclude_from_search\' => false,
\'publicly_queryable\' => true,
\'rewrite\' => $rewrite,
\'capability_type\' => \'page\',
\'show_in_rest\' => true,
);
register_post_type( \'updates\', $args );
}
add_action( \'init\', \'updates_post_type\', 0 );
}