homepage Welcome to WebmasterWorld Guest from 23.20.77.156
register, free tools, login, search, pro membership, help, library, announcements, recent posts, open posts,
Become a Pro Member
Home / Forums Index / Code, Content, and Presentation / Apache Web Server
Forum Library, Charter, Moderators: Ocean10000 & incrediBILL & phranque

Apache Web Server Forum

    
Mod Rewrite and Coldfusion
mafgibson




msg:4644470
 1:48 pm on Feb 12, 2014 (gmt 0)

Hi guys, longtime lurker, first time poster :-)

I am in the process of cleaning up our url's using mod_rewrite. I have created a new rule to redirect .html to our product pages, however I am not sure how to setup redirects for our category pages.

We have three redirects that we need to setup

example.co.uk/category1/ to subcat.cfm?catname=$1
example.co.uk/category1/category2 to subsubcat.cfm?secondcatname=$1
example.co.uk/category1/category2/category3/ to results.cfm?thirdcatname=$1

Can this be done? Here is our current .htaccess.




#######################################
# Rewrite rules for non www entrances
RewriteEngine On
RewriteBase /
# skip v3 from rewrite
RewriteRule ^v3(/.*)?$ - [NC,L]
RewriteCond %{HTTP_HOST} !^www.example.co.uk$ [NC]
RewriteRule ^(.*)$ http://www.example.co.uk/$1 [L,R=301]


# Rewrite rules - current rules
RewriteRule ^(.*).html$ /Details.cfm?ProductUrl=$1 [NC]
RewriteRule (.*)-sku-(.*)$ /DetailsSKU.cfm?Name=$1&ProductCode=$2 [NC]
RewriteRule (.*)-shop-(.*)$ /Results.cfm?bname=$1&Brand=$2 [NC]
RewriteRule (.*)-cat1-(.*)$ /SubCat.cfm?catname=$1&category=$2 [NC]
RewriteRule (.*)-cat2-(.*)$ /SubSubCat.cfm?secondcatname=$1&secondary=$2 [NC]
RewriteRule (.*)-cat3-(.*)$ /Results.cfm?thirdcatname=$1&third=$2 [NC]
RewriteRule (.*)-shop$ /ResultsShop.cfm?bname=$1 [NC]

# Rewrite rules - old rules
RewriteRule (.*)_sku_(.*)$ /Details2.cfm?Name=$1&ProductCode=$2 [NC]
RewriteRule Product-(.*)-(.*)-(.*)-(.*)-(.*)-(.*).html$ /Details2.cfm?Name=$1&ProdID=$2&category=$3&secondary=$4&third=$5&brand=$6 [NC]
RewriteRule (.*)_cat1_(.*)$ /SubCat2.cfm?catname=$1&category=$2&secondary=$3 [NC]
RewriteRule (.*)_cat2_(.*)$ /SubSubCat2.cfm?secondcatname=$1&secondary=$2 [NC]
RewriteRule (.*)_cat2new_(.*)$ /SubSubCat3.cfm?secondcatname=$1&secondary=$2 [NC]
RewriteRule (.*)_cat3_(.*)$ /Results2.cfm?thirdcatname=$1&third=$2 [NC]

# Rewrite rule - old shop redirect
RewriteRule (.*)_shop$ /Results2.cfm?bname=$1 [NC]
RewriteRule Brands-(.*)-(.*)\.html$ /Results2.cfm?bname=$1&brand=$2 [NC]
RewriteRule (.*)-Brands$ /Results2.cfm?bname=$1 [NC]

# Rewrite rule - If no extension specified use cfm
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.cfm -f
RewriteRule ^(.*)$ $1.cfm

# Rwerite rule - 404 redirect rule
ErrorDocument 404 /cferror.cfm

[edited by: phranque at 7:21 pm (utc) on Feb 12, 2014]
[edit reason] Please Use example.com [webmasterworld.com] [/edit]

 

