1

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

1 回答 1

0

我现在已经从 Razor 继续前进了。如果有办法使用 Razor 进行分层模板扩展,那么我不知道它是什么。

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

http://dotliquidmarkup.org/

到目前为止看起来还不错,它似乎不支持开箱即用的分层模板扩展,尽管我能够使用标签很容易地实现它。

Razor 会很好,特别是因为它具有紧密的 C# 集成,但 DotLiquid 可以完成这项工作,我喜欢类似 Django 的语法。

于 2012-08-13T04:21:07.140 回答