Complex URL rewriting with .htaccess - .htaccess

Here is what i am trying to achieve
www.example.com/category
www.example.com/category/subcategory
www.example.com/category/subcategory/product
www.example.com/static-page (like /about-us, /contact, /our-services)
(category, subcategory, products, static-pages etc are dynamic text and there is a permalink foreach thing in the database)
if you see all above requests, you will notice that they are just like extending the directory sturcutre one step each time when the link is clicked, e.g, first was category, and then when I clicked on the subcatogery, I was sent to category/subcategory/ and the finally to product page
Anybody can help me how to acheive all this, i have tried lot to achieve this but in vain yet.
Currently i am using this .htaccess
RewriteRule c/(.*)/(.*)/ cat-details.php?permalink=$1&subcat=$2
RewriteRule c/(.*)/(.*) cat-details.php?permalink=$1&subcat=$2
RewriteRule news/(.*)/(.*)/ news-detail.php?news-id=$1&permalink=$2
RewriteRule news/(.*)/(.*) news-detail.php?news-id=$1&permalink=$2
RewriteRule d/(.*)/(.*)/(.*)/(.*)/ download-detail.php?download-id=$1category=$2&subcategory=$3&permalink=$4
RewriteRule d/(.*)/(.*)/(.*)/(.*) download-detail.php?download-id=$1category=$2&subcategory=$3&permalink=$4
As you can see i have to add c/, news/, d/ etc for each link, i am trying to get rid of this and want to make links pretty whitout proceeding c/, news/, d/ etc

About the only way you're going to be able to do this in Apache proper, is to provide info on which URLs map to which scripts. Apache lets you do this via the RewriteMap directive, but that won't work in .htaccess files. Without it, and without the news/ or c/, Apache doesn't have enough info to route the URLs properly.
What you could do, is simply rewrite every URL that doesn't refer to an existing file, to a script that knows which scripts to run in response. A "router" or "front controller" script, they call it. Something like this:
RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !-d
RewriteRule (.*) router.php?path=$1 [QSA]
And in the script, you examine $_GET['path'], decide which script should handle the request, and load/include/require it.

I have found a way myself, just posting it if it could help anyone else in trouble just like me :p
RewriteRule ^([^/]*)\/$ /romuniverse/cat.php?permalink=$1 [L]
RewriteRule ^([^/]*)/([^/]*)\/$ /romuniverse/sub-cat.php?permalink=$1&subcat=$2 [L]
RewriteRule ^([^/]*)/([^/]*)/([^/]*)/([^/]*)\.rar$ /romuniverse/download-detail.php?download-id=$1&category=$2&subcategory=$3&permalink=$4 [L]

Related

.htaccess RewriteRule query isn't working

I can't get the following RewriteRule to work.
I have a PHP SQL query to display a web page. It requires a RewriteRule rule which I'm trying to achieve in a .htaccess file.
Here is the full URL at the moment.
www.example.com/category/sub-cat/page.php?art_url=a-page-of-mine
I can't get it to do
www.example.com/category/sub-cat/a-page-of-mine
My Code below:
Options +MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
ErrorDocument 404 /error-404.php
#error 404
RewriteRule ^error/?$ error-404.php [NC,L]
RewriteRule ^category/sub-cat/(0-9a-zA-Z]+) category/sub-cat/page.php?art_url=$1 [NC,L]
Can someone help me out?
AS I said in the comments
Missing a few things here (0-9a-zA-Z]+) like [- as in ([-0-9a-zA-Z]+)
This is going to bite you too...
RewriteRule ^([^\.]+)$ $1.php [NC,L]
Match everything that doesn't have a dot and add .php to it with the [L] last flag. I would bet it will never pass that one in the first place.
Generally you want the more specific rules first, followed by the more generic ones last.
Also if I recall correctly the NC i no case, so you can get rid of the A-Z and just do [-a-z0-9]+
A better way
I try to avoid query string rewrites and rely on the URI method of rewriting common in MVC frameworks
example.com/index.php/category/sub-cat/a-page-of-mine
And then use a router and HTACCESS to only remove the index.php it's much simpler that way.
I have a pretty bare bones router on my GitHub page that shows how to route URL's like that.
https://github.com/ArtisticPhoenix/MISC/tree/master/Router
One big issue with messing with the query string is you can lose the ability to use $_GET the way it's designed to be used for things like search forms etc. So it's better to route not rewrite. Also the MVC way gives you a single entry point for all requests to go through which can make it easier to manage things like Constants, and Autoloaders....
Oh well, this is broken of course:
(0-9a-zA-Z]+)
The charclass lacks the opening [ and doesn't contain/match a literal - as well.
Right. To get this working I needed to add QSA as in [QSA,NC,L]. After how many weeks!!??

I can't get the second rewrite rule to work in my .htaccess file

I am working locally on Windows 7 with wamp server (v2.5). I have one working rewrite rule for the main front controller in my project, like this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php/$1 [NC,L]
It successfully strips .php from the queries. From this main front controller index.php I have a link to another front controller named theme.php, where I use menu links w/o the.php file extension, like this:
theme/regions
in stead of
theme.php/regions
For that to work I need to add a second rewrite rule to add the php exension, like so:
RewriteRule ^theme($|/$) theme.php/$1 [NC,L]
The only thing I get is a 404 page though :-(.
I would be very grateful for some hints on how to go about this.
You need to put your theme rule before the general route to index.php. And you need to reference what comes after the /theme/ so something like:
RewriteRule ^theme(/?.*)$ theme.php$1 [L]
Additionally, this rule won't work if you have Multiviews turned on, but, this is actually something that's perfectly suited for Multiviews anyways, so you could just try turning that on instead of using a rule to rewrite theme:
Options +Multiviews
Your second RewriteRule works independently of the others and should be placed above the others in your question.
In addition, the format is wrong - you don't need to capture or append anything.
RewriteRule ^theme/?$ theme.php [NC,L]

how joomla htaccess identifies what is the get method for particular alias?

Im developing a website which supports SEF urls. I use PHP as serverside language. I know htaccess basic codes how works with it. But the problem is if I want to rewrite a php get link I have to put each both links on htaccess like this.
RewriteRule ^sign-in$ index.php?view=signin
RewriteRule ^register$ index.php?view=register
RewriteRule ^jobs$ index.php?id=2
Is there any possible way to automate urls with htaccess and url particular alias instead of adding Rewrite rules manually? something like joomla? I was trying to understand how joomla htaccess connects with particual alias. But I still couldn't understand how it works. I cant uderstand how joomla htaccess makes relationship with article aliases. Please help. Thanks in advance.
If there isn't any difference for how an id looks like compared to how a view looks like (in your example, register is a view and jobs is an id=2), then you have to do one or the other individually:
To "automate" the views you could try just doing this:
RewriteEngine On
# all id's here:
RewriteRule ^jobs$ index.php?id=2 [L]
RewriteRule ^something-else$ index.php?id=3 [L]
RewriteRule ^another$ index.php?id=4 [L]
# this will do all views
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?view=$1 [L]
EDIT: If you need to do these mappings via an external set of aliases, you need to take a look at the RewriteMap directive. You will need to have access to the server or vhost configs in order to setup the map, but your rules can stay in an htaccess file.
Say you have a text file called "joomla_maps.txt" that looks like:
jobs id=2
another id=3
sign-in view=sign-in
register view=register
etc...
You can use that mapping by setting it up in a RewriteMap (in vhost/server config)
RewriteMap joomla txt:/path/to/joomla_maps.txt
And later in your htaccess:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?${joomla:$1} [L]
Take a look through the RewriteMap docs to get some examples of other kinds of maps, including executing a script or using a dbm hash map.

Change Displayed URL Structure using mod_rewrite NOT Working

I need to change the structure of the displayed client-side URL. I'm not too skilled using regex and coding for the .htaccess file. Basically, I have a structure that looks something like:
http://www.example.com/catalog/index.php?cat=lt&sec=lt1-1&id=nmlt10.
I would like this to be displayed in the address bar as:
http://www.example.com/catalog/lt/lt1-1/nmlt10.
This is what I came up with, but it has had no effect:
RewriteEngine On
RewriteRule ^([^/]*)/([^/]*)/([^/]*)\$ /catalog/index.php?cat=$1&sec=$2&id=$3 [L]
I tested and removed any other rules in the .htaccess file to ensure nothing was being overwritten. I'm on a shared hosting apache server, and know that mod_rewrite is enabled, because I use it to rewrite non-www to www urls. I don't receive and 500 error messages, I just do not notice any change at all. I'm not sure where I'm going wrong here, so hopefully someone can point me in the right direction.
Finally found a solution that worked:
RewriteEngine On
RewriteRule ^([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/([A-Za-z0-9-]+)/?$ index.php?cat=$1&sec=$2&id=$3 [QSA,L]
Appreciate LazyOne's response to get me on the right track; however, when using:
RewriteEngine On
RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ index.php?cat=$1&sec=$2&id=$3 [QSA,L]
I wasn't able to following links that were already placed on the site, it treated different directories as the variables, for example, when browsing to an image or file, say:
folder/folder/image.png
It would grab "folder" - "folder" - and "image" as the variables. I can see why that was happening, if anyone has a different solution or an explanation, please let me know, I'm always willing to learn.
Since your .htaccess is in website root folder, then you should use thus rule:
RewriteEngine On
RewriteBase /
RewriteRule ^catalog/([^/]+)/([^/]+)/([^/]+)$ /catalog/index.php?cat=$1&sec=$2&id=$3 [QSA,L]
If you place it in .htaccess in /catalog/ folder, then you can remove catalog from it:
RewriteEngine On
RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ index.php?cat=$1&sec=$2&id=$3 [QSA,L]
I have tested rule before posting -- works fine for me.
This rule (same as above) will check if URL is a file or folder and will only rewrite if it is not:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/([^/]+)$ index.php?cat=$1&sec=$2&id=$3 [QSA,L]

.htaccess mod_rewrite problem - shot myself in the foot?

I have a page called category.php5 that uses $_GET["category"] to fetch the right content from the database. I want to pretty it up so is looks like:
sinaesthesia.co.uk/category/psoriasis
which would equal:
sinaesthesia.co.uk/category.php5?category=psoriasis
I have successfully done this sort of rewriting before, but since I can't get it to work now, I'm worred that I might have rules in place that are somehow screwing me. Here is my entire .htaccess file - the last couple of lines are supposed to do the above rewrite:
RewriteEngine On
#remember to change this to aromaclear
RewriteCond %{HTTP_HOST} !^sinaesthesia\.co.uk$ [NC]
RewriteRule ^(.*)$ http://sinaesthesia.co.uk/$1 [R=301,L]
#Translate default page to root
RewriteCond %{THE_REQUEST} ^GET\ .*/index\.(php5|html)\ HTTP
RewriteRule ^(.*)index\.(php5|html)$ /$1 [R=301,L]
#translate any .html ending into .php5
RewriteRule ^(.*)\.html$ /$1\.php5
#change / for ?
RewriteRule ^(.*)\.html/(.*)$ /$1\.html?$2
#strip .html from search res page
RewriteRule ^(.*)search/(.*)$ /$1search_results\.html/search=$2
#translate product details link from search res page
RewriteRule ^products/(.*)/(.*)/(.*)$ /product_details.php5?category=$1&title=$2&id=$3 [L]
#Translate products/psorisis/chamomile-skin-cream-P[x] to productview.php5?id=1
RewriteRule ^products/.*-P([0-9]+) /productview.php5?id=$1 [L]
#Translate /category/psoriasis to /category.php5?category=$1
RewriteRule ^category/(.*) /category.php5?category=$1 [L]
When I manually enter category.php5/category=psoriasis, it works great. When I enter category.php5/category/psoriasis, it doesn't. I'm worried that my line that changes a html/ to html? is an error, however when I take that line out, it still doesn't work. Everything else works as expected.
As a general strategy, strip down your file by commenting everything out, then re-enable things piece by piece until you find the rule that causes it to break.
Bear in mind that browsers sometimes cache redirects, so starting a fresh browser instance is a good idea. A useful service is http://web-sniffer.net/ which will give you an uncached result.
In general, looking at your set of redirects, this seems a little convoluted to me because of the chaining/sieve -type system you seem to be using. Instead, I would recommend starting with URLs that can be identified specifically, e.g. starting with
RewriteRule ^category/(.*) /category.php5?category=$1 [L]
and then leaving the rather messy .html => .php conversion stuff towards the end, if you end up needing it at all. I've done a lot of sites using redirects and have never needed generic conversions like that, so they should be avoidable.
Also bear in mind that .* means matching anything or nothing, so you probably want to use .+ instead.
Ah: because I have a document called category.php5 and I'm trying to use category/psoriasis, the server tries to resolve that as category.php5/psoriasis, which fails. Fixed it now!

Resources