通过在调用代码而不是模板中指定布局来构建RazorEngine模板?

时间:2014-03-10 18:18:44

标签: razor razorengine

使用Antaris RazorEngine,给出两个字符串:

  • 没有指定布局的Razor模板

    <h1>My template</h1>
    
  • 以及应该呈现它的布局

    <html>RenderBody()</html>
    

我希望能够解析/编译字符串并在执行解析的代码中设置布局。类似的东西:

ParseWithTemplate(templateAsString, layoutAsString, model, etc.);

我如何实施此ParseWithTemplate(String, String, ...)方法?

背景:我正在构建一个静态站点生成器,并想要一种提供默认布局的方法,所以我不必在我的多个站点页面中的每一个都指定它。如果模板中提供了Layout = "layoutName",则应该可以覆盖默认值。

3 个答案:

答案 0 :(得分:1)

如果预编译布局模板,则应该能够通过将模板转换为TemplateBase来直接设置布局。如果稍后在模板标记中指定布局,则会在模板执行时根据需要覆盖代码中的值。

ITemplateService templateService = ...;

// Ensure layout template is cached with layoutCacheName
templateService.GetTemplate(layoutAsString, model, layoutCacheName);

ITemplate template = templateService.GetTemplate(templateAsString, model, templateCacheName);
var templateBase = template as TemplateBase;
if (templateBase != null) templateBase.Layout = layoutCacheName;

答案 1 :(得分:0)

虽然我最终决定转而使用RazorMachine以及其他许多原因,但对于需要它的人来说,这是一个hacky修复:

var finalHtml = layoutHtml.Replace(@"@RenderBody()", templateHtml);

(感谢Github上的aviatrix。)

答案 2 :(得分:0)

扩展Ryan Norbauer的答案,实现布局的最简单方法是:

您的 _Layout.cshtml 与典型的@RenderBody()

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html>
    <head>
    </head>
    <body>
        <div>
            @RenderBody()
        </div> 
    </body> 
</html>

您的RazorEngine模板 MyTemplate.cshtml

@using RazorEngine.Templating
@inherits TemplateBase<myviewmodel>

<h1>Hello People</h1>
<p>@Model</p>

无论你在哪里调用RazorEngine模板:

var TemplateFolderPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EmailTemplates");
var template = File.ReadAllText(Path.Combine(TemplateFolderPath,"MyTemplate.cshtml"));
var layout = File.ReadAllText(Path.Combine(TemplateFolderPath, "_Layout.cshtml"));
var templateService = new TemplateService();
var templateHtml = templateService.Parse(template, myModel, null, null);
var finalHtml = layout.Replace(@"@RenderBody()", templateHtml);

正如您所看到的那样非常简单,只需放置MyTemplate.cshtml在@RenderBody()中返回的内容