'Rewriting WordPress URLs and parameters with nginx
Help , i need rewrite url with nginx . I have installed plugin "Ajax Search Pro" for replace theme search , but when i search , i got error when i move to page 2,3 and go on , it show post from homepage , not from keyword search .
Example
https://abccom/?s=abc => Work , it show post from keyword search
https://abccom/page/2/?s=abc => Not work , it show result page 2 post from homepage , not keywords search .
https://abccom/?s=abc&paged=2 => Work , move to page 2 search keyword work well , but this url is write manually , just only me know it , visitor don't know it .
So i need a code nginx can rewrite rules , url for this
rewrite that url
https://abccom/page/2/?s=abc
to
https://abccom/?s=abc&paged=2
Parameter is Value Keyword and Number Page .
Thanks everyone !
Solution 1:[1]
Spoofing the actual request URI that is seen by the WordPress is a bit tricky. That's because the WordPress core relies on REQUEST_URI
FastCGI variable to see the original request URI entered by user. Inside the default fastcgi_params
file usually included to every PHP handler location
block that variable defined the following way:
fastcgi_param REQUEST_URI $request_uri;
As described in the nginx documentation the $request_uri
variable always contains full original request URI (with arguments). It does not get changed with the rewrite
directive, it is the normalized $uri
one that does. That is, no matter what rewrite rules you use, doing that won't help to change the request URI seen by the WordPress. Moreover, using the most common WordPress-hosting nginx configuration like
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location ~ \.php$ {
... PHP-FPM configuration here
}
every request containing WordPress route (but not the request for some JS/CSS/image assets) will end up at the second location with the $uri
variable being rewritten to /index.php
due to the last try_files
directive argument.
Being that said, the only way to made the WordPress see something else that the original request URI is to redefine the REQUEST_URI
after it is defined in the fastcgi_params
file. But before that we need to somehow obtain its new value for substitution. Here we go. The following fragment should be placed into your server block under the server
context (outside of any existing location):
set $tweaked_uri $request_uri;
if ($arg_s) {
rewrite ^/page/(\d+)/$ /?paged=$1;
set $tweaked_uri $uri?$args;
}
What happened here?
The first line stores the $request_uri
variable value into a new $tweaked_uri
one. The second line checks if the s
query argument is not empty (every query argument is available via $arg_<name>
variable). Next, if it isn't empty (i.e. the s
query argument is present), the rewrite rule is applied to the current normalized URI (note that the normalized URI doesn't include the query string part and for the /page/2/?s=abc
request the normalized URI will be equal to /page/2/
). If an URI matches the given PCRE regex pattern ^/page/(\d+)/$
(which will match any /page/<number>/
string), an URI gets rewritten to /
and the query string (available via $args
or $query_string
variables, consider these as synonyms) gets prepended with the paged=$1&
where $1
is a backreference to the (\d+)
regex capture group. For the given /page/2/
URI that $1
variable value will be equal to 2
.
Note that using the given rewrite rule new query argument is being prepended to the existing query string (resulting in $paged=2&s=abc
) rather than being appended to it. This is slightly differs from your example. Usually it should not matter for the WordPress core, but if for some strange reason it is, the following rewrite rule can be used instead:
rewrite ^/page/(\d+)/$ /?$args&paged=$1?;
You can check the rewrite
directive documentation to find out what happens in each case (I provided the link earlier as well as links to documentation for every other nginx directive or built-in variable I'm gonna use here).
Ok, lets continue. What happens if the normalized request URI does not match our regex pattern? Nothing. The rewrite rule isn't applied, neither $uri
nor $args
variables gets changed. On the next line $tweaked_uri
variable is recomposed using the $uri
and $args
variables, either changed or not. All this happens only if the s
query argument is present in the request, otherwise $tweaked_uri
variable remains equal to the $request_uri
one. In every possible case $tweaked_uri
now contains the value we need for the REQUEST_URI
FastCGI variable.
The last part is the PHP-FPM handler location (usually something like location ~ \.php$ { ... }
). Put the
fastcgi_param REQUEST_URI $tweaked_uri;
line somewhere below the include fastcgi_params;
(or include snippets/fastcgi-php.conf
in case your handler uses that file instead - the include fastcgi_params;
line is there). This should do the trick you are asking for.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Ivan Shatsky |