Keywords-labels in Tridion using MVC

    One of the main advantages in Tridion is the possibility for translating content. Usually the components are localized and translated for the current content publication.

A typical design for managing the languages in the blueprinting hierarchy is having a root content language publication and other child languages (for example: Content EN publication inherited by Content BG publication ). That makes the translation of components rather easy and clean. But what happens with all this additional text that is not related to our components. If you think about it you have plenty of this content – greetings, form titles, button’s text and so on.

So what is the way to manage this text in out Multilanguage Tridion site? There are many ways to do this, but personally I think keywords are a good and simple way to go.

The steps of implementing labeling with keywords are the following:

  1. Create a category in Categories and keywords with name “TextLabels” or something that makes sense to you.
    category_textLabels
  2. Add your “other text” in keywords. Value will be the technical name that we will use for referring the keyword and the Description will be the one translated.
    keyword_prop
  3. Publish keywords-labels category.
  4. In your VS solution add the LabelHelper class.
    				
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Linq;
    using Tridion.ContentDelivery.Taxonomies;
    namespace TridionHelpers
    {
        public class LabelHelper!
        {
             public static IEnumerable<Tuple<string, string>> GetKeywords(stringcategoryId)
    	 {
    	      CompositeFilter compFilter = new CompositeFilter();
    	      var taxFac = new TaxonomyFactory();
    	      IEnumerable taxonomy =
    		   taxFac.GetTaxonomyKeywords(categoryId, compFilter, new TaxonomyHierarchyFormatter()).KeywordChildren.Cast();
    
    	      return taxonomy.Select(x => new Tuple<string,string&gt (x.KeywordName, x.KeywordDescription));
    	  }
         }
    }
    				
  5. In the web.config – appSettings we store the id of the current publication and a placeholder with the tcm for the “TextLabels” category.
    				
    <add key="DD4T.PublicationId" value="8" />
    <add key="LabelsCategoryIdPlaceholder" value="tcm:{0}-17-512" />
    				
  6. In the ComponentController.cs class add the ViewBag property Labels that will store the information collected from the Broker.
    				
    var pubId = ConfigurationManager.AppSettings["DD4T.PublicationId"];
    var categoryPlaceholderId = ConfigurationManager.AppSettings["DefaultCategoryIdPlaceholder"];
    var tcmId = string.Format(categoryPlaceholderId, pubId);!
    ViewBag.Labels = LabelHelper.GetKeywords(tcmId);!
    				
  7. (Optional) Add cache mechanism for getting the keywords. Very nice article about the caching in ASP here.
  8. Whenever you need a keyword in the view just refer it from the ViewBag and show its description
    				
    < strong >
    @((ViewBag.Labels as IEnumerable<Tuple<string,string>>)
    	.FirstOrDefault(x => x.Item1 == "ImportantAlertsTitle").Item2)
    < /strong >
    				
  9. Localize and translate in the other language publications.

*If you have too many labels you can split them just by adding additional non mandatory parameter to the method that gets the keywords:

		
  public static IEnumerable<Tuple<string, string>> GetKeywords(string categoryId,
        string parentKeywordName = null)
	{
	     CompositeFilter compFilter = new CompositeFilter();
	     var taxFac = new TaxonomyFactory();
	     IEnumerable taxonomy = taxFac.GetTaxonomyKeywords(categoryId,
		   compFilter, new TaxonomyHierarchyFormatter()).KeywordChildren.Cast();
	     if (parentKeywordName != null)
	     {
		var parent = taxonomy.FirstOrDefault(k => k.KeywordName == parentKeywordName);
					taxonomy = parent.KeywordChildren.Cast();
	     } 
	     return taxonomy.Select(x => new Tuple<string, string>(x.KeywordName, x.KeywordDescription));
	}
		
    Some of the main disadvantages I see in this kind of labeling:

  • The connection between the “Value” of the keywords and the actual code is missing. Once created the value should not be changed, the only think that changes is description.
  • The connection between pages and keywords is missing. You cannot find from the Content management where some keyword is used (our favorite survival trick with the function “Where used” won’t work).
  • Leaving behind old, not anymore used in the site keywords can be just additional and not needed work for the translators, and also the creation of duplicated keywords.

    Keep in mind that labeling that way is depending strongly of the way that the keywords will be structured and divided in the Content management, and also on the way they will be managed (better make a clean separation of the words to be clear where some word in the site should be found, if needs to be changed).

In the end I want to mention a couple thing about these code snippets. I’m using structures like Tuple and ViewBag just to avoid distracting the reader from the logic of the implementation. If you use this in a real project I strongly suggest you to modify the code depending on your needs and maybe improve the quality a bit. For example don’t use Tuple – create a class for the keyword-label type. Don’t use ViewBag, try to slip the labels in the model of your view and you will avoid all the casting that comes with the ViewBag. I proposed the division of the keyword-labels with parent keyword, but it can be done in many ways depending on your needs – you can also use a couple categories for the labeling. Don’t forget about the caching, no one needs real-time keywords for every request.

    So I want to say this is not some general solution, but rather showing some way of managing all of the “other text” text in your site. You might also be interested in this article that goes in other direction for solving the labeling problem.
Have a nice time labeling!

Author: Elena Kirilova