如何在自定义帖子类型永久链接中添加自定义分类?

Posted

技术标签:

【中文标题】如何在自定义帖子类型永久链接中添加自定义分类?【英文标题】:How to add custom taxonomy in custom post type permalink? 【发布时间】:2020-01-05 23:53:12 【问题描述】:

我有一个名为 campaign 的自定义分类和一个名为 asset 的自定义帖子类型。对于资产,我希望具有以下永久链接结构:mysite.com/<campaign_name>/<asset_name>。我已经通过以下代码实现了这一点,但是现在如果我转到任何具有 url 结构 mysite.com/<pagename> 的普通页面,它会给出 404。当我注释掉用于注册自定义帖子类型的函数中的 rewrite slug 部分时,或者改为添加 ams/%campaign%,它可以工作,但这不是我想要的自定义帖子类型的 URL 结构。

自定义分类注册代码:

...
'rewrite' => array(
    'slug' => '',
    'with_front' => true,
),
...

自定义帖子类型注册代码:

...
rewrite' => array(
    'slug' => '%campaign%',
    'with_front' => true,
),
...

重写规则的功能:

function ams_asset_add_rewrite_rules( $rules ) 
    global $post;
    if ($post->post_type == 'asset' ) 
        $new = array();
        $new['([^/]+)/(.+)/?$'] = 'index.php?asset=$matches[2]';
        $new['(.+)/?$'] = 'index.php?campaign=$matches[1]';
        return array_merge( $new, $rules );
    
    return $rules;

add_filter( 'rewrite_rules_array', 'ams_asset_add_rewrite_rules' );

// Handle the '%campaign%' URL placeholder
function ams_asset_filter_post_type_link( $link, $post = 0 ) 
    if ( $post->post_type == 'asset' ) 
        $cats = wp_get_object_terms( $post->ID, 'campaign' );
        if ( $cats ) 
            $link = str_replace( '%campaign%', $cats[0]->slug, $link );
        
    
    return $link;

add_filter( 'post_type_link', 'ams_asset_filter_post_type_link', 10, 2 );

【问题讨论】:

【参考方案1】:

首先,注册您的分类,然后注册您的自定义帖子类型。您可能还需要保存您的永久链接。我认为您不希望将“with_front”设置为 true。其余的可能没问题,但这是一个工作示例。

/**
 * Register a 'campaign' taxonomy for post type 'asset'.
 *
 * @see register_post_type for registering post types.
 */
function wpdocs_create_campaign_tax_rewrite() 
    register_taxonomy( 'campaign', 'asset', array(
        'rewrite' => array(
            'slug' => '',
            'with_front' => false,
        ),
    ) );

add_action( 'init', 'wpdocs_create_campaign_tax_rewrite', 0 );


/**
 * Implements init_hook to register post type.
 * https://codex.wordpress.org/Function_Reference/register_post_type
 */
function generic_create_posttype_asset() 
    register_post_type(
        'asset',
        array(
            'labels'       => array(
                'name'          => __( 'Assets' ),
                'singular_name' => __( 'Assets' ),
                'add_new'       => __( 'New Asset' ),
                'add_new_item'  => __( 'New Asset' ),
                'edit_item'     => __( 'Edit Asset' ),
            ),
            'description'  => 'Campaign ...',
            'public'       => true,
            'hierarchical' => true,
            'has_archive'  => true,
            'rewrite' => array(
                'slug' => '%campaign%',
                'with_front' => false,
            ),
            'show_in_menu' => true,
            'menu_icon'    => 'dashicons-category', // https://developer.wordpress.org/resource/dashicons/ .
            'supports'     => array( 'title', 'editor', 'revisions', 'thumbnail' ),
        )
    );

add_action( 'init', 'generic_create_posttype_asset' );

/**
 * Rewrite '%campaign%' with taxonomy assigned.
 */
function asset_show_permalinks( $post_link, $post )
    if ( is_object( $post ) && $post->post_type == 'asset' )
        $terms = wp_get_object_terms( $post->ID, 'campaign' );
        if( $terms )
            return str_replace( '%campaign%' , $terms[0]->slug , $post_link );
        
     else 
            return $post_link;
    

add_filter( 'post_type_link', 'asset_show_permalinks', 1, 2 );

function generic_cpt_rewrite_flush() 
    generic_create_posttype_asset();
    flush_rewrite_rules();

register_activation_hook( __FILE__, 'generic_cpt_rewrite_flush' );

【讨论】:

您好,谢谢,但我以前尝试过。这适用于自定义帖子类型,但每当我转到一个页面时,它都会给出 404。 奇怪,它对我有用。您是否尝试转到设置 > 永久链接,然后保存永久链接?【参考方案2】:

首先,注册您的分类并将 rewrite 的 slug 参数设置为显示:

register_taxonomy(
    'campaign',
    'asset',
    array(
        'rewrite' => array( 'slug' => 'shows', 'with_front' => false ),
        // your other args...
    )
);

接下来,注册您的帖子类型并将 slug 设置为 shows/%show_category%,并将 has_archive 参数设置为 shows:

register_post_type(
    'show',
    array(
        'rewrite' => array( 'slug' => 'campaign/%asset%', 'with_front' => false ),
        'has_archive' => 'asset',
        // your other args...
    )
);

最后,为 post_type_link 添加一个过滤器,以替换单个节目永久链接中的节目类别:

function wpa_show_permalinks( $post_link, $post )
    if ( is_object( $post ) && $post->post_type == 'asset' )
        $terms = wp_get_object_terms( $post->ID, 'campaign' );
        if( $terms )
            return str_replace( '%campaign%' , $terms[0]->slug , $post_link );
        
    
    return $post_link;

add_filter( 'post_type_link', 'wpa_show_permalinks', 1, 2 );

【讨论】:

以上是关于如何在自定义帖子类型永久链接中添加自定义分类?的主要内容,如果未能解决你的问题,请参考以下文章

如何获取在 Wordpress 中按类别过滤的自定义帖子类型的永久链接?

Gatsby:在自定义帖子类型上使用 GraphQL 查询和自定义分类

php 在自定义帖子类型中显示所有自定义分类中的所有帖子。

使用特定标签在自定义帖子类型和分类中搜索

如何在自定义帖子类型UI菜单图标区域添加字体真棒图标?

将类别添加到永久链接时,WordPress CPT 会导致 404