Copied to clipboard

Flag this post as spam?

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


  • Jonas Eriksson 930 posts 1825 karma points
    May 22, 2013 @ 22:36
    Jonas Eriksson
    0

    Anyone has a "Catch all routes under node url" ?

    Let's say I have a node under mysite/products and I like it to catch all routes underneath, mysite/products/A , mysite/products/B - and handle the rest of the url myself from a macro on the template for mysite/products. 

    I don't think I can do that with any current package or built in behaviour? Other than manually adding urlrewriter rules.

    So, I made a small 404 handler to achieve that behaviour. The handler simply looks for a "umbracoCatchAll" property in all parent urls above a not found url, and redirects to that one if found.

    So this is a question for comments and for info about existing solutions. Before I make a package.

    https://gist.github.com/joeriks/5630458

    Thanks

    Jonas

  • Andreas Iseli 150 posts 427 karma points
    May 23, 2013 @ 08:40
    Andreas Iseli
    0

    You add rewrites in the UrlRewriting.config file. Would that help?

  • Jonas Eriksson 930 posts 1825 karma points
    May 23, 2013 @ 09:00
    Jonas Eriksson
    0

    Hi,

    thanks, yes, but I never really liked that approach, editing a config file, plus the syntax is a bit hard/different. I like to handle these things in my node tree and use the same kind of syntax I'm familiar with:

    I add the umbracoCatchAll=1 to my node on the /mysite/products , and then I add a razor script like this:

    @{
       var productBrand = CatchAll.UrlParts[0]; 
       var productName = CatchAll.UrlParts[1];
       var product = SomeDb.SingleOrDefault<dynamic>("SELECT * FROM Product WHERE Brand=@0 AND Name=@1", productBrand, productName);
    }
    <h1>@product.Description</h1>
    <img src="@product.ImageUrl"/> 

    ยจ

    ... and I can show db stored products under my /mysite/products urls

    CatchAll.UrlParts is a static helper function that splits all parts of the url that are to the right of the current node url (the same exists in WebPages)

    What do you think?

  • Andreas Iseli 150 posts 427 karma points
    May 23, 2013 @ 09:28
    Andreas Iseli
    0

    Well perhaps you can achieve your desired behavior with a plugin controller that defines an area:

    http://our.umbraco.org/documentation/Reference/Mvc/surface-controllers

    I've never tried it yet but I still have an open project that requires the same behavior as yours. Another and perhaps better approach for you would be defining your custom routes in a class that inherits from IApplicationEventHandler:

    http://our.umbraco.org/documentation/Reference/Mvc/custom-routes

    I do unterstand that you don't like the config file approach (me neither), but we still work with a CMS that has some limitations but offers more opportunities. I personally would not overwrite the error file, even when you are checking that the target node exists.

  • Jonas Eriksson 930 posts 1825 karma points
    May 23, 2013 @ 10:33
    Jonas Eriksson
    0

    Afaiu custom-routes takes me out of Umbraco pipeline, which I do not like in this case. I like to maintain the product pages template the same way I do with the others. 

    Surface controllers is for child actions, and would not handle the routes for me.

    True, the 404 handler does seem like an unusual way to catch routes, and it would indeed feel a bit more correct to add a custom route handler of some kind, to happen before the umbraco route handler, not least to make it quick. However, it's still only a way to deal with the routing handler pipeline, even if its called 404 handlers, and I think the extra performance cost is small.

    Jonas

     

  • Andreas Iseli 150 posts 427 karma points
    May 23, 2013 @ 10:38
    Andreas Iseli
    0

    You may be right, but I was so sure there is another way... perhaps someone else knows more about it or finds the blog entry I cannot found any more ;-)

    Unfortunately I cannot tell you more at the moment. I'm going to have a closer look at it as soon as possible, but currently I'm too busy.

    Regards

  • Jonas Eriksson 930 posts 1825 karma points
    May 23, 2013 @ 10:48
    Jonas Eriksson
    1

    Thanks for the discussion, I'll play around with this to begin with and see what happens :)

  • Stephen 767 posts 2273 karma points c-trib
    May 23, 2013 @ 10:55
    Stephen
    100

    If I understand correctly you have a url that may look like /path/to/our/products/category/product and products is a catch-all node, and /category/product does not actually exist in the tree, right?

    Of course the first thing that comes to mind is a rewriting rule that would rewrite to /path/to/our/products?show=category/product but I understand you'd rather avoid rewriting rules.

    In 6.1+ you'd create an IContentFinder... and in anything before you need to create a NotFoundHandler. So, since you're on 4.x, you need a NotFoundHandler. Yours seems OK in that context. Though maybe you can avoid recursion when trying the different urls?

    Also... uQuery.GetNodeByUrl(...) uses the IContentFinder to find content (even in 4.x, only in 4.x IContentFinder are still internal) and there's some efficient cache in there... so instead of looking for /path/to/our/products/category/product then /path/to/our/products/category then... I'd rather do /path then /path/to then /path/to/our... because these are going to be _fast_. You keep track of which has the umbracoCatchAll property and use the last one that was found.

    Also you could optimize if you know how many items /category/products will contain...

    Stephan

  • Jonas Eriksson 930 posts 1825 karma points
    May 23, 2013 @ 11:16
    Jonas Eriksson
    0

    Hi Stephen, thank you very much for your feedback! 

    Yep, that's the way I meant the urls to behave.

    Ok, changing to search from the shortest url first, makes sense, esp if there's a lot of urlparts outside, thx.

    Good to know about the IContentFinder. Will explore that for a future version :)

    Cheers

    Jonas

  • Jonas Eriksson 930 posts 1825 karma points
    May 23, 2013 @ 13:59
    Jonas Eriksson
    0

    I changed the code to better performance, and then I remembered a discussion I had with (um, I forgot who, sorry...) that it would be nice to be able to just add a document named * and it should catch all sibling url calls.

    For example /products/* will catch /products/foo and /products/bar as well as /products/bar/12345.

    I like that better than having to add another property. The handler now supports both alternatives. Code is still in need of some polish.

    https://gist.github.com/joeriks/5630458

Please Sign in or register to post replies

Write your reply to:

Draft