.htaccess url rewrite with two variables - .htaccess

i tried and tried with examples posted here, but i didn't manage to make my htaccess run properly.
Here's the situation:
i have links looking like this
domain.com/sport/football/index.php?lang_id=1&page_id=500 (home page)
domain.com/sport/football/index.php?lang_id=1&page_id=505 (players)
domain.com/sport/football/index.php?lang_id=1&page_id=510 (coaches) ...
i would like to rename them to
domain.com/sport/football/
domain.com/sport/football/players/
domain.com/sport/football/coaches/
etc...
and for all non-designated page_id's to redirect to home page.
All help is very much appreciated.

In the htaccess file in your document root, add:
RewriteEngine On
RewriteRule ^sport/football/$ /sport/football/index.php?lang_id=1&page_id=500 [L,QSA]
RewriteRule ^sport/football/players/?$ /sport/football/index.php?lang_id=1&page_id=505 [L,QSA]
RewriteRule ^sport/football/coaches/?$ /sport/football/index.php?lang_id=1&page_id=510 [L,QSA]
RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /sport/football/index\.php
RewriteCond %{QUERY_STRING} ^(.*)page_id=500($|&)
RewriteRule ^ /sport/football/? [L,R=301]
RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /sport/football/index\.php
RewriteCond %{QUERY_STRING} ^(.*)page_id=505($|&)
RewriteRule ^ /sport/football/players/? [L,R=301]
RewriteCond %{THE_REQUEST} ^(GET|HEAD)\ /sport/football/index\.php
RewriteCond %{QUERY_STRING} ^(.*)page_id=510($|&)
RewriteRule ^ /sport/football/coaches/? [L,R=301]

You can use RewriteMap Directive for that. You must define the mapping from names to ids
players 505
coaches 510
and tell Apache about the map
RewriteMap football txt:/path/to/footballmap.txt
The RewriteMap must be in either the main configuration file or inside a VirtualHost directive.
Now you can use this map
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^sport/football/(.*)/?$ /sport/football/index.php?lang_id=1&page_id=${footballmap:$1|500} [L]
If there's no key found, the default 500 (homepage) will be used. If you have lots of mappings, you can also use a hashfile instead.
Update:
When you don't have access to the server or virtual host configuration file, you can only have a fixed RewriteRule "map"
RewriteRule ^sport/football/players/?$ /sport/football/index.php?lang_id=1&page_id=505 [L]
RewriteRule ^sport/football/coaches/?$ /sport/football/index.php?lang_id=1&page_id=510 [L]
# maybe other similar rules ...
# this is a catch everything else and must come last
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^sport/football/ /sport/football/index.php?lang_id=1&page_id=500 [L]

Related

.htaccess RewriteRule(s) not working

