I've developed a custom section in which webshop products can be managed. These products are stored in custom tables I've added to the database. Now I'd like to use url rewrite when these products are viewed in the webshop. What's the best approach for this? Is there an Umbraco tv episode available where I can learn how to do custom url rewrite? I'm using Umbraco 4.5 with ASP.NET 4.0 so I could also use the new url routing features of ASP.NET to do this. I'm currently watching this tekpub video about it.
Should I use the default umbraco url rewrite or the new ASP.NET 4.0 url routing features to solve this? Thanks.
Well I got the UrlRewriting.Net plugin from Umbraco working, but I must be doing something wrong because the page get's called constantly. If I debug the page load method the breakpoint get hit's constantly. Here is what I've done:
Thanks for the tip. Somehow it now works. Didn't change anything, but the page load breakpoint now only get's hit once. If the problem happens again I'll use Fiddler :).
With respect to the multiple hit problem, have a close look at your regex. You could either use a lazy quantifier (with a different multiplicity) or an exclusion group to restrict the eagerness of the match, and you can also use the end of input marker to make it a little clearer. You can also drop the unnecessary groups. All these things reduce the possibility of an unintended match leading to a redirect loop.
For example:
lose the groups: ^~/nl/artikelen/detail/.*/.*/([A-Za-z0-9\-]+)/
lazy quantifier: ^~/nl/artikelen/detail/.+?/.+?/([A-Za-z0-9\-]+)/ (this means that it will not match /nl/artikelen/detail/1/2/3/id/, nor will it match a double slash (//))
OR an exclusion: ^~/nl/artikelen/detail/[^/]+/[^/]+/([A-Za-z0-9\-]+)/
also, optionally, add the end of line marker: ^~/nl/artikelen/detail/.+?/.+?/([A-Za-z0-9\-]+)/$ (watch out for the interaction with the query string here)
and you can make the trailing slash optional: ^~/nl/artikelen/detail/.+?/.+?/([A-Za-z0-9\-]+)/?$
For the rewriting tool, I'd probably come down on the side of the inbuilt engine, as kipusoep did. It's simple, it gets the job done, and it's there in umbraco independent of your server's configuration. It's also a technique that other devs are more likely to grasp, making your solution easier to maintain.
The only drawback that I found (and I believe that this may also be the case with the IIS7 rewriter) is that the ASP.NET form element's action attribute uses the URL _after_ rewrite. This means that when you postback, your user starts to see the formerly hidden URL. To get around this, you need to use the ControlAdapter architecture of ASP.NET via the App_Browsers. EF has a full implementation of this, but I'll cherry pick a couple of items:
1. create a class that overrides the Umbraco form rewriting (extends umbraco.presentation.urlRewriter.UrlRewriterFormWriter):
public override void WriteAttribute(string name, string value, bool fEncode)
{
if (name == "action")
{
HttpContext current = HttpContext.Current;
if (current.Items["ActionAlreadyWritten"] == null)
{
string virtualUrl = (string)current.Items["UrlRewritingNet.UrlRewriter.VirtualUrl"];
if (!string.IsNullOrEmpty(virtualUrl))
{
// rewrite taken place, change the form action
value = virtualUrl;
// set the context flag so the umbraco control doesn't overwrite it
current.Items["ActionAlreadyWritten"] = true;
}
}
}
2. Create the hook ControlAdapter class that will activate this:
public class FormRewriteControlAdapter : ControlAdapter
{
protected override void Render(HtmlTextWriter writer)
{
// this is the class created above
base.Render(new UrlRewriterFormRewriter(writer));
}
}
3. Enable this in the App_Browsers/Form.browser file:
I got this technique from a combination of Umbraco forum posts (which I can't remember now) and the ever-trusty Reflector :)
With regard to ASP.NET routing, I don't know enough about it. However, rewrite will do the job simply and easily, so I'm not sure what this would gain for you.
As for IIS7 rewrite, I don't think our servers have IIS7, and I'm pretty sure this module isn't available for IIS6. It's pretty good though, and when we eventually upgrade this will be great for us.
What we do have though is ISAPIRewrite. This is as powerful or more so than the IIS7 rewrite (it's pretty much the Apache mod_rewrite, which rocks) and it's installed on the servers. It's ISAPI, so I'm pretty sure it's outside the processing pipeline which means that you don't have to worry about the form action attribute. However, it limits the portability to other servers as it's an extra dependency. That is, if you need to install it on another host, you'll either need a license or you'll be changing your implementation.
Now if I go to /nl/test1 it redirects me to ~/nl/artikelen/artiekel-overzicht but if I go to /nl/test1/subtest1 it still goes to ~/nl/artikelen/artiekel-overzicht instead of ~/nl/artikelen/artiekel-details.
What am I doing wrong here? Probably got something to do with the regex I'm using, but I don't know how to solve this.
2 Other url's also get redirected to these pages.
For example if I create a news section the url is /nl/news, but because of the url rewritting it still goes to ~/nl/artikelen/artiekel-overzicht. Is there a way to say url's generated from Umbraco shouldn't redirect?
Thanks Stefan you solved my first problem :). As for the second problem I guess I could make it unique though I would have hoped there would be a better solution. At least I'll make them unique by this: "^~/nl/([A-Za-z0-9\-]+)/artikel$" this way the unique part is at the back of the url which is better for SEO.
You're right about the unique part. That's '([A-Za-z0-9\-]+)' and '/artikel' is only so the url rewrite knows which template should be used.
As for the SEO part here's something our SEO expert wrote:
"Good SEO or any readable URLs for that matter are usually composed by a simple idea; a breadcrumb path.
This would translate to the following in some news or blog sites /YYYY/MM/DD/Post-title
And for webshops or other item related websites Product view: /Main-category/sub-category/product-title Subcategory view: /Main-category/sub-category Category view: /Main-category
As you can see, removing any of the rightmost items will result in a naturally occurring page.
However this can be troublesome for sites that have other pages (such as contact etc.) this would force you to use switch statements or other maintenance horrors. Not to mention sites that use multiple languages and multiple templates.
So one solution would be /language-ISO-code/products/main-category/sub-category/product-title
Or to eliminate template choosing /language-ISO-code/products/main-category/sub-category/product-title/template-name
And finally to make the path even shorter /language-ISO-code/main-category/sub-category/product-title/template-name
So for example: /en/elevators/glass/turbo-tube-taker/detail And: /en/elevators/glass/overview"
That's why I'm moving the template part to the back of the url.
Hmm, that shouldn't happen... I tested it with RegExr and it works as it should.
Can you try using IIS UrlRewriting add-on? That way you can test if UrlRewriting.NET is buggy (well, IIS UrlRewriting owns UrlRewriting.NET anyway :P )
I agree with @kipusoep, fwiw, that slash doesn't match in that regex. It's has to be a bug or somehow your config was cached incorrectly. It might sound stupid, but have you tried bouncing IIS/windows?
URL rewrite for custom data
Hello,
I've developed a custom section in which webshop products can be managed. These products are stored in custom tables I've added to the database. Now I'd like to use url rewrite when these products are viewed in the webshop. What's the best approach for this? Is there an Umbraco tv episode available where I can learn how to do custom url rewrite? I'm using Umbraco 4.5 with ASP.NET 4.0 so I could also use the new url routing features of ASP.NET to do this. I'm currently watching this tekpub video about it.
Should I use the default umbraco url rewrite or the new ASP.NET 4.0 url routing features to solve this? Thanks.
Jeroen
There is another option though; UrlRewrite module for IIS
Thanks for the tip :). What would you recommand? I'd rather do it without doing something to IIS and just manage it inside the code.
Jeroen
Well, if you can, use the UrlRewriting.Net plugin which umbraco uses.
I say 'if you can', because it doesn't support everything unlike the UrlRewrite module.
As fas as .NET 4.0 url routing concerns; I don't have experience with it yet ;-)
Well I got the UrlRewriting.Net plugin from Umbraco working, but I must be doing something wrong because the page get's called constantly. If I debug the page load method the breakpoint get hit's constantly. Here is what I've done:
Config settings:
The url I'm calling:
http://localhost:3748/nl/artikelen/detail/test/itworks/600/
Somehow it looks like it's in loop. Anyone had this before? Thanks.
Jeroen
Use Fiddler to see what happens; is it a infinite loop and if so, what's the response header of the first request?
Thanks for the tip. Somehow it now works. Didn't change anything, but the page load breakpoint now only get's hit once. If the problem happens again I'll use Fiddler :).
Jeroen
There's a few things here...
With respect to the multiple hit problem, have a close look at your regex. You could either use a lazy quantifier (with a different multiplicity) or an exclusion group to restrict the eagerness of the match, and you can also use the end of input marker to make it a little clearer. You can also drop the unnecessary groups. All these things reduce the possibility of an unintended match leading to a redirect loop.
For example:
For the rewriting tool, I'd probably come down on the side of the inbuilt engine, as kipusoep did. It's simple, it gets the job done, and it's there in umbraco independent of your server's configuration. It's also a technique that other devs are more likely to grasp, making your solution easier to maintain.
The only drawback that I found (and I believe that this may also be the case with the IIS7 rewriter) is that the ASP.NET form element's action attribute uses the URL _after_ rewrite. This means that when you postback, your user starts to see the formerly hidden URL. To get around this, you need to use the ControlAdapter architecture of ASP.NET via the App_Browsers. EF has a full implementation of this, but I'll cherry pick a couple of items:
1. create a class that overrides the Umbraco form rewriting (extends umbraco.presentation.urlRewriter.UrlRewriterFormWriter):
I got this technique from a combination of Umbraco forum posts (which I can't remember now) and the ever-trusty Reflector :)
With regard to ASP.NET routing, I don't know enough about it. However, rewrite will do the job simply and easily, so I'm not sure what this would gain for you.
As for IIS7 rewrite, I don't think our servers have IIS7, and I'm pretty sure this module isn't available for IIS6. It's pretty good though, and when we eventually upgrade this will be great for us.
What we do have though is ISAPIRewrite. This is as powerful or more so than the IIS7 rewrite (it's pretty much the Apache mod_rewrite, which rocks) and it's installed on the servers. It's ISAPI, so I'm pretty sure it's outside the processing pipeline which means that you don't have to worry about the form action attribute. However, it limits the portability to other servers as it's an extra dependency. That is, if you need to install it on another host, you'll either need a license or you'll be changing your implementation.
I hope this helps!
Regards from down under :)
Thank you James! Used your example and postbacks now also work :). Glad your my colleague ;).
Jeroen
Yes, the form action on postbacks is a bitch ;-)
http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx
Hello,
I've been using the umbraco url writing for a while now with succes, but I'd like to adjust the custom url and this goes wrong.
Currently I've got this in the UrlRewritting.config file:
Now I'd like to remove the "overzicht" and "details" part of url so it get's shorter. This gives me 2 problems:
1 Both pages always redirect to the first url.
Here is an example:
Now if I go to /nl/test1 it redirects me to ~/nl/artikelen/artiekel-overzicht but if I go to /nl/test1/subtest1 it still goes to ~/nl/artikelen/artiekel-overzicht instead of ~/nl/artikelen/artiekel-details.
What am I doing wrong here? Probably got something to do with the regex I'm using, but I don't know how to solve this.
2 Other url's also get redirected to these pages.
For example if I create a news section the url is /nl/news, but because of the url rewritting it still goes to ~/nl/artikelen/artiekel-overzicht. Is there a way to say url's generated from Umbraco shouldn't redirect?
Hope someone can help me with this :). Thanks.
Jeroen
Solution to your first problem:
About your second problem; you should really make the URL unique...
Something like "^~/nl/artikel/([A-Za-z0-9\-]+)$"
Thanks Stefan you solved my first problem :). As for the second problem I guess I could make it unique though I would have hoped there would be a better solution. At least I'll make them unique by this: "^~/nl/([A-Za-z0-9\-]+)/artikel$" this way the unique part is at the back of the url which is better for SEO.
Jeroen
Hmm no, the unique part of the url itself is the '([A-Za-z0-9\-]+)' part, the '/artikel' part is only the unique identifier for you url rewrite.
You see this on the web all the time, think of blogposts, the unique part at the end like this: /2010/10/12/the-title-of-the-article
Hi Stefan,
You're right about the unique part. That's '([A-Za-z0-9\-]+)' and '/artikel' is only so the url rewrite knows which template should be used.
As for the SEO part here's something our SEO expert wrote:
"Good SEO or any readable URLs for that matter are usually composed by a simple idea; a breadcrumb path.
This would translate to the following in some news or blog sites
/YYYY/MM/DD/Post-title
And for webshops or other item related websites
Product view: /Main-category/sub-category/product-title
Subcategory view: /Main-category/sub-category
Category view: /Main-category
As you can see, removing any of the rightmost items will result in a naturally occurring page.
However this can be troublesome for sites that have other pages (such as contact etc.) this would force you to use switch statements or other maintenance horrors. Not to mention sites that use multiple languages and multiple templates.
So one solution would be
/language-ISO-code/products/main-category/sub-category/product-title
Or to eliminate template choosing
/language-ISO-code/products/main-category/sub-category/product-title/template-name
And finally to make the path even shorter
/language-ISO-code/main-category/sub-category/product-title/template-name
So for example:
/en/elevators/glass/turbo-tube-taker/detail
And:
/en/elevators/glass/overview"
That's why I'm moving the template part to the back of the url.
Jeroen
I've got a new small problem. This is my url rewrite now:
If I go to the url "/nl/tilliften/overzicht/" in the request.querystring I get "tilliften/". Is there something I can do so I don't get the slash?
Jeroen
Hmm, that shouldn't happen... I tested it with RegExr and it works as it should.
Can you try using IIS UrlRewriting add-on? That way you can test if UrlRewriting.NET is buggy (well, IIS UrlRewriting owns UrlRewriting.NET anyway :P )
I agree with @kipusoep, fwiw, that slash doesn't match in that regex. It's has to be a bug or somehow your config was cached incorrectly. It might sound stupid, but have you tried bouncing IIS/windows?
is working on a reply...