【问题标题】:StringTemplate C# override array behaviourStringTemplate C# 覆盖数组行为
【发布时间】:2014-01-18 00:45:50
【问题描述】:

我使用 StringTemplate4 允许用户将 HTML 模板和页面 ID 传递给 Web 服务,然后获取解析结果。字段的名称和数量是动态的,这意味着虽然某些页面可能只为给定字段返回一个值,但其他页面可能会返回许多值。一个例子是页面 URL。每个页面可以有多个 URL,但第一个应该被视为默认 URL(规范 URL)。我希望我的用户能够将$url$ 添加到模板中,它只会输出第一个 URL。我知道 StringTemplate 不提供对数组的索引,所以我不能只说$url[0]$,所以我采取了不同的方法。这是我的代码:

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();
}

正如您通过查看我的模板所看到的那样,我希望$m.url$ 将呈现“/home”而不是“/home/index/default”,就像它目前所做的那样。我试图通过覆盖 TemplateValue 类上的 ToString() 方法来实现这一点,但无济于事。我试图查看 StringTemplate 的源代码,但找不到一种方法来更改对象在呈现时返回的值。谁能指出我正确的方向?

【问题讨论】:

  • 我对 StringTemplate 不熟悉,猜测有自定义格式化程序或格式提供程序。尝试搜索与IFormatProviderICustomFormatter 相关的内容。

标签: c# templates stringtemplate stringtemplate-4


【解决方案1】:

您可以使用$first(url)$。如果项目不是数组(或集合),那么这个表达式的结果就是项目本身。

【讨论】:

    【解决方案2】:

    我最终切换到 XSLT。我最初避免使用它是因为我认为它不够优雅(例如,与 Razor 相比)。但它有很多优点可以胜过这一缺点:

    • 只要我可以将我的类表示为 XML,我可以在传递给模板解析器的对象中具有任意级别的复杂性。
    • 我不需要像 TemplateField 和 TemplateValue 这样的自定义类来表示我的对象:简单的 XML 就可以了。
    • 这是一项标准技术,因此支持比我对 3rd 方库的预期要好得多,而且让新开发人员跟上速度会容易得多。
    • 它让我可以在模板中使用标准逻辑。
    • 有效!

    【讨论】:

      猜你喜欢
      • 2012-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-11
      • 1970-01-01
      • 2011-04-08
      • 1970-01-01
      相关资源
      最近更新 更多