Allow question marks (?) in WordPress permalinks

I am using a plugin called Custom Permalinks for that purpose, which works well, except for one thing: it strips all “?” and “=” characters from URLs, a so-called “sanitation” function.

This needs taking up with the plugin authors for the =, and is likely because WP itself would perform the same sanitisation, but ? won’t work for the reasons listed below regardless of the plugin used.

Some sources are suggesting that the question mark may be interfering with WordPress’s query parameters. I want to know:

whether that’s really the issue and

Yes. WP should be okay with =, but it will only process the URL parts that come before the first ? character in the pretty permalink system.

So this URL: /example=test?storyid=123 will always be processed as the pretty URL example=test by WordPress

Why ? can’t be used in pretty permalinks/slugs

The fundamental problem is that WP does not consider the ? to be a part of the permalink, and only considers everything before the ?.

If we look at parse_request in the WP class which is responsible for taking rewrite rules and matching the URL against them, we see this:

            list( $req_uri ) = explode( '?', $_SERVER['REQUEST_URI'] );

$req_uri is what is used to match rewrite rules further down ( there’s some logic that assigns it to a new variable unless the request is empty in which case it doesn’t use rewrite rules ).

This means that no matter how many ? characters there are in the request URI the rewrite rule itself, the post slug, or their location in the string, they will never be considered for the permalink handling process, WP considers them GET parameters/URL query parameters and treats them accordingly. Only the “path” as PHP considers it is evaluated, which for test.php?foo=bar results in /test.php.

This is why you can’t match posts with ? in their slug using rewrite rules, because everything after and including the first ? is ignored when evaluating the rules.

What About Ugly Permalinks?

Despite this, nothing prevents the ugly index.php?name=.... from being used to access a post with a slug that contains a ?, though it may then do a canonical redirect that breaks it, but those can be disabled.

Could This Be Overriden?

If you wanted to change this, you’d need to replace the entire rewrite rule engine, as well as some follow up code. Specifically the parse_request filter would need to be used to throw away the previous result and undo what it did, then put your own in. You would also need to filter the sanitisation code to allow ?. note that this means the rewrite rule process would run twice, and you would need to keep your copy up to date to include bug fixes made upstream. This is also ignoring the problems this might cause elsewhere with permalinks that no longer match when ? is used, so you’ll need to include very specific exceptions for the cases that you need it to work in.

Take a look at wp-includes/class-wp.php, in particular parse_request and the main function for more context.

What About =?

I can’t find any evidence against this, renaming test.php to foo=bar.php reveals $req_uri to be /foo=bar.php.


how I can work around it?

how I can work around it in order to get the permalink structure above. I am not concerned about trading some query parameter functionality for getting all legacy URLs to work.

Fundamentally, you don’t need the URL parameters to be in the post slug for it to be in the permalink. In fact the slug could be ignored completely.

Take as an example post permalinks that use the post ID e.g. /p/123. Nothing stops you from registering a query variable named storyid that then gets automatically picked up from the GET variables, then writing a filter to take get_query_var( 'storyid' ) and modify the main query to put its value in the post ID parameter, or add a post meta query to match it. the rest would be a matter of filtering the URLs to look the way you want them. Only storyview.php would need to match in the rewrite rule system.

Note that there are many many ways of doing this, but none of them involve putting URL parameters in pretty permalinks in the way your question asked.

techhipbettruvabetnorabahisbahis forumueduedueduseduedusedueduseduseduedu