I am trying to learn how to use RewriteRule.
I have 2 'pages' (wordpress)-
domain.com/webinars/ (shows list of all webinars)
and
domain.com/webinar/ (shows specific webinar details)
I have trying to set the following conditions -
(1) domain.com/webinars/{Year}/{Month}/ will load /webinar/?year={Year}&month={Month}
(2) domain.com/webinar/ (with no /{Year}/{Month}) will load /webinars/
(3) domain.com/webinar/?year={Year}&month={Month} will redirect to /webinars/{Year}/{Month}/ and then apply condition #1
This is my attempted code
RewriteEngine On
RewriteRule ^/webinars/([0-9]+)/([A-Za-z0-9]+)/$ /webinar/?year=$1&month=$2 [NC]
RewriteRule ^/webinar/$ /webinars/
RewriteRule ^/webinar/year=(\d+)$month=([\w-]+)$ /webinars/%1/%2? [R=301,L]
Condition #1 results in a 404 page not found
Condition #2 shows /webinar/ and not /webinars/
Condition #3 stays on domain.com/webinar/?year={Year}&month={Month} and does not redirect
What am I doing wrong? Only other code in my htaccess file is the default wordpress block.
Try the following :
Options +FollowSymlinks
RewriteEngine on
RewriteRule ^webinars/([^/]+)/([^/]+) /webinar/?year=$1&month=$2 [NC]
The rest could be done the same way .
Try with below rules,
RewriteCond %{REQUEST_URI} ^/webinar$
RewriteCond %{QUERY_STRING} ^year=([^/]+)&month=([^/]+)
RewriteRule ^ http://example.com/webinars/%1/%2/? [R=302]
RewriteCond %{REQUEST_URI} ^/webinars/([^/]+)/([^/]+)/$
RewriteRule ^ webinar/?year=%1&month=%2 [L,END]
RewriteCond %{REQUEST_URI} ^/webinar/$
RewriteRule ^ webinars/ [L]
You can use this
RewriteEngine on
# if /webinar/ is requested skip the rules and serve /webinar/ directory
RewriteRule ^webinar/?$ - [L]
#redirect /webinar/?year={year}&month={month}
#To /webinar/year/month
RewriteCond %{THE_REQUEST} /webinar/\?year=([^\s&]+)&month=([^\s&]+) [NC]
RewriteRule ^.+$ /webinar/%1/%2? [L,R]
# rewrite new url to the old one
RewriteRule ^webinar/([^/]+)/([^/]+)/?$ /webinar/?year=$1&month=$2 [L,NC]

Hiding multiple dynamically-named subdirectories with mod_rewrite in .htaccess

I am having difficulty configuring a mod_rewrite rule in my .htaccess file to hide certain subdirectories.
Input:
https://example.com/hidden_sub1/hidden_sub2/additional_sub/file.php?lang=en-US
Desired output:
https://example.com/en-US/additional_sub/file
I had code that allowed me to hide something if I specifically name it:
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^GET\ /hidden_sub1/hidden_sub2/ [NC]
RewriteRule ^hidden_sub1/hidden_sub2/(.*) /$1 [L,R=301]
RewriteRule !^hidden_sub1/hidden_sub2/ hidden_sub1/hidden_sub2%{REQUEST_URI} [L]
However, it stopped working once I added in the following language subdirectory code:
RewriteRule ^([a-z]{2}(-[A-Z]{2})?)/(.*) $3?lang=$1 [L,QSA]
Besides, the name of the subdirectory is dynamic. "hidden_sub1" might be "random_name243". However, they would always be the first two subdirectories.
So how do I take out the first two randomly-named subdirectories while still keeping the language subdirectory?
I appreciate any help.
To change your url from the form
https://example.com/hidden_sub1/hidden_sub2/additional_sub/file.php?lang=en-US
To the form :
https://example.com/en-US/additional_sub/file
You can use the following Rewrite rule
RewriteEngine On
RewriteBase /
#1)externally redirect "/hidden_sub1/hidden_sub2/foo.php?lang=bar" to "/bar/foo"
RewriteCond %{THE_REQUEST} /hidden_sub1/hidden_sub2/([^.]+)\.php\?lang=(.+)\sHTTP [NC]
RewriteRule ^ /%2/%1? [L,R=301]
#2)internally rewrite "/bar/foo" to "/hidden_sub1/hidden_sub2/foo.php?lang=bar"
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+)/?$ /hidden_sub1/hidden_sub2/$2.php?lang=$1 [NC,L]
Tested on apache 2.2. and 2.4.

Force https and non-www urls, not working in subdomain

