Dodo
Dodo

Reputation: 69

htaccess rewrite remove folder from file request

Developing a multi-lingual website. The language is stored as a session variable and each language's content is loaded into the same page – effectively different translations of the English content. However I need different URLs for each language.

The language will always be a 2 character folder at the start of the URI, however English will have no folder. For example:

www.mydomain.com/product/detail [English]
www.mydomain.com/fr/product/detail [French]
www.mydomain.com/de/product/detail [German]
www.mydomain.com/ja/product/detail [Japanese]

All of those URLs would fetch the same file at:

www.mydomain.com/product-detail.php

Here are my current htaccess rules:

# ==== REWRITE URLS ====
RewriteEngine On

# Permanently redirect "foo.php" to "/foo"#
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NE,L,R=301]

# pass through root
RewriteRule ^(index\.php|Sitemap\.xml)?$ - [L]

# no more / so add extension
RewriteCond $1 !/
RewriteCond $1 !\.php$
RewriteCond ${REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /$1.php [L]

RewriteCond %{REQUEST_URI} !\.php$
RewriteRule ^(_css|_includes|_assets|_scripts)($|/) - [L] #exclude these folders using the 'last: L' flag
RewriteRule ^(.*)/(.*)$ /$1-$2 [L]

# === end rewrite URLs ===

So I need an extra rewrite rule that says 'ignore the first folder if it is 2 characters long and matches FR|DE|JA' but also works with the existing rules.

Any help would be greatly appreciated as htaccess is not my strength...

Upvotes: 1

Views: 85

Answers (1)

user2493235
user2493235

Reputation:

Your rules could do with an overhaul, as they're a little ambiguous, inconsistent and long-winded in places. That aside, since it's clear they are working regardless of that[1], changing the last rule to this looks like it should do as you ask:

RewriteRule ^(?:(?:fr|de|ja)/)?(.*)/(.*)$ /$1-$2 [L]

It only works with lower-case language codes, as in your examples. It can be changed to support any case if you need that, as in your description, by changing the flags in square brackets at the end to [L,NC].

1 - The implication is that making changes later could not work as intended, or some things may not work as expected

Update

To also work with URLs like /product, try adding this at the end:

RewriteCond %{REQUEST_URI} !\.php$
RewriteRule ^(?:(?:fr|de|ja)/)(.*)$ /$1 [L]

Update 2

So at the end it should look like this:

RewriteCond %{REQUEST_URI} !\.php$
RewriteRule ^(_css|_includes|_assets|_scripts)($|/) - [L] #exclude these folders using the 'last: L' flag
RewriteRule ^(?:(?:fr|de|ja)/)?(.*)/(.*)$ /$1-$2 [L]

RewriteCond %{REQUEST_URI} !\.php$
RewriteRule ^(?:(?:fr|de|ja)/)(.*)$ /$1 [L]

Update 3

Change of plan, sorry, but just realised that's not going to work. Try this instead, replacing the second to last section:

# no more / so add extension
RewriteCond $1 !/
RewriteCond $1 !\.php$
RewriteCond ${REQUEST_FILENAME} !-f
RewriteRule ^(?:(?:fr|de|ja)/)?(.*)$ /$1.php [L]

The last section should go back to:

RewriteCond %{REQUEST_URI} !\.php$
RewriteRule ^(_css|_includes|_assets|_scripts)($|/) - [L] #exclude these folders using the 'last: L' flag
RewriteRule ^(?:(?:fr|de|ja)/)?(.*)/(.*)$ /$1-$2 [L]

And just to reiterate, I don't like this at all, it's not an elegant solution, but it should work and is a natural progression of how it's already set up. Really it all needs rewriting.

Here's the whole thing just to be clear:

# ==== REWRITE URLS ====
RewriteEngine On

# Permanently redirect "foo.php" to "/foo"#
RewriteCond %{THE_REQUEST} /([^.]+)\.php [NC]
RewriteRule ^ /%1 [NE,L,R=301]

# pass through root
RewriteRule ^(index\.php|Sitemap\.xml)?$ - [L]

# no more / so add extension
RewriteCond $1 !/
RewriteCond $1 !\.php$
RewriteCond ${REQUEST_FILENAME} !-f
RewriteRule ^(?:(?:fr|de|ja)/)?(.*)$ /$1.php [L]

RewriteCond %{REQUEST_URI} !\.php$
RewriteRule ^(_css|_includes|_assets|_scripts)($|/) - [L] #exclude these folders using the 'last: L' flag
RewriteRule ^(?:(?:fr|de|ja)/)?(.*)/(.*)$ /$1-$2 [L]

# === end rewrite URLs ===

Upvotes: 1

Related Questions