Posted in: Umbraco

Umbraco 7 Code-First Dictionary Key Manager

Posted on June 19, 2015 by Michael Roma

This post shows a simple code-first dictionary manager for Umbraco 7. Click here to download the source.

First define the attribute class and a helper to get the details of an attribute by key name

// define the dictionary key attributes
public class DictionaryKeyAttribute : Attribute
{
    // define fields
    public string Name { get; set; }
    public string DefaultText { get; set; }

    // constructor
    public DictionaryKeyAttribute(string name, string defaultText)
    {
        Name = name;
        DefaultText = defaultText;
    }
}   

// helper that gets the details
private static DictionaryKeyAttribute GetDetails(Keys key)
{
    return key.GetType()
        .GetField(key.ToString())
        .GetCustomAttributes(typeof(DictionaryKeyAttribute), false)
        .SingleOrDefault() as DictionaryKeyAttribute;            
}

Here is the function that initializes the keys by creating new Umbraco dictionary entries if the key does not already exist

// function that inits the dictionary and add new items if needed
public static void Init()
{
    // get the service
    var locationService = ApplicationContext.Current.Services.LocalizationService;

    // get all languages
    var langs = locationService.GetAllLanguages();

    // go through each key
    foreach(var key in Enum.GetValues(typeof(Keys)))
    {
        // get details, check if any
        var keyDetails = GetDetails((Keys)key);
        if (keyDetails != null)
        {
            string keyName = String.Concat(Prefix, keyDetails.Name);
            if (!locationService.DictionaryItemExists(keyName))
            {
                // init the new item
                var newItem = new DictionaryItem(keyName);
                newItem.Translations = langs
                    .Select(lang => new DictionaryTranslation(lang, keyDetails.DefaultText));                        

                // save
                locationService.Save(newItem);
            }
        }
    }

}

The following functions can be used to extract the dictionary text by key

// function that returns a dictionary string
public static string GetText(string key)
{
    // get the service
    var locationService = ApplicationContext.Current.Services.LocalizationService;

    // find the dictionary item
    var item = locationService.GetDictionaryItemByKey(String.Concat(Prefix, key));
    if (item != null && item.Translations != null)
    {
        // get the current language
        int languageId = GetCurrentLanguage();

        // get the translation
        var t = item.Translations.FirstOrDefault(x => x.Language.Id == languageId);
        if (t == null)
        {
            t = item.Translations.FirstOrDefault();
        }

        // check if a translation
        if (t != null)
        {
            // return
            return t.Value;
        }
    }

    // fallback to empty
    return "";
}

// function that gets the dictionary string
public static string GetText(Keys key)
{
    // get the dictionary key details
    var keyDetails = GetDetails((Keys)key);
    if( keyDetails != null)
    {
        return GetText(keyDetails.Name);
    }

    // fallback to empty
    return "";
}

Last, define your key prefix and keys

// define prefix
public const string Prefix = "roma";

// define dictionary items
public enum Keys
{            
    [DictionaryKey("PageTitle", "{0} | Michael Roma Development")] PageTitle,
    [DictionaryKey("CategoriesTitle", "Categories")] CategoriesTitle
}

Here is a helper to get the current page's language

// function that gets the current language
public static int GetCurrentLanguage()
{
    // get the current page
    var currentPage = new UmbracoHelper(UmbracoContext.Current)
        .TypedContent(UmbracoContext.Current.PageId.Value);

    // check if a page
    if (currentPage != null)
    {
        // get the home page
        var home = currentPage.AncestorOrSelf(1);
        if (home != null)
        {
            // get the domains for home
            var domains = umbraco.cms.businesslogic.web.Domain.GetDomainsById(home.Id);
            if (domains.Count() > 0)
            {
                return domains[0].Language.id;
            }
        }
    }

    // if here, no language
    return 0;
}

Umbraco CMS Content Query functions using Examine

Posted on June 16, 2015 by Michael Roma

This post discusses a ContentHelper class that can be used to query the Umbraco content tree. Click here to download the source

The following functions take a Umbraco path or an IPublishedContent object to search for content under that given path/content. It also takes a parameter for "Type" which can be used to select only certain Document Types. You can use String.Empty for the path to search all documents.

// function that queries for the given path and type
public static IEnumerable<IPublishedContent> Query(string path, string type, bool cache)
{
    // define query
    Func<IEnumerable<IPublishedContent>> f = delegate()
    {
        // get the helper
        var helper = new UmbracoHelper(UmbracoContext.Current);

        // get examine
        var examine = Examine.ExamineManager.Instance;

        // build the criteria
        var criteria = examine.CreateSearchCriteria();

        // check if a type
        if (!String.IsNullOrEmpty(type))
        {
            criteria.NodeTypeAlias(type);
        }

        // check if a path
        if (!String.IsNullOrEmpty(path))
        {
            criteria.Field("__Path", path.MultipleCharacterWildcard());
        }

        // get the results
        var results = examine.Search(criteria);

        // return the list
        if (results != null)
        {
            return helper.TypedContent(results.Select(x => x.Id)).Where(x => x != null).OrderBy(x => x.SortOrder);
        }

        // else, empty 
        return new List();
    };

    // else, return
    return f();            
}

// function that query for the path of the given item and type
public static IEnumerable<IPublishedContent> Query(IPublishedContent item, string type)
{
    return Query(item.Path, type);
}

The following is a helper that finds the closest parent with the given Document Type

// function that finds the closest parent for the given type and given document
public static IPublishedContent GetClosestParent(IPublishedContent item, string type)
{
    // loop while a document
    while (item != null)
    {
        // check if the correct type
        if (item.DocumentTypeAlias == type)
        {
            // return it
            return item;
        }

        // go up
        item = item.Parent;
    }

    // if here, nothing
    return null;
}

// function that finds the closest parent for the given type and current document
public static IPublishedContent GetClosestParent(string type)
{
    // get the current document, if exists
    if (UmbracoContext.Current != null && UmbracoContext.Current.PageId.HasValue)
    {
        return GetClosestParent(GetContentById(UmbracoContext.Current.PageId.Value), type);
    }

    // else, null
    return null;
}