Reputation: 5605
I'm using StringTemplate4 to allow users to pass an HTML template and page ID to a web service, then get the parsed result. The name and number of fields is dynamic, meaning that while some pages might return only one value for a given field, other pages might return many. An example is page URL. Each page can have several URLs, but the first should be considered the default URL (the canonical URL). I want my users to be able to add $url$
to the template and it just spit out the first URL. I know that StringTemplate doesn't provide indexing on arrays, so I can't just say $url[0]$
, so I took a different approach. Here is my code:
public class TemplateField : Dictionary<string, dynamic>
{
// Empty class
}
public class TemplateValue : List<string>
{
public override string ToString(){
return this.FirstOrDefault();
}
}
// This is a test method to render a template using my planned objects
public static string ReplaceTokens()
{
var template = @"
<Title>$Title$</Title>
<ul class=""menu"">
$menu:{m|<li><a href=""$m.url$"">$m.name$</a></li>};separator=""\n""$
</ul>";
var g = new TemplateGroup('$','$');
var t = new Template(g,template);
var menu = new List<TemplateField>();
var item1 = new TemplateField();
item1.Add("name", new TemplateValue { "Home" });
item1.Add("url", new TemplateValue {
"/home",
"/index",
"/default"
});
t.Add("menu",item1);
var item2 = new TemplateField();
item2.Add("name", new TemplateValue { "About Us" });
item2.Add("url", new TemplateValue { "/about-us" });
t.Add("menu", item2);
var item3 = new TemplateField();
item3.Add("name", new TemplateValue { "Contact" });
item3.Add("url", new TemplateValue { "/contact" });
t.Add("menu", item3);
t.Add("Title", new TemplateValue { "My test" });
return t.Render();
}
So as you can see by looking at my template, I am hoping that $m.url$
will render out "/home" instead of "/home/index/default" as it is doing currently. I have tried to accomplish this by overriding the ToString() method on the TemplateValue class but to no avail. I have tried to look through the source for StringTemplate and couldn't find a way to change the value returned by an object when it is rendered. Can anyone point me in the right direction?
Upvotes: 0
Views: 422
Reputation: 5605
I ended up switching to XSLT in the end. I'd originally avoided it because I didn't think it was elegant enough (compare to Razor, for instance). But it has a lot of pros to outweight that one con:
Upvotes: 0
Reputation: 99869
You can use $first(url)$
. If the item is not an array (or collection), then the result of this expression is just the item itself.
Upvotes: 1