In the public_html folder which is the root folder of my main site thesite.com, I have this htaccess file:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^m\.thesite\.com$ [NC]
RewriteCond %{HTTP_HOST} ^blog\.thesite\.com$ [NC]
RewriteRule ^ - [L]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} ^www\.thesite\.com [NC]
RewriteRule ^(.*)$ https://thesite.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^category/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ category\_product\_list.php?mid=$1&sid=$2&did=$3 [L]
RewriteRule ^category/([^/\.]+)/([^/\.]+)/?$ category\_product\_list.php?mid=$1&sid=$2 [L]
RewriteRule ^category/([^/\.]+)/?$ category\_product\_list.php?mid=$1 [L]
RewriteRule ^p/([^/\.]+)/([^/\.]+)/([0-9]+)/([0-9]+)/([0-9]+)/?$ product.php?id=$2&vid=$3&mid=$4 [L]
RewriteRule ^p/([^/\.]+)/([^/\.]+)/([0-9]+)/([0-9]+)/?$ product.php?id=$2&vid=$3 [L]
RewriteRule ^p/([^/\.]+)/([^/\.]+)/([0-9]+)/?$ product.php?id=$2 [L]
RewriteRule ^offer/(.*) product_offer.php?ind=$1
RewriteRule ^([^/\.]+)/?([^/\.]*)/?$ $1.php [QSA,L]
Here, am forcing non-www url as well as forcing https URL for the thesite.com. And I have two subdomains: m.thesite.com and blog.thesite.com.
Both are in separate subfolders inside public_html.
The m.thesite.com is in /public_html/m.thesite.com/ folder. And it has this htaccess file:
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
RewriteCond %{HTTP_HOST} ^www\.m\.thesite\.com [NC]
RewriteRule ^(.*)$ https://m.zapteka.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^category/([^/\.]+)/([^/\.]+)/([^/\.]+)/?$ category\_product\_list.php?mid=$1&sid=$2&did=$3 [L]
RewriteRule ^category/([^/\.]+)/([^/\.]+)/?$ category\_product\_list.php?mid=$1&sid=$2 [L]
RewriteRule ^category/([^/\.]+)/?$ category\_product\_list.php?mid=$1 [L]
RewriteRule ^p/([^/\.]+)/([^/\.]+)/([0-9]+)/([0-9]+)/([0-9]+)/?$ product.php?id=$2&vid=$3&mid=$4 [L]
RewriteRule ^p/([^/\.]+)/([^/\.]+)/([0-9]+)/([0-9]+)/?$ product.php?id=$2&vid=$3 [L]
RewriteRule ^p/([^/\.]+)/([^/\.]+)/([0-9]+)/?$ product.php?id=$2 [L]
RewriteRule ^([^/\.]+)/?([^/\.]*)/?$ $1.php [QSA,L]
RewriteRule ^offer/(.*) product_offer.php?ind=$1
For this subdomain also, I need to force https urls as well as non-www urls.
It seems to be working for the main site. I mean thesite.com. But when I try to access the m.thesite.com, it seems to be internally redirecting to the files of thesite.com instead of the m.thesite.com. I mean the url is being shown as https://m.thesite.com/ but the pages are from https://thesite.com
I have been trying to debug the issue for several hours now. Probably it could be something small that I missed. Any ideas?
BTW, thesite.com is having Wildcard SSL installed.
EDIT
Am sorry if my explanation was confusing. When I said url is showing as https://m.thesite.com/ but the content is from https://thesite.com/, I meant to say that in browser the url is shown as https://m.thesite.com. But the template file contents where from the desktop version of the main site thesite.com. The m.thesite.com is mobile version of the site. The pages that displays the contents where separate in both the desktop and mobile version of the site.
Like you see in the htaccess code that I included above, there is some PHP files inside the /public_html/ folder for the desktop version. All the files for the mobile version of the site is in /public_html/m.thesite.com/ folder.
So, in short, when I try to access the https://m.thesite.com/, it is displaying the index.php page from /public_html/index.php instead of /public_html/m.thesite.com/
So that's how I found that there's issue in the routing.
EDIT
VirtualHost entries fetched by using this command /usr/local/apache/bin/httpd -S:
I have also checked the Apache version and saw that it's 2.2.27 using the command: httpd -V
So I tried adding this line in the htaccess file:
RewriteLog "/logs/rewrite.log"
RewriteLogLevel 9
But it was giving internal server error. So I tried this line instead also:
LogLevel mod_rewrite.c:trace8
That was also giving me internal server error when site is accessed. So I commented it out.

