'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