Copied to clipboard

Flag this post as spam?

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


  • Tom van Enckevort 107 posts 429 karma points
    Apr 27, 2018 @ 16:56
    Tom van Enckevort
    0

    Set domain on root node but skip to next child node for home page

    I'm working on a multi-site setup (with multiple domains) and was wondering if something like this is possible:

    enter image description here

    So I set the domain (e.g. site-1.com) on the root node (Site 1), but that is just a 'virtual node' without any template.

    But by default this will now get the home URL as well (site-1.com/) and the actual home page node (Home) will get the site-1.com/home/ URL.

    Is there any way I can skip the root node and have the first child node as the home URL? I'm thinking it might need a custom UrlProvider to achieve this, but not sure how to best implement this.

    The reason why I haven't set the domain on the Home node is because I need a handful of pages in the Website Components folder as well (with a template and URL), and assigning site-1.com to Home and site-1.com/website-components to Website Components doesn't seem to work when linking to one of those pages from the home page (plus I'd rather set the domain in single place).

  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    Apr 29, 2018 @ 08:45
    Nik
    0

    Hi Tom,

    On your Site 1 node, add a property called umbracoInternalRedirectId and make it's type a content picker. Then pick the home node you want to redirect to.

    This property is a clever build in property that will perform an internal redirect and show the correct page instead.

    More info:

    Thanks,

    Nik

  • Tom van Enckevort 107 posts 429 karma points
    Apr 29, 2018 @ 10:34
    Tom van Enckevort
    0

    Hi Nik,

    Thanks for the suggestion.

    Although that would work to 'redirect' to the right home page, in the CMS it would still show site-1.com/home/ as the URL of the Home page. And I would like to get rid of that as well.

  • Nik 1593 posts 7151 karma points MVP 6x c-trib
    Apr 29, 2018 @ 11:36
    Nik
    0

    Hi Tom,

    One option is to have a redirect of /home to /

    Another option is to assign the domain to the home node instead of the root node. Although I'm not quite sure how that will work as it's not something I've tried.

    Nik

  • Tom van Enckevort 107 posts 429 karma points
    Apr 30, 2018 @ 07:22
    Tom van Enckevort
    100

    I think I have managed to get it working with a custom UrlProvider and ContentFinder:

    public class SiteUrlProvider : DefaultUrlProvider
    {
        public override IEnumerable<string> GetOtherUrls(UmbracoContext umbracoContext, int id, Uri current)
        {
            var urls = base.GetOtherUrls(umbracoContext, id, current);
    
            var content = umbracoContext.ContentCache.GetById(id);
    
            if (content?.DocumentTypeAlias == MySite.ModelTypeAlias)
            {
                // add the node ID to the URL, since this shouldn't be the home page URL
                urls = urls.Select(u => $"{u}{id}/");
            }
    
            var homeNode = content?.AncestorOrSelf<MyHomePage>();
    
            if (homeNode != null)
            {
                // remove the home node url name, since this should be the home page URL
                urls = urls.Select(url =>
                {
                    string path;
    
                    if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
                    {
                        var uri = new Uri(url);
                        path = uri.GetAbsolutePathDecoded();
                    }
                    else
                    {
                        path = url;
                    }
    
                    var newPath = path.TrimStart($"/{homeNode.UrlName}/").EnsureStartsWith("/");
    
                    url = url.Replace(path, newPath);
    
                    return url;
                });
            }
    
            return urls;
        }
    
        public override string GetUrl(UmbracoContext umbracoContext, int id, Uri current, UrlProviderMode mode)
        {
            var url = base.GetUrl(umbracoContext, id, current, mode);
    
            var content = umbracoContext.ContentCache.GetById(id);
    
            if (content?.DocumentTypeAlias == MySite.ModelTypeAlias)
            {
                // add the node ID to the URL, since this shouldn't be the home page URL
                url += $"{id}/";
            }
    
            var homeNode = content?.AncestorOrSelf<MyHomePage>();
    
            if (homeNode != null)
            {
                // remove the home node url name, since this should be the home page URL
                string path;
    
                if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
                {
                    var uri = new Uri(url);
                    path = uri.GetAbsolutePathDecoded();
                }
                else
                {
                    path = url;
                }
    
                var newPath = path.TrimStart($"/{homeNode.UrlName}/").EnsureStartsWith("/");
    
                url = url.Replace(path, newPath);
            }
    
            return url;
        }
    }
    

    And the ContentFinder class:

    public class SiteContentFinder : IContentFinder
    {
        public bool TryFindContent(PublishedContentRequest docRequest)
        {
            var contentCache = docRequest.RoutingContext.UmbracoContext.ContentCache;
    
            string route;
    
            if (docRequest.HasDomain)
            {
                var domainNode = contentCache.GetById(docRequest.UmbracoDomain.RootContentId.Value);
    
                // get first child node of domain node, as that will be the home node
                var homeNode = domainNode?.Children.FirstOrDefault();
    
                // include url name of the home node in the route path
                route = docRequest.UmbracoDomain.RootContentId.ToString() + (homeNode != null ? $"/{homeNode.UrlName}" : null) + 
                            DomainHelper.PathRelativeToDomain(docRequest.DomainUri, docRequest.Uri.GetAbsolutePathDecoded());
            }
            else
            {
                route = docRequest.Uri.GetAbsolutePathDecoded();
            }
    
            docRequest.PublishedContent = contentCache.GetByRoute(route);
    
            return docRequest.PublishedContent != null;
        }
    }
    

    Register them in the ApplicationStarting event before the defaults:

    protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
    {
        // register custom URL provider
        UrlProviderResolver.Current.InsertTypeBefore<DefaultUrlProvider, SiteUrlProvider>();
        ContentFinderResolver.Current.InsertTypeBefore<ContentFinderByNiceUrl, SiteContentFinder>();
    }
    
Please Sign in or register to post replies

Write your reply to:

Draft