Find langauge af Item

Nov 7, 2008 at 9:19 AM
... or perhaps, find all items of particular language. I've been mucking around with the database for a while now -- is it correct that, to determine the language of a particular node, you have to walk up the content-tree until you find an item imbued with a 'LanguageCode' detail (that item being the language root)? Is there an elegant way to that using the N2 persistence layer?
Nov 7, 2008 at 10:19 AM
I use this function to (always) get a language root returned.
First, traverse the tree to find a best fit from parentnodes, if that fails use a GeoIP database to find the users language and see if there is a root with that language.
If all fails, get a default root (in thsi case en-US).

    public static Overview BestFitLanguageRoot
    {
        get
        {
            foreach (
                ContentItem item in
                    N2.Persistence.GenericFind<ContentItem, ContentItem>.EnumerateParents(
                        GenericFind<ContentItem, ContentItem>.CurrentPage, null, true))
            {
                Overview lhp = item as Overview;
                if (lhp != null)
                    return lhp;
            }
            LookupService ls = new LookupService(HttpContext.Current.Server.MapPath("/GeoIP/GeoIP.dat"),
                                                 LookupService.GEOIP_MEMORY_CACHE);
            Country c = ls.getCountry(HttpContext.Current.Request.UserHostAddress);

            string langCode = c.getCode().ToLower();
            if (gateway != null && gateway.Enabled)
            {
                foreach (ILanguage language in gateway.GetAvailableLanguages())
                {
                    if (langCode == language.LanguageCode)
                    {
                        return
                            (Overview)
                            GenericFind<ContentItem, ContentItem>.Items.Where.Detail("LanguageCode").Eq(langCode).Select
                                ()[0];
                    }
                }
            }
            return
                (Overview)
                GenericFind<ContentItem, ContentItem>.Items.Where.Detail("LanguageCode").Eq("en-US").Select()[0];
        }
    }
Nov 7, 2008 at 11:40 AM
> GeoIP database

Why not simply use the language(s) requested by the user in Request.UserLanguages?
Nov 7, 2008 at 11:44 AM
I was actually most interested in grabbing nodes of a particular language. Here's linqtosql code that does it:
        private static string GetLanguage(n2Item item)
        {
            var db = new DBContextDataContext();
            n2Detail detail = db.n2Details.Where(d => d.ItemID == item.ID && d.Name == "LanguageCode").SingleOrDefault();
            if (detail == null)
            {
                return GetLanguage(GetParent(item));
            }
            else
            {
                return detail.StringValue;
            }
        }

        private static n2Item GetParent(n2Item item)
        {
            var db = new DBContextDataContext();
            return db.n2Items.Where(i => i.ID == item.ParentID).Single();
        }

Nov 7, 2008 at 11:45 AM
I doubt that many user's actually are aware of that so "requested by" is not really valid in my opinion.
But, it is a valid option if you want to follow the language of the operating system (which is the default for that).

In this scenario we chose to use the location of the user because that was more relevant for our customer. It is a more and more used variable these days since the (free) availability of IP databases.
We always provide a way to change the language btw.

All language-related programming is based on choices and preferences. Another choice is always good, if it suits your needs.
Nov 7, 2008 at 11:52 AM
 > (free) availability of IP databases.

Free? We use a Geo-IP database but it's not free - where can I get a free one? :-)
Nov 7, 2008 at 12:16 PM
http://www.maxmind.com/app/geolitecountry