Wordpress Url Rewrite with Multiple Parameters and Templates - Dynamic Path/Parameter Placement - wordpress

We're having some trouble figuring out WP URL rewrite rules when we have tokens separated by parameters. Very briefly, we'd like to have the following common format for user pages and video libraries:
/users/steve/videos/2
...where "users" is the PHP page template that displays details on a user. So if we go to:
/users/steve/
...we see Steve's home page. If we go to:
/users/steve/videos/
...we hit the page template for the video library, and we see Steve's list of videos. And if we go to:
/users/steve/videos/2
...we hit a third page template, the video player page, where we see video id 2 displayed.
So we have three separate page templates, and we would like the child / parent relationship between them to be user page -> video library page -> video player page, for our breadcrumbs display.
The trick we can't figure out is that "steve" and "2" are really params inserted into the url, interrupting the parent/child token relationship. And second, for the video player, there really isn't a token there at all that maps to the video player page template. It's just the presence of the "videos" token plus the additional numerical parameter that tells us this maps to the video player page template.
As alternative, we've figured out how to get /users/videos/steve/2 working. We've added this rewrite rule to our child theme's functions.php file:
add_rewrite_rule(
'^users/videos/([^/]*)/([^/]*)/?',
'index.php?pagename=users/videos&users_filter_name=$matches[1]&user_video_id=$matches[2]',
'top');
(we've also defined the variables "users_filter_name" and "user_video_id" and we are successfully parsing them in the template)
But since what we really would like is /users/steve/videos/2 we tried updating the rule to:
add_rewrite_rule(
'^users/([^/]*)/videos/([^/]*)/?',
'index.php?pagename=users/videos&users_filter_name=$matches[1]&user_video_id=$matches[2]',
'top');
That didn't seem to work (it just loaded the '/users/' page) so we're obviously doing it incorrectly. Is what we want achievable with this structure?
Thanks!

The link structure of /users/steve/videos/2/ format is not a problem for Wordpress, and you actually wrote all the right code, but there is a small mistake somewhere.
Most likely you have a problem in the code section where you add new variables to query_vars.
Perhaps you are adding a second variable in too late action.
When Wordpress sees an obscure variable, it often behaves as you described.
Try removing all of your code and copy this to functions.php top
add_rewrite_rule(
'^users/([^/]*)/videos/([^/]*)/?',
'index.php?pagename=users/videos&users_filter_name=$matches[1]&user_video_id=$matches[2]',
'top');
add_filter( 'query_vars', function( $vars ){
$vars[] = 'users_filter_name';
$vars[] = 'user_video_id';
return $vars;
} );
If it doesn't work, try changing the code to this
add_rewrite_rule(
'^users/([^/]*)/videos/([^/]*)/?',
'index.php?page_id=54&users_filter_name=$matches[1]&user_video_id=$matches[2]',
'top');
add_filter( 'query_vars', function( $vars ){
$vars[] = 'users_filter_name';
$vars[] = 'user_video_id';
return $vars;
} );
Where 54 = your page ID
After each change you must go to the settings and turn off/on permalinks to reset the cache
I tested this code on my demo it works 100%.

Related

add_rewrite_rule not working when referencing child page name as matches

Is anyone able to comment why this does not work.
I have created a custom post type called "knowledge-hub". I also then created a page called "knowledge-hub" to act as the landing page for my CPT listings, which I show using code. On one of the CPT pages, "minimum-wage-policies", I want to be able to access a variable in the URL, e.g. ?some_var=xyz. But I want it friendly like /knowledge-hub/minimum-wage-policies/xyz.
So I have created rewrite URLs. The page name "minimum-wage-policies" will vary for many of the CPT pages, so I cant hard code this. I want to access it using a URL part.
But I cant get the add_rewrite_rule() to match matches[1] to the page name. If I hard code this page name in the add_rewrite_rule it works! But as soon as I replace it with matches[1] it does not work, its either a 404 or a redirect back to minimum-wage-policies with no variable on the end.
URL would be:
http://my-domain.com/knowledge-hub/minimum-wage-policies/some_var
Referencing the child page name works:
add_rewrite_rule(
'knowledge-hub/([^/]*)?/([^/]*)/?$',
'index.php?post_type=knowledge-hub&pagename=minimum-wage-policies&my_var=$matches[2]',
'top'
);
matches[2] is working in this case as I can see the value passed in the URL in my code.
But using matches[1] does not work and returns a 404:
add_rewrite_rule(
'knowledge-hub/([^/]*)?/([^/]*)/?$',
'index.php?post_type=knowledge-hub&pagename=$matches[1]&my_var=$matches[2]',
'top'
);
Visiting the WP URL http://my-domain.com/index.php?post_type=knowledge-hub&pagename=minimum-wage-policies&my_var=xyz works, so that structure is OK.
I have tried various regex expressions used by various others on the internet, so not just ([^/])?. So am not sure if it is to do with the regex and I just have not found the right one. I want to match anything. Same issue with (.)
I also have this:
function add_my_vars($vars)
{
$vars[] = 'my_var';
return $vars;
}
add_filter('query_vars', 'add_my_vars');
Update:
Using $request->matched_query I could see the URLs being called.
When I use pagename=minimum-wage-policies the URL is as expected:
post_type=knowledge-hub&pagename=minimum-wage-policies&my_var=xyz
When I use matches[1] is completely changed which is quite bizarre:
knowledge-hub=minimum-wage-policies%2Fxyz&page=
I managed to get it working with this rewrite_rule but I have not found this structure online so not sure if its technically correct but it works. Note the use of knowledge-hub=$matches[1]. This was discovered from viewing the $request->matched_query I mentioned was bizarre above. Replicating it in the rewrite_rule makes it work.
add_rewrite_rule(
'knowledge-hub/([^/]*)?/([^/]*)/?$',
'index.php?knowledge-hub=$matches[1]&my_var=$matches[2]',
'top'
);

Home page url rewriting Wordpress

I want to do a URL rewrite in the WordPress home page
I want to change my URL http://mysite.loc/?pays=senegal to look like http://mysite.loc/senegal.
The problem is that I am on the WordPress home page, so it will be confused with the URL of another page like http://transfert.loc/page-example.
I have already tried several optins but am completely blocked.
Here is my code example:
public function rewrite_urls(){
add_rewrite_tag( '%pays%','([^&]+)' );
add_rewrite_rule(
'([^/]+)',
'index.php?pays=$matches[1]',
'top'
);
}
Can someone help me please!
Thanks
Two problems I see- rewrite rules need to set query vars that will result in a successful main query. Setting just a custom var like slide doesn't parse to anything WordPress can load. Additionally, slide needs to be added to the recognized query vars for it to get parsed within a rule.
So, what would a rule look like that would load the front page posts in the main query? That's a good question- the posts page is a special case, the absence of any other query vars. I haven't found a way to do that with a rule, though it may exist.
An easier way to do this is with a rewrite endpoint:
function wpd_endpoint(){
add_rewrite_endpoint( 'page-example', EP_ROOT );
}
add_action( 'init', 'wpd_endpoint' );
Keep in mind that if you have code accessing values via $_GET, this still won't work, because WordPress doesn't put query vars there when rules are parsed. You can change the code to use get_query_var, or just assign it before the code tries to access it:
$_GET['page-example'] = get_query_var('page-example');

Make WordPress show the same page on two different url patterns

I need to make WordPress show the same page on two different URLs:
https://sitename.com/%postname%/
https://sitename.com/%postname%/tail/
* I can only use functions.php
I used a few similar cases and guides and here is code which worked out for me:
function tail_rewrite()
{
add_rewrite_rule('^([^/]*)/tail?', 'index.php?name=$matches[1]', 'top');
// first parameter for posts: p or name, for pages: page_id or pagename
}
add_action('init', 'tail_rewrite');
don't forget to flush the rules by visiting Settings > Permalinks
OR use flush_rewrite_rules() in the plugin activation (don't execute it at every page load).

Wordpress re write rule

Lets say I have a URI thats portfolio_categories/guttersspouting/
How could I rewrite a function to change it too "products"
ok as requested this matches the uri "product" exactly. This is not advisable if releasing code to a third party, as if they create a page called product, it will follow this rule.
Btw I am assuming you mean post_type = page (will also work for posts, see the post_id= in the add_rewrite_rule? You need to change this to the post id of the page you want to redirect to.
add_action('init', 'new_rewrite_rule');
function new_rewrite_rule(){
// matches product exactly, product/aproduct will fail, etc
// you need to add your own post_id into the function below.
add_rewrite_rule('^product$','index.php?page_id=12','top');
}
You will need to flush the rewrite rules for this to work (go to the permalinks setting page and just hit the save button)
code version of flush rewrite rules, not a good idea to have it running on wp_loaded, should be on a activation hook really but for testing this will do:
function new_flush_rewrite_rules() {
flush_rewrite_rules();
}
add_action( 'wp_loaded', 'new_flush_rewrite_rules' );
Just to note you can also do this manually in the post edit screen.

how to hide a page from being seen in wordpress backend and frontend

In my plugin i have created a custom template that prints a requested sidebar. and for running the code of this template i assigned a custom page to it (by calling update_metadata) .
Is it a good idea for getting content of a specific sidebar into Ajax call ?
Now my problem is that WORDPRESS shows it in the dashboard and front page , and after searching i have not found any easy to understand solution for Hiding a page completely so only can be accessed by its id .
Can any one tell me how to do that ?
you are going about this the wrong way. You can create a function that can create anything that can be created on a wordpress page.
But if you really must you can create a page outside of the database, etc:
add_action('init', 'add_rewrite_rule');
function add_rewrite_rule(){
// add_rewrite_rule(REGEX url, location, priority (i.e. top is before other rewrite rules)
// I created a custom post type for this plugin called market -- replace post_type with whatever you want
//basically tell wordress to add a query var if sidebar is added to url.
add_rewrite_rule('^sidebar?','index.php?is_sidebar_page=1&post_type=market','top');
}
// register a query var
add_action('query_vars','market_set_query_var');
function market_set_query_var($vars) {
array_push($vars, 'is_sidebar_page');
return $vars;
}
// associate a template with your quer_var
add_filter('template_include', 'market_include_template', 1000, 1);
function market_include_template($template){
if(get_query_var('is_sidebar_page')){
$new_template = (theme or plugin path).'/pages/yourpage.php'; // change this path to your file
if(file_exists($new_template))
$template = $new_template;
}
return $template;
}
This will not be a page that will be in the admin section or in any query that relates to pages but someone could of course navigate to this page. But as i said above you would be better to create a function to create your sidebar. If you want a seperate file to handle the "view" you use require_once 'filename'; a file and keep your functions area free of html.
If you are creating functions in a wordpress plugin dont forget many functions may not be available until later in the load process. Use add_action() if you run into any undefined functions
edit:
you are loading wordpress before you get to the template so you have all the functions. (google wp load for more info) + get_header() / get_footer() will also load a few things like css, etc. I had a small typo in the code above, fixed that but basically what you are doing is telling wordpress if someone lands on www.example.com/sidebar to apply a query_var (rewrite rule). Wordpress will look up its saved vars (final function) and return the template assoc. The 2nd function just registers the var.
You also have wp_functions in any file you create and include in a plugin, etc hence why you can create a file that does exactly the same as this page.

Resources