I have a little PHP framework like this:


?page=page-name%slug=slug-name (in the case of plural list pages)

I'm trying to pretty her up.

/exercises → ?page=exercises
/exercises/exercise-slug → ?page=exercise?slug=exercise-slug
/layouts/layout-slug → ?page=module?slug=module-slug
(in this case changing the resource name)

I don't have the vocabulary (yet) to describe the problem - but it seems like the second rule is taking over for the first one because it matches both?

<a href='/exercises'>...
<a href='/exercises/exercise-slug'>...

Here's what I've put together so far (and this work for all the single pages)

# turn rewriting on
RewriteEngine On

# /page-name →  ?page=page-name
RewriteRule ^([0-9a-zA-Z_-]+)$ ./index.php?page=$1 [NC,L]

# /projects  →  ?page=projects
# getting tangled up with the next one

# /projects/project-name  →                        ?page=projects&slug=project-slug
RewriteRule ^projects/([0-9a-zA-Z_-]+)$ ./index.php?page=project&slug=$1 [NC,L]

# /exercises/exercise-name  →                       ?page=exercise&slug=exercise-slug
RewriteRule ^exercises/([0-9a-zA-Z_-]+)$ ./index.php?page=exercise&slug=$1 [NC,L]

# /layouts/layout-name →                         ?page=module&slug=module-slug
RewriteRule ^layouts/([0-9a-zA-Z_-]+) ./index.php?page=module&slug=$1 [NC,L]

I thought that the $ would tidy up that match - and then the [L] would stop it from moving on if if already matched. I also played with the order a bit.


# turn rewriting on
RewriteEngine On

# /projects  →  ?page=projects  (layouts, exercises too)d
# getting tangled up with the next one

# /projects/project-name  →             ?page=projects&slug=project-slug
RewriteRule ^projects/([0-9a-zA-Z_-]+)$ ?page=project&slug=$1 [NC,L]

# /exercises/exercise-name  →            ?page=exercise&slug=exercise-slug
RewriteRule ^exercises/([0-9a-zA-Z_-]+)$ ?page=exercise&slug=$1 [NC,L]

# /layouts/layout-name →              ?page=module&slug=module-slug
RewriteRule ^layouts/([0-9a-zA-Z_-]+) ?page=module&slug=$1 [NC,L]

# /page-name →                 ?page=page-name
RewriteRule ^([0-9a-zA-Z_-]+)$ ?page=$1 [NC,L]
  • 1
    The "L" is indeed suppose to stop it from moving on. Did you check if the browser cache is turned on? Nov 11, 2022 at 21:29
  • RE: cache I did all the normal things I do. Command + shirt + R, dev tools, incognito. Leads to http://portfolio.site:8888/projects/?page=projects Nov 11, 2022 at 22:02
  • For clarity, aren't your examples with the arrows after "I am trying to pretty her up" around the wrong way? I would expect to see what you have on the left to (->) what you want on the right.
    – Steve
    Nov 11, 2022 at 22:29
  • page-name is currently listed first, I believe that should be a catch all that should be last. I would commit that out while on the sandbox, to test the other three regular expressions. You could use (.*) instead of ([0-9a-zA-Z_-]+) as you would still need to filter the slug=value (somebody could just manually enter the URL with any value)so the pre-check does not give you any real benefit. Nov 11, 2022 at 22:40
  • To clarify the ^ marks the beginning of the string and the $ the end ... so I'm seeing example.com/projects/slug where a example.com/projects/slug/reject will not be redirected because the "/" is not part of ([0-9a-zA-Z_-]+) and the slug extents all the way to the $ end. ^projects/([0-9a-zA-Z_-]+)/$ would be the match case for example.com/projects/slug/ Noting the ending /. Nov 11, 2022 at 22:51


Your Answer

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

Browse other questions tagged or ask your own question.