g1smd




msg:4644508
 3:29 pm on Feb 12, 2014 (gmt 0)

Do you mean redirect or do you mean rewrite? They are separate but related operations. Both can be coded using a RewriteRule with the right syntax and flags.

Which one of each URL pair in your example is the URL that the user sees and uses and which is the internal filesystem location where the content really resides.

mafgibson




msg:4644510
 3:39 pm on Feb 12, 2014 (gmt 0)

hi g1smd, I apologise. I meant rewrite.

The external example.co.uk/category1/
the internal subcat.cfm?catname=$1

and so on.

Thankyou for your help

[edited by: phranque at 7:21 pm (utc) on Feb 12, 2014]
[edit reason] Please Use example.com [webmasterworld.com] [/edit]

g1smd




msg:4644536
 7:15 pm on Feb 12, 2014 (gmt 0)

This is a fairly simple set of coding as long as "category1" is used exactly as is in "$1".

You'll need:
- a redirect to the friendly URL,
- your standard non-www/www redirect,
- an internal rewrite matching friendly requests.

Each one can be coded with a RewriteRule. The first two also need to have one or more preceding RewriteCond directives.

The most important part is to alter the links on your pages to point to the new URLs. Everything begins with that click.

The htaccess code has been covered here many times before as this question has come up several times per month for the last decade or more.

lucy24




msg:4644574
 10:08 pm on Feb 12, 2014 (gmt 0)

I'm not going to paste in the boilerplate again, but here's a relatively recent thread:

[webmasterworld.com...]

mafgibson




msg:4644769
 1:23 pm on Feb 13, 2014 (gmt 0)

ok thank you I think I have it now, ok so here is our htaccess-:

Only thing is the images and css aren't being excluded by the rule marked ****

##############################################
# Rewrite rules for non www entrances
RewriteEngine On

RewriteBase /
# skip v3 from rewrite
RewriteRule ^v3(/.*)?$ - [NC,L]
RewriteCond %{HTTP_HOST} !^www.example.co.uk$ [NC]
RewriteRule ^(.*)$ http://www.example.co.uk/$1 [L,R=301]

# Rewrite rules - current rules
RewriteRule ^(.*).html$ /Details.cfm?ProductUrl=$1 [NC]

# Rewrite rules - new rules
****RewriteCond %{REQUEST_URI} !^/(images|css|favicon\.ico|robots\.txt)
RewriteRule ^([^/]+)/$ /SubCat5.cfm?catname=$1 [NC,L]
RewriteRule ^([^/]+)/([^/]+)/$ /SubSubCat5.cfm?catname=$1 [NC,L]

# Rewrite rules - old rules
RewriteRule (.*)-sku-(.*)$ /DetailsSKU.cfm?Name=$1&ProductCode=$2 [NC]
RewriteRule (.*)-shop-(.*)$ /Results.cfm?bname=$1&Brand=$2 [NC]
RewriteRule (.*)-cat1-(.*)$ /SubCat.cfm?catname=$1&category=$2 [NC]
RewriteRule (.*)-cat2-(.*)$ /SubSubCat.cfm?secondcatname=$1&secondary=$2 [NC]
RewriteRule (.*)-cat3-(.*)$ /Results.cfm?thirdcatname=$1&third=$2 [NC]
RewriteRule (.*)-shop$ /ResultsShop.cfm?bname=$1 [NC]
RewriteRule (.*)_sku_(.*)$ /Details2.cfm?Name=$1&ProductCode=$2 [NC]
RewriteRule Product-(.*)-(.*)-(.*)-(.*)-(.*)-(.*).html$ /Details2.cfm?Name=$1&ProdID=$2&category=$3&secondary=$4&third=$5&brand=$6 [NC]
RewriteRule (.*)_cat1_(.*)$ /SubCat2.cfm?catname=$1&category=$2&secondary=$3 [NC]
RewriteRule (.*)_cat2_(.*)$ /SubSubCat2.cfm?secondcatname=$1&secondary=$2 [NC]
RewriteRule (.*)_cat2new_(.*)$ /SubSubCat3.cfm?secondcatname=$1&secondary=$2 [NC]
RewriteRule (.*)_cat3_(.*)$ /Results2.cfm?thirdcatname=$1&third=$2 [NC]
RewriteRule (.*)_shop$ /Results2.cfm?bname=$1 [NC]
RewriteRule Brands-(.*)-(.*)\.html$ /Results2.cfm?bname=$1&brand=$2 [NC]
RewriteRule (.*)-Brands$ /Results2.cfm?bname=$1 [NC]

