1

I am trying to create custom end point for the custom taxonomy - 'species'

I am trying to use urls like

https://example.com/dogs/shop/
https://example.com/cats/shop/

https://example.com/dogs/services/
https://example.com/cats/services/

https://example.com/dogs/sales
https://example.com/cats/sales

where dogs, cats is taxonomy term

Following is the code

function my_register_my_taxes_species() {

    add_rewrite_endpoint( 'shop', EP_PAGES );

    add_rewrite_endpoint( 'services', EP_PAGES );

    add_rewrite_endpoint( 'sales', EP_PAGES );

    add_filter('request', function($vars) {
        if (isset($vars['shop'])) {
            $vars['shop'] = true;
        }
        if (isset($vars['services'])) {
            $vars['services'] = true;
        }

        if (isset($vars['sales'])) {
            $vars['sales'] = true;
        }          
        return $vars;
    });

    add_filter('template_include', function($template) {
        if (is_tax('species') && get_query_var('shop')) {
            $post = get_queried_object();
            $end_template = plugin_dir_path( __FILE__ ) . 'templates/shop.php';
            return $end_template;
        }
        if (is_tax('species') && get_query_var('services')) {
            $post = get_queried_object();
            $end_template = plugin_dir_path( __FILE__ ) . 'templates/services.php';
            return $end_template;
        }
        if (is_tax('species') && get_query_var('sales')) {
            $post = get_queried_object();
            $end_template = plugin_dir_path( __FILE__ ) . 'templates/sales.php';
            return $end_template;
        }
        return $template;
    });
    
    $args = [
        "label" => __( "Species", "hello-elementor-child" ),
        "public" => true,
        "publicly_queryable" => true,
        "hierarchical" => true,
        "rewrite" => [ 'slug' => 'species', 'with_front' => true,'ep_mask'=> EP_PAGES, 'hierarchical' => true ],
    ];
    register_taxonomy( "species", [ "job_listing", "product" ], $args );
}
add_action( 'init', 'my_register_my_taxes_species' );

This code above works fine upto one endpoint but not working for multiple endpoints like following

https://example.com/dogs/shop/prod-cat1
https://example.com/dogs/shop/prod-cat2
https://example.com/cats/shop/prod-cat1
https://example.com/cats/shop/prod-cat2

Uses template shop-cat.php & value of query variable i.e prod-cat1, prod-cat2 available on template

https://example.com/dogs/services/sr1
https://example.com/dogs/services/sr2 
https://example.com/cats/services/sr3
https://example.com/cats/services/sr4

Uses template services-cat.php & value of query variable i.e sr1, sr2 available on template

https://example.com/dogs/sales/sl1
https://example.com/dogs/sales/sl2
https://example.com/cats/sales/sl3
https://example.com/cats/sales/sl4

uses template sales-cat.php & value of query variable i.e sl1, sl2 available on template

How can I create multiple endpoints and the assign templates and use the query variables

6
  • Sounds like you are using WooCommerce in this mix?
    – Bazdin
    Jan 27, 2022 at 20:34
  • Yes Mark it is Woocommerce + wp job manager Jan 27, 2022 at 20:58
  • @SallyCJ I have been looking around and I found multiple answers by you related to this topic.. Will you please able to help me on this please Mar 1, 2022 at 23:54
  • 1
    I swear we get this question every week
    – Bysander
    Mar 7, 2022 at 12:51
  • 1
    @SallyCJ Yes you are right. Archive for this custom taxonomy was - /species/dogs but i wanted them like /dogs i.e without taxonomy slug.So I used a plugin to get rid of that. So to answer your question- Yes i need it like this /dogs/shop/ /dogs/services/ /dogs/sales/ till this where there is just one endpoint the code works but I need to be able to get the query variable of second end point /prod-cat1 in example.com/dogs/shop/prod-cat1 /sr1 in example.com/dogs/services/sr1 and assign templates accordingly Mar 8, 2022 at 21:58

1 Answer 1

2
+100

This code above works fine up to one endpoint but not working for multiple endpoints like following

https://example.com/dogs/shop/prod-cat1
https://example.com/dogs/shop/prod-cat2
https://example.com/cats/shop/prod-cat1
https://example.com/cats/shop/prod-cat2

Uses template shop-cat.php & value of query variable i.e prod-cat1, prod-cat2 available on template

Your request hook callback is always setting the query var to true, like so (for the shop var):

if (isset($vars['shop'])) {
    $vars['shop'] = true;
}

So instead of doing that, you can use this which sets the var to true only if it is empty(-ish):

if (isset($vars['shop']) && ! $vars['shop']) {
    $vars['shop'] = true;
}

So with that, at example.com/dogs/shop/, get_query_var( 'shop' ) would return true, whereas at example.com/dogs/shop/prod-cat1, you'd get prod-cat1.

And then now you could just use your own conditional to load different templates based on the query var value.

For example, in your template_include hook callback, replace the $end_template = ...; part with:

$filename = ( true === get_query_var( 'shop' ) ) ?
    // shop-cat.php is used if a custom value like prod-cat1 is set (in the URL)
    'shop.php' : 'shop-cat.php';

$end_template = plugin_dir_path( __FILE__ ) . "templates/$filename";

Just copy that and the above if for the other vars (sales and services), and replace shop with the correct var.

Alternate solution without having to modify the query var value.

  1. Remove the add_filter('request', function($vars) { ... }); from your code.

  2. Replace your entire template_include code with:

    add_filter( 'template_include', function ( $template ) {
        // Do nothing if we're not on a 'species' taxonomy/term archive page.
        if ( ! is_tax( 'species' ) ) {
            return $template;
        }
    
        // I used a `foreach` instead of 3 "if" blocks with identical code.
        foreach ( array( 'shop', 'sales', 'services' ) as $var ) {
            if ( isset( $GLOBALS['wp']->query_vars[ $var ] ) ) {
                // <var>-cat.php is used if a custom value like prod-cat1 is set (in the URL)
                $filename = get_query_var( $var ) ? "$var-cat.php" : "$var.php";
    
                return plugin_dir_path( __FILE__ ) . "templates/$filename";
            }
        }
    
        return $template;
    } );
    

So in the above code, if $GLOBALS['wp']->query_vars[ $var ] is set, then we change the template.

9
  • thanks a lot .. I will implement this code and get back to you if any issues Mar 9, 2022 at 22:53
  • So did it work?
    – Sally CJ
    Mar 12, 2022 at 7:10
  • Hey I am really sorry for the delayed response.. I tried it just now... it works well but it created issue on single post type .. for eg: for a single post with url like example.com/dogs/services/parent-service-1/child-parent-2/… This is supposed to use single-job_listing.php template but is using taxonomy-species.php Mar 13, 2022 at 18:38
  • If it works well, then I'd appreciate an upvote from you? And I don't know which "it"/code you've tried or are using now, but as for the (single) CPT permalink issue and with the 2nd snippet in my answer, try adding if ( false !== strpos( get_query_var( $var ), '/' ) ) { return $template; } right below the foreach ( array( 'shop', 'sales', 'services' ) as $var ) {.
    – Sally CJ
    Mar 14, 2022 at 0:26
  • Ofcouse. I was doing it to accept is as answerayways because it answers my question .. It is problem of my complex permalink struture.. SO I have voted it up and accepted answer but I hope you will help me get the fix Mar 14, 2022 at 0:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.