Razor Template Scripting with jQuery

Recently I discovered template scripting in Razor (not sure what the actual name for it is) and it’s really saved me in some recent projects.  It’s basically a markup template/placeholder inside of a script tag, with dynamic references to model attributes. This lets you render new content onto your page using jQuery’s .render() and .appendTo() functions by targeting the ID of the template.

It starts with a controller action or method. You’ll need to return an instance of the model you’re using or a generic list of instances, depending on your situation. In my case, I made my controller action return a list of items to be added to a grid, if the user clicked a button indicating they wanted to see more items.

Some very basic code:

public ActionResult GetItems(type param1, type param2)
 {
    var itemList = new List<MyModel>();
    itemList = GetNewContent(param1, param2);
    if (itemList.Count < 1)
    {
       return Json(new { success = false }, JsonRequestBehavior.AllowGet);
    }
    return Json(new { success = true, nextItems = itemList }, JsonRequestBehavior.AllowGet);
 }

 The markup looks a little like this:

2016-03-16 14_19_27-SubZero - Microsoft Visual Studio (Administrator).png

Notice the dynamic variables in purple – those are your model attributes, which should exist in the model objects you returned in the controller action.

The JS call:

$('#gridItemTemplate').render(data.nextItems).appendTo('div#subItemGrid');

Because the type of data.nextItems is a list of those model objects, this code knows what those attributes are and how to get them. This will then append the new data based on the template provided, to the element you specify – in my case, a div.

This is a very useful method for rendering markup on the fly using jQuery.

 

Creating a Sitecore Dictionary Parser in Javascript

If you have ever worked on a multi-language site, you know the difficulty of having to make sure every last word is translated correctly. Most of this text may be on your views or web pages in which it is relatively easy to translate. However, when we write scripts for website we implement validation in them, which creates more static text that needs to be translated.

I eventually ran into a situation just like this, where the client requested that pretty much everything be translated correctly depending on the current site language. So I was stuck – how do I grab the value of the French version of a Sitecore item somewhere inside the CMS, from Javascript?

It starts with JSON, which is no surprise. Essentially you need to create a JSON dictionary in a controller method and get all the dictionary items you need, depending on the current site language, then serve that to the view in a tag, which your JS can easily read and interpret. Let’s look at some code.

Step 1: Create a DictionaryItem class (optional).

In my example, I created a DictionaryItem class to make creating the list of dictionary items easier.

public class DictionaryItem
{
   public string Key { get; set; }
   public string Phrase { get; set; }

   public DictionaryItem()
   {
   }

   public DictionaryItem(string key, string phrase)
   {
      Key = key;
      Phrase = phrase;
   }
}

Step 2: Create your controller method.

In your controller, create a public method with a return value of string. It might look something like this:

public string GetJsonDictionary()
{
   // Get a list of all dictionary items.
   var db = Database.GetDatabase(EnvironmentHelper.IsProduction ? "pub" : "web");
   var dictionaryFolder = db.GetItem("your sitecore item id as string");
   var dictionaryItems = dictionaryFolder.Axes.GetDescendants().ToList();
   var condensedDictionaryItemList = new List();

   foreach (var dictionaryItem in dictionaryItems)
   {
      var dict = new DictionaryItem();

      // Get the field value of the item based on the item ID - your implementation may differ
      dict.Key = SitecoreApiHelper.GetFieldValue(dictionaryItem.ID.ToString(), "Key");

      // Get the dictionary item from Sitecore matching dict.Key.
      dict.Phrase = GetDictionaryItem(dict.Key);
      condensedDictionaryItemList.Add(dict);
   }
   var result = JsonConvert.SerializeObject(condensedDictionaryItemList);
   return result;
}

Step 3: Call the controller method from your view.

I dynamically created an object ‘window.ncpDictionary’ for this purpose. In the Html.Action() call, the first parameter is the method name, the second, the controller name (minus “Controller”).

Make sure to make this call before any other calls that depend on it.

@using (Html.BeginScripts())
{
   window.ncpDictionary = @Html.Action("GetJsonDictionary", "NCP");
}

Step 4: Create a Javascript function to get a phrase from the dictionary given the key (and any parameters (optional)). I created a new script for shared functions across an entire section of the project, but this is optional.

function getDictionaryPhrase(key, parameter) { 
   var value = ""; 
   parameter = parameter || ""; 
   if (window.ncpDictionary != null) { 
      window.ncpDictionary.forEach(function (element) { 
         if (element.Key == key) { 
            // TODO: Enhance later to allow multiple parameters. 
            value = element.Phrase.replace('{0}', parameter);
         }
      }); 
   } 
   if (value == "") { return key; } return value; 
}

This code iterates through the dictionary we created in the controller method and checks for the supplied key to the function. If it finds it, send back the phrase (value). You may include a parameter as well; in this case, if your dictionary phrase includes {0}, this will replace it with the supplied parameter, if any.

Step 5: The function call!

Here is an example:

getDictionaryPhrase('please-enter-a-valid-day-01-31'))

Just like that, you’ve created a parser that you can use throughout your website to make sure everything gets translated nicely. Happy Sitecoring.