Copied to clipboard

Flag this post as spam?

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


  • Neil Hartley 8 posts 78 karma points
    Mar 15, 2018 @ 19:55
    Neil Hartley
    0

    I just cant figure out routing

    Hi guys,

    Im trying to create a blog using umbraco and by design I have the following simple structure.

    Blog - Post - Post - etc.. Category

    When you create a post, you select a single category for it from the list.

    Currently by default to get to a post the url would be /Blog/My-Post-Name

    Im trying to build a route so that I can include the category wo it should look like this.

    /Blog/My-Category/My-Post-Name

    Ive tried creating a route and using FindContent from UmbracoVirtualNodeByIdRouteHandler but I can never seem to get it to work. This is my current route.

    RouteTable.Routes.MapUmbracoRoute(
                "PostRoute",
                "Blog/{category}/{action}",
                new
                {
                    controller = "CustomPost",
                    category = UrlParameter.Optional
                },
                new CustomPostsRouteHandler(1234));
    

    I then have the following custom route handler

    public class CustomPostsRouteHandler : UmbracoVirtualNodeByIdRouteHandler
    {
    
        public CustomPostsRouteHandler(int realNodeId) : base(realNodeId)
        {
        }
    
        protected override IPublishedContent FindContent(RequestContext requestContext, UmbracoContext umbracoContext, IPublishedContent baseContent)
        {
            var bob = 123;
    
            return base.FindContent(requestContext, umbracoContext, baseContent);
        }
    }
    

    And the following Controller

    public class CustomPostController : RenderMvcController
    {
        public ActionResult Default(RenderModel model, string category)
        {
            return View("Post", model);
        }
    }
    

    Any help you guys might be would be greatly appreciated.

    Thanks

    Neil

  • Alex Brown 129 posts 620 karma points
    Mar 16, 2018 @ 09:06
    Alex Brown
    0

    I had a bit of trouble with routing too. I ended up using IContentFinders in the end. Hope you'll be able to achieve what you want with the following.

    1) Create a class and make it inherit from IContentFinder, then implement its method "TryFindContent". IConentFinders are called in every initial request after building, so you'll have to write some specific logic here to detect whether {category} is actually a category or not.

    2) Write the logic to detect if the second segment of the url is a category name (use contentRequest.Uri.AbsolutePath to get the url). Maybe use UmbracoHelper class and get all category nodes, then compare their Url property with the current {category}.

    3) Next you need to do the same as above and detect if My-Post-Name is a legit blog post. If it is, then get that blog post's IPublishedContent and set it to contentRequest.PublishedContent and return true; Otherwise return false.

    Hopefully this helps/works. If not and you have a custom viewmodel then you might need to create a controller which inherits from RenderMvcController. The controller must be named after the blog post's document type, and the action must be named after that document type's default template name. Hope this isn't too much info or wastes your time.

  • Neil Hartley 8 posts 78 karma points
    Mar 16, 2018 @ 10:24
    Neil Hartley
    0

    Hey its not a waste of time at all, Ill have a go at your suggestions and see where I get.

    I updated my post with some of the other code I had in place, im thinking the action name in the controller is incorrect as the template name is post, so I guess the action name needs to be post aswell.

    Thanks

    Neil

  • Alex Brown 129 posts 620 karma points
    Mar 16, 2018 @ 10:45
    Alex Brown
    0

    Yeah the template name has to match the action in the controller. Here's some of my code which will hopefully elaborate what I talked about:

    IContentFinder - in here I call my own custom interface which has logic that detects whether the url is valid:

    public bool TryFindContent(PublishedContentRequest contentRequest)
    {
        var productUrlService = DependencyResolver.Current.GetService<IProductUrlService>();
    
        var url = contentRequest.Uri.AbsolutePath;
    
            if (productUrlService.IsCustomUrl(url))
            {
                contentRequest.PublishedContent = //get blog post IPublishedContent with UmbracoHelper
    
                return true;
            }
        return false;
    }
    

    Then the controller is hit if it's true

    public class ProductController : RenderMvcController
    {
            public ActionResult Product(IPublishedContent content)
            {
                    var model = BuildMyCustomModel();
    
                    return View(model);            
            }
    }
    

    So my document type alias is "Product", therefore ProductController, my template is also called Product, so I named the action the same.

    You might not need a controller though if you're simply returning an IPublishedContent model (I've never tried without a controller).

Please Sign in or register to post replies

Write your reply to:

Draft