我在C#控制台应用程序中使用Razor模板引擎,并尝试将对象树扩展为文本文件。我很难搞清楚如何让层次扩展工作。
我很可能完全误解了分层模板扩展应该如何在Razor中工作。我需要知道我当前的方法是否几乎是正确的,只是需要修复,或者如果我完全以错误的方式完成,那么这样做的正确方法是什么?
奖金问题:Razor是否适合这种工具,还是有更好的选择?
我已经创建了一个小型测试应用来证明这个问题。类TemplateTreeModel
定义传递给Razor的模型。此类定义树,Children
成员是子TemplateTreeModel
实例的列表。
我想实例化模型并将其传递给Razor,如下所示:
var model = new TemplateTreeModel();
... add children to the tree ...
var expanded = Razor.Parse(Template, model);
TemplateTreeModel
有一个成员函数ExpandChildren
,用于执行分层扩展。我在模板中使用它,如下所示:
@(Model.ExpandChildren())
我的测试应用会产生非常奇怪的结果。一些叶节点在输出中重复,并且仅存在3级节点。输出中缺少根节点(级别1)和级别2节点。
更新:关于这方面的更多上下文,真正的用例是我想从抽象语法树生成代码。所以我有一堆模板代表了为每个AST节点输出的脚本。然后,我想从根AST节点递归扩展,将AST转换为脚本文件。
以下是测试应用的完整代码。要使其正常工作,您需要将代码放在C#控制台应用程序中并引用RazorEngine(此处为http://razorengine.codeplex.com/提供)。
using System;
using System.Collections.Generic;
using System.Text;
using RazorEngine;
using RazorEngine.Templating;
namespace RazorTest
{
public class Program
{
public class TemplateTreeModel
{
private static int nextID = 1;
public TemplateTreeModel(string template, int level)
{
this.Level = level;
this.ID = nextID++;
this.Template = template;
this.Children = new List<TemplateTreeModel>();
}
public int Level { get; private set; }
public int ID { get; private set; }
public string Template { get; private set; }
public List<TemplateTreeModel> Children { get; private set; }
public string ExpandChildren()
{
var output = new StringBuilder();
foreach (var child in this.Children)
{
output.Append(child.Expand());
}
return output.ToString();
}
public string Expand()
{
var expanded = Razor.Parse(this.Template, this);
return expanded;
}
public TemplateTreeModel DefineChild(TemplateTreeModel child)
{
this.Children.Add(child);
return this;
}
}
public static void Main(string[] args)
{
try
{
var template = "Node: @Model.ID (Level @Model.Level):\n@(Model.ExpandChildren())\n";
var root =
new TemplateTreeModel(template, 1).
DefineChild(
new TemplateTreeModel(template, 2).
DefineChild(
new TemplateTreeModel(template, 3)
).DefineChild(
new TemplateTreeModel(template, 3)
)
).DefineChild(
new TemplateTreeModel(template, 2).
DefineChild(
new TemplateTreeModel(template, 3)
).DefineChild(
new TemplateTreeModel(template, 3)
)
);
var expanded = root.Expand();
Console.WriteLine(expanded);
}
catch (TemplateCompilationException ex)
{
Console.WriteLine("Template compilation errors:");
foreach (var error in ex.Errors)
{
Console.WriteLine(error);
}
}
}
}
}
答案 0 :(得分:0)
我现在已经离开了Razor。如果有办法用Razor进行分层模板扩展,那么我就不知道它是什么。
然而,我已经转移到使用DotLiquid模板引擎。到目前为止似乎相当不错,它似乎并不支持开箱即用的分层模板扩展,尽管我能够使用标签轻松实现它。
Razor本来不错,特别是因为它有紧密的C#集成,但DotLiquid完成了这项工作,我喜欢类似Django的语法。