I want to break out of the Umbraco /folder/node scenario. It's too restrictive. MVC & IUrlSegmentProvider the provides the perfect way for me to take back some control of Urls, but I need to understand how I can leverage this in Umbraco.
The problem, here is my folder structure. This is perfect for my content editors.
So you want to remove "The-World" from your urls, right?
Outbound: you want a IUrlProvider (not a IUrlSegmentProvider) that modifies the whole Url by removing its first segment.
Inbound: because you modify the whole url and not only a segment, you need a content finder to map that url to a node... you probably could inherit from the default "finder by url" and check for ("The-World" + request)...Just add it after the default "finder by url". That should do it.
See what I mean, or do you need more details?
I'll be offline soon, and 'till monday, so don't be surprised if I stop responding, though.
I did have a play with this and looked at the source. I could modify the the Url and remove the "The World" from the Url by inheriting from the default "finder by url", but I got a bit lost with the source (it does all sorts of stuff with Urls, Domains, Absolute and Relative Paths).
public class CustomFinder : ContentFinderByNiceUrl { public override bool TryFindContent(PublishedContentRequest request) { // copy ContentFinderByNiceUrl but add your prefix back where it's missing const string PREFIX = "/The-World";
Thank you for this. I can register the finder... but do I add it after the default one or before?
I did try to figure out how to remove it, but it was a bit "brute force" (just used .Replace("/The-World","") on the route. Could you show me how you'd do it? (Keen to learn the right way!)
You add it in place of the default one... so I'd insert it before ContentFinderByNiceUrl, then remove ContentFinderByNiceUrl.
As for building the url... there could be a nicer way than .Replace() but I'm not sure it'll work because of some stuff that are private/internal. So probably the best is:
public class MyUrlProvider : DefaultUrlProvider { public override string GetUrl(UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode) { return base.GetUrl(umbracoContext, id, current, mode).Replace("/The-World", ""); } }
And register it in place of the default url provider.
No prob. And don't hesitate to explain what you're about to do and ask for opinion: because many things have changed, it's always better to ask before spending hours re-inventing something that's just poorly documented (yes, I suck at writing docs).
I need to do something similar and just looking at this post - some useful stuff - @Stephen - how do I register my own urlprovider in place of the default one?
Managing MVC Urls
I want to break out of the Umbraco /folder/node scenario. It's too restrictive. MVC & IUrlSegmentProvider the provides the perfect way for me to take back some control of Urls, but I need to understand how I can leverage this in Umbraco.
The problem, here is my folder structure. This is perfect for my content editors.
Umbraco would treat these urls as
I know I can take control of these in various ways, particularly using the
IUrlSegmentProvider
. Can start introducing node id's into the url;I could do something like <node id>-<node name>;
http://www.my-site.com/The-World/1234-Country/
And look for the node id for fast a faster lookup.
This works great, but ideally I want to manipulate the Url but avoid a url like
http://www.my-site.com/The-World/1234-Country/5678-Region
How would I create a cleaner url that my users can guess and that can be assigned to the .Url parameter in Umbraco?
http://www.my-site.com/Country/Region
Whilst still retaining the "The-World" folder where my content editors know to look.
So you want to remove "The-World" from your urls, right?
Outbound: you want a IUrlProvider (not a IUrlSegmentProvider) that modifies the whole Url by removing its first segment.
Inbound: because you modify the whole url and not only a segment, you need a content finder to map that url to a node... you probably could inherit from the default "finder by url" and check for ("The-World" + request)...Just add it after the default "finder by url". That should do it.
See what I mean, or do you need more details?
I'll be offline soon, and 'till monday, so don't be surprised if I stop responding, though.
Stephan
Ah, another thing to look into... the IUrlProvider. I'll check the source.
Any quick examples would be appreciated. I can think of a few more example that break this scenario. :-)
I did have a play with this and looked at the source. I could modify the the Url and remove the "The World" from the Url by inheriting from the default "finder by url", but I got a bit lost with the source (it does all sorts of stuff with Urls, Domains, Absolute and Relative Paths).
The following finder should add your prefix back:
Then you need to register the finder. Know how to do it?
Have you been able to work out the url provider?
Stephan
Thank you for this. I can register the finder... but do I add it after the default one or before?
I did try to figure out how to remove it, but it was a bit "brute force" (just used
.Replace("/The-World","")
on the route. Could you show me how you'd do it? (Keen to learn the right way!)You add it in place of the default one... so I'd insert it before ContentFinderByNiceUrl, then remove ContentFinderByNiceUrl.
As for building the url... there could be a nicer way than .Replace() but I'm not sure it'll work because of some stuff that are private/internal. So probably the best is:
And register it in place of the default url provider.
Stephan
Thank you so much for these examples. So much good stuff to play with in 6! :)
No prob. And don't hesitate to explain what you're about to do and ask for opinion: because many things have changed, it's always better to ask before spending hours re-inventing something that's just poorly documented (yes, I suck at writing docs).
Hello guys,
I need to do something similar and just looking at this post - some useful stuff - @Stephen - how do I register my own urlprovider in place of the default one?
Thanks
@James: you need to create an ApplicationEventHandler class and override the starting method, and in there...
UrlProviderResolver.Current.Add<YourProvider>()
You can also insert, insert before, etc.
Making sense?
ah yeah of course! thanks!
is working on a reply...