I've recently had a use for a custom "magic" property, specifically one that works like the umbracoRedirect property, but instead of redirecting to a node in the existing Umbraco, I needed it to redirect to a URL (e.g., the client is using a custom gift-card solution and would like to have a "Gift Card" navigation link that just opens that URL).
For the navigation option it's quite simple for me to just render the custom URL (using a standard property) without hard-coding anything in the macro/partial - that part works fine. But the custom property would enable me to also have the domain.com/gift-card/ URL automatically redirect to the entered URL, without having to write any URLrewrites etc. (and it would seamlessly handle the navigation too).
As with all things code-related, I'm sure there's more than one way of solving this - just know that if I can solve it with a single file in the App_Code folder and not have to build a DLL, I'll be very happy :-)
Just to clarify, you want a umbracoRedirectUrl property that, when set on a node, causes requests for that node to redirect (as in, browser-redirect) to that url. Correct?
Then...
public class RedirectRequests : ApplicationEventHandler
{
protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
{
PublishedContentRequest.Prepared += (sender, args) =>
{
var request = sender as PublishedContentRequest;
if (request == null || !request.HasPublishedContent) return;
var redirect = request.PublishedContent.GetPropertyValue<string>("url");
if (string.IsNullOrWhiteSpace(url)) return;
request.SetRedirect(url);
}
}
}
Just to clarify, you want an umbracoRedirectUrl property that, when set on a node, causes requests for that node to redirect (as in, browser-redirect) to that URL. Correct?
Yes - that's it - looks pretty simple so will give it a try - Merci!!
If you are defining the document type where you want the redirect then my version below will only be run when the specific document type is requested rather than on every request as above.
Great info - thanks. I'm specifically looking for something that can be used in the "standard" Umbraco way, and thus, will work even when picked in a content picker of some sorts.
Render controllers are standard ( Specific to Umbraco) my example works on any request to the "RedirectPage" document type by naming convention on the controller.
As Umbraco is .net MVC I would expect to find anything handling specific requests to document types to be done in a controller rather than a generic event callback to the model setup of every document type.
Maybe just from my non Umbraco MVC background though!
Really appreciate your view on this, as it's the totally opposite of my own :-)
I don't use Visual Studio at all, though I have no problems understanding C# code, and I can easily see why you'd much rather have it structured that way.
Of course you may want to add some logic in that event handler, such as testing the content type, etc - but the good thing is, the event will trigger on every request, after we have identified which document to render, and before we render it.
Not so sure about the controller approach as you would need to route the request to the controller, which is not what you want for every request.
Not sure I get what you mean by "even when picked..."?
Not sure I get what you mean by "even when picked..."?
Just that I'd like it to work for navigations where the individual items are picked with e.g. one of the nuPickers;
So basically: The node gets a "standard" Umbraco URL - but when Umbraco needs to show that URL, it detects and performs the redirect (302 as I understand it, which is perfectly fine).
The routing for controller hijacking is provided by Umbraco out of the box based on naming convention, so the code I provided about works without anything else for a document type named "RedirectPage". See here
Just thought I'd make the point for consistency of the post - no additional routing is needed.
The advantage to my approach is that as the requested is handled by the Umbraco routing so I don't need to add the additional logic to check for document type and it is still done before anything is rendered as the controller has not returned a View();
The code I've proposed would let Umbraco show the old url, and only when the visitor browses to it, redirect to the new url. Which you probably will need in any case. But to achieve what you want we need an extra thing, a special IUrlProvider that would substitute the url of the target node, whenever you get sourceNode.Url.
How can I create a custom "magic" property?
I've recently had a use for a custom "magic" property, specifically one that works like the
umbracoRedirect
property, but instead of redirecting to a node in the existing Umbraco, I needed it to redirect to a URL (e.g., the client is using a custom gift-card solution and would like to have a "Gift Card" navigation link that just opens that URL).For the navigation option it's quite simple for me to just render the custom URL (using a standard property) without hard-coding anything in the macro/partial - that part works fine. But the custom property would enable me to also have the domain.com/gift-card/ URL automatically redirect to the entered URL, without having to write any URLrewrites etc. (and it would seamlessly handle the navigation too).
As with all things code-related, I'm sure there's more than one way of solving this - just know that if I can solve it with a single file in the App_Code folder and not have to build a DLL, I'll be very happy :-)
/Chriztian
Just to clarify, you want a umbracoRedirectUrl property that, when set on a node, causes requests for that node to redirect (as in, browser-redirect) to that url. Correct?
Then...
Should do it. Stephan
Hi Stephan,
Yes - that's it - looks pretty simple so will give it a try - Merci!!
/Chriztian
Just from an optimization point of view.
If you are defining the document type where you want the redirect then my version below will only be run when the specific document type is requested rather than on every request as above.
Thanks
Great info - thanks. I'm specifically looking for something that can be used in the "standard" Umbraco way, and thus, will work even when picked in a content picker of some sorts.
/Chriztian
Hi Chriztian
Render controllers are standard ( Specific to Umbraco) my example works on any request to the "RedirectPage" document type by naming convention on the controller.
As Umbraco is .net MVC I would expect to find anything handling specific requests to document types to be done in a controller rather than a generic event callback to the model setup of every document type.
Maybe just from my non Umbraco MVC background though!
Hi Carl,
Really appreciate your view on this, as it's the totally opposite of my own :-)
I don't use Visual Studio at all, though I have no problems understanding C# code, and I can easily see why you'd much rather have it structured that way.
Again - thanks very much for your input!
/Chriztian
You can use a custom render controller and a document type with a string property
Something like :
I tend to work in VS and so keep all my code compiled - not sure if controllers can go in the app_code folder!
Thanks
Of course you may want to add some logic in that event handler, such as testing the content type, etc - but the good thing is, the event will trigger on every request, after we have identified which document to render, and before we render it.
Not so sure about the controller approach as you would need to route the request to the controller, which is not what you want for every request.
Not sure I get what you mean by "even when picked..."?
Just that I'd like it to work for navigations where the individual items are picked with e.g. one of the nuPickers;
So basically: The node gets a "standard" Umbraco URL - but when Umbraco needs to show that URL, it detects and performs the redirect (302 as I understand it, which is perfectly fine).
/Chriztian
Hi, Stephen.
The routing for controller hijacking is provided by Umbraco out of the box based on naming convention, so the code I provided about works without anything else for a document type named "RedirectPage". See here
Just thought I'd make the point for consistency of the post - no additional routing is needed.
The advantage to my approach is that as the requested is handled by the Umbraco routing so I don't need to add the additional logic to check for document type and it is still done before anything is rendered as the controller has not returned a View();
Thanks
Carl
The code I've proposed would let Umbraco show the old url, and only when the visitor browses to it, redirect to the new url. Which you probably will need in any case. But to achieve what you want we need an extra thing, a special IUrlProvider that would substitute the url of the target node, whenever you get sourceNode.Url.
Can be done - just no time right now.
This will work totalt fine, no worries!
(Just need to get my YSOD-Driven Development on :-)
Thanks,
Chriztian
Sorry to jump in with a "there's a blog post for that", well... there's a blog post for that... by Matt:
http://www.theoutfield.co.uk/blog/2013/10/handling-external-urls-in-umbraco-6
Says it for Umbraco v6, still applies to v7 :-)
Ha! Lee - I even commented on that years ago - totally forgotten about it (and never had the use for it until now, apparently :-)
Thanks!
is working on a reply...