# Rewrite rule - If no extension specified use cfm
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.cfm -f
RewriteRule ^(.*)$ $1.cfm

# Rwerite rule - 404 redirect rule
ErrorDocument 404 /cferror.cfm
####################################

[edited by: phranque at 2:06 pm (utc) on Feb 13, 2014]
[edit reason] Please Use example.com [webmasterworld.com] [/edit]

lucy24




msg:4644823
 3:16 pm on Feb 13, 2014 (gmt 0)

(.*)-sku-(.*)$

Oh, how glad I am that it's half past seven AM and therefore long past my bedtime...

mafgibson




msg:4644834
 3:34 pm on Feb 13, 2014 (gmt 0)

Ok so I'm a beginner, please don't shoot me down for trying to learn this is my first post.

Perhaps I should go back to lurking!

phranque




msg:4644848
 4:09 pm on Feb 13, 2014 (gmt 0)

welcome to WebmasterWorld, mafgibson!


the images and css aren't being excluded by the rule marked ****

RewriteCond %{REQUEST_URI} !^/(images|css|favicon\.ico|robots\.txt)
RewriteRule ^([^/]+)/$ /SubCat5.cfm?catname=$1 [NC,L]
RewriteRule ^([^/]+)/([^/]+)/$ /SubSubCat5.cfm?catname=$1 [NC,L]

the RewriteCond only applies the the RewriteRule that follows.
perhaps you need to repeat that condition for the second rule as well?

RewriteRule Product-(.*)-(.*)-(.*)-(.*)-(.*)-(.*).html$ /Details2.cfm?Name=$1&ProdID=$2&category=$3&secondary=$4&third=$5&brand=$6 [NC]

there are quite a few possible combinations with that regular expression.
i would tighten that up with something more like this:
RewriteRule Product-([^-]+)-([^-]+)-([^-]+)-([^-]+)-([^-]+)-([^-]+).html$ /Details2.cfm?Name=$1&ProdID=$2&category=$3&secondary=$4&third=$5&brand=$6 [NC]

lucy24




msg:4644968
 11:16 pm on Feb 13, 2014 (gmt 0)

But wait.
/$

This is exactly what you'd want: put the most important constraint in the body of the rule, not in a condition. Since non-page files always have extensions, you've already excluded them. This in turn means that if your /images/ directory contains nothing but images, you don't need the condition at all.

The form (.*)blahblah will work, sure-- but in a server (as opposed to, say, text editing) you want to consider every last nanosecond. Regular Expressions are greedy by default, meaning that they will capture everything and then stop short "Oh, oops, I was supposed to leave room for 'blahblah'." It may help to think of them as operating in just one dimension. You're looking at the paper and can see there is 'blahblah' coming up, but the Regular Expression engine doesn't know it yet.

No matter what the pattern is, you would never want it to have * at the beginning, because surely you don't have URLs that start with -blahblah- do you? Here it looks as if what you want is

^([^-]+)-blahblah

so you never capture beyond the first hyphen. If you do have URLs in the form
^something-somethingelse-blahblah
with additional hyphens before the -sku- then we can fine-tune the rule.

mafgibson




