Copied to clipboard

Flag this post as spam?

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


  • Peter Cort Larsen 349 posts 800 karma points
    Sep 18, 2019 @ 10:16
    Peter Cort Larsen
    0

    Hi,

    I have a site where nodes of type 'Course' that are placed under a parent of type 'Courses'.

    Each Course has a category.

    But at the moment the url of a course works in both these situation:

    1. DOMAIN/courses/course
    2. DOMAIN/courses/category/course

    I want only option 2 to be valid. I have a IContentFinder and a IUrlProvider. But i can figure out how to change these to only allow option 2.

    Can anyone help?

    IUrlProvider

    namespace Website.UrlProviders
    {
        public class CoursesWithCategoryUrlProvider : IUrlProvider
        {
            public string GetUrl(UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode)
            {
                var content = umbracoContext.ContentCache.GetById(id);
                if (content != null && content.DocumentTypeAlias == Course.ModelTypeAlias)
                {
                    if (content is Course course)
                    {
                        var category = course?.Categories?.Last();
    
                        if (category == null) return null;
    
                        return $"/{CourseContants.UrlSegmentName}/{category.UrlName}/{course.UrlName}";
                    }
                }
                return null;
            }
    
            public IEnumerable<string> GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current)
            {
                return Enumerable.Empty<string>();
            }
    
        }
    }
    

    IContentFinder

    namespace Website.ContentFinders
    {
        public class CoursesWithCategoryContentFinder : IContentFinder
        {
            public bool TryFindContent(PublishedContentRequest contentRequest)
            {
                if (contentRequest == null) return false;
    
                var pathValues = contentRequest.Uri
                    .GetAbsolutePathDecoded()
                    .Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
    
                if(pathValues.Length == 3 && pathValues.First().Equals(CourseContants.UrlSegmentName))
                {
                    var course = UmbracoContext.Current.ContentCache?
                        .GetByXPath(CourseContants.XPathChildren)?
                        .Where(x => x.UrlName.Equals(pathValues.Last()))?
                        .FirstOrDefault();
    
                    if (course != null)
                    {
                        contentRequest.PublishedContent = course;
                    }
                }
                return contentRequest.PublishedContent != null;
            }
        }
    }
    
  • Marc Goodson 995 posts 6568 karma points MVP 4x c-trib
    Sep 18, 2019 @ 11:17
    Marc Goodson
    0

    HI Peter

    If your CoursesWithCategoryContentFinder IContentFinder is registered in the ContentFinderCollection 'before' the core's default ContentFinderByUrl IContentFinder, then you have the chance to handle the shorter version of the Url too

    What's happening at the moment is your

    /courses/course

    request isn't being handled by your CoursesWithCategoryContentFinder... either because it's being handled first by ContentFinderByUrl or it is falling through your CoursesWithCategoryContentFinder (because it's path length when split will be less than 3) and then it is being handled by the ContentFinderByUrl.

    So if you ensure your CoursesWithCategoryContentFinder is ahead of the ContentFinderByUrl

    and then add a further check to see if the length of the paths is 2, and that the last item is a course, you can then issue a 301 redirect to the desired category version of the Url, (or return a 404) ... but if you do nothing and return false, the pesky default ContentFinderByUrl will find it...!

    ... I'm guessing a course can be in more than one category? otherwise you could structure your content tree /courses/category/course ?

    regards

    Marc

Please Sign in or register to post replies

Write your reply to:

Draft