I have links in my site that pass queries to pages that query from an external database. This works fine e.g.
mysite.com/catalog/?tl=flooring
however i want to rewrite this url to appear as
mysite.com/catalog/flooring
Ive tried modifying the rewrite rules in wordpress but it always displays the index page
add_filter('rewrite_rules_array','wp_insertMyRewriteRules');
add_filter('query_vars','wp_insertMyRewriteQueryVars');
add_filter('init','flushRules');
// Remember to flush_rules() when adding rules
function flushRules(){
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
// Adding a new rule
function wp_insertMyRewriteRules($rules)
{
$newrules = array();
$newrules['(catalog)/([a-zA-Z0-9 ]+)$'] = '/catalog/?tl=$matches[2]';
return $newrules + $rules;
}
// Adding the id var so that WP recognizes it
function wp_insertMyRewriteQueryVars($vars)
{
array_push($vars, 'id');
return $vars;
}
Rewrite rules in WordPress don't quite work like how you're expecting them to. All rewrite rules map to a file handler (almost always index.php), not another URL.
Here is a shortened code example;
$rules['catalog/(.*)/?'] = 'index.php?pagename=catalog&tl=$matches[1]';
array_push($query_vars, 'tl'); // note query var should match your query string
This would map catalog/whatever to the WordPress page 'catalog', and pass along the query var 'tl'. You could create a page template for 'catalog', then pick up the value of 'tl' using get_query_var('tl').
Also avoid using query vars like id - use something more unique (like 'tl') to avoid clashes with WordPress.
And don't flush rules on every init! It's bad practice, and will write to .htaccess and call database updates on every page load!
WordPress will always flush permalinks whenever you update a post or your permalink structure (simply update your permalinks when you make changes to your code).
This article over at Raazorlight goes into a bit more detail on the process of grabbing querystrings and URL rewriting in WP.
Also, check the comments there to see why calling flushRules() may not be necessary if you re-save permalinks. Optionally, flushRules() can be called just once during plugin activation callback.
Digging deeper, commenter 'pmdci' links over to an instructive post/saga on the related topic of passing a query to a custom post type using a custom taxonomy.
Related
I build a Wordpress website with a page called 'Nieuwsberichten'.
The url looks like
https://www.example.com/nieuwsberichten
This page is dynamic and I need an extra parameter called 'news_page'
https://www.example.com/nieuwsberichten/?news_page=recent
The URL above is not friendly so I create a rewrite rule for this and I add the variable 'news_page'.
functions.php
function add_query_vars($vars){
$vars[] = 'news_page';
return $vars;
}
add_filter( 'query_vars', 'add_query_vars', 10, 1 );
function rewrite_paged(){
add_rewrite_rule('^nieuwsberichten/([0-9]+)/?', 'nieuwsberichten?news_page=$matches[1]', 'top');
}
add_action('init', 'rewrite_paged');
After this I flushed the permalinks
menu -> settings -> permalinks -> save
If I browse to
https://www.example.com/nieuwsberichten/recent/
It will redirect to
https://www.example.com/nieuwsberichten/
What do I miss in my code?
Hope somebody can help me with this
In the regex part, you specify an entry for numbers only, but you pass text like recent in your url. Maybe the error is here. Please check if it works with number input, edit your expression if that's the problem. Also, the url structure you specified does not seem to be quite correct.
Anyway, I'm not sure of my answer so I'd appreciate it if you could confirm after checking.
https://developer.wordpress.org/reference/functions/add_rewrite_tag/
This may be the function you should use for the parameters you add. This function will also not require the query_var function. So I think you won't need to use the other function.
I'm not in a position to check or test right now. If your problem is not solved, I will look into it in detail.
You can use it like this:
function rewrite_paged(){
add_rewrite_tag('%news_page%', '([^/]+)');
add_rewrite_rule('^nieuwsberichten/?([^/]*)$', 'nieuwsberichten?news_page=$matches[1]', 'top');
}
add_action('init', 'rewrite_paged');
Also if you are pointing to a page you will need to use page id or pagename. A blog or a product etc. If it is, there will still be parameters you need to use and you should redirect this url to index.php. I'm leaving an example for you to understand what I'm saying, and for your review, you can take a look at the rewrites on your site as follows:
Review examples:
global $wp_rewrite;
print_r($wp_rewrite);
Examples:
Match Pagename:
add_rewrite_rule('^nieuwsberichten/?([^/]*)$', 'index.php?pagename=nieuwsberichten&news_page=$matches[1]', 'top');
Match Page ID:
add_rewrite_rule('^nieuwsberichten/?([^/]*)$', 'index.php?page_id=10000&news_page=$matches[1]', 'top');
If you have an installation outside of wordpress your example is correct but if it will be inside wordpress all requests should be directed to index.php. Therefore, you may need to edit the code I have given like these examples.
I have a page called 'all-products' on Wordpress, and I want to get products using id in the url as domain.com/all-products/4382zcxs2133
function add_my_var($public_query_vars) {
$public_query_vars[] = 'routeparam';
return $public_query_vars;
}
add_filter('query_vars', 'add_my_var');
function do_rewrite() {
add_rewrite_rule('all-products/[a-zA-Z0-9]/?$', 'index.php?pagename=all-products&routeparam=$matches[1]','top');
}
add_action('init', 'do_rewrite');
Then, when I tried using $wp_query->query_vars['routeparam'], it says 'undefined index'.
When I var_dump($wp_query->query_vars), I can actually see the value in an index called page but that only works for numbers. If I use letters and numbers instead, I get 404 error.
Edit:
/all-products/213213 - works
/all-products/ - works
/all-products/21321dsa3fsa - doesn't work
I tried the regex on a fiddle, it works, but on Wordpress in add_rewrite_rule, it doesn't work. Here is the fiddle
Edit 2:
I've commented out my write rule line, and it looks like it can still access product/123 so somehow, my rewrite rule is not registering.
I tried var_dump($wp_rewrite) and I can confirm that my rewrite rule is registered but I believe that default wordpress pagination ('pagination_base' exactly) may cause this.
Because when I comment out add write rule and visit the url through /all-products/123, I can still access the page without a 404 and I can see that '123' value I have provided is shown as 'page' in $wp_query->query_vars.
You can use
'products(?:/([a-zA-Z0-9]+))?/?$'
or if this part is always at the beginning, add ^:
'^products(?:/([a-zA-Z0-9]+))?/?$'
Note the + and (...) parentheses around [a-zA-Z0-9]+ that form Group 1 and its value will be used via $matches[1].
And Do not forget to flush and regenerate the rewrite rules database after modifying rules. From WordPress Administration Screens, Select Settings -> Permalinks and just click Save Changes without any changes..
I'm want to redirect a custom URL same like example in docs here
EX: http://domain.com/find/324 to http://domain.com/?text=324
This is the code , for some reason it keeps redirect me to homepage without the parameter "text" in the URL..
function custom_rewrite_basic() {
add_rewrite_rule('find/(.+)/?', 'index.php?text=$matches[1]', 'top');
}
add_action('init', 'custom_rewrite_basic');
The "text" parameter is not a build in WoprPress function, i'm going to use it with custom code of mine.
I flushed that links cache, still redirects to homepage without the parameters.
What i'm missing?
You cannot add custom query vars directly. Custom query vars have to be added using the query_vars filter to be parsed within rules. You can add custom query vars as seen below.
function wpd_add_query_vars( $qvars ) {
$qvars[] = 'text'; //I used the one in your example
return $qvars;
}
add_filter( 'query_vars', 'wpd_add_query_vars' );
Then you get get the query vars like this:
get_query_var('text')
check https://wordpress.stackexchange.com/questions/271931/add-rewrite-rule-parameter-is-not-received-by-the-page?rq=1 for more detail.
I've been looking for hours trying to find a straightforward answer to this but I just can't seem to find anything out there which tackles this issue. There are numerous examples for rewriting standard URLs, but nothing in-terms of rewriting pages from within a custom plugin.
I've created a custom plugin with a special directory in it called test. The test directory has several pages which are blah.php and shmeh.php. Is it possible to create rewrite rules to these pages i.e. http://example.com/blah, http://example.com/shmeh
Thank you very much for all the help.
So essentially what you are looking for, is to have Wordpress load a specific page template (blah.php) when the user visits http://example.com/blah/. Also, you need it to to be completely generated in your plug-in without actually creating any pages or posts. You are on the right track. What you want to do here is create a rewrite rule that utilizes a specific query var to load the page. Here it is step by step:
Step 1: Rewrite rules
http://codex.wordpress.org/Function_Reference/add_action
http://codex.wordpress.org/Plugin_API/Action_Reference/init
http://codex.wordpress.org/Rewrite_API/add_rewrite_rule
/* Rewrite Rules */
add_action('init', 'yourpluginname_rewrite_rules');
function yourpluginname_rewrite_rules() {
add_rewrite_rule( 'blah/?$', 'index.php?blah=true', 'top' );
}
So in the above code, your just telling Wordpress that example.com/blah/ should be treated as if the user were visiting example.com/index.php?blah=true. Now "blah" is a query var that you will set up in the next function below. Query vars are just what Wordpress calls $_GET variables. However they must be registered with Wordpress so it can properly store the value (which is "true" in this case). We will do that below in the next function. It's also worth noting the third setting in the function "top", which gives this rewrite rule priority over other rewrite rules. Alternatively, setting it to "bottom" would check that no other rewrite rules match first before using this one.
Step 2: Query Vars
http://codex.wordpress.org/Function_Reference/add_filter
http://codex.wordpress.org/Plugin_API/Filter_Reference/query_vars
/* Query Vars */
add_filter( 'query_vars', 'yourpluginname_register_query_var' );
function yourpluginname_register_query_var( $vars ) {
$vars[] = 'blah';
return $vars;
}
In the code above, your just registering the query var "blah" with Wordpress. That way, when someone visits example.com/blah/, which your rewrite rule tells Wordpress to treat it like they are visiting example.com/index.php?blah=true, Wordpress actually bothers to save it's value (which is set to true). This is so you can use it in the next function, which loads the template you want when users visit your url.
Step 3: Template Include
http://codex.wordpress.org/Function_Reference/add_filter
http://codex.wordpress.org/Plugin_API/Filter_Reference/template_include
http://codex.wordpress.org/Class_Reference/WP_Query#Interacting_with_WP_Query
http://codex.wordpress.org/Function_Reference/plugin_dir_path
/* Template Include */
add_filter('template_include', 'yourpluginname_blah_template_include', 1, 1);
function yourpluginname_blah_template_include($template)
{
global $wp_query; //Load $wp_query object
$page_value = $wp_query->query_vars['blah']; //Check for query var "blah"
if ($page_value && $page_value == "true") { //Verify "blah" exists and value is "true".
return plugin_dir_path(__FILE__).'test/blah.php'; //Load your template or file
}
return $template; //Load normal template when $page_value != "true" as a fallback
}
In the code above, you are simply telling Wordpress to use your blah.php template any time the query var "blah" is present and set to true. In this case it is present because a user is visiting a url with a rewrite rule that utilizes the "blah" query var. The function checks if the "blah" query var is present, then checks if "blah" is set to true, and if so loads the template. Also note that the template path is test/blah.php. You are using plugin_dir_path(__FILE__) to relatively include the template based on the location of your plugin. That way it's relative as a plug-in should be.
Step 4: The Actual Template (blah.php)
http://codex.wordpress.org/Function_Reference/get_header
http://codex.wordpress.org/Function_Reference/get_footer
http://codex.wordpress.org/Function_Reference/get_sidebar
Your template file will need to load the header, footer, and sidebar itself. When using template_include, Wordpress will not automatically load the header and footer as if you were using a page template. Be sure your template file calls get_header(), get_footer(), and get_sidebar() so that you get your complete layout.
Notes
Hope this helps, I was searching for something similar the other day and had to figure it out the hard way. It's also worth noting that I have prefixed all of the functions as "yourpluginname_". You can change this to whatever you want your prefix to be, but be sure to update the function names to match as well.
I'm hosting an event and using WordPress to manage the site. We have a separate table (not WP user table) of attendees and I'd like for each of them to have a page on our site:
example.com/user1, example.com/user2, etc.
I've been reading up about WP_Rewrite but am a bit confused about how to conditionally redirect if the user exists, otherwise go about the normal flow.
Any help in achieving this would be much appreciated, thank you!
Edit:
There is a single one-off page that I'm trying to forward to. Right now, it's accessed with:
example.com/user?username=user1
If i understood your problem, you're going to create a page for each user, so in the permalink structure add tag %postname%, and maybe install no-category base plugin.
Check if the .htaccess it's created with the configuration that wp write for that structure, if it's not you can just copy and paste.
I ended up doing this by prepending a user's url with a tilde (~). The rewrite code is as follows:
// Uncomment only when new rewrites have been made
//add_filter('init', 'wds_flush');
// Leave uncommented
add_filter('rewrite_rules_array', 'wds_user_rewrite');
add_filter('query_vars','wds_query_vars');
function wds_flush()
{
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
function wds_user_rewrite($rules)
{
global $wp_rewrite;
$newRule = array(
'^~(.+)$' => 'index.php?pagename=user&uid=$matches[1]&act=show',
);
$newRules = $newRule + $rules;
return $newRules;
}
function wds_query_vars($vars)
{
array_push($vars, 'uid');
array_push($vars, 'act');
return $vars;
}