msg:4652644
 9:56 am on Mar 10, 2014 (gmt 0)

Thanks for all your help on this guys . @lucy24 I tried your method but it led to 404 errors for some reason, it must be the way the url variables were formatted. @phranque That is actually an old rewrite rule so I removed it from myhtaccess.

I managed to get the rules working so they now rewrite as follows

ourwebsite.co.uk/product.html
ourwebsite.co.uk/category1/
ourwebsite.co.uk/category1/category2/
ourwebsite.co.uk/category1/category2/category3/


The only thing is that I really wanted the links to work without the trailing slash.

ourwebsite.co.uk/category1 just raises an error. It would be great if we could redirect customers from /category1/ to /category1 and so on with all our category pages.

here is my current htaccess,

# Rewrite rules for non www entrances
RewriteEngine On

RewriteCond %{HTTP_HOST} !^www\.
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [R=301,L]

# skip v3 from rewrite
RewriteCond %{REMOTE_ADDR} !^private IP 1
RewriteCond %{REMOTE_ADDR} !^private IP 2
RewriteCond %{REMOTE_ADDR} !^private IP 3
RewriteCond %{REQUEST_URI} v3 [NC]
RewriteRule ^(.*)$ / [F,L]

# Rewrite rules for static pages
RewriteRule ^about-us /information/about-us/ [NC,L]
RewriteRule ^opening-hours /information/opening-hours/ [NC,L]
RewriteRule ^delivery /information/delivery/ [NC,L]
RewriteRule ^terms-conditions /information/terms--conditions/ [NC,L]
RewriteRule ^privacy-policy /information/privacy-policy/ [NC,L]

# Rewrite rules for shop pages
RewriteCond %{REQUEST_URI} !^/(admin|v3|images|css|fonts|favicon\.ico|robots\.txt)
RewriteRule ^(.*).html$ /Details.cfm?ProductUrl=$1 [NC,L]
RewriteRule ^brands/(.*)/$ /Results.cfm?BrandUrl=$1 [NC,L]
RewriteRule ^information/(.*)/$ /Information.cfm?InfoUrl=$1 [NC,L]
RewriteRule ^search/(.*)/$ /Results.cfm?Keywords=$1 [NC,L]
RewriteRule ^(.*)/(.*)/(.*)/$ /Results.cfm?ThrdCatUrl=$3&ScndCatUrl=$2&CatUrl=$1 [NC,L]
RewriteRule ^(.*)/(.*)/$ /SubSubCat.cfm?ScndCatUrl=$2&CatUrl=$1 [NC,L]
RewriteRule ^(.*)/$ /SubCat.cfm?CatUrl=$1 [NC,L]

# Rewrite rule - If no extension specified use cfm
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.cfm -f
RewriteRule ^(.*)$ $1.cfm

Any advice on this would be great, I am getting there and your help is much appreciated :-)

[edited by: phranque at 1:24 pm (utc) on Mar 12, 2014]
[edit reason] unlinked url [/edit]

lucy24




msg:4652649
 10:38 am on Mar 10, 2014 (gmt 0)

# Rewrite rules for static pages
RewriteRule ^about-us /information/about-us/ [NC,L]

Yikes. Never use [NC] in an internal rewrite-- unless you're rewriting to a php script that will Deal With It. Otherwise you're laying yourself open to well-nigh infinite duplicate content as the search engines start asking for
example.com/AbOuT-uS

Rewriting to a bare directory will work. (I tried it once, for some reason which now escapes me.) But why create the extra work for mod_dir? Rewrite to the actual named physical file that holds the content.

If you have a string of similar conditionless rules, it may be OK to run them together without intervening space. But ALWAYS leave a blank line before and after any ruleset that includes conditions.

RewriteCond %{REQUEST_URI} !^/(admin|v3|images|css|fonts|favicon\.ico|robots\.txt)
RewriteRule ^(.*).html$ /Details.cfm?ProductUrl=$1 [NC,L]