.htaccess, Rewriterule not working as i want

I have this link: http://www.domain.com.mk/lajmi.php?id=2790,
and i want to change it to http://www.domain.com.mk/lajmi/2790
With this code I can change the link to /lajmi/2790 but i get 404 error.
I mean i get the link
http://www.domain.com.mk/lajmi/2790, but it has 404 error (i dont se the content)
This is my code:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain\.com\.mk$ [OR]
RewriteCond %{HTTP_HOST} ^www\.domain\.com\.mk$
RewriteCond %{QUERY_STRING} ^id=([0-9]*)$
RewriteRule ^lajmi\.php$ http://domain.com.mk/lajmi/%1? [R=302,L]
What I am doing wrong ?
Try this one :
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com\.mk$
RewriteCond %{QUERY_STRING} ^id=(\d*)$
RewriteRule ^lajmi\.php$ http://domain.com.mk/lajmi/%1? [R=302,L]
RewriteRule ^lajmi/(\d*)$ lajmi.php?id=$1&r=0 [L]
(the &r=0 in the final rule is for not getting an infinite loop)
Single direction rewrite:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com\.mk$
RewriteRule ^lajmi/(\d*)$ lajmi.php?id=$1 [L,QSA]
This means that every uri of kind /lajmi/2790 will be passed to /lajmi.php?id=2790 in a sub-request.
However, in this case, if the user hits /lajmi.php?id=2790 by himself, then this is the url he will see in the browser, not the "beautified one".
Bi-directional rewrite:
RewriteEngine On
RewriteBase /
; Redirect lajmi.php?id=2790 to a beutified version, but only if not in sub-request!
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com\.mk$
RewriteCond %{IS_SUBREQ} !=true
RewriteCond %{QUERY_STRING} ^id=(\d*)$
RewriteRule ^lajmi\.php$ lajmi/%1 [R=301,L]
; Make the beutified uri be actually served by lajmi.php
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com\.mk$
RewriteRule ^lajmi/(\d*)$ lajmi.php?id=$1 [L]
Here, an additional RewriteCond was added to the first rule checking that this is not a sub-request, to ensure that the rules do not loop.
You can pick which way you like, but the first approach is enough if you build the links in your HTML in the 'beautified' way already (no need to redirect the browser twice just to see the page).

htaccess rewrite still some problems, getting a bit complex eek!

Another edition to my .htaccess rewriting saga. Everything is now working to a degree but still have some issues.
I have numerous rules to move old urls to new urls, passing variables etc - however there are still a couple of things i need to add, and for the life of me cannot figure out.
I have 3 urls that are directing/rewriting as below.
1 www.mydomain.com/news/dentistry_dental/index.php
2 www.mydomain.com/news/dentistry_dental/index.php?month=April&year=2011
3 www.mydomain.com/news/dentistry_dental/article_detail.php?article=1234&title=some-title
These are redirected & rewritten perfectly to the new urls respectively
1 www.mydomain.com/dental_news/
2 www.mydomain.com/dental_news/April-2011
3 www.mydomain.com/dental_news/1234-some-title
However... Here is the problem #1 The following urls are also redirecting as below
4 www.mydomain.com/news/it_technology/index.php?month=April&year=2011
5 www.mydomain.com/news/it_technology/article_detail.php?article=1234&title=some-title
Which are also directing to the same urls as the dental redirects
4 www.mydomain.com/dental_news/April-2011
5 www.mydomain.com/dental_news/1234-some-title
Which shouldnt be happening. The it_technology news articles have now been removed so i wish to redirect them either to my homepage with a 410 or something similar, whichever is the best option really.
My current .htaccess looks as follows.
Options +FollowSymlinks
RewriteEngine on
rewritecond %{http_host} ^mydomain.com [nc]
rewriterule ^(.*)$ http://www.mydomain.com/$1 [r=301,nc]
# Rewrite all index.php to root: / ( with perm redirect )
RewriteCond %{REQUEST_URI} !/generator/
RewriteCond %{THE_REQUEST} ^.*/index.php
RewriteRule ^(.*)index.php$ http://www.mydomain.com/$1 [R=301]
RewriteRule ^products/dental-digital-imaging/([^/]*)_([^/]*)$ /products/digital_xray.php?id=$1&product=$2 [L]
RewriteRule ^products/package_deals.php$ http://www.mydomain.com/products/dental-computer-network-bundles [R=301]
RewriteRule ^products/computer_hardware.php$ http://www.mydomain.com/products/dental-computer-solutions [R=301]
RewriteRule ^products/individual_computers.php$ http://www.mydomain.com/products/dental-computer-systems [R=301]
RewriteRule ^products/digital_xray_imaging.php$ http://www.mydomain.com/products/dental-digital-imaging [R=301]
RewriteRule dental_news/$ /news/dentistry_dental/?rewrite [L]
# Rewrite dental news article to neat nice url
# Protect from looping because of previous rules
RewriteCond %{QUERY_STRING} !rewrite
RewriteRule ^dental_news/([0-9]*)-([^/]*)$ news/dentistry_dental/article_detail.php?article=$1&title=$2&rewrite [L]
#Conditional rewrite of old news article path to new one with 301 redirect
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} article=([0-9]*)&title=([^&]*)$
RewriteRule (.*) /dental_news/%1-%2? [L,R=301]
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} month=([^&]*)&year=([^&]*)$
RewriteRule (.*) /dental_news/%1-%2? [R=301]
# Protect from looping because of previous rules
RewriteCond %{QUERY_STRING} !rewrite
RewriteRule news/dentistry_dental/$ /dental_news/ [R=301]
# Protect from looping because of previous rules
RewriteCond %{QUERY_STRING} !rewrite
RewriteRule ^dental_news/([a-zA-Z]*)-([0-9]*)/?$ news/dentistry_dental/index.php?month=$1&year=$2&rewrite [L]
# Rewrite URL stripping .php Extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
My only other requirement would be to add a trailing slash to the php files served ( that have allready add the .php extension removed with the last rule in my .htaccess.
I have tried numerous ways that i have found via google, but all of them cuase probelms with my other rules.
Hopefully someone can help me finish this off once and for all.
Regards
M
Sure is getting complicated :) Try changing these lines (I think there are 2):
RewriteCond %{REQUEST_URI} !^/dental_news/
to:
RewriteCond %{REQUEST_URI} ^/news/dentistry_dental/
That way its only going to redirect the old dental news URLs to there respective new ones.
Trivially, your problem is the catch-all rules:
#Conditional rewrite of old news article path to new one with 301 redirect
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} article=([0-9]*)&title=([^&]*)$
RewriteRule (.*) /dental_news/%1-%2? [L,R=301]
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} month=([^&]*)&year=([^&]*)$
RewriteRule (.*) /dental_news/%1-%2? [R=301]
Restrict them to the path you want to rewrite, i.e. replace .* with something more specific, like:
#Conditional rewrite of old news article path to new one with 301 redirect
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} article=([0-9]*)&title=([^&]*)$
RewriteRule ^news/dentistry_dental/index.php$ /dental_news/%1-%2? [L,R=301]
RewriteCond %{REQUEST_URI} !^/dental_news/
RewriteCond %{QUERY_STRING} month=([^&]*)&year=([^&]*)$
RewriteRule ^news/dentistry_dental/index.php$ /dental_news/%1-%2? [R=301]
You can do the news/it_technology redirect as a standard redirect.
RewriteRule ^news/it_technology http://www.thepage.com/ [R=301,L]
It might technically be more correct to do a 410, but the 410 code is really optional. You might also want to make it 404, and then have a link from the 404 page to the main page.

Resources