Copied to clipboard

Flag this post as spam?

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


  • Jason Espin 368 posts 1335 karma points
    Apr 27, 2015 @ 17:31
    Jason Espin
    0

    Accessing the language / culture of a page from the Umbraco content service

    Hi all,

    We are in the process of producing another automated website that is driven by our external desktop software an I have some questions regarding Umbraco multi-language support.

    In previous projects we have only dealt with one language and we handle the creation of new pages by traversing through the Umbraco tree structure based upon a pages relation to the root/homepage node.

    However, in this new project we will have multiple homepages in our Umbraco installation as we will be making use of the cultures and hostnames functionality.

    My question is, how can I seperate and identify each of the homepages using the Umbraco content service when used in an API controller.

    Currently I do the following the get the homepage:

    IContent umb_homepage = Application.Context.Current.Services.ContentService.GetRootContent().ElementAt(0);
    

    Now I understand that GetRootContent naturally returns an

    IEnumerable<IContent>
    

    so I have tried adapting the code to the following and accessing the language property of each of the pages as so:

    IEnumerable<IContent> umb_homepages = ApplicationContext.Current.Services.ContentService.GetRootContent();
    
    foreach(IContent homepage in umb_homepages){
       string language = homepage.Language;
    }
    

    However, when I run this in debug mode in Visual studio and stick a breakpoint in my foreach, I find that language is coming through as Null.

    I have ensured that my culture and hostnames values of each of the homepage nodes in my Umbraco installation are set so why am I not getting anything returned when accessing this language property?

    Is there anything else I can do to differentiate between the two (or more) pages?

    Any help would be greatly appreciated.

  • Jason Espin 368 posts 1335 karma points
    Apr 27, 2015 @ 18:27
    Jason Espin
    0

    I have also tried the following:

    foreach (IContent homepage in umb_homepages)
    {
       var lang = umbraco.library.GetCurrentDomains(homepage.Id)[0].Language;
    }
    

    However, this results in a:

    System.NullReferenceException

  • Jonathan Richards 288 posts 1742 karma points MVP
    Apr 27, 2015 @ 18:41
    Jonathan Richards
    0

    I had a requirment to get the home page from within WebApi, and after a bit of rummaging around the only simple solution I had was to access some of the internal functionality of Umbraco using reflection. I did release a package that contains this code, called AutoRouteTemplate, but if you want the code within it looks like this.

    Note: You might notice that anyrepeated requests are cached, which can make it faster than using other methods when being used outside a WebApi - Like a standard razor page, for example


    namespace AutoRouteTemplate
    {
        public static class Site
        {
            static Dictionary<string, IPublishedContent> cache = new Dictionary<string, IPublishedContent>();
    
            public static IPublishedContent GetNode(UmbracoContext context = null)
            {
                if (context == null)
                    context = UmbracoContext.Current;
                string domain = context.HttpContext.Request.Url.GetLeftPart(UriPartial.Authority);
    
                lock (cache)
                {
                    IPublishedContent node = null;
                    if (cache.TryGetValue(domain, out node))
                        return node;
                    try
                    {
                        Uri root = new Uri(context.HttpContext.Request.Url.GetLeftPart(UriPartial.Authority));
                        Umbraco.Web.Routing.RoutingContext route = (Umbraco.Web.Routing.RoutingContext)(context.GetType().
                            GetProperty("RoutingContext", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly).GetValue(context, null));
                        var contentRequest = (Umbraco.Web.Routing.PublishedContentRequest)typeof(Umbraco.Web.Routing.PublishedContentRequest).GetConstructor(
                              BindingFlags.NonPublic | BindingFlags.Instance,
                              null, new Type[] { typeof(System.Uri), typeof(Umbraco.Web.Routing.RoutingContext) }, null).Invoke(new object[] { root, route });
    
                        contentRequest.GetType().GetMethod("Prepare", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(contentRequest, null);
    
                        if (contentRequest.InitialPublishedContent.Id == contentRequest.PublishedContent.Id)
                            node = contentRequest.PublishedContent;
                        else if (contentRequest.PublishedContent.Path.Split(',').Any(x => x == contentRequest.InitialPublishedContent.Id.ToString()))
                            node = contentRequest.InitialPublishedContent;
                        else
                            node = contentRequest.PublishedContent;
                    }
                    catch (Exception)
                    {
                        // Swallow errors
                    }
                    cache.Add(domain, node);
                    return node;
                }
            }
        } 

    } 

     

    Hope this helps.
     

  • Sebastiaan Janssen 5045 posts 15478 karma points MVP admin hq
    Apr 27, 2015 @ 19:26
    Sebastiaan Janssen
    103

    Please, please, please do not use the ContentService for querying. It's going straight to the database and should ONLY be used when you need to create, update or delete data.

    In 7.2.3/7.2.4 you can simple do the following:

    UmbracoHelper helper = new UmbracoHelper(UmbracoContext.Current);
    var items = helper.TypedContentAtRoot();
    items.First().GetCulture();
    

    Of course, if you need anything but the First() you can do something like: items.First(x => x.Name == "UK").GetCulture() or something like that.

  • Jason Espin 368 posts 1335 karma points
    Apr 27, 2015 @ 22:01
    Jason Espin
    0

    I am creating content though and I've been using this methodology since Umbraco 7 was introduced. I select my homepage as a reference point then traverse the tree to find where to create the content from our web services.

  • Sebastiaan Janssen 5045 posts 15478 karma points MVP admin hq
    Apr 27, 2015 @ 22:09
    Sebastiaan Janssen
    0

    Okay, but you only need to use the ContentService for querying if you need to find unpublished content. You can still use the above method for published content.

  • Jason Espin 368 posts 1335 karma points
    Apr 28, 2015 @ 10:14
    Jason Espin
    0

    Hi Sebastiaan,

    I'm afraid that method doesn't even work. In Visual Studio I get the following error:

    Error 1 'Umbraco.Core.Models.IPublishedContent' does not contain a definition for 'GetCulture' and no extension method 'GetCulture' accepting a first argument of type 'Umbraco.Core.Models.IPublishedContent' could be found (are you missing a using directive or an assembly reference?)

  • Sebastiaan Janssen 5045 posts 15478 karma points MVP admin hq
    Apr 28, 2015 @ 10:56
    Sebastiaan Janssen
    0

    This is a new extension method in 7.2.3 and 7.2.4 though, are you using an older version?

  • Jason Espin 368 posts 1335 karma points
    Apr 28, 2015 @ 11:17
    Jason Espin
    0

    That might be why. For some reason the version I have is 7.2.1 despite only pulling it down from NuGet the other day. Is this something that was fixed recently?

  • Sebastiaan Janssen 5045 posts 15478 karma points MVP admin hq
    Apr 28, 2015 @ 11:30
    Sebastiaan Janssen
    0

    Oh.. Update-Package UmbracoCms :-)

    Sometimes you get a version from your local cache, you should try to clear it. It's usually located in C:\Users\<your_username>\AppData\Local\NuGet\Cache.

  • Jason Espin 368 posts 1335 karma points
    Apr 28, 2015 @ 12:08
    Jason Espin
    0

    Thanks for your help with this Sebastiaan. It seems to be working. Just a quick question about the UmbracoHelper method though:

    https://our.umbraco.org/forum/umbraco-7/using-umbraco-7/64377-Get-ancestor-at-level-one-using-the-UmbracoHelper-method

  • Jason Espin 368 posts 1335 karma points
    Apr 28, 2015 @ 17:47
    Jason Espin
    0

    Well, I thought this was the solution but it turns out that it doesn't work. If I use Model.Content.GetCulture() on a page that is assigned a language of "is-IS" then it is showing up as "en-US" when it is output to the page.

Please Sign in or register to post replies

Write your reply to:

Draft