Apache modrewrite .htaccess - similar link - regex

I am wondering if it is possible to achieve this bellow:
Sometimes second attribute will be submenu
RewriteRule ^([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2 [L,QSA]
Sometimes it will be location
RewriteRule ^([\w-]+)/([\w-]+)/?$ index.php?menu=$1&news=$2 [L,QSA]
But normally, this way it does not work. Is there any possible way to achieve this?
EDIT:
Current complete rewrite rule:
RewriteEngine on
ErrorDocument 404 /error
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^([\w-]+)/?$ index.php?menu=$1 [L,QSA]
RewriteRule ^([\w-]+)/([\w-]+)/?$ index.php?menu=$1&news=$2 [L,QSA]
RewriteRule ^([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2 [L,QSA]
RewriteRule ^([\w-]+)/([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2&news=$3 [L,QSA]

To elaborate on my comment further you can have rules like this:
ErrorDocument 404 /error
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^([\w-]+)/?$ index.php?menu=$1 [L,QSA]
RewriteRule ^([\w-]+)/n-([\w-]+)/?$ index.php?menu=$1&news=$2 [L,QSA]
RewriteRule ^([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2 [L,QSA]
RewriteRule ^([\w-]+)/([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2&news=$3 [L,QSA]
Now your news links should like this: http://domain.com/main-menu/n-sports

Consider that your regex starts matching \w, which stands for "word character", usually [A-Za-z0-9_]. Notice the inclusion of the underscore and digits. This also means that this doesn't match accented characters for example. For sure this don't match the leading slash that begins every path in urls.
You should change your rewrites adding a leading slash:
RewriteRule ^/([\w-]+)/?$ index.php?menu=$1 [L,QSA]
RewriteRule ^/([\w-]+)/([\w-]+)/?$ index.php?menu=$1&news=$2 [L,QSA]
# RewriteRule ^/([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2 [L,QSA]
RewriteRule ^/([\w-]+)/([\w-]+)/([\w-]+)/?$ index.php?menu=$1&submenu=$2&news=$3 [L,QSA]
I have also commented the third rule because the regex is identical to the second. Your approach also have a logical problem, since there is no difference between these lines, so there is no way to call index.php?menu=$1&submenu=$2

Related

Regex pattern to exclude specific words at the start of url using htaccess

[Edited code]*
This is the current code I am using
Options +FollowSymLinks
RewriteCond %{REQUEST_URI} (bus/(.*))
RewriteRule bus/(.*) page1.php?param=$1 [L,NC,QSA]
RewriteCond %{REQUEST_URI} (car/(.*))
RewriteRule car/(.*) test/page2.php?param=$1 [L,NC,QSA]
RewriteCond %{REQUEST_URI} (bike/(.*))
RewriteRule bike/(.*) test/page3.php?param=$1 [L,NC,QSA]
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+)/(.+)$ new.php?param1=$1&param2=$2 [L,QSA]
I am trying to get the wild card condition in the last line if the above conditions fail. But the server returning with the 404. Its not catching the condition.
Any Help would be appreciated.
Keep all specific rules are top and 3rd generic catch-all rule at the last:
RewriteEngine On
RewriteRule ^bus/(.+)$ page1.php?param=$1 [L,NC,QSA]
RewriteRule ^car/(.+)$ test/page2.php?param=$1 [L,NC,QSA]
RewriteRule ^bike/(.+)$ test/page3.php?param=$1 [L,NC,QSA]
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.+)/(.+)$ new.php?param1=$1&param2=$2 [L,QSA]
Two RewriteCond are required before last rule to prevent rewriting actual files and directories.
Your need to use the L flag at the end of your rules to stop multiple rule processing :
RewriteRule ^ask/(.*) forum.php?param=$1 [L,NC]
RewriteRule ^city/(.*) city.php?param=$1 [L,NC]

mod-rewrite when index.php is in the URL

I wish to rewrite http://example.com/admin/pages/index.php to http://example.com/index.php?admin=admin&cid=pages.
It works for http://example.com/admin/pages (which I also want), but not for http://example.com/admin/pages/index.php.
How is this accomplished?
RewriteEngine On
RewriteBase /
# If the request is for a valid directory, file, or link, don't do anything
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
#remove the trailing slash
RewriteRule (.+)/$ $1
# If you add this first rule to support views, be sure to remove the QSA flag from the second rule (maybe not required since the first rule has the L flag)
#replace admin/cid with index.php?admin=admin&cid=cid
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?admin=$1&cid=$2 [L,QSA]
#replace mypage with index.php?admin=mypage
RewriteRule ^([^/]+)/?$ index.php?admin=$1 [L,QSA]
EDIT
Random changes shows that this might be correct.
RewriteRule ^([^/]+)/([^/]+)/index.php/?$ index.php?admin=$1&cid=$2 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?admin=$1&cid=$2 [L,QSA]
#replace mypage with index.php?admin=mypage
RewriteRule ^([^/]+)/index.php/?$ index.php?admin=$1 [L,QSA]
RewriteRule ^([^/]+)/?$ index.php?admin=$1 [L,QSA]
Problem is your first rule that is skipping all files & directories from rules.
Replace your rules with this:
RewriteEngine On
RewriteRule ^index\.php$ - [L,NC]
#remove the trailing slash
RewriteRule (.+)/$ $1 [L,R=302]
# If you add this first rule to support views, be sure to remove the QSA flag from the second rule (maybe not required since the first rule has the L flag)
#replace admin/cid with index.php?admin=admin&cid=cid
RewriteRule ^([^/]+)/([^/]+)(?:/?|/index\.php)$ index.php?admin=$1&cid=$2 [L,QSA]
#replace mypage with index.php?admin=mypage
RewriteRule ^([^/.]+)/?$ index.php?admin=$1 [L,QSA]

mod rewrite is not working and not giving any error

We want to change links "www.example.com/page/login/" to "www.example.com/sayfa/giris". I tried this: RewriteRule ^page/^(.+[^/])$/ /sayfa/^(.+[^/])$ [L] But nothing is change. Is there any error?
Thank you very much for your response #geert3 and #anubhava. But all trying failed. Here is my .htaccess content:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^(.*)/{2,}(.*)$
RewriteRule . %1/%2 [R=301,L]
RewriteCond %{REQUEST_URI} /+[^\.]+$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
RewriteRule /(uploads/.*) $1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ page.php?url=$1 [QSA,L]
You can use this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} ^(.*)/{2,}(.*)$
RewriteRule . %1/%2 [R=301,L]
RewriteCond %{REQUEST_URI} /+[^\.]+$
RewriteRule ^(.+[^/])$ %{REQUEST_URI}/ [R=301,L]
RewriteRule /(uploads/.*) $1 [R=301,L]
RewriteRule ^sayfa/giris/?$ /page/login [L,NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ page.php?url=$1 [QSA,L]
Make sure there is not .htaccess in /sayfa/ folder.
I think you need to remove the second ^ and add an initial slash after the first ^. The slash after $ must be removed.
^/page/(.+[^/])$
^ at the start of an expression means "beginning of line" (i.e. in your case you want /page in front of the path). After a square bracket it means "none of the listed characters" (i.e. in your case no slash). In other places, it makes no sense.
$ means "end of line" so it makes no sense to add stuff after it.
Also as #Croises noted, you can't have "matches" on the right. Right side is your target URL, so there you can either re-use matches you made on the left side, use environment variables or hardcoded text, but no new matches. So no ^, [], $ etc.
So for instance the whole rule would become:
^/page/(.+[^/])$ /sayfa/giris [L]

htaccess rewriteRule to uri with repeated pattern

How to redirect "www.mydomain.com/pattern/pattern/value" to "www.mydomain.com/pattern/value" ?
Using:
RewriteRule ^pattern/(.*) /$1 [l,r,qsa]
Redirects to: www.mydomain.com/value, missing the pattern directory.
It is because rule is executing twice due to this pattern: ^pattern/(.*)
It matches /pattern/pattern/value and redirects to /pattern/value
It matches /pattern/value again and redirect to /value
Replace your rule with this:
RewriteCond %{QUERY_STRING} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^[^/]+/(.+)$ /$1?r [L,R]
Thanks anubhava on pointing me to the right direction:
This is my final code
RewriteRule ^search/(.*) search.php?q=$1 [qsa]
RewriteRule ^search/images/(.*) images/$1
RewriteRule ^search/css/(.*) css/$1
RewriteRule ^search/search/(.*) /search/$1?s [l,r]
RewriteCond %{HTTP_REFERER} search/(.*)
RewriteCond %{QUERY_STRINg} !^s$
RewriteRule ^search/(.*) /$1 [l,r]
I'm adding the ?s QUERY_STRING only in case of double pattern, to keep it as clean as possible.
The HTTP_REFERER is used to apply the rule only if the link comes from the page with the query result.

Rewrite URL with 1 or more parameters?

I'm strugglening with my .htaccess file in orther to achieve this:
a.com/male-items (OR)
a.com/male-items/popularity -> a.com/index.php?g=m&sort-popularity
a.com/female-items (OR)
a.com/female-items/popularity -> a.com/index.php?g=f&sort=popularity
a.com/male-items/alphabet -> a.com/index.php?g=m&sort=alphabet
a.com/male-items/alphabet/a -> a.com/index.php?g=m&sort=alphabet&l=a
(and same for female)
I know it should be something like
RewriteRule ^a$ a.com/index.php?q=$1
But actually looking into the different mod-rewrite / regex explanations and cheat-sheets doesn't help a lot with getting it to work. The hard part is to understand how do you define the different parametes in the address and then use them in the rewritten url.
(any explanations with your solution would be appretiated)
Use these rules in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteRule ^male-items/?$ /index.php?g=m&sort=popularity [L,QSA]
RewriteRule ^male-items/([^/]+)/?$ /index.php?g=m&sort=$2 [L,QSA]
RewriteRule ^male-items/([^/]+)/([^/]+)/?$ /index.php?g=m&sort=$2&l=$3 [L,QSA]
RewriteRule ^female-items/?$ /index.php?g=f&sort=popularity [L,QSA]
RewriteRule ^female-items/([^/]+)/?$ /index.php?g=f&sort=$2 [L,QSA]
RewriteRule ^female-items/([^/]+)/([^/]+)/?$ /index.php?g=f&sort=$2&l=$3 [L,QSA]
These htaccess lines redirect all nonexisting files/folders to index.php:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
RewriteRule ^.*$ index.php [NC,L]
inside index.php you can use: $_SERVER['REQUEST_URI'] to parse your parameters.