Forum Moderators: phranque

Message Too Old, No Replies

Redirect SEF to non-SEF

         

QED Motorsport

10:42 am on Mar 20, 2009 (gmt 0)

10+ Year Member



Hi all,

I'm changing the format of our existing SEF URLs but the problem is that the site has already been up and running for quite some time so I need to redirect some of the old SEF urls to non-SEF urls.

Basically, I want requests that come in like this:

[domain.tld...]

to be re-written to:

[domain.tld...]

I've tried:

RewriteCond %{REQUEST_URI} ^/shop* [NC]
RewriteRule ^shop/?$ /$1&option=com_virtuemart [R=301,L]

but it comes out like this:

[domain.tld...]

I've tried so many iterations of the above code, including doing 2 rewrite rules (one to make /shop into /index.php and another to append the query string) but nothing seems to work.

Additionally, I want URLs like this:

[domain.tld...]

to be re-written as:

[domain.tld...]

Not had much luck with that at all. I tried this:

RewriteCond %{REQUEST_URI} ^/the\-engines/lotus/twin\-cam* [NC]
RewriteRule ^/twin-cam([^-0-9].*)$ /the-engines/lotus-twin-cam$1 [R=301,L]

...and variations of it but no dice :(

I've spent a fair amount of time on this, can anyone offer some advise? I starting to wonder if my dev server is at fault as so many of the example I've tried just aren't working.

[edited by: QED_Motorsport at 10:44 am (utc) on Mar. 20, 2009]

g1smd

10:50 am on Mar 20, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Specifying a domain name and/or R=301 makes it a redirect, not a rewrite.

If you want a rewrite, omit both of those things.

A rewrite does not 'make' a URL.

A rewrite takes a URL request and translates that to a different internal filepath to get the content from. That is, the pattern on the left contains the URL pattern, and the filepath on the right is the filepath inside the server where the content really resides.

A rewrite connects URLs 'used on the web' with internal filepaths. The browser URL bar will not show the filepath of that internal location.

A redirect takes a URL request and tells the browser to make a new request for a different URL. A redirect will contain both a domain name and [R=301,L]. The browser URL bar will change to show that new URL.

.

*** Additionally, I want URLs like this: WXYZ to be re-written as: ABCD. ***

You need to sort out your terminology here. It is unclear which of those is the URL that users 'see and use' on the web, and which is an internal filepath inside the server, You should say:

For a rewrite, I want external URL requests for example.com/XYZ to fetch content from this server-internal filepath /ABC?cba=123

If BOTH of those things are URLs used on the web (one an old one that people used to use, and the other the new URL that people use), then you don't want a rewrite at all - you need a redirect.

.

If you are changing the URLs that people 'see' and 'use' on the web, then you need to change the links on your pages to use the URLs that people need to click on. It is links that 'define' URLs.

So, if you can reword the question to use two URLs when you talk about redirects, and one URL and one filepath when you talk about rewrites, we can move on to the coding bit...

QED Motorsport

11:04 am on Mar 20, 2009 (gmt 0)

10+ Year Member



/me slaps forehead

It all makes more sense now! I feel like such a n00b :P

Thanks for taking the time to answer, you've opened my eyes!

Basically, our site is joomla based and up to now has been using joomla's (limited) ability to generate SEF links. I want to add a third party component that does a better job, unfortunately it will only redirect the old non-SEF links, not the SEF ones and as the search engines have only ever indexed the SEF links, I need to fiddle.

Funny thing is, I posed the same questions to a couple of fairly experienced web devs and they were as stumped as me!

[edited by: QED_Motorsport at 11:10 am (utc) on Mar. 20, 2009]

g1smd

11:36 am on Mar 20, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



OK. That makes sense. The new component makes "new URLs in the links on the pages" and rewrites those new URL requests back to the standard Joomla internal server filepath. This, I guess, leaves your current URL format as going nowhere, all URLs for your pages that people already know about, will 404.

.

You'll need to link to the new URL format from within the pages of your site. That makes search engines 'see' and 'use' those new URLs.

You'll need to redirect old URL format requests to the new URL format, with a 301 redirect. That forces anyone that has stored the old URL formats locally (search engines, browser bookmarks, links from other sites) to be redirected to the new URL, and optionally they will update their records to use the new URL that you want them to 'see' and 'use'.

You'll also need a rewrite to connect the new URL request format to the real internal filepath where the content actually resides inside the server.

g1smd

11:55 am on Mar 20, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Content on the server is located at: /index.php?cat=123&product=12345678. This is the real internal filepath.

The URL for that content is: example.com/index.php?cat=123&product=12345678.

Note that example.com/?cat=123&product=12345678 and example.com/index.php?product=12345678&cat=123 and example.com/?product=12345678&cat=123 would also work and you would need to cater for that too - though I have not done so in the following examples.
.

Let's say you have decided to add the simple SEF generator...

You change things so that you now link to example.com/cat/123/product/12345678 on your pages. This is a new URL.

You now need to add a redirect so that external requests for example.com/index.php?cat=123&product=12345678 are redirected to use the new URL for that content at: example.com/cat/123/product/12345678. This stops the old URLs being indexed as Duplicates and forces people to use the new URL (you would also need to cater for all those other alternative URL formats, mentioned above, too - they all need to be redirected).

You also add a rewrite so that requests for the new URL at: example.com/cat/123/product/12345678 can be serviced by fetching the content from the server internal filepth at: /index.php?cat=123&product=12345678.

.

Now you want to change to a better SEF generator:

You must change things so that you link to example.com/123/12345678 on your pages. This is another new URL. You must use this format in your links in order for that URL to be 'seen'.

The redirect for external requests like example.com/index.php?cat=123&product=12345678 previously redirected the user to the URL at example.com/cat/123/product/12345678 and that redirect now needs to be altered so that requests for example.com/index.php?cat=123&product=12345678 are redirected to the new URL at: example.com/123/12345678. *** This avoids a chained redirect for these requests.

You also need an additional redirect so that requests for the old SEF URLs like example.com/cat/123/product/12345678 are now redirected to the new URL at: example.com/123/12345678. This replaces the rewrite that was in place for those types of URL requests. You no longer want to rewrite the old SEF URLs to an internal filepath, you need to redirect them to the new external URL. This stops the old URLs being indexed as Duplicates and forces people to use the new URLs.

Finally, you need to set up a new rewrite. This will accept URL requests for the new format URLs like example.com/123/12345678 and rewrite the request to get the content from the same old server internal filepath located at: /index.php?cat=123&product=12345678 that it always did.

.

In all this, the difference between an externally used URL and a server internal filepath is crucial.

Likewise the difference between a redirect and a rewrite is absolutely crucial here.

Redirects will contain the domain name and [R=301,L] and rewrites will not contain a domain name and will end with just [L].

.

You link to the new URLs so that people 'see' and 'use' the format that appears in the links.

You rewrite those requests to a server-internal filepath to fetch the content for the user without exposing what that server-internal filepath actually is.

You set up redirects for anyone trying to use the server-internal filepath as a direct-access URL, or trying to use the old SEF URLs, so that they are forced to use the very latest URL. This prevents the content being directly accessed under multiple Duplicate Content URLs.

In your code you must list all of the redirects ahead of any rewrites.

[edited by: g1smd at 12:30 pm (utc) on Mar. 20, 2009]

QED Motorsport

12:03 pm on Mar 20, 2009 (gmt 0)

10+ Year Member



Right, here is my final code for part one:

Redirect /shop http://domain.tld [R=301,L]
RewriteCond %{REQUEST_URI} ^/ [NC]
RewriteCond %{QUERY_STRING} page=shop*
RewriteCond %{QUERY_STRING} !option=com_virtuemart*
RewriteRule /? ?option=com_virtuemart&Itemid=61 [QSA,L]

This redirects:

[domain.tld...]

to

[domain.tld...]

and then appends to query string to:

[domain.tld...]

At this point, the new SEF component kicks in and turns the above into:

[domain.tld...]

Sorted :D

Now for part two....

[edited by: QED_Motorsport at 12:04 pm (utc) on Mar. 20, 2009]

g1smd

12:07 pm on Mar 20, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



You cannot use Redirect and RewriteRule in the same .htaccess file. They come from two different Apache modules.

For directives that come from different modules the directives are NOT processed in the order the directives are written.

You must use RewriteRule for all of them otherwise the processing order of your redirects and rewrites is 'indeterminate'.

That is, should there be a redirect after a rewrite, the server internal filepath that you wanted to stay hidden will actually be exposed back out to the external URL.

Redirect and RewriteRule are in different Apache modules and the .htaccess file is processed one modules worth at a time.

.

Be aware of chained redirects. You should get from old URL to new URL in just one hop ... and that should be true if the old URL is non-www or is www too. See the paragraph marked *** in the piece above.

That is I have original URL A and 'old' SEF URL B and 'new' SEF URL C.

If I ask for A, I should be redirected to C in just one hop.
If I ask for B, I should be redirected to C in just one hop.

If I ask for A, I should not be redirected to B and then redirected to C in a chain.

Use the Live HTTP Headers extension for Firefox to check this out.

[edited by: g1smd at 12:54 pm (utc) on Mar. 20, 2009]

QED Motorsport

12:38 pm on Mar 20, 2009 (gmt 0)

10+ Year Member



Ok, revised code:

RewriteCond %{QUERY_STRING} page=shop*
RewriteCond %{QUERY_STRING} !option=com_virtuemart*
RewriteRule ^.*$ /index\.php\?$1&option=com_virtuemart&Itemid=61 [R=301,QSA,L]

Works perfectly :D

QED Motorsport

12:58 pm on Mar 20, 2009 (gmt 0)

10+ Year Member



Sorry, I obviously omitted why it had to be done this way

I want the new SEF URLs to contain the product name and the products nested category. The new SEF component can only redirect the original URL (A) to the new url (C) but the site always used the old SEF url (B). This means I have to redirect B -> A -> C as I have absolutely no plans to write 1000+ htaccess entries redirecting the old SEF url to the new SEF url.

g1smd

1:24 pm on Mar 20, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Where does the $1 part get populated from?

There's no back-reference created in the rule, or in the RewriteCond above?

The * on the end of both RewriteCond lines is likely an error.

You have that as a redirect, but if that is the case, you MUST include the domain name in the target (otherwise there's a www and non-www duplication problem created by the rule).

Don't escape the . or ? in the target URL. Escaping is only needed in the pattern on the left.

Use the Live HTTP Headers extension for Firefox to inspect exactly what happens in the HTTP headers for all of your requests.

[edited by: g1smd at 1:45 pm (utc) on Mar. 20, 2009]

QED Motorsport

1:29 pm on Mar 20, 2009 (gmt 0)

10+ Year Member



...and here's my code for part 2

RedirectMatch ^/the-engines/lotus/twin-cam/([-0-9]+)(.*)$ /the-engines/lotus-twin-cam/$2 [R=301,L]

Works perfectly too :D

Thanks for the inspiration ;)

[edited by: QED_Motorsport at 1:30 pm (utc) on Mar. 20, 2009]

g1smd

1:31 pm on Mar 20, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



Don't use Redirect or RedirectMatch here.

Use RewriteRule for all of the rules.

See the stuff about 'different modules' above.

For a redirect you MUST include the domain name in the target (otherwise there's a www and non-www duplication problem created by the rule).

If you have a lot of folders to change from this format /lotus/twin-cam/ to this format /lotus-twin-cam/ then you could easily do that for all of them using one simple pattern-based rule.

g1smd

1:47 pm on Mar 20, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



At this point it would be a good idea to read the entire thread again s-l-o-w-l-y, as I made a number of edits and improvements which you might not have seen.

g1smd

7:27 pm on Mar 22, 2009 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



How are you getting on with this?