1

My C# TBB returns Keywords from a specific Category as XML:

XmlDocument keywordsXml = new XmlDocument();
keywordsXml.LoadXml(cat.GetListKeywords().OuterXml);
Item output = package.CreateXmlDocumentItem(ContentType.Xml, keywordsXml);
package.PushItem("MyKeywords", output);

I see in Template Builder that the TBB return results but not sure how to consume this XML in my Razor template. I would like to get Title of each Keyword. Below is what TBB returns:

<tcm:ListKeywords xmlns:tcm="http://www.tridion.com/ContentManager/5.0" Managed="0">
<tcm:Item ID="tcm:41-117739-1024" Title="Keyword1 Title" Icon="T1024L0P0" Type="1024" IsNew="false" Modified="2017-10-16T06:52:15" Key="Keyword1 Title" IsAbstract="false" IsRoot="true" CategoryID="tcm:41-12269-512" CategoryTitle="Category Title"/>
<tcm:Item ID="tcm:41-117740-1024" Title="Keyword2 Title" Icon="T1024L0P0" Type="1024" IsNew="false" Modified="2017-10-16T06:52:31" Key="Keyword2 Title" IsAbstract="false" IsRoot="true" CategoryID="tcm:41-12269-512" CategoryTitle="Category Title"/>

5
+50

AFAIK, you won't be able to get the Keyword titles directly in a Razor TBB; however, you can create your own custom function in the Razor TBB that manipulates the XML and returns the titles.

The example below is a custom function that takes in as parameter a category XML string and returns the Keyword titles as a list:

@using System;
@using System.Collections.Generic;
@using System.Linq;
@using System.Xml;
@using System.Xml.Linq;
@using Tridion.ContentManager.Templating;

@functions 
{
    public List<string> GetKeywordsTitleFromCategoryXML(string categoryXml) 
    {
        XDocument xDocument = XDocument.Parse(categoryXml);
        XNamespace ns = XNamespace.Get("http://www.tridion.com/ContentManager/5.0");
        var list = xDocument.Descendants(ns + "Item").Attributes("Title").ToList();

        List<string> keywordTitles = new List<string>();

        foreach (String keywordTitle in list)
        {
            keywordTitles.Add(keywordTitle);
        }

        return keywordTitles;
    }
}

Then, you could do something like this to render the Keyword titles:

@{
    var categoryXmlString = @Package.GetByName("MyKeywords").GetAsXmlDocument().OuterXml;
    var keywordTitleList = @GetKeywordsTitleFromCategoryXML(categoryXmlString);
}

@foreach(var keywordTitle in keywordTitleList)
{
   <p>@keywordTitle</p>
}
  • Thank you Sabarish. I was thinking on similar lines. Let me try it out. – Rakesh Choudhary Oct 26 '17 at 4:43
  • It worked perfectly. – Rakesh Choudhary Oct 26 '17 at 5:13
3

Adding to @Sabarish's answer, If you are interested in Titles only; get the lighter XML for Keyword list which only contains ID and Title. To do so you should apply the filter in your TOM.NET C# Code as Below:

XmlDocument keywordsXml = new XmlDocument();

//Filtering to get ID and Title only
Filter fltr = new Filter();
fltr.BaseColumns = ListBaseColumns.IdAndTitle;
keywordsXml.LoadXml(cat.GetListKeywords(fltr).OuterXml);


Item output = package.CreateXmlDocumentItem(ContentType.Xml, keywordsXml);
package.PushItem("MyKeywords", output);

Also, if you don't want to re-use; you can avoid creating the function and use the code inline.

3

Piggy-backing on the answers of Saurabh and Sabarish, I would suggest doing something similar, but moving the XML processing code Sabarish suggests (with Saurabh's modification) out of the Razor template and into your C# TBB. Then you could simply add your Keyword titles to the package as an array and iterate through it with a foreach loop in your Razor template, or better yet, depending on how the titles are being used, you could format them as you plan to use them in your Razor template and write them out as single item on the package and not need any loops in your Razor template.

The reason for this seeming nitpicking on location is actually quite important: While the Razor mediator is a powerful tool and allows for the writing of complex logic as functions within your Razor templates, it is also single threaded. This means only one TBB can use the Razor mediator at once. If you have more than one rendering thread in your environment, each thread will have to wait to use the mediator. This isn't such a large issue if you keep the Razor templates simple, but the more logic and processing you put into your templates the more chance you'll create a bottleneck with the mediator and slow down your publishing to an untenable degree.

  • Thanks Tanner. The C# TBB doesn't allow me to pass back a list that is why I am passing back an XML. As suggested by Sabarish I used a Razor custom function to get titles from XML. – Rakesh Choudhary Oct 26 '17 at 13:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.