Forums / Cotonti / Support / mod_rewrite HELP needed

url rewriting in .htaccess to create SEO subdomains and subfolders

donP
#1 2010-03-17 21:39
I already answered this question but nobody could help me... But i think this would be a great enancement for a Cotonti-driven website, giving webmasters the ability to create more structure, using fake subdomains and subfolders, also for SEO...

Now, I need to work with Rewriting Rules in .htaccess to create fake subdomains for the main categories of my page-structure, like this:

FOR LISTS:
http://www.sangelo.net/list.php?c=cat    ==>    http://cat.sangelo.net
http://www.sangelo.net/list.php?c=subcat    ==>    http://cat.sangelo.net/subcat/
http://www.sangelo.net/list.php?c=subsubcat    ==>    http://cat.sangelo.net/subcat/subsubcat/

FOR PAGES:
http://www.sangelo.net/page.php?al=ALIAS    ==>    http://cat.sangelo.net/alias.html
http://www.sangelo.net/ (of a subcat) page.php?al=ALIAS    ==>    http://cat.sangelo.net/subcat/alias.html
http://www.sangelo.net/ (of a subsubcat) page.php?al=ALIAS    ==>    http://cat.sangelo.net/subcat/subsubcat/alias.html

Actually, I'm only albe to do the first rewriting
http://www.sangelo.net/list.php?c=cat    ==>    http://cat.sangelo.net
using this code:
RewriteCond %{HTTP_HOST} !www.sangelo.net$ [NC]
RewriteCond %{HTTP_HOST} ^([A-Za-z0-9\-]+).sangelo.net$ [NC]
RewriteRule (.*) list.php?c=%1 [NE,NC,L,QSA]

But when I try to do the second level (adding a subcat like a fake subfolder), with this rule:
RewriteCond %{HTTP_HOST} ^([A-Za-z0-9\-]+).sangelo.net/([A-Za-z0-9\-]+) [NC]
RewriteRule (.*) list.php?c=%2 [NE,NC,L,QSA]
nothing happens... it still present me the subdomain path (cat.sangelo.net) and its real content (list.php?c=cat)

Why?

Anyone can help me?
in [color=#729FCF][b]BLUES[/b][/color] I trust
This post was edited by donP (2010-03-17 22:26, 14 years ago)
donP
#2 2010-03-18 17:56
tensh:
Also, I think that the last example might have a typo... no $ at the end.
It's irrilevant, it works well also without $ at the end.
tensh:
It's because there's no reflection of the category structure in lists - you have two variables in htaccess rule and only one variable in list.php, how do you imagine script should act in this case?
I'm only trying to read the last variable in rewrite rule. Other variables could also been filled with casual values (the right strings come from function-custom.php, that I've already written successfully), 'cause the really relevant value to call the appropriate structure-code for list.php?c=catcode is only the last value included between / and /, with a backreference, as you can see in the rules written by Trustmaster:
### Combined pages & lists ###
# Level 3
RewriteRule ^(articles|downloads|news|docs)/([a-z\-]+)/([a-z\-]+)/([0-9]+) page.php?id=$4 [QSA,NC,NE,L]
RewriteRule ^(articles|downloads|news)/([a-z\-]+)/([a-z\-]+)/add$ page.php?m=add&c=$3 [QSA,NC,NE,L]
RewriteRule ^(articles|downloads|news|docs)/([a-z\-]+)/([a-z\-]+)/([a-zA-Z0-9\-_]+) page.php?al=$4 [QSA,NC,NE,L]
RewriteRule ^(articles|downloads|news)/([a-z\-]+)/([a-z\-]+)/ list.php?c=$3 [QSA,NC,NE,L]

# Level 2
RewriteRule ^(articles|downloads|news|docs)/([a-z\-]+)/([0-9]+) page.php?id=$3 [QSA,NC,NE,L]
RewriteRule ^(articles|downloads|news)/([a-z\-]+)/add$ page.php?m=add&c=$2 [QSA,NC,NE,L]
RewriteRule ^(articles|downloads|news|docs)/([a-z\-]+)/([a-zA-Z0-9\-_]+) page.php?al=$3 [QSA,NC,NE,L]
RewriteRule ^(articles|downloads|news)/([a-z\-]+)/ list.php?c=$2 [QSA,NC,NE,L]

# Level1
RewriteRule ^(articles|downloads|news|docs)/([0-9]+) page.php?id=$2 [QSA,NC,NE,L]
RewriteRule ^(articles|downloads|news|docs)/add$ page.php?m=add&c=$1 [QSA,NC,NE,L]
RewriteRule ^(articles|downloads|news|docs)/([a-zA-Z0-9\-_]+) page.php?al=$2 [QSA,NC,NE,L]
RewriteRule ^(articles|downloads|news|docs)/ list.php?c=$1 [QSA,NC,NE,L]

With that rules, for example, you can write in browser url adress bar:
www.sangelo.net/cat1/subcat2/ and however you'll go to list.php?c=subcat2, cause the rule tells the Server intepreter to read the last backreference and use it to call the appropriate subcategory with list.php?c=subcatcode
tensh:
See the docs for classic category example, adjust it to reflect subdomain.
As you can see, this is what I have done (but adding a RewriteCond, cause to change the domain part of url that's the only way).
in [color=#729FCF][b]BLUES[/b][/color] I trust
donP
#3 2010-03-18 21:23
tensh:
This is not what exactly you did. Trustmaster's rewrite rule contains in a bracket the main list directories. Your example doesn't mention any main directories which the server should look for in first place. That's what I meant and that's how I imagine it works. Otherwise there would be no brackets with defined core categories, only the brackets with variable patterns.
Also My rules contain in a bracket the main list directories. I wrote only a general example not to list here my own categories... otherwise, a general form like that one could be usefull for a continually changing page-structure (a e-commerce website, for example).

tensh:
I suggested that you might toy with definedmaincat.sangelo.net rewrite rules, like:
^(articles|downloads|news|docs).sangelo.net/([A-Za-z0-9\-]+) [blablabla]
That IS my rewrite rule:
RewriteCond %{HTTP_HOST} ^(articles|downloads|news|docs)\.sangelo\.net/([a-z\-]+)$ [NC]
RewriteRule (.*) list.php?c=%2 [QSA,NC,NE,L]
but it doesn't work :/
in [color=#729FCF][b]BLUES[/b][/color] I trust
donP
#4 2010-03-19 06:00
I've heard somewhere (between the tons of documentation pages I've read) it's better to escape dots with dashes, but it's the same thing, with or without dashes: first level it's working, but not the second level... :(
in [color=#729FCF][b]BLUES[/b][/color] I trust
donP
#5 2010-03-19 17:35
It isn't a problem of plugin or custom function (I've already created system/functions.custom.php, addressed by datas/ultrans.dat, that translate Cotonti urls for my needs).
The problem is only in RewriteCond & RewriteRule syntax.
I'm trying to understand how to tell Apache mod_rewrite module to read the value of last string passed by backreference among the two last dashes, like Trustmaster exaple does (unfortunately, only for the second part of url, after the domain part, 'cause that example uses only RewriteRule and not RewriteCond).

Indeed, I don't want to pass more values to list.php, but to read the right part of rewritten url and then pass it to list.php as c=structure-code value, got it?

My goal is to tell the Server:

Read this string (the one in red):
http://cat.sangelo.net/blablabla/subcat/) (I don't mind what is passed by the other blablabla variables, 'cause I'll write them right with a custom function) and pass it to list.php as c=structure-code

In other words:
Read this url: http://sport.sangelo.net/blablabla/basket/ and give me http://www.sangelo.net/list.php?c=basket

Got it? ;)

I'm sure this is possible, only finding the right RewriteCond/RewriteRule syntax.
in [color=#729FCF][b]BLUES[/b][/color] I trust
GHengeveld
#6 2010-03-19 20:39
Simplest solution is to allow any subdomain and any subfolder (subcat) to be set when calling a page, regardless of whether or not that page resides in that category. You can control that with the Cotonti rewrite.

RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteRule . - [S=7]
RewriteRule ^/$ http://www.example.com/list.php?c=%1 [NC,QSA]
RewriteRule ^([a-z0-9_-]+)/$ http://www.example.com/list.php?c=$1 [NC,QSA]
RewriteRule ^([a-z0-9_-]+)/([a-z0-9_-]+)/$ http://www.example.com/list.php?c=$2 [NC,QSA]
RewriteRule ^([a-z0-9_-]+)/([a-z0-9_-]+)/([a-z0-9_-]+)/$ http://www.example.com/list.php?c=$3 [NC,QSA]
RewriteRule ^([a-z0-9_-]+)\.html$ http://www.example.com/page.php?al=$1 [NC,QSA]
RewriteRule ^([a-z0-9_-]+)/([a-z0-9_-]+)\.html$ http://www.example.com/page.php?al=$2 [NC,QSA]
RewriteRule ^([a-z0-9_-]+)/([a-z0-9_-]+)/([a-z0-9_-]+)\.html$ http://www.example.com/page.php?al=$3 [NC,QSA]

This should:
- Rewrite main cat from subdomain to list.php
- Rewrite subcats from subfolder to list.php (up to 3 levels)
- Rewrite .html files to page.php?al= (up to 3 levels)

Note that I've included the full domain each time, to make sure calls are made to the www subdomain and not the fake (category) subdomain (where your files aren't located). You can leave the domain out if you've set a * CNAME example.com in your DNS records.
Also note that subfolders (categories) have to end with a slash. Page aliases and category codes may only consist of alphanumeric chars, - and _
donP
#7 2010-03-20 21:19
# tensh : I was talking about a plugin, not custom function.
You're quite rude.

You better listen to Koradhil and do not ask for rewrite help anymore.

Koradhil solution doesn't work at all (also because we can't use only one RewriteCond for many RewriteRule commands...). However, thanks to Koradhil for his always generous and kind answers...

I'm trying (step by step) to find a solution by myself, although I'm not so good with Apache Commands syntax.

By the way, tensh, I think I'm not so rude (I hope you tell me that only because of a misunderstanding in language interpretation), at least not as much as one man of Support Team telling me no to ask for any help anymore :(

Anyway, I think I'll post here the complete solution when I'll find it, for the benefit of all of those users that would need it but would be afraid of asking some help after your threats.
in [color=#729FCF][b]BLUES[/b][/color] I trust
GHengeveld
#8 2010-03-21 01:21
donP, you should do your research better. The second line of my code makes the RewriteCond work for the next 7 lines (actually it will skip 7 lines when false, hence the S=7):
RewriteRule . - [S=7]
Note that I haven't tested it, so you might be right in saying it doesn't work. I'm just trying to push you in the right direction.

Update: I checked the Apache documentation on this, and I think the RewriteCond needs to change. Try this one:
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
This is more likely to work since the second line skips 7 lines when the Cond is true (not false). My first suggestion would actually make it skip all rules when a category subdomain was set (while they should be skipped when it is NOT a category subdomain, so www).
This post was edited by Koradhil (2010-03-21 01:34, 14 years ago)
donP
#9 2010-03-21 23:01
Thanks, Koradhil ;)
Now everything seems to work fine but the
RewriteRule ^/$ http://www.example.com/list.php?c=%1 [NC,QSA]
I think because the %1 would be a backreference from last matched RewriteCond directive in the current bunch of conditions (as Apache documentation says), and in
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
there are no backreferences at all..

I had tried changing RewriteCond with this one:
RewriteCond %{HTTP_HOST} !^(articles|downloads|news|docs)\.sangelo\.net$ [NC]
but nothing happens... all levels (pages and lists) works well... but http://articles.sangelo.net or http://downloads.sangelo.net etc displays me the main page of site (like www.sangelo.net) and they don't guide me to list.php?c=maincat

It's the
RewriteRule ^/$ list.php?c=%1 [QSA,NC,NE,L]
written in right syntax?

Elsewhere I found
RewriteRule ^(.*)$ list.php?c=%1 [QSA,NC,NE,L]
but that one causes me many errors... :/
in [color=#729FCF][b]BLUES[/b][/color] I trust
GHengeveld
#10 2010-03-22 01:57
Try:
RewriteCond %{HTTP_HOST} ^(articles|downloads|news|docs)\.sangelo\.net$ [NC]
donP
#11 2010-03-22 02:35
I've tried, but, as I'd imagined, nothing works anymore, cause with a positive condition instead of a negative one, it will skip all following Rewriting rules...
The positive one works well, but it seems I can't tell the last rewriterule to capture the right backreference to transform http:/maincat.sangelo.net/ in list.php?c=maincat

Added 4 hours 30 minutes later:

Eureka! I finally found it! :)

RewriteCond %{HTTP_HOST} ^www\.sangelo\.net$ [NC]
RewriteRule . - [S=8]
RewriteRule ^([a-z\-]+)/([a-z\-]+)/([0-9]+)\.html$ page.php?id=$3 [NC,QSA,L]
RewriteRule ^([a-z\-]+)/([a-z\-]+)/([a-z0-9_-]+)\.html$ page.php?al=$3 [NC,QSA,L]
RewriteRule ^([a-z\-]+)/([0-9]+)\.html$ page.php?id=$2 [NC,QSA,L]
RewriteRule ^([a-z\-]+)/([a-z0-9_-]+)\.html$ page.php?al=$2 [NC,QSA,L]
RewriteRule ^([0-9]+)\.html$ page.php?id=$1 [NC,QSA,L]
RewriteRule ^([a-z0-9_-]+)\.html$ page.php?al=$1 [NC,QSA,L]
RewriteRule ^([a-z\-]+)/([a-z\-]+)/?$ list.php?c=$2 [NC,QSA,L]
RewriteRule ^([a-z\-]+)/?$ list.php?c=$1 [NC,QSA,L]

RewriteCond %{HTTP_HOST} ^(articles|downloads|news|docs)\.sangelo\.net$ [NC]
RewriteRule ^([a-z\-]*)$ list.php?c=%1 [QSA,NC,NE,L]

Many thanks to Koradhil for his assistence and support! ;)
And to my patience to try all possible combination and reading millions of pages about Apache mod_rewriting!

P.S. I've added page.php?id=ID rule and also modified list rules to match either ending slash form and form without ending slash.
I've also restricted cat and subcat RegEx to lowercase alphabetical characters to speedup Server.
in [color=#729FCF][b]BLUES[/b][/color] I trust
This post was edited by donP (2010-03-22 07:05, 14 years ago)