admin管理员组

文章数量:1418083

I have a custom post type of news_archive and they are using WordPress Categories. I would like to get some archive pages for these categories with only the CPTs and not core Posts. I managed to come across this url, which does exactly what I want when tied with my custom archive page:

/stories/category/in-the-news/?post_type=archived_news/

Where stories is the blog post permalink set in Custom Structure on the Permalinks page.

What I'd like to do is turn that into

/news/category/in-the-news/

where news is the rewrite for archived_news posts

I was trying something like:

function category_cpt_rewrites() {
    $categories = array( 'in-the-news', 'press-release' );
    foreach ( $categories as $category ) {
        $rule    = '/stories/category/' . $category . '/?post_type=archived_news';
        $rewrite = '/archived_news/category/' . $category . '/';
        add_rewrite_rule( $rule, $rewrite, 'top' );
    }
}

add_action( 'init', 'category_cpt_rewrites' );

But I don't think I have the syntax right. Do I even have the right idea?

*edit Ok I got it working, sort. Had to swap the rule/rewrite values and then use the correct regex.

function category_cpt_rewrites() {
    $categories = array( 'in-the-news', 'press-release' );
    foreach ( $categories as $category ) {
        $rule    = '^news/category/([^/]*)/?';
        $rewrite = 'index.php?post_type=archived_news&category=' . $category;
        add_rewrite_rule( $rule, $rewrite, 'top' );
    }
}

add_action( 'init', 'category_cpt_rewrites' );

I'm still getting both categories displaying, but I think I'm close. However, now pagination doesn't work and I'm not sure why. /news/category/press-release/page/2/ returns the same posts as the first page but /stories/category/press-release/page/2/?post_type=archived_news gives me the next page of posts

I have a custom post type of news_archive and they are using WordPress Categories. I would like to get some archive pages for these categories with only the CPTs and not core Posts. I managed to come across this url, which does exactly what I want when tied with my custom archive page:

/stories/category/in-the-news/?post_type=archived_news/

Where stories is the blog post permalink set in Custom Structure on the Permalinks page.

What I'd like to do is turn that into

/news/category/in-the-news/

where news is the rewrite for archived_news posts

I was trying something like:

function category_cpt_rewrites() {
    $categories = array( 'in-the-news', 'press-release' );
    foreach ( $categories as $category ) {
        $rule    = '/stories/category/' . $category . '/?post_type=archived_news';
        $rewrite = '/archived_news/category/' . $category . '/';
        add_rewrite_rule( $rule, $rewrite, 'top' );
    }
}

add_action( 'init', 'category_cpt_rewrites' );

But I don't think I have the syntax right. Do I even have the right idea?

*edit Ok I got it working, sort. Had to swap the rule/rewrite values and then use the correct regex.

function category_cpt_rewrites() {
    $categories = array( 'in-the-news', 'press-release' );
    foreach ( $categories as $category ) {
        $rule    = '^news/category/([^/]*)/?';
        $rewrite = 'index.php?post_type=archived_news&category=' . $category;
        add_rewrite_rule( $rule, $rewrite, 'top' );
    }
}

add_action( 'init', 'category_cpt_rewrites' );

I'm still getting both categories displaying, but I think I'm close. However, now pagination doesn't work and I'm not sure why. /news/category/press-release/page/2/ returns the same posts as the first page but /stories/category/press-release/page/2/?post_type=archived_news gives me the next page of posts

Share Improve this question edited Jul 30, 2019 at 19:57 zfors asked Jul 30, 2019 at 17:54 zforszfors 17911 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

You want display posts of a given type ({post_type}) from category ({term}) and structure of link should looks like this:

{post_type} / category / {term}

To avoid collisions with links to pages and "blog" posts, expression can not start with ([^/]+), but should contain slug of post type entered explicitly. This means a separate rule for each custom post type.

$regex = '^news/category/(.+?)/?$';

For the above expression, the $redirect should contain category_name and post_type parameters:

$redirect = 'index.php?category_name=$matches[1]&post_type=news';

And in case of a custom taxonomy (^news/custom_tax_slug/(.+?)/?$):

$redirect = 'index.php?CUSTOM_TAX_SLUG=$matches[1]&taxonomy=CUSTOM_TAX_SLUG&post_type=news';

To handle pagination you need another rule, which is an extended version of the above one.

$regex = '^news/category/(.+?)/page/?([0-9]{1,})/?$';
$redirect = 'index.php?category_name=$matches[1]&post_type=news&paged=$matches[2]';

All together:

function category_cpt_rewrites()
{
    add_rewrite_rule( '^news/category/(.+?)/page/?([0-9]{1,})/?$',
        'index.php?category_name=$matches[1]&post_type=news&paged=$matches[2]',
        'top'
    );
    add_rewrite_rule( '^news/category/(.+?)/?$',
        'index.php?category_name=$matches[1]&post_type=news',
        'top'
    );
}

Or:

function category_cpt_rewrites()
{
    $post_types = [ 'news' ];
    foreach ( $post_types as $cpt )
    {
        add_rewrite_rule( '^'. $cpt .'/category/(.+?)/page/?([0-9]{1,})/?$',
            'index.php?category_name=$matches[1]&post_type='. $cpt .'&paged=$matches[2]',
            'top'
        );
        add_rewrite_rule( '^'. $cpt .'/category/(.+?)/?$',
            'index.php?category_name=$matches[1]&post_type=' . $cpt,
            'top'
        );
    }
}

本文标签: custom post typesCPT Archive with core Category