I'm trying to make an XML feed show nice and pretty permalinks rather than showing query strings. The problem is I can't get my /products/ endpoint to show up when trying to process my custom rewrite template tag. Here's what I have:

/** Register Query Vars **/
function theme_custom_query_vars( $vars ){
    $vars[] = 'custom_category';
    $vars[] = 'products';
    return $vars;
add_filter( 'query_vars', 'theme_custom_query_vars' );

/** Register Endpoint **/
function theme_register_endpoints() {
    add_rewrite_rule( '^products/?', 'index.php?products=products', 'top' );
    add_rewrite_rule( '^products/([^/])/?', 'index.php?products=products&custom_category=$matches[2]', 'top' );

    add_rewrite_tag( '%custom_category%', '([0-9])' );
add_action( 'init', 'theme_register_endpoints' );

That's fine - my products endpoint exists and I can redirect it to a specific template. Now the issue is that while wp_query knows that custom_category exists and has a value assigned to it, the passed $permalink only shows my base URL ( http://domain.com/ ) so I cannot replace the template tag since it doesn't exist in my $permalink variable.

/** Process our Rewrite Tag **/
function theme_rewrite_tags_filter( $permalink ) {
    global $wp_query;
    printf( '<pre>%s</pre>', print_r( $wp_query, 1 ) );
    die( $permalink );

    if( false !== strpos( $permalink, '%custom_category%' ) ) {
        die( 'made it!' );

    return $permalink;
add_filter( 'page_link', 'theme_rewrite_tags_filter' );

I gotta be missing something in regards to template tags or maybe I have a misunderstanding of how endpoints are structured but the $permalink just isn't showing the products endpoint or the %custom_category% template tag:

The Situation

I'm working with an external API that gives me an XML feed of items and categories. The API works with category IDs and returns items in that category. What I'm trying to do is the following:

  • Make an endpoint products which shows all the available categories: domain.com/products/
  • Make a dynamic endpoint that passes the category ID via query string ?custom_category=2 and rewrites it into a pretty permalink like domain.com/products/categoryname/ - I don't know the category names so I need to ask the API the category name by the given ID.
  • Finally, in a similar fashion as above I need to take a given item ID via query string item_id=17 and rewrite it into a pretty permalink of which I'm not picky: domain.com/products/productname/ or domain.com/products/categoryname/productname/ - I don't know the item names so I need to ask the API the item name by the given ID.

I have to use IDs in links because the API is old and doesn't understand slugs ( so I can't pass my API a slug and expect results I need to pass an ID of some kind ) but I was hoping to grab the ID from the query string, hit the API to get the name, make it URL friendly and put it into the URL.

1 Answer 1


Rewrite tags aren't used in the context of add_rewrite_rule. If you were to use your tag in the post permalink settings under Settings > Permalinks, then your tag would be present in the link passed to the post_link filter. I think you need to add a new permalink structure containing the tag directly to the rewrite object to have a custom tag in there. As it stands, it's redundant since you're already adding query vars (which add_rewrite_tag also does). Also note that in your 2nd rule, the value of custom_category is in $matches[1]. For your page_link filter, you can use the 2nd argument passed to the filter, which is the page object, to check if that page has a custom_category and build the permalink you need in that case.

  • The post_link filter doesn't seem to "catch" my hook and kill the page like page_link does for some reason, I keep seeing post_link in the tutorials but it doesn't seem to work in this context. The issue with the $post object is that page_link doens't pass an object but an int post_id and even so, the actual page doesn't exist, I just need to process the given query val, return a nice string from an API I'm using then display a custom template accordingly. I'm not sure what you mean by I think you need to add a new permalink structure containing the tag... can you elaborate?
    – Howdy_McGee
    Nov 17, 2015 at 22:33
  • Also, I tried adding the template tag into my permalinks /%custom_category%/postname/ but it didn't seem to make a difference in the output of the filter, wp_query or the permalink. Thanks for giving it some thought though!
    – Howdy_McGee
    Nov 17, 2015 at 22:36
  • I meant if you used a rewrite tag within the post permalink settings, you should see that tag within the post_link filter. You don't see a tag in the page_link filter because nothing is inserting that tag anywhere, that's not what add_rewrite_rule does. New permalink structures can be added via add_permastruct, where I believe you can use rewrite tags, which then in turn generates rewrite rules. I'm not really understanding the context in which you're using the page_link filter.
    – Milo
    Nov 17, 2015 at 22:42
  • Honestly, I don't think the page_link filter is the correct filter I need to get the job done so I am probably using it in a poor context. post_link doesn't seem to work with the endpoint products though either since it's not killing the page with the die() at the top. So I have an imaginary page products in which I need to catch, process, and rewrite an additional query value. I'm looking into add_permastruct() now though to see if I can get somewhere with that, thanks for the suggestion.
    – Howdy_McGee
    Nov 17, 2015 at 22:57
  • sorry, post_link isn't relevant in your case, I was just pointing out a situation where add_rewrite_tag would be useful, for adding tags that you can use in the default post permalink structure. if you can back up a few steps and explain in more detail in your question what you're trying to do, I can maybe offer more help!
    – Milo
    Nov 18, 2015 at 3:59

Your Answer

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

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