Since you're not capturing, there is fortunately no need for the dreaded
^.*
;) Just say
\.html$
remembering to escape the literal period.

In patterns like this
RewriteRule ^search/(.*)/$ /Results.cfm?Keywords=$1 [NC,L]

you clearly don't want .* because that would admit requests for
search//
and nothing more. Say
/([^/]+)/$
though I'm not sure I understand why the URL requires a final slash. You probably explained it at some point.

More to follow. Fortunately g1 lives in a widely different time zone, so you are always covered. With any luck he will figure out what I said that led to a 404 :(

I just split two directories. In a masterful imitation of the bingbot, the googlebot promptly came along and found the one internal link that hadn't been updated to give the correct directory name.

mafgibson




msg:4652670
 11:35 am on Mar 10, 2014 (gmt 0)

Thanks Lucy, I removed the static pages and created cfm pages for each rule on the root directory. Why not give mod rewrite a break, it's already getting passed enough work to do from the rest of the rules ;-)

I have also changed the rules that read /(.*)/$ to /([^/]+)/$ - this seems to work fine now.

However I tried \.html$ and it just redirected to the home page.

I think there is a problem with my slashes somewhere which are causing redirects! Perhaps that's why my categories don't work without a trailing slash.

lucy24




msg:4652756
 3:58 pm on Mar 10, 2014 (gmt 0)

I tried \.html$ and it just redirected to the home page.

Do you mean in this rule?
RewriteCond %{REQUEST_URI} !^/(admin|v3|images|css|fonts|favicon\.ico|robots\.txt)
RewriteRule ^(.*).html$ /Details.cfm?ProductUrl=$1 [NC,L]

That's definitely weird. Well, beyond weird. In fact the rule and the condition don't match, so let's go back to the drawing board on that one.

mafgibson




msg:4653008
 1:45 pm on Mar 11, 2014 (gmt 0)

Yes I did try it in that rule Lucy, it never worked unfortunately. I know it is weird...

I guess the biggest issue we have is with the backslash at the end or the url strings in the categories redirects.

I think it's a problem that category1/ works and category1 doesn't. Can you suggest how to rewrite the rules for the categories and redirect traffic with a slash to the categories without?

Thankyou

lucy24




msg:4653135
 9:25 pm on Mar 11, 2014 (gmt 0)

Backtracking for a moment:

Do your /fonts/ and /css/ and so on directories actually contain files in .html that are accessible to the public? You definitely don't have files named "favicon.ico.html" and the like, so scratch those. I think what you really want is more like

RewriteCond %{REQUEST_URI} !^/(admin|v3)
RewriteRule ^([^.]+)\.html$ /Details.cfm?ProductUrl=$1 [L]


omitting the [NC] because any request in .HTML (capitalized) deserves a 404. Unless your .cfm page itself looks at those and issues a redirect; then you can keep the [NC]. If your URLpaths happen to contain literal periods, the [^.] part obviously has to be replaced with something more complicated, but let's not borrow trouble.

I think it's a problem that category1/ works and category1 doesn't.

Why is that a problem? Each page has only one URL-- either with or without / slash-- so the other one doesn't have to "work".

I went back to the first post and looked at it from scratch:
example.co.uk/category1/ to subcat.cfm?catname=$1
example.co.uk/category1/category2 to subsubcat.cfm?secondcatname=$1
example.co.uk/category1/category2/category3/ to results.cfm?thirdcatname=$1

Were the ugly URLs in "subcat.cfm" and so on ever used? I hope not, because "category1" and "category2" are obviously not deducible from "category3", and the URL contains all three while the query gives only one. For redirecting you'd have to rewrite to a php script. Or, I guess, a parallel cfm page, possibly using the same database in either direction. (Don't look at me. I don't "do" databases.)

RewriteRule ^category1/category2/category3/([^./]+)$ /results.cfm?thirdcatname=$1

RewriteRule ^category1/category2/([^./]+)$ /results.cfm?secondcatname=$1

RewriteRule ^category1/([^./]+)$ /results.cfm?catname=$1

Was that what you meant? The original post had a bunch of "$1" without making it really clear what was to be captured.

mafgibson




msg:4653270
 12:04 pm on Mar 12, 2014 (gmt 0)

Thank you Lucy, now the product pages with .html work great :-)

No there were not any files with the .html extension in those folders that were accessible to the public! Much better.

With our categories we don't have category1 etc at the beginning of the url, it is simply the category name.

So I think without creating an index of all categories and setting up a new page say redirect.cfm we are stuck using ourwebsite.co.uk/books/ with the slash.

Which is fine, I just wanted to make sure if a user doesn't put the hash in then it would work.

Originally yes our website was indexed on google and bing using the ugly urls.

subcat.cfm?cat=1
subsubcat.cfm?scnd=2
results.cfm?thrd=3

Perhaps I should create a redirect rule to redirect people to our new category url's...

Think we're almost there, thanks for your help.

mafgibson




msg:4653272
 12:12 pm on Mar 12, 2014 (gmt 0)

FYI this is our current rule set now

## REWRITE RULES - CURRENT ##
RewriteCond %{REQUEST_URI} !^/(admin|v3)
RewriteRule ^([^.]+)\.html$ /Details.cfm?ProductUrl=$1 [L]
RewriteRule ^brands/([^/]+)/$ /Results.cfm?BrandUrl=$1 [L]
RewriteRule ^information/([^/]+)/$ /Information.cfm?InfoUrl=$1 [L]
RewriteRule ^search/([^/]+)/$ /Results.cfm?Keywords=$1 [L]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/$ /Results.cfm?ThrdCatUrl=$3&ScndCatUrl=$2&CatUrl=$1 [L]
RewriteRule ^([^/]+)/([^/]+)/$ /SubSubCat.cfm?ScndCatUrl=$2&CatUrl=$1 [L]
RewriteRule ^([^/]+)/$ /SubCat.cfm?CatUrl=$1 [L]

g1smd




msg:4653416
 7:14 pm on Mar 12, 2014 (gmt 0)

You have seven rules.

They might run a bit more efficiently if ordered 2 - 3 - 4 - 1 - 7 - 6 - 5.

The Condition applies only to the rule that immediately follows it.

Add a comment before each rule describing what it does, and a blank line after each rule.

Before all of these rules you need another set of rules to redirect from old to new URL. Each one needs a preceding Condition looking at THE_REQUEST to prevent an infinite loop.

The final redirecting rule should be the non-www to www canonical hostname redirect.

Your existing seven rewrites go after that.

lucy24




msg:4653470
 10:07 pm on Mar 12, 2014 (gmt 0)

The Condition applies only to the rule that immediately follows it.

I think it's intentional. The first rule is meant to intercept any and all requests ending in ".html" except the ones aimed for specified directories. The following six rewrites are for requests ending in / so that automatically excludes non-page requests.

Since rules 5,6,7 cover all directories, you might throw in a supplementary
RewriteRule ^(images|css|fonts) - [L]
(no closing anchor) at the beginning of this block of rewrites. Then the rewrite engine doesn't even have look at requests for these directories. The patterns will never be met, so why bother to check?

Global Options:
 top home search open messages active posts  
 

Home / Forums Index / Code, Content, and Presentation / Apache Web Server
rss feed

All trademarks and copyrights held by respective owners. Member comments are owned by the poster.
Home ¦ Free Tools ¦ Terms of Service ¦ Privacy Policy ¦ Report Problem ¦ About ¦ Library ¦ Newsletter
WebmasterWorld is a Developer Shed Community owned by Jim Boykin.
© Webmaster World 1996-2014 all rights reserved