htaccess conditional rewrite - apache

I am fiddling around with .htaccess and mod_rewrite. I have a site that has two types of URLs which I want to rewrite:
/index.php?nav=$2
/index.php?nav=41&intNewsId=$3 -- 41 is static, the news nav is always 41
I want to rewrite them to:
/pagename/id
/news/pagename/id
I already made a piece of code that works, BUT if I add the last line the second line stops working, and I can imagine thats because the conditions in the third block are also true for the second block. But I cant figure out how to use conditions right. (Both blocks work individual)
Options +FollowSymlinks
RewriteEngine on
# Reroute rules that end on /
RewriteRule ^(.*)\/([0-9]|[1-9][0-9]|[1-9][0-9][0-9])$ /$1/$2/ [R]
# Make the system understand pagename/96
RewriteRule ^(.*)\/([0-9]|[1-9][0-9]|[1-9][0-9][0-9])/$ /index.php?nav=$2
# Make the system understand news/pagename/99
RewriteRule ^(.*)\/(.*)\/([0-9]|[1-9][0-9]|[1-9][0-9][0-9])/$ /index.php?nav=41&intNewsId=$3
I tried everything I could think of, but I'm not too familiar with this regex style of typing or conditional blocks in htaccess.
Solution:
I fixed my own code, I just stripped the second $ so the condition didnt interfere with the last one
Options +FollowSymlinks
RewriteEngine on
# Reroute rules that end on /
RewriteRule ^(.*)\/([0-9]|[1-9][0-9]|[1-9][0-9][0-9])$ /$1/$2/ [R]
# Make the system understand pagename/96
RewriteRule ^(.*)\/([0-9]|[1-9][0-9]|[1-9][0-9][0-9])/ /index.php?nav=$2
# Make the system understand news/pagename/99
RewriteRule ^(.*)\/(.*)\/([0-9]|[1-9][0-9]|[1-9][0-9][0-9])/$ /index.php?nav=41&intNewsId=$3
Thanks for the answers all!

Try this:
RewriteRule ^news/.+/([^/]*)$ /index.php?nav=41&intNewsId=$1 [L]
RewriteRule ^.+/([^/]*)$ /index.php?nav=$1 [L]

Another approach, perhaps slightly more concise:
RewriteRule ^pagename/(\d+)$ index.php?nav=$1
RewriteRule ^news/pagename/(\d+)$ index.php?nav=41&intNewsId=$1

Try this:
# Make the system understand pagename/96
RewriteCond %{REQUEST_URI} ^/pagename/([0-9]*)
RewriteRule .* /index.php?nav=%1
# Make the system understand news/pagename/99
RewriteCond %{REQUEST_URI} ^/news/pagename/([0-9]*)
RewriteRule .* /index.php?nav=41&intNewsId=%1

Related

How to prevent rewrite .htaccess file conflict problem

RewriteEngine on
RewriteRule ^([^/\.]+)/?$ category.php?slug=$1
RewriteRule ^([^/\.]+)/([^/\.]+)$ product-details.php?slug1=$1&slug=$2
RewriteRule ^([^/\.]+)/?$ infrastructure-details.php?slug=$1
what I have already tried
This is my htaccess file. problem is when I am trying to execute (infrastructure-details.php?slug=$1) its move to (category.php?slug=$1) conflict with first rule of htaccess.
I tired multiple rewrite methods but its not working. Please help to solve this issue.
localhost/project/category.php?slug=pump, localhost/project/infrastructure-details.php?slug=paint second url i want to be-> localhost/project/paint both page is different. can you please specify how to write rules for this different pages.
There is no discernible pattern that differentiates these two URLs so the only way to implement these two rewrites is to hardcode them. For example:
RewriteRule ^pump$ category.php?slug=$0 [L]
RewriteRule ^paint$ infrastructure-details.php?slug=$0 [L]
Where the $0 backreference in the substitution string contains the entire match by the RewriteRule pattern (just saves some repetition).
If you need a more general solution (as your directives suggest) then there needs to be a discernible pattern in the URL that differentiates URLs that should be rewritten to category.php and infrastructure-details.php respectively.
I'm assuming your .htaccess file, and other files, are is inside the /project subdirectory.
RewriteRule ^([^/\.]+)/?$ category.php?slug=$1
RewriteRule ^([^/\.]+)/([^/\.]+)$ product-details.php?slug1=$1&slug=$2
RewriteRule ^([^/\.]+)/?$ infrastructure-details.php?slug=$1
Rule #1 and #3 conflict - they use exactly the same pattern (regex) to match against the requested URL. The first rule is always going to "win" and rewrite the request before rule#3 is able to process the request, so rule#3 never matches.
To write a generic rule like this there needs to be a discernible difference between the URL types that you can match with a pattern/regex. For example:
/category/pump
/infrastructure/paint
And then you can construct rules...
Options -MultiViews
RewriteRule ^category/([^/]+)$ category.php?slug=$1 [L]
RewriteRule ^infrastructure/([^/]+)$ infrastructure-details.php?slug=$1 [L]
Note that the order of these directives can be important. More specific rules need to be before more generalised rules.
Options -MultiViews
RewriteEngine on
RewriteRule ^infrastructure/([^/]+)$ infrastructure-details.php?slug=$1 [L]
RewriteRule ^([^/\.]+)/?$ category.php?slug=$1 [L]
RewriteRule ^([^/\.]+)/([^/\.]+)$ product-details.php?slug1=$1&slug=$2 [L]
This is work fine for me. (infrastructure-details.php?slug=$1 [L]) put on top.

RewriteRule 301 redirect for whole directory and sub-directories

I really need your help with this one...
I'm simply trying to redirect EVERYTHING in a directory to another. It looks simple when I read about it, but in real life, it's not working... Here is my entire .htaccess file right now:
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# Redirect all to HTTPS
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.org/$1 [R]
# End redirect
#301 REDIRECTS
Options +FollowSymLinks
RewriteRule ^mydir/(.*)$ /mydir-and-more/$1 [R=301,NC,L]
Fisrt, there is Wordpress stuff in didn't mess with.
Then, the code i copy/pasted from some site to redirect http to https. It works well. Note that i removed the "L" argument from the list to make sure my next rules will work.
After comes the part I'm strugling with.
So, it really is like that. My new directory starts with the same word then my old directory.
I copied this line from there: https://coolestguidesontheplanet.com/redirecting-a-web-folder-directory-to-another-in-htaccess/
On the Apache web site (https://httpd.apache.org/docs/current/mod/mod_rewrite.html) it says that i should use a / between ^ and mydir. Tried it, didn't work.
I tried moving Options +FollowSymLinks at the top of the file. Nothing.
When i use something like this:
RedirectMatch 301 ^/mydir/ https://example.org/mydir-and-more/
This works. But only moves the exact /mydir/ address. It doesn't move the whole directory. Also, if I type in https://example.org/mydir without the last /, it won't work. If i add the / in the Redirect match, it doesn't work anymore because its the same word!
So, here I am, totally confused! Please, any expert advise on this one? Thanks!!
You need to move you rules before the wordpress defined ones.
In fact if you try to access you site the rewrite rules elaboration stops at
RewriteRule . /index.php [L]
That instruction means "manage all paths that are not already beign managed by upper rule and stop elaboration ([L] stands for last)".
You can safely place your rules above the wordpress ones, better in a ifmodule
<IfModule mod_rewrite.c>
RewriteRule ^/mydir/(.*)$ /mydir-and-more/$1 [R=301,NC,L]
</IfModule>
# BEGIN WordPress
Funniest thing is, I solved my problem by fooling around! I didn't really need the RewriteRule, all I needed to write instead of the RewriteRule was exactly this :
Redirect 301 /mydir https://example.org/mydir-and-more
I don't even need the Options +FollowSymLinks.

mod_rewrite RewriteRule is not working always

how can i make the following condition work if there is no number, so it can handle www.example.com/en/fourthcategory as well as www.example.com/en/fourthcategory/8562
RewriteRule en/fourthcategory/([0-9]+) ?l=en&c=c4&p=$1 [L]
i could use two rules, but would prefer using only one, since in the end there would be double as much rules and there will be quite a lot of categories in at least four languages...
RewriteRule en/fourthcategory/([0-9]+) ?l=en&c=c4&p=$1 [L]
RewriteRule en/fourthcategory ?l=en&c=c4 [L]
or is this not the right approach to create RewriteRules for every possible category separately?
You can try this:
RewriteEngine On
RewriteRule en/fourthcategory/?([0-9]*) ?l=en&c=c4&p=$1 [L]
Be carefull, with http://www.example.com/en/fourthcategory/8562, you'll get a final URL like this:
/index.php?l=en&c=c4&p=8562
index.php can be any DirectoryIndex filename of your apache server.

Using .HTACCESS Rewrite Rule

I'm trying to rewrite URLs for my dynamically generated PHP site.
I load new templates into index.php by using the following GET:
localhost/dmk/?req=signin
localhost/dmk/?req=useraccount
I want these links to appear as:
localhost/dmk/signin
localhost/dmk/useraccount
But for the life of me I cannot figure out how to do this. Everything I try either produces a 500 Internal Server Error, or has no effect at all.
I must be missing the point of RewriteRule.
You should read some documentation in this direction. I know it's a bit frustrating at first to write the rules, but it gets easier. You need to learn regular expressions to write the rules (you can start here: http://www.regular-expressions.info/)
As for the rules you need, they go like this:
RewriteEngine On
RewriteRule ^signin$ index.php?req=signin [L,QSA]
RewriteRule ^useraccount$ index.php?req=useraccount [L,QSA]
or
RewriteRule ^(signin|useraccount)$ index.php?res=$1 [L,QSA]
You can paste the rules you have used, maybe someone will explain you what you did wrong.
Try this
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d # not a dir
RewriteCond %{REQUEST_FILENAME} !-f # not a file
RewriteRule ^dmk/(.+)$ dmk/?req=$1 [NC,QSA,L]
This would redirect any URL like /dmk/page that does not conflict with an existing file or directory to /dmk/?req=page. I'm assuming your index.php is in /dmk directory.

apache htaccess map first segment as parameter without disturbing other parameters

This is might be a classic .htaccess question, but still I couldn't find the question for my specific case. Here's the closest I found (parameters involve in my case). Done implementing the two answers. Couldn't work for my case.
My case
1) I want any access for this URL,
mywebsite.com/any-first-segment?param1=a&param2=b&param3=c&paramN=anything
will be remapped to
mywebsite.com/index.php?p=any-first-segment&param1=a&param2=b&param3=c&paramN=anything
2) Still working if there's no param.
3) I will never have more than one segment. (zero segment still works, mapped to index.php as usual)
Could you suggest me the working RewriteRule for this case?
Here's the last .htaccess, which is still not working
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.+)$ index.php?p=$1 [QSA,L]
[Updated!]
It's working. I found I messed up with Options +FollowSymLinks after reading this
Here's the working .htaccess. With exception.
RewriteEngine On
RewriteCond $1 !^(index\.php|images|robots\.txt|css)
RewriteRule ^(.+)$ index.php?p=$1 [QSA,L]
Using the QSA flag in your rule will append the current query string to the rewritten form.