1

I'm extending our Wordpress site to render pages that aren't coming from the database. We want those pages to have pretty URLs, without parameters in the URL.

Imagine we're selling apples: I'd like the URL to be http://myfictionalstore.com/apple/golden-delicious or http://myfictionalstore.com/apple/granny-smith.

I can't make this style of URL work.

Under the hood, we can pass a URL to the page template that fetches apple related information from an API, so we can happily render a page like this:

http://myfictionalstore.com/apple/?apple=granny-smith

I've told WordPress about my new Query var:

function add_query_vars($aVars) {
$aVars[] = "apple";
 return $aVars;
}

add_filter('query_vars', 'add_query_vars');

And in the template, I can happily use that:

$apple_key = get_query_var( 'apple', 'rotten' ) ;

What I can't do is configure Nginx to make an internal redirect so it can render the pretty URL. Even though it works above, this Nginx config doesn't:

location ~ /apple/([^/]+)/? {
    try_files /dev/null /index.php?pagename=apple&apple=$1;
}

That config returns a 404 when I try and query one of the pretty URLs. I can query just using WordPress query variables:

http://myfictionalstore.com/index.php?pagename=apple&apple=orange-pippin

But for whatever reason, that doesn't work as an internal redirect. I can use phpinfo() to prove that the params are making it to WordPress:

QUERY_STRING pagename=apple&apple=braeburn

So perhaps:

  • WordPress isn't liking something about the request environment?
  • Nginx isn't handling the internal redirect properly?

The wall has a dent, and my forehead is bleeding.

Update:

Thanks to Richard, this made it work:

  location ~ /apple/([^/]+)/? {
    fastcgi_pass unix:/var/run/hhvm/hhvm.sock;
    include /etc/nginx/fastcgi_params;
    fastcgi_param SCRIPT_FILENAME /var/www/index.php;
    fastcgi_param REQUEST_URI     /index.php;
    fastcgi_param QUERY_STRING    page_id=12345&apple=$1&;
    fastcgi_pass_request_headers off;
  }

There was an issue loading the page via the Wordpress page_name, so I ended up changing my query slightly; that was a step forward, then removing the original request headers made it all go. Thanks!

1 Answer 1

1

This is more of a suggestion than an answer. The nginx internal redirect does not rewrite the $request_uri which is later used to set REQUEST_URI for WordPress. It's possible that WordPress uses REQUEST_URI in preference to QUERY_STRING in order to support pretty permalinks.

The obvious solution is to let WordPress handle your pretty permalinks internally, but that may not be a practical solution for your specific implementation.

Another solution would be to change the value of REQUEST_URI to:

fastcgi_param  REQUEST_URI $uri$is_args$args;

So that it matches your internally rewritten value rather than the externally presented value. This is a global change and needs extensive testing.

If you encounter problems with that, the third solution would be to duplicate a custom php code block within your new location. Such as:

location ~ /apple/([^/]+)/? {
  fastcgi_param SCRIPT_FILENAME $document_root/index.php;
  fastcgi_param REQUEST_URI     /index.php?pagename=apple&apple=$1;
  fastcgi_pass ...;
  ...
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! A bump in the right direction and a whack with a clue-by-four was what I needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.