4

Been hitting my head against the wall on this for a while. If I have a add_rewrite_rules like so:

    $aNewRules = array('my-books/?$'  => 'index.php?pagename=my-books');

This works correctly; going to http://example.com/my-books/ shows http://example.com/index.php?pagename=my-books.

However, this is case sensitive - going to "/My-bOoKs/" does not trip the rule (and thus shows the 404 page instead).

Is there an easy way to just mark it as case insensitive? I only make links with the lower case, sure, but users may add a capital on their own and I'd hate to lose the traffic to a 404 page.

Thanks! Alex

6
  • If you want to achieve such thing you'll have to add a rewrite rule for each assumption e.g My-bOoKs, My-books, etc .. but the perfect solution here I guess is to redirect those to the normal pagename 'my-books'..
    – Ismail
    May 23, 2016 at 21:43
  • @SamuelElh - At that point, I could do something more like '[Mm][Yy]-[Bb][Oo][Oo][Kk][Ss]/?$' . . . but I have a lot of these rules in place, so I'd like something a bit less tedious of possible :).
    – Alex Gold
    May 23, 2016 at 21:57
  • That totally does it! why not implement that one?
    – Ismail
    May 23, 2016 at 22:00
  • Just because it's messy and tedious - if there's no other way, I'll do that, but I was hoping there's a simple tag (like '?i' or something) I could add to do that instead - I've found a number of things online with [NC] or some "i" related tag that is meant to do this in Regex, just can't get any of them to work in Wordpress at this level :).
    – Alex Gold
    May 23, 2016 at 22:02
  • 1
    Haha, yeah - I'd rather just use the brackets :D
    – Alex Gold
    May 23, 2016 at 22:27

2 Answers 2

1

As the answer below mentions, it is not possible to pass a flag to add_rewrite_rule(); however, it is possible to use an inline modifier. In your example, you would do this:

$aNewRules = array('(?i)my-books/?$' => 'index.php?pagename=my-books');

(note the (?i) in the regular expression).

The advantage of this approach is that your rewrite rules are much cleaner and more performant.

See this page on regular expression modifiers for more information.

-1

Not directly. The wordpress API is using preg_match / preg_replace but is not exposing the flags parameter. That's what you'd need to pass the insensitive flag (i).

See their implementation here: https://github.com/WordPress/WordPress/blob/a8802232ecac8184cbe6e8dbe9c6a7bd0f5b7dee/wp-includes/class-wp-rewrite.php

Probably the simplest solution is just to use a little helper function to do this for you:

function anyCase($rules){
    $insensitive = array();
    foreach ($rules as $regex => $mapping) {
      $regex = preg_replace_callback('([A-Za-z])', function($matches){
            return "[" . strtoupper($matches[1]) . strtolower($matches[1]) . "]";
      }, $regex);
      $insensitive[$regex] = $mapping;
    }
    return $insensitive;
  }

Given

$rules = array('my-books/?$'  => 'index.php?pagename=my-books');
var_dump(anyCase($rules));

Will output array(1) { ["[Mm][Yy]-[Bb][Oo][Oo][Kk][Ss]/?$"]=> string(27) "index.php?pagename=my-books" }

So you can keep your rules clean / simple :-)

If you're running an older PHP that doesn't support closures you can just this instead:

  function lowerOrUpper($matches){
    return "[" . strtoupper($matches[0]) . strtolower($matches[0]) . "]";
  }

  function anyCase($rules){
    $insensitive = array();
    foreach ($rules as $regex => $mapping) {
      $regex = preg_replace_callback('([A-Za-z])', lowerOrUpper, $regex);
      $insensitive[$regex] = $mapping;
    }
    return $insensitive;
  }

Cheers

1
  • I ended up down this path, but after some research, I found what I think is a better solution (using inline regex modifiers). Hope it helps! Aug 10, 2018 at 15:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.