RazorEngine串布局和板块? [英] RazorEngine string layouts and sections?

查看:114
本文介绍了RazorEngine串布局和板块?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用这样的剃须刀引擎:

I use razor engine like this:

public class EmailService : IService
{
    private readonly ITemplateService templateService;

    public EmailService(ITemplateService templateService)
    {
        if (templateService == null)
        {
            throw new ArgumentNullException("templateService");
        }
        this.templateService = templateService;
    }

    public string GetEmailTemplate(string templateName)
    {
        if (templateName == null)
        {
            throw new ArgumentNullException("templateName");
        }
        Assembly assembly = Assembly.GetAssembly(typeof(EmailTemplate));
        Stream stream = assembly.GetManifestResourceStream(typeof(EmailTemplate), "{0}.cshtml".FormatWith(templateName));
        string template = stream.ReadFully();
        return template;
    }

    public string GetEmailBody(string templateName, object model = null)
    {
        if (templateName == null)
        {
            throw new ArgumentNullException("templateName");
        }
        string template = GetEmailTemplate(templateName);
        string emailBody = templateService.Parse(template, model, null, null);
        return emailBody;
    }
}



我使用的模板业务注入虽然它只是一个默认的实现:

The templating service I use is injected although it's just a default implementation:

    internal ITemplateService InstanceDefaultTemplateService()
    {
        ITemplateServiceConfiguration configuration = new TemplateServiceConfiguration();
        ITemplateService service = new TemplateService(configuration);
        return service;
    }



由于在这种情况特别是我将建立从这些模板的电子邮件。我希望能够使用 @section S为email'a主题和邮件体的不同部分,同时采用的布局,我指定是常见的样式整个电子邮件结构(这看起来像 MailChimp 的可能之一)。

Since in this case in particular I will be building emails from these templates. I want to be able to use @sections for the email'a subject, and different sections of the email body, while using a layout where I specify the styles that are common to the whole email structure (which will look like one of MailChimp's probably).

接下来的问题是双重的:

The question is then twofold:


  • 如何在指定布局RazorEngine

  • 如何指定字符串的这些布局(或流)?因为你可以看到,我使用嵌入的资源来存储剃刀电子邮件模板。

也许我不太清楚,但我指的是 RazorEngine

Maybe I wasn't clear, but I'm referring to the RazorEngine library.

推荐答案

原来,我们只是有 _layout声明它们而不是布局

Turns out after some digging that layouts are supported, we just have to declare them with _Layout instead of Layout

至于嵌入的资源问题,我采取了以下 ITemplateResolver

As for the embedded resource issue, I implemented the following ITemplateResolver

using System;
using System.IO;
using System.Reflection;
using Bruttissimo.Common;
using RazorEngine.Templating;

namespace Website.Extensions.RazorEngine
{
    /// <summary>
    /// Resolves templates embedded as resources in a target assembly.
    /// </summary>
    public class EmbeddedTemplateResolver : ITemplateResolver
    {
        private readonly Assembly assembly;
        private readonly Type type;
        private readonly string templateNamespace;

        /// <summary>
        /// Specify an assembly and the template namespace manually.
        /// </summary>
        /// <param name="assembly">The assembly where the templates are embedded.</param>
        /// <param name="templateNamespace"></param>
        public EmbeddedTemplateResolver(Assembly assembly, string templateNamespace)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException("assembly");
            }
            if (templateNamespace == null)
            {
                throw new ArgumentNullException("templateNamespace");
            }
            this.assembly = assembly;
            this.templateNamespace = templateNamespace;
        }

        /// <summary>
        /// Uses a type reference to resolve the assembly and namespace where the template resources are embedded.
        /// </summary>
        /// <param name="type">The type whose namespace is used to scope the manifest resource name.</param>
        public EmbeddedTemplateResolver(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException("type");
            }
            this.assembly = Assembly.GetAssembly(type);
            this.type = type;
        }

        public string Resolve(string name)
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }
            Stream stream;
            if (templateNamespace == null)
            {
                stream = assembly.GetManifestResourceStream(type, "{0}.cshtml".FormatWith(name));
            }
            else
            {
                stream = assembly.GetManifestResourceStream("{0}.{1}.cshtml".FormatWith(templateNamespace, name));
            }
            if (stream == null)
            {
                throw new ArgumentException("EmbeddedResourceNotFound");
            }
            string template = stream.ReadFully();
            return template;
        }
    }
}



然后你刚丝像这样的:

Then you just wire it like this:

    internal static ITemplateService InstanceTemplateService()
    {
        TemplateServiceConfiguration configuration = new TemplateServiceConfiguration
        {
            Resolver = new EmbeddedTemplateResolver(typeof(EmailTemplate))
        };
        ITemplateService service = new TemplateService(configuration);
        return service;
    }

您传递的类型仅仅是引用集和命名空间,其中的资源。嵌入式

The type you pass is just for referencing the assembly and namespace where the resources are embedded.

namespace Website.Domain.Logic.Email.Template
{
    /// <summary>
    /// The purpose of this class is to expose the namespace of razor engine templates in order to
    /// avoid having to hard-code it when retrieving the templates embedded as resources.
    /// </summary>
    public sealed class EmailTemplate
    {
    }
}

最后一件事,为了与我们的解析器解析的模板,我们必须解决这些问题是这样的:

One last thing, in order to have the templates resolved with our resolver we have to resolve them like this:

ITemplate template = templateService.Resolve(templateName, model);
string body = template.Run();
return body;



.RUN 只是一个简单的扩展方法因为我无法找到一个 ViewBag

.Run is just a simple extension method since I can't find any use for a ViewBag.

public static class ITemplateExtensions
{
    public static string Run(this ITemplate template)
    {
        ExecuteContext context = new ExecuteContext();
        string result = template.Run(context);
        return result;
    }
}



更新



下面是缺少扩展

UPDATE

Here are the missing extensions

    public static string FormatWith(this string text, params object[] args)
    {
        return string.Format(text, args);
    }

    public static string ReadFully(this Stream stream)
    {
        using (StreamReader reader = new StreamReader(stream))
        {
            return reader.ReadToEnd();
        }
    }

这篇关于RazorEngine串布局和板块?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