如何实现分层剃刀模板扩展?

时间:2012-08-10 01:38:55

标签: c# razor template-engine

我在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);
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

我现在已经离开了Razor。如果有办法用Razor进行分层模板扩展,那么我就不知道它是什么。

然而,我已经转移到使用DotLiquid模板引擎。

http://dotliquidmarkup.org/

到目前为止似乎相当不错,它似乎并不支持开箱即用的分层模板扩展,尽管我能够使用标签轻松实现它。

Razor本来不错,特别是因为它有紧密的C#集成,但DotLiquid完成了这项工作,我喜欢类似Django的语法。