Firstly, I have tried several different suggestions from other stackoverflow users but I haven't had any luck.
I'm trying to build a kind of api from inside a plugin. The task is to let an external system call a URL within my plugin in order for it to initiate an internal procedure.
Currently I have a class which has a contructor. This is inside that constructor.
add_action( 'init', 'my_rewrite' );
function my_rewrite() {
global $wp_rewrite;
$plugin_url = plugins_url( 'my-api.php', __FILE__ );
$plugin_url = substr( $plugin_url, strlen( home_url() ) + 1 );
add_rewrite_rule('/my-api/(.*)', $plugin_url ,'top');
$wp_rewrite->flush_rules(true);
}
This then generates a RewriteRule in my htaccess file.
RewriteRule ^/my-api/(.*) /wp-content/plugins/my-api/classes/my-api.php [QSA,L]
Below is the whole .htaccess file for context
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteRule ^/slurp-api/(.*) /wp-content/plugins/slurp/classes/my-api.php [QSA,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
For whatever reason when I visit site.dev/my-api I see a 404 page rather than the echo statement that should run from my-api.php
The dev site is being run through mamp pro if that is any help.
Any pointers as to why this rewrite isn't playing fair would be greatly appreciated.
Thanks
Remove the leading forward slash from the original request
RewriteRule ^my-api/(.*) /wp-content/plugins/my-api/classes/my-api.php [QSA,L]
And make sure the file my-api.php exists at the location you give in the rewrite target:
/wp-content/plugins/my-api/classes/my-api.php
So as not to intentionally give it a non-existent target.
As #Starkeen mentions in the comments, you can remove the leading forward slash from the target also, like this
RewriteRule ^my-api/(.*) wp-content/plugins/my-api/classes/my-api.php [QSA,L]
So, after much tinkering I came upon the correct answer.
I changed this line to
add_rewrite_rule('my-api', $plugin_url ,'top');
I tried many variations on this but this one finally worked. Thanks for the help.
Related
I know this can be done using Rewrite engine but I am unable to do this
This is my .htaccess file
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
I have this url www.mysite.com/report?page=my-report-name
Now what I want to acheive is this : www.mysite.com/report/my-report-name
The file where I am accessing this get variable name page is reports.php and its not in my root directory
Path to my file is : root/themes/fount/intel/reports.php
Can anyone help?
Try this code,
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
# /anything/anything -> anything.php?url=anything
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([A-Za-z0-9_])/([^/]*)$ /$1.php?url=$2 [L]
</IfModule>
If the page.php filename will always be the same, then do it like this:
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine on
RewriteBase /
# /page/anything -> page.php?url=anything
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^page/([^/]*)$ /page.php?url=$1 [L]
</IfModule>
Thanks!
Updated answer
To add a routing which points to an external handler PHP file, the following snippet should be used:
function wprre_add_rewrite_rules() {
global $wp_rewrite;
// pattern with regexps
$wp_rewrite->add_external_rule( '^wp_report/([\w\d-]+)/?', PATH_TO_THE_EXTERNAL_HANDLER.'report.php?report_name=$1' );
}
add_action('init', 'wprre_add_rewrite_rules');
You can spot one difference in the parameter handling between add_external_rule() and the add_rewrite_rule. You must use the match selector as the Apache uses it in this case.
This snippet must placed in a file which is always loaded by your plugin or theme. If you write a plugin it can be the main plugin file. In case of theme development it can be the main functions.php file.
The custom GET parameter registration is working as it was mentioned in the Original answer.
IMPORTANT
After you edited the rewrite rules via code (external or internal both) you must go to the Permalink settings page in the admin panel and click to the Save button without any changes. This is necessary, because this will flush the rewrite rules and the WP will write into the .htaccess file the rules.
This is the reason why I recommend you to hook on the plugin activation event and register the rewrite rules then and immediately run a flush_rewrite_rules() command.
NOTES
The problem with the original answer was that, the add_rewrite_rule() function only works if you route to the default basic index.php. You can only modify the parameters, but you can not route to an external file.
Original answer
I think you should use the WordPress API to achieve this. You will need to add a rewrite rule and tag in you theme or plugin with this syntax:
!! Disclaimer this is only working to route to the basic index.php !!
For the routing, add a rewrite rule which points to your PHP file.
function custom_rewrite_basic() {
add_rewrite_rule('^report/([\w-]+)/?', 'index.php?page=$matches[1]', 'top');
}
add_action('init', 'custom_rewrite_basic');
If you want to use a query parameter which is not in the standard WP parameter list, you need to add that custom parameter name.
function custom_rewrite_tag() {
add_rewrite_tag('%page%', '([^&]+)');
}
add_action('init', 'custom_rewrite_tag', 10, 0);
Be aware to you use built in parameters if you do not use as the WP API.
In this Codex article you find more details about the topic:
https://codex.wordpress.org/Rewrite_API/add_rewrite_rule
For troubleshooting and deeper dive understanding you might to check this Codex article too, which describes the proper rewrite rule usage. Because some in circumstances you need to reset the rewrite rules (plugin activation / deactivation).
https://codex.wordpress.org/Function_Reference/flush_rewrite_rules
Finally this solution worked for me
I have added this in my functions.php file that is in our theme folder
function rewrite_photo_url(){
add_rewrite_rule('^report/([^/]*)/?','index.php?page_id=2671&value=$matches[1]','top');
}
function register_custom_query_vars($query_vars){
$query_vars[] = 'value';
return $query_vars;
}
add_action('init','rewrite_photo_url');
add_filter('query_vars','register_custom_query_vars');
and then in my php file I use get_query_var('vale') to get my parameter value
I have a custom URL like this:
website.com/show/?id=9999&n=page-name
I'm trying to come up with a rewrite rule to convert it to:
website.com/show/9999/page-name/
Note that this is a WordPress site and /show/ is WP page name.
Here's the rules I'm using in .htaccess:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteBase /
RewriteRule ^show/(.*)$ /show/?id=$1 [R=301,NC,QSA]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
This is working; it rewrites website.com/show/?id=9999 to website.com/show/9999/.
Then I modified the rule for the second query string:
RewriteRule ^show/(.*)/(.*)$ /show/?id=$1&n=$2 [R=301,NC,QSA]
But now website.com/show/9999/page-name/ returns a 404 error. It works if I go to: website.com/show/9999/?n=page-name.
What am I doing wrong?
Update
The 404 problem is now solved.
However, now I need to redirect the old query string URL:
website.com/show/?id=9999&n=page-name
to the new SEO friendly URL:
website.com/show/9999/page-name
How do I setup that redirect?
Try this:
Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteRule ^show/(\d+)/?([^/]*)/?$ /show/?id=$1&n=$2 [L,NC,QSA]
# Wordpress defaults:
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
## Results
# show/9999 => show/?id=9999&n=
# show/9999/ => show/?id=9999&n=
# show/9999/page-name => show/?id=9999&n=page-name
# show/9999/page-name/ => show/?id=9999&n=page-name
As you see, when page-name is not available, there will be an empty n query string parameter. In your PHP script, instead of checking for the parameter presence using isset(), try using empty().
One last note; The above rules do not redirect the request, it maps the request under the hood, so that the URL stays clean. If you need a redirect, just add a R flag.
404
Even if you remove your custom rewrite rules, you'll get a 404 from WordPress. That's because, as you said, the rewrite target (/show) is a WordPress page and ultimately get mapped to the index.php file. Then, WordPress checks its database to see if it can find a page with that path or throws a 404 if it can't. Obviously, the latter is your case.
Update
Regarding your recent update; To redirect the old URL to the new one, you need some rewrite rules along the lines of:
Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{QUERY_STRING} ^id=(\d+)(&n=)?(.*)$
RewriteRule ^show/?$ /show/%1/%3 [R=301,QSD,L]
# Wordpress default rules:
# ...
</IfModule>
## Results
# show?id=9999 => show/9999
# show?id=9999&n=page-name => show/9999/page-name
# show/?id=9999&n=page-name => show/9999/page-name
Don't use [R=301] until you're 100% sure that everything's working fine, as it's aggressively get cached by the browser.
I think I figured it out... almost.
#sepehr is correct that WordPress is checking, not finding the page, and throwing a 404. So I needed to use WordPress' own rewrite engine to define the rewrite rules so it recognizes what I'm doing.
So I added this to my WordPress theme's functions.php file:
add_action( 'init', 'init_custom_rewrite' );
function init_custom_rewrite() {
add_rewrite_rule(
'^show/([^/]*)/([^/]*)/?',
'index.php?page_id=2382&id=$matches[1]&n=$matches[2]',
'top'
);
}
add_filter('query_vars', 'my_query_vars', 10, 1);
function my_query_vars($vars) {
$vars[] = 'id';
$vars[] = 'n';
return $vars;
}
Now the URL website.com/show/9999/page-name works correctly, not throwing a 404.
However, now I need to redirect the old query string URL to this new one. See my updated question.
Update
Here's the rewrite rule to redirect the old query string URLs to the new SEO friendly URLs:
RewriteCond %{QUERY_STRING} ^id=([^/]*)&n=([^/]*)$
RewriteRule ^show/?$ /show\/%1\/%2\/? [R=301,L]
Please check below rule in to your .htaccess.
RewriteRule ^show/(.+)/(.+)$ show/?id=$1&n=$2 [L,QSA]
I am looking over my code for 3 hours and I don't get it. I hope that you can help me.
I have a wordpress blog with Custom Post Types and Advanced Custom Fields installed. Its working pretty nice. I use a basic filter function over the custom fields as described here: http://www.advancedcustomfields.com/resources/creating-wp-archive-custom-field-filter/
To filter the custom fields I use the get-parameters form the url. So the url comes in the form like:
www.domain.tld/?post_type=movie&land=usa&typ=love&actor=kidman
Now I would like the have a pretty url in the form:
www.domain.tld/movie/usa/love/kidman
And hier comes the issue, I cant get the .htaccess right :(
My Code is:
AddHandler php56-cgi .php
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^movie/(.*)/(.*)/(.*)$ /?post_type=movie&land=$1&typ=$2&actor=$3 [L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
It's not working. The result is a 404. I believe is's a "wordpress-thing" that I don't get.
If I change the code to:
RewriteRule ^movie/(.*)/(.*)/(.*)$ http://www.domain.tld/?post_type=movie&land=$1&typ=$2&actor=$3 [L]
It works as a normal redirect.
If I change it to
RewriteRule ^movie/(.*)/(.*)/(.*)$ file.php/?post_type=movie&land=$1&typ=$2&actor=$3 [L]
where file.php is a non wordpress file, it works as well (It shows the content of file.php)
It seems that I'am not able to "call" a wordpress-specific file like index.php.
I hope you can help me, and thanks that you read through my non native english ;)
Greetings from germany
Dominik
I solved my problem on my own :)
As always, the solution is pretty simple if know where to look.
I had a deep look into: http://codex.wordpress.org/Rewrite_API/add_rewrite_rule and http://codex.wordpress.org/Rewrite_API/add_rewrite_tag
Finally the coin dropped.
First I deleted every custom code I made in the .htaccess cause its not the location to solve my problem.
I added the following to my functions.php
function custom_rewrite_basic() {
add_rewrite_rule('^movie/(.*)/(.*)/(.*)?', 'index.php?post_type=movie&land=$matches[1]&typ=$matches[2]&actor=$matches[3]', 'top');
}
add_action('init', 'custom_rewrite_basic');
function custom_rewrite_tag() {
add_rewrite_tag('%land%', '([^&]+)');
add_rewrite_tag('%typ%', '([^&]+)');
add_rewrite_tag('%actor%', '([^&]+)');
}
add_action('init', 'custom_rewrite_tag', 10, 0);
After you edited your function.php don't forget to save the permalinks in your wordpress settings.
Now I have access to the "query_vars" in the template:
$wp_query->query_vars['land']
or the functions.php:
$query->query_vars[ land ]
It works perfect :)
Thank u anyway and have a nice weekend
Dominik
I have a problem I never had and I can't find the reason.
I moved my site to another host and now it doesnt "read" the $_GET variables.
I have this url: http://whatever.com/path?filtro=si&provincia=Santa+Fe&localidad=Rosario
And if I call this:
$localidad = $_GET['localidad'];
$provincia = $_GET['provincia'];
$filtro = $_GET['filtro'];
echo $localidad;
echo "hola";
echo $provincia;
echo $filtro;
Nothing prints except "hola", so there is no PHP error.
Here's my .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
Im working on a Wordpres site, perhaps it has something to do with Permalinks or something, Im really lost. Thank you very much, I appreciate your help.
EDIT
I renamed my .htacces so it wont read it and the page broke, so I went to permalink settings in wordpress and set them to
- Post Name http://luminias.com/index.php/example-page/
And now IT WORKS, but, now this is thw url:
http://whatever.com/index.php/path/?filtro=si&provincia=Santa+Fe&localidad=Rosario
And it prints all the $_GET, but I need that "/index.php/" gone..
Add add_rewrite_tag function in your function.php for all parameter :
function custom_rewrite_tag() {
add_rewrite_tag('%localidad%', '([^&]+)');
}
add_action('init', 'custom_rewrite_tag', 10, 0);
And you can call your parameter in template using
$wp_query->query_vars['localidad']
Here is the full documentation
Note that using $_GET on a rewritten URL will not work, even if the
rewrite includes the querystring variables. You must use $wp_query.
I had problems with WordPress migration from one server to another, and generally now it works but I have many smaller problems..
Before I use domain oldexample.com and now i use domain newexample.com/something . Generally everything on the page works but changing language isn't work (qTranslate plugin).
I think that I found the reason of this - in admin menu I found in some places situation that href links start from "/" for example: "/wp-admin/..." and in result it change the URL from newexample.com/something/wp-admin to newexample.com/wp-admin. I see this problem in qTranslate settings links and when I want delete some plugins. I get the error message "404 Not Found - nginx/1.4.5" in results...
Did you see this problem before? Maybe I should change something in WordPress core files? .htaccess? Now it looks like this:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?newexample\.com\/something$ [NC]
</IfModule>
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
After long time I find the solution! All "href" are generated by using $_SERVER['REQUEST_URI'], and this variable show only the rest part of the path (without /something/. I add to wp-settings.php this part of code: $_SERVER['REQUEST_URI'] = '/something'.$_SERVER['REQUEST_URI']; (on the very beggining) all forms generate good path.