rewrite url for 2 or 3 "subfolders" - .htaccess

I have a working rewrite rule for
domain.com/companyname
its a wildcard rule since i wont know whats in the position of "companyname". And rules to take care of urls that DO exist
So far so good
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*?)$/ profile/index.php?company=$1
But sometimes i might need to add an extra subfolder if a company has several departments line
domain.com/companyname/london/ or domain.com/companyname/berlin
The following rule will do that
RewriteRule ^(.*?)/(.*?)$ profile/index.php?company=$1&city=$2
But the problem is that the first rule will also catch the url with city subfolder.
How can i make both rules work ? i guess i need to make sure rule 1 only takes those with companyname and no city.

You can have more specific rule first:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/(.+?)/?$ profile/index.php?company=$1&city=$2 [L,QSA]
RewriteRule ^(.+?)/?$ profile/index.php?company=$1 [L,QSA]

Related

Multiple rewrite rules in htaccess

I have an .htaccess file that rewrites urls for SEO purposes
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /display.php?page=$1 [L,NC,QSA]
RewriteRule ^search/([^/\.]+)/?$ search.php?what=$1&where=$2 [L,NC,QSA]
Now the first rewrite rule works fine. (www.domain.com/user goes to display.php?page=user)
but the second one should work like (www.domain.com/search/something/else must go to search.php?what=something&where=else
What am I doing wrong here?
Your second rule is incorrect for what you are looking for. You are requesting the result of two captures, but are only making one capture.
Try this instead:
RewriteRule ^search/([^/\.]+)/([^/\.]+)/?$ search.php?what=$1&where=$2 [L,NC,QSA]
Edit: You'll also need to switch your rules around. Your first rule captures everything, and would therefore discard the second.
So, swap them around, and use the L flag, as suggested already.
You are using the [L] flag, which causes mod_rewrite to stop processing the rule set.
Try removing the L flag from the first Rewrite Rule, like this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /display.php?page=$1 [NC,QSA]
RewriteRule ^search/([^/\.]+)/?$ search.php?what=$1&where=$2 [L,NC,QSA]

Rewrite Rule Loop. How to stop applying rules

I have an .htaccess file redirecting blog post urls like /blog/2012/11/30/this-post to /blog/post.php?id=this-post. Works fine until I apply a second rule below it that is also a match. This rule is set to take a path formatted url like /this/is/a/pageid and redirect to /page.php?id=pageid. It doesn't care how long the path is, it just uses the last directory in the path as the id. Unfortunately, this rule matches everything and I'm not sure how to stop the redirect after the first match. Here is my .htacess
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/([0-9]+)/([0-9]+)/([0-9]+)/([A-Za-z0-9-]+)$ /blog/post.php?id=$4 [L]
RewriteRule ([^/]+)/?$ /page.php?id=$1 [L]
Thanks in advance for the help.
You can add an optional query parameter after you redirect the first time and combine that with a simple rewrite condition on the query string to check if that parameter exists or no, try this :
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^blog/([0-9]+)/([0-9]+)/([0-9]+)/([A-Za-z0-9-]+)$ /blog/post.php?id=$4 [L]
RewriteCond %{QUERY_STRING} !^(.*&)?r=0(&.*)?$
RewriteRule ([^/]+)/?$ /page.php?id=$1&r=0 [L]

htaccess does not work rewrite rule

I've been struggling with my .htaccess file for weeks now, I changed it many times but it just won't work.
I have this in my .htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^/([^./]+)\.html$ category.php?id=$1
RewriteRule ^/([^./]+)\.html$ tag.php?id=$1
RewriteRule ^/([^./]+)\.html$ play.php?id=$1
but it does not work.
Are you sure that mod_rewrite is turned on in Apache? Do you have access to httpd.conf? It would be better to do redirects there instead of with a .htaccess file.
Your conditions are only being applied to the first rule. Each set of RewriteCond's only get applied to the immediately following RewriteRule. So the conditions only get applied to RewriteRule ^/([^./]+)\.html$ category.php?id=$1 and the last 2 rules have no conditions at all.
Your conditions is to rewrite something that exists to something else, which will cause a rewrite loop. You probably wanted:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Your 2nd and 3rd rules will never be applied because if someone requests /some-page.html the first rule's regex will match it and rewrite the URI to /category.php?id=some-page, then the next to rules will never match because the first rule already rewrote the URI to category.php.
Your regular expressions match a leading slash, URI's being applied in rewrite rules that are inside an htaccess file has the leading slash stripped out, so you want this instead:
RewriteRule ^([^./]+)\.html$ category.php?id=$1
1, 2 and 4 is easy. 3, not so much. You're going to have to figure out a unique way to represent an html page as a category, tag, or play. You can't have all 3 look identical, there's no way to tell which one you want. Take:
/something.html
Is that supposed to be a category? A tag? or a Play? Who knows, your rewrite rules surely don't. But if you preface each with a keyword, then you can differentiate:
/category/something.html
/tag/something.html
/play/something.html
And your rules would look like:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^category/([^./]+)\.html$ category.php?id=$1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^tag/([^./]+)\.html$ tag.php?id=$1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^play/([^./]+)\.html$ play.php?id=$1

mod rewrite - allow full stops

I need a rewrite rule that allows full stops. How can I allow for this? What I want is for
shop/domain/www.test.com to become shop/domain/controller.php?param1=www.test.com
The original rule I have is below:
RewriteRule ^shop/domain/([^/.]+)/?$ shop/stock/controller.php?param1=$1 [NC]
This works but only if I remove the full stop.
I have also tried the following:
RewriteRule ^shop/domain/([^/]+)/?$ shop/domain/controller.php?param1=$1 [NC]
This allows the full stop but then has controller.php is the parameter when it should be www.test.com.
If all domains begin with "www.", you could do this
RewriteRule ^shop/domain/www\.([^/]+)/?$ shop/domain/controller.php?param1=$1 [NC,L]
The problem with your rule is, that it also matches controller.php as if it were a domain. You can add the following two rewrite conditions to prevent this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^shop/domain/([^/]+)/?$ shop/domain/controller.php?param1=$1 [NC,L]
!-d means not an existing directory, !-f means not an exisiting file (e.g. controller.php).

Rewrite rule to hide folder, doesn't work right without trailing slash

i have a strange apache mod_rewrite problem. I need to hide a sub-directory from the user, but redirect every request to that sub-directory. I found several quite similar issues on stackoverflow, but nothing really fits, so i decided to post a new question.
My .htaccess looks like this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)?$ foo/$1 [QSA,L]
The document-root only contains the following folder/files:
/foo/bar/index.html
I would now expect that example.com/bar and example.com/bar/ would just show me the contents of index.html.
Instead example.com/bar/ show me the content as expected but example.com/bar redirects me with a 301 to example.com/bar/foo/ an then shows the contents. I really don't get why there is a 301 redirect in this case.
When i put something this
RewriteCond %{REQUEST_URI} !^[^.]*/$
RewriteCond %{REQUEST_URI} !^[^.]*\.html$
RewriteCond %{REQUEST_URI} !^[^.]*\.php$
RewriteRule ^(.*)$ $1/ [QSA,L]
on top of that rule it seems to work, but that would require me to list every used file extension...
Is there any other way i can omit the redirect, the folder "bar" should never be seen by an outside user.
Thanks in advance!
1st rewrite rule is redirect from /foo/(.) to ($1) and second - from (.) to $1.
just idea, this has not been tested.
Better late than never...
Got it working with a simple RewriteRule which append a / to every url that doesn't have on.
# only directories
RewriteCond %{REQUEST_FILENAME} !-f
# exclude there directories
RewriteCond %{REQUEST_URI} !^/excluded-dirs
# exclude these extensions
RewriteCond %{REQUEST_URI} !\.excluded-extension$
# exclude request that already have a /
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ /$1/ [R=301,L]

Resources