How to setup optional parameters in mod_rewrite - .htaccess

I am in a new project and I'm designing the URL structure,
the thing is I want URLs look like this:
/category-23/keyword/5/
Where the normal page is:
/search.php?q=keyword&cat=23&page=5
So my question is, cat and page fields, must be optional, I mean if I go to /keyword it should be
/search.php?q=keyword (page 1)
and if I go to
/category/keyword should be:
/search.php?q=keyword&cat=category&p=1
and also if I go to
/keyword/5/ it must be: /search.php?q=keyword&p=5
Now I have my .htaccess like this:
RewriteEngine On
RewriteBase /
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)/(.*)/(.*)$ search.php?q=$2&cat=$1&page=$3 [L]
I cannot make it working and the CSS / image files don't load.
I'd thank a lot who could give me a solution.

You can do this with four rules, one for each case:
RewriteRule ^([^/]+)$ search.php?q=$1
RewriteRule ^([^/]+)/([0-9]+)$ search.php?q=$2&p=$1
RewriteRule ^([^/]+)/([^/]+)$ search.php?q=$2&cat=$1&p=1
RewriteRule ^([^/]+)/([^/]+)/([0-9]+)$ search.php?q=$2&cat=$1&p=$3
And with this rule in front of the other rules, any request that can be mapped onto existing files will be passed through:
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^ - [L]
Now your last issue, that externally linked resources cannot be found, is due to that you’re probably using relative URL paths like css/style.css or ./css/style.css. These relative references are resolved from the base URL path that is the URL path of the URL of the document the references are used in. So in case /category/keyword is requested, a relative reference like css/style.css is resolved to /category/keyword/css/style.css and not /css/style.css. Using the absolute URL path /css/style.css makes it independent from the actual base URL path

While i know this was answered succinctly by #Gumbo a few months back, I ran into a similar issue recently... and didn't want to include full/absolute paths in my app, to keep it dynamic and not having a bunch APP_PATH (php) vars all over the place... so I just added a base[href] html tag with the
like so...
<base href="http://<?php echo $_SERVER[HTTP_HOST];?><?php echo APP_PATH;?>"/>
Hoping that helps others... and this is not trying to discount #Gumbo's reply in the least... they're right-e-o on :).

Shouldn't it be
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule ^ - [L]
in #Gumbo's answer above? Works with me like that. If it is a file (like CSS), let it pass through.

Related

.htaccess cascading conditions

I'm trying to figure out how to manage potentially conflicting conditions in .htaccess
My setup is the following:
- I have a CMS running on a server that can be accessed through myCMSdomain.com where myCMSdomain.com would be CMS home page and myCMSdomain.com/admin would be the admin interface.
- Sites using this CMS should be pointing to myCMSdomain.com/sites/index.php
- Images for all sites are available somewhere behind myCMSdomain.com/admin/images/sitename/...
So here is how I tried to tackle this problem:
RewriteCond %{HTTP_HOST} !^(www.)?myCMSdomain.com$ [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . sites/index.php
With this, all incoming requests coming from other domain names are treated correctly by the index.php file but as images are hosted somewhere else, I'd like to use a rule saying that images should be fetched somewhere else like this:
Visible url format for images is: images-[sitename]/[image_path]
Real location of the images is: admin/site/[sitename]/[image_path]
The following rule works but not in combination with the first rule
RewriteRule images-([a-zA-Z0-9]+)/(.*)$ admin/site/$1/images/$2
Images end up calling index.php instead of using the rule I defined for them.
I have tried to excluse the image directory from the conditions but it doesn't work either:
RewriteCond %{REQUEST_URI} !(images-([a-zA-Z0-9]+)/(.*))
I might have similar issues in the future with other exception so I was wondering if there was a way to handle this.
Thanks!
Laurent
UPDATE 1:
If I use the following rule on top of all other
it works only if I'm using myCMSdomain.com domain name
if I use any other domain like anotherdomain.com, the rule leads to a http 500
RewriteRule images-([a-zA-Z0-9]+)/(.*)$ manager/site/$1/images/$2
So http://www.myCMSdomain.com/images-test/test.jpg leads me to the correct image
But http://www.anotherdomain.com/images-test/test.jpg leads me to a 500 http error code while this domain is pointing correctly to sites/index.php
UPDATE 2:
On Justin's request, here is a view on the physical directory structure on the server
/admin/
/admin/site
/admin/site/site_name/
/admin/site/site_name/images/
/sites/
/sites/js
/sites/css
You can rearrange your conditions logic.
# if www.myCMSdomain.com or myCMSdomain.com -> do nothing
RewriteCond %{HTTP_HOST} ^(?:www\.)?myCMSdomain\.com$ [NC]
RewriteRule ^ - [L]
# if we reach here, this means it's a subdomain/another domain
# images rule
RewriteRule ^images-([^/]+)/(.+)$ /admin/site/$1/images/$2 [L]
# not a file/directory -> sites/index.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /sites/index.php [L]
It is also possible the way you did but it would be longer to write.
Also, keep in mind that conditions (RewriteCond) are non-cumulative: they are for next rule (RewriteRule) only.
I've been struggling with this issue for some time now but at last I think I have found the issue. It looks like there was something wrong in the domain name configuration, I don't know exactly what but once I had re-saved the mapping of all domains, the htaccess worked the way it should.
In the end I have used Justin's proposition, it looks more future proof than mine.
Thanks for your help and happy new year to all
Laurent

Multiple Clean Url Variables

I was wondering how to pass several (two) values through url as a clean url.
I've done clean urls before, but never with multiple values and it doesn't seem to be working.
This is what the url looks like now:
http://example.com/?user=Username&page=1
This is what I want it to look like
http://example.com/user/Username/page/1
I've tried other answers that I've seen on here, but they aren't working for this certain deal.
RewriteEngine On
# Don't match real existing files so CSS, scripts, images aren't rewritten
# RewriteCond %{REQUEST_FILENAME} !-f
# RewriteCond %{REQUEST_FILENAME} !-d
# Match the first two groups before / and send them to the query string
RewriteRule ^([^/]+)/([^/]+) index.php?user=$1&page=$2 [L]
Thanks. :)
I'm using PHP by the way. :)
Also, will I still be able to use $_GET with this? I thought so, but I also somewhere else where it said you can't... :D
You're missing several matches, try:
RewriteEngine On
# Don't match real existing files so CSS, scripts, images aren't rewritten
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+) index.php?$1=$2&$3=$4 [L]
This will take a URL like:
http://example.com/a/b/c/d
to the URI:
/index.php?a=b&c=d
will I still be able to use $_GET with this? I thought so, but I also somewhere else where it said you can't.
In the above example, when you look at $_GET['a'] you'd get b.

changing link url using .htacces

This is the link http://djmobi.in/?dir=/Mobile_Ringtones&p=1&sort=1/Mobile_Ringtones.html
Please tell me how to remove ?dir= from the above link I want to make it look like below link eg.
http://www.finewap.com/Category/9497/Mobile_Ringtones.html
You must not think the way "How to remove ?dir=", but "Which link use instead of this complex one".
This is the kinf of .htaccess you'll need :
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([A-Za-z0-9-]+)\.html$ index.php?dir=$1 [L]
This .htaccess will redirect each url like http://www.domain.com/foo.html to http://www.domain.com/index.php?dir=foo (this will be transparent)
This is a good start, I let you search for some documentation to add your pages and sort management (we don't have enought datas to give you a working piece of code)

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]

ignore specific directories in htaccess using mod_rewrite

I've got the following code in my .htaccess to strip out index.php from the urls in my CMS-based site.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
This code works great and it routes requests exactly how I want. For example, with URL: http://example.com/contact/ the directory contact doesn't actually exist if you look in the FTP; instead index.php handles the request and shows my contact info. Perfect. Well, almost perfect.
I want to modify this code to specify a couple directories in FTP that should be ignored. For example, if I've got a folder called assets, when I go to http://example.com/assets/ the default DirectoryIndex page is displayed. Instead, I want this directory to be ignored -- I want index.php to handle /assets/.
TL;DR: How can I modify the above code to explicitly ignore certain existing directories (so that index.php handles them instead of the DirectoryIndex)?
Why not adding this below or before your code?
RewriteRule ^(assets/.*)$ /index.php/$1 [L]

Resources