Copied to clipboard

Flag this post as spam?

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


  • Sébastien Richer 194 posts 430 karma points
    Apr 17, 2014 @ 21:19
    Sébastien Richer
    0

    Looking to get 404 setup in a multi-lingual site

    Hi!

    I'm used to using uComponents for my 404 management. But with version 7.1+ how do we get this setup?

    I have this content tree: 

    Site
        - FR
            - Some pages...
            - I would like my 404 page to be here so I can edit the text with RTE
        - EN
            - Some pages...
            - I would like my 404 page to be here so I can edit the text with RTE

    Has anyone got this setup with version 7.1+ ? Should I look into writing my own handler?

    Thanks much!

  • Richard Soeteman 4049 posts 12922 karma points MVP 2x
    Apr 18, 2014 @ 06:04
    Richard Soeteman
    101

    Hi,

    You might want to check out SEO Checker that does this and a lot of SEO related things for you out of the box. You can specify the 404 page using a picker for every configured domain/language. Free trial works on localhost.

    If you want to code it yourself you might want to check out this blogpost

    Best,

    Richard

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Apr 18, 2014 @ 09:38
    Dave Woestenborghs
    0

    +1 for SEO checker.

  • Sébastien Richer 194 posts 430 karma points
    Apr 18, 2014 @ 15:27
    Sébastien Richer
    0

    Thanks Richard, that blog post looks like it's exactly what I'm looking for, I'll get that in my solution, will be useful forall my projects! Thanks! I'll post back if it worked!

  • Sébastien Richer 194 posts 430 karma points
    Apr 18, 2014 @ 17:41
    Sébastien Richer
    0

    Hey Richard, 

    Ok I think I have the basics in, but my problem is this, I have a Manage Hostnames set to my FR node. basically like this:

    MySite
        - FR (Hostname: mysite.local)

    My english node for this version of the website is not ready yet so I default to the french site and this way I don't see mysite.local/fr/[...].

    Problem is that in my code, I run this:

        var node = contentRequest.RoutingContext.UmbracoContext.ContentCache.GetByRoute(pathToNextNode);

    I'm running this test with this "mysite.local/pageThatDoesNotExist", my pathToNextNode is then set to "/". Basically, I'm using the path to move up the content tree to find a node that will have a property "404Page" set, so that I can use that. My problem is that this GetByRoute, does not give me my FR node, but rather my Site node... It's like it's bypassing my hostname settings.

    Ever seen this?

    Bellow is the full code I'm running!

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Umbraco.Core;
    using Umbraco.Web;
    using Umbraco.Web.Routing;
    
    // Needs interfaces and cms references
    
    namespace PrixModeMtlCms.Code
    {
        public class Umbraco404Handler : IContentFinder
        {
    
            public bool TryFindContent(PublishedContentRequest contentRequest)
            {
    
                // Safety check, this should never occur
                if (contentRequest != null)
                {
    
                    // Check request is a 404
                    if (contentRequest.Is404)
                    {
    
                        var path = contentRequest.Uri.GetAbsolutePathDecoded();
    
                        // Reversed parts of the path
                        var parts = path.Split(new[] { '/' }, System.StringSplitOptions.RemoveEmptyEntries).Reverse();
    
                        // Loop up the parts, until you find a node
                        foreach (var part in parts)
                        {
    
                            // Remove the last part since it's not found
                            parts = parts.Where(x => x != part).ToArray();
    
                            var pathToNextNode = "/" + String.Join("/", parts);
    
                            // Try to find that node
                            var node = contentRequest.RoutingContext.UmbracoContext.ContentCache.GetByRoute(pathToNextNode);
    
                            // If we can't find that node either we'll let the loop continue
                            if (node == null)
                            {
                                continue;
                            }
    
                            // We've found a node, let's find our root nodes to find our 404 page
                            var site = node.AncestorOrSelf("Site");
                            var lang = node.AncestorOrSelf("AccueilLangage");
    
                            // Use lang or site
                            var nodeToUse = lang;
                            if (lang == null)
                            {
                                nodeToUse = site;
                            }
    
                            int notFoundNodeId = 0;
                            if (nodeToUse != null)
                            {
                                notFoundNodeId = nodeToUse.AsDynamic().page404; // Unset content picker, cast to int, will be 0
                                if (notFoundNodeId == 0)
                                {
                                    notFoundNodeId = site.AsDynamic().page404;
                                }
                            }
    
                            // Get the 404 node
                            if (notFoundNodeId != 0)
                            {
    
                                var notFoundNode = contentRequest.RoutingContext.UmbracoContext.ContentCache.GetById(notFoundNodeId);
                                if (notFoundNode == null)
                                {
                                    // The specified 404 node can't be found, break here and let resolve normally
                                    break;
                                }
    
                                // Set Response Status to be HTTP 404
                                contentRequest.SetResponseStatus(404, "404 Page Not Found");
    
                                // Set the node to be the not found node
                                contentRequest.PublishedContent = notFoundNode;
    
                            }
    
                        }
    
                    }
    
                }
    
                // Finally, we return weather we have found a node to use for this request
                return contentRequest.PublishedContent != null;
            }
    
        }
    }

     Edit: Fixed a bug that was in there. This runs good, but does not give me multilingual support, coming from the hostnames.

  • Sébastien Richer 194 posts 430 karma points
    Apr 18, 2014 @ 18:03
    Sébastien Richer
    0

    Ok! Strike that! I guess I had towrite the long version to figure out the short version. This works the way I want! (Well the minimum, I can scope creep later on :))

    Turns out using contentRequest.Domain.RootNodeId was really smooth!

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Umbraco.Core;
    using Umbraco.Web;
    using Umbraco.Web.Routing;
    
    // Needs interfaces and cms references
    
    namespace MyNamespace.Code
    {
        public class Umbraco404Handler : IContentFinder
        {
    
            public bool TryFindContent(PublishedContentRequest contentRequest)
            {
    
                // Safety check, this should never occur
                if (contentRequest != null)
                {
    
                    // Check request is a 404
                    if (contentRequest.Is404)
                    {
                        var domainNode = contentRequest.RoutingContext.UmbracoContext.ContentCache.GetById(contentRequest.Domain.RootNodeId);
                        if (domainNode != null)
                        {
                            int notFoundNodeId = domainNode.AsDynamic().page404; // Unset content picker, cast to int, will be 0
                            if (notFoundNodeId != 0)
                            {
                                // Get the 404 node
                                var notFoundNode = contentRequest.RoutingContext.UmbracoContext.ContentCache.GetById(notFoundNodeId);
                                if (notFoundNode != null)
                                {
    
                                    // Set Response Status to be HTTP 404
                                    contentRequest.SetResponseStatus(404, "404 Page Not Found");
    
                                    // Set the node to be the not found node
                                    contentRequest.PublishedContent = notFoundNode;
    
                                }
                            }
                        }
                    }
    
                }
    
                // Finally, we return weather we have found a node to use for this request
                return contentRequest.PublishedContent != null;
            }
    
        }
    }
Please Sign in or register to post replies

Write your reply to:

Draft