Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Oct 23, 2015 @ 07:57
    Chriztian Steinmeier
    0

    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

  • Stephen 767 posts 2273 karma points c-trib
    Oct 23, 2015 @ 09:57
    Stephen
    1

    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);
        }
      }
    }
    

    Should do it. Stephan

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Oct 23, 2015 @ 10:02
    Chriztian Steinmeier
    0

    Hi Stephan,

    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!!

    /Chriztian

  • Carl Jackson 139 posts 478 karma points
    Oct 23, 2015 @ 10:05
    Carl Jackson
    0

    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

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Oct 23, 2015 @ 10:11
    Chriztian Steinmeier
    0

    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

  • Carl Jackson 139 posts 478 karma points
    Oct 23, 2015 @ 10:23
    Carl Jackson
    0

    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!

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Oct 23, 2015 @ 11:08
    Chriztian Steinmeier
    1

    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

  • Carl Jackson 139 posts 478 karma points
    Oct 23, 2015 @ 10:01
    Carl Jackson
    1

    You can use a custom render controller and a document type with a string property

    Something like :

        public class RedirectPageController : RenderMvcController
    {
        public override ActionResult Index(RenderModel model)
        {
            return Redirect(model.Content.GetPropertyValueAsString("redirectTo"));
        }
    }
    

    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

  • Stephen 767 posts 2273 karma points c-trib
    Oct 23, 2015 @ 12:05
    Stephen
    0

    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..."?

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Oct 23, 2015 @ 12:11
    Chriztian Steinmeier
    0

    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

  • Carl Jackson 139 posts 478 karma points
    Oct 23, 2015 @ 16:42
    Carl Jackson
    0

    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

  • Stephen 767 posts 2273 karma points c-trib
    Oct 23, 2015 @ 13:18
    Stephen
    1

    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.

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Oct 23, 2015 @ 14:35
    Chriztian Steinmeier
    0

    This will work totalt fine, no worries!

    (Just need to get my YSOD-Driven Development on :-)

    Thanks,

    Chriztian

  • Lee Kelleher 4026 posts 15836 karma points MVP 13x admin c-trib
    Oct 23, 2015 @ 16:54
    Lee Kelleher
    101

    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 :-)

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    Oct 23, 2015 @ 22:18
    Chriztian Steinmeier
    0

    Ha! Lee - I even commented on that years ago - totally forgotten about it (and never had the use for it until now, apparently :-)

    Thanks!

Please Sign in or register to post replies

Write your reply to:

Draft