categories - Custom Post Type Category URL

admin2025-04-20  0

I've created a simple CPT named shop which contains some shop items. After that I've added category support to it which works fine ('taxonomies' => array( 'category' )). Then I created template-shop.php where I keep all my logic (I use template because I have multilingual support via polylang).

So lets say that currently my URL looks like: www.foo/shop

And now I want to "filter" my categories and I currently use the URL params to filter:

<?php 

  $current_url = strtok($_SERVER["REQUEST_URI"], '?');

  // if param category exists filter by it

  if (isset($_GET['category'])) {
    $category = $_GET['category'];

    $args = array (
      'post_type' => array( 'shop' ),
      'order' => 'ASC',
      'posts_per_page' => -1,
      'category_name' => $category
    );

  } else {

    $args = array (
      'post_type' => array( 'shop' ),
      'order' => 'ASC',
      'posts_per_page' => -1
    );

  }

  $shop = new WP_Query( $args );
?>

And it works fine

www.foo/shop/?category=bar
www.foo/shop/?category=baz
etc.

My question is - can I somehow "update" the logic so the URLs looks better? I'd wanted to for it to be:

www.foo/shop/category/bar
www.foo/shop/category/baz
etc.

Or something like that.

I've created a simple CPT named shop which contains some shop items. After that I've added category support to it which works fine ('taxonomies' => array( 'category' )). Then I created template-shop.php where I keep all my logic (I use template because I have multilingual support via polylang).

So lets say that currently my URL looks like: www.foo/shop

And now I want to "filter" my categories and I currently use the URL params to filter:

<?php 

  $current_url = strtok($_SERVER["REQUEST_URI"], '?');

  // if param category exists filter by it

  if (isset($_GET['category'])) {
    $category = $_GET['category'];

    $args = array (
      'post_type' => array( 'shop' ),
      'order' => 'ASC',
      'posts_per_page' => -1,
      'category_name' => $category
    );

  } else {

    $args = array (
      'post_type' => array( 'shop' ),
      'order' => 'ASC',
      'posts_per_page' => -1
    );

  }

  $shop = new WP_Query( $args );
?>

And it works fine

www.foo/shop/?category=bar
www.foo/shop/?category=baz
etc.

My question is - can I somehow "update" the logic so the URLs looks better? I'd wanted to for it to be:

www.foo/shop/category/bar
www.foo/shop/category/baz
etc.

Or something like that.

Share Improve this question asked Oct 1, 2019 at 15:28 VuckoVucko 1631 gold badge1 silver badge10 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

Option 1: Enable the post type archives and use a post type archive template.

  1. Enable the archives; e.g. when registering the post type using register_post_type():

    register_post_type( 'shop', [
        'has_archive' => 'shop', // the archives are accessible at example/shop
        // ...
    ] );
    
  2. Then create a custom archive template just for that post type; i.e. archive-shop.php.

  3. And you can use add_rewrite_rule() to rewrite example/shop/category/<category slug> to example/?category_name=<category slug>&post_type=shop:

    // This should be called in `init`.
    add_rewrite_rule(
        '^shop/category/([^/]+)/?$',
        'index.php?category_name=$matches[1]&post_type=shop',
        'top'
    );
    
  4. You'd need to use the pre_get_posts hook to filter the main WordPress query (since I could see you're using some custom query vars/values). But in the archive template, you wouldn't need the custom WP_Query query (i.e. $shop = new WP_Query).

Option 2: If you need to use a custom Page which displays posts in the custom post type.

And by "custom Page", I'm referring to a post having the type page. Also, the advantage of using this option is that you don't need to enable the default post type archives.

  1. So firstly, get the ID of the page which is using the custom template (template-shop.php).

  2. You'd use add_rewrite_rule() to rewrite example/shop/category/<category slug> to example/?shop_cat=<category slug>&page_id=<page ID>"shop_cat" can be changed to other non-reserved name, but you'll also need to change the name in step #3 & #4 below:

    // This should be called in `init`.
    add_rewrite_rule(
        '^shop/category/([^/]+)/?$',
        // Make sure to use the correct Page ID.
        'index.php?shop_cat=$matches[1]&page_id=2',
        'top'
    );
    
  3. You'd use the query_vars hook to add the shop_cat variable to the public WordPress query vars:

    add_filter( 'query_vars', function ( $vars ) {
        $vars[] = 'shop_cat';
        return $vars;
    } );
    
  4. In template-shop.php or wherever necessary, just call get_query_var( 'shop_cat' ) to retrieve the category slug from the URL:

    $args = array(
        'post_type'      => array( 'shop' ),
        'order'          => 'ASC',
        'posts_per_page' => -1,
    );
    
    if ( $category = get_query_var( 'shop_cat' ) ) {
        $args['category_name'] = $category;
    }
    
    $shop = new WP_Query( $args );
    

Last but not least, there are other variations to both the above options, but the ones I provided should help you get started.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1745114509a285783.html

最新回复(0)