10

I have a custom page which uses a template called "Stores" http://example.com/stores/. This page will have a list of states and/or companies as categories. For this system I have a custom post type "store" which can be assigned to a single category (either state or company),

Each store is not a specific page, but contact information which is displayed in a sort of phone-book style layout for states/companies.

The problem I have now is, how can I allow my "Stores" template accept URL requests from http://example.com/stores/california/ (without throwing 404 error)?

California in this sense is not a page, but a query. I also do not want to manually create a page for each of these categories (As it is pulled from database, and automatic). I could use ?state=california for this purpose, but I would like to learn the proper way to allow this URL within wordpress.

Is the correct way to edit htaccess file manually? Wouldn't that be overwritten if you edit the permalink structure? How would I format the htaccess?

4 Answers 4

17

Create a Page Template

Add a new page and give it the slug stores

Add A Public Query Variable

add_filter('query_vars', 'add_state_var', 0, 1);
function add_state_var($vars){
    $vars[] = 'state';
    return $vars;
}

Add a rewrite rule

This will direct your request to your stores page.

add_rewrite_rule('^stores/([^/]*)/?','index.php?post_type=page&name=stores&state=$matches[1]','top');

Within your Template

You can access your state variable as follows:

 $state = get_query_var('state');

Flush your Permalinks

Visit Settings->Permalinks to flush your permalinks and add your rewrite rule to the stack.

4
  • Sorry about the delay. This code is working, but there is a problem that I can't identify with the wiki. Now when I go to stores/alabama instead of getting a 404 page it correctly loads the Store page. But, it redirects me back to /stores/, and there is no sign of the query variable "state" (even dumped the $wp_query in my template, nothing about alabama). Why is it redirecting back to /state/? I flushed permalinks (thus the URL is still "working"). Sep 3, 2012 at 9:22
  • 1
    Update: If I remove post_type=page&name=stores then I arrive at the landing page, however the query variable "state" does exist. The redirect is removing the query var, although I am still not sure why specifying the post type is causing a redirect in the first place. Sep 3, 2012 at 9:42
  • The solution with 'post_type=page&name=stores' is not working for me either. Had to use the approach from Jareds solution with the page IDs.
    – Kevin
    Jun 7, 2017 at 9:36
  • If we make changes in permalinks, won't it affect all the URLs including other custom post types and pages which may not have that particular field? May 6, 2019 at 9:47
7

I found the answer on Wordpress' website and have tested the solution: https://codex.wordpress.org/Rewrite_API/add_rewrite_rule#Using_Custom_Templates_with_custom_querystring

Create a Page Template

Create a page template for stores and apply it to a page.

$stores = get_query_var('stores');

Add a Rewrite Tag

In your functions.php add a rewrite tag, which lets Wordpress know to look for the specific tag

function custom_rewrite_tag() {
  add_rewrite_tag('%stores%', '([^&]+)');
}
add_action('init', 'custom_rewrite_tag', 10, 0);

Add a Rewrite Rule

Now to format the URL and point it to the index.php with the vars, enter the following in your functions.php. Note: You have to update the page_id to the page_id of the stores page (it's 12 in this example).

  function custom_rewrite_rule() {
    add_rewrite_rule('^stores/([^/]*)/?','index.php?page_id=12&stores=$matches[1]','top');
  }
  add_action('init', 'custom_rewrite_rule', 10, 0);

From there you can browse to /stores/south-dakota/ and the $stores variable in your page template will be "south-dakota".

3

I was also trying to do the same and finally did it in following way.

Add the following code to your functions.php inside your theme.

add_filter('query_vars', 'add_state_var', 0, 1);
function add_state_var($vars){
    $vars[] = 'state';
    return $vars;
}

add_rewrite_rule('^stores/([^/]+)/?$','index.php?pagename=stores&state=$matches[1]','top');

Inside you template, get the query variable using this

$state = get_query_var('state');
0

Here is working example to manage dynamic slug and assign template for it:

Manage your custom endpoint or slug dynamically or define it in file

/** set rewrite rule for custom userlist-table */

$customendpoint = get_option('dynamic_slug_custom_endpoint');
 
add_action('init', 'setRewriteRule);

function setRewriterule() {
    add_rewrite_rule($customendpoint . '/?', 'index.php?' . $customendpoint . '=parent-xml-page', 'top');
}

/** Whitelist specifc query param * */

add_filter('query_vars', 'getQueryvar');

public function getQueryvar($query_vars) {
    $query_vars[] = $customendpoint;
    return $query_vars;
}

Include your custom template for that slug:

 /** Check query param and redirect it to template file * */

add_action('template_include',  'redirectTemplate');

function redirectTemplate($template) {

    if (get_query_var($customendpoint == false || get_query_var($customendpoint == '') {
        return $template;
    }

    return  'your-template.php';
}

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