Nancy的本地化没有剃刀视图

r03*_*r03 11 c# razor nancy

目前我在南希使用剃须刀作为我的视图引擎.
我可以在剃刀中访问我的资源文件:

@Text.text.greeting
Run Code Online (Sandbox Code Playgroud)

但我想切换到另一个视图引擎.
是否有其他可用的视图引擎支持TextResource?
本地化如何在超级简单视图引擎中运行?

或者有没有办法使用模型访问资源?

ctr*_*usb 17

好问题!这是我自己需要做的事情.

我设法使用@ Karl-JohanSjögren给你的建议来解决这个问题 - 即我能够创建超级简单视图引擎(SSVE)的扩展.


的背景

SSVE的设计方式使您可以注入额外的"匹配器",允许您对视图模板进行一些处理,因为它们是为请求的输出而呈现的.

您将注意到SSVE中的以下构造函数(截至2014/05/12),允许您传入其他"匹配器":

    public SuperSimpleViewEngine(IEnumerable<ISuperSimpleViewEngineMatcher> matchers)
    {
        this.matchers = matchers ?? Enumerable.Empty<ISuperSimpleViewEngineMatcher>();

        this.processors = new List<Func<string, object, IViewEngineHost, string>>
        {
            PerformSingleSubstitutions,
            PerformContextSubstitutions,
            PerformEachSubstitutions,
            PerformConditionalSubstitutions,
            PerformPathSubstitutions,
            PerformAntiForgeryTokenSubstitutions,
            this.PerformPartialSubstitutions,
            this.PerformMasterPageSubstitutions,
        };
    }
Run Code Online (Sandbox Code Playgroud)

大多数模板替换在SSVE中工作的基本方法是对视图模板进行非常简单的正则表达式匹配.如果匹配正则表达式,则调用替换方法,在该方法中发生适当的替换.

例如,SSVE附带的默认PerformSingleSubstitutions处理器/匹配器用于执行基本的"@Model".换人.可能会发生以下处理器工作流:

  • 文本"@ Model.Name"在视图模板中匹配.
  • 替换方法是针对Model参数替换而触发的.
  • 针对动态模型进行一些反射以获取"名称"属性的值.
  • 然后,使用'Name'属性的值替换视图模板中的'@ Model.Name'字符串.

实施

好了,现在我们已经有了基础,这里是你如何创建自己的翻译匹配器.:)

首先,您需要创建一个ISuperSimpleViewEngineMatcher的实现.以下是我为了说明而创建的一个非常基本的示例:

internal sealed class TranslateTokenViewEngineMatcher :
    ISuperSimpleViewEngineMatcher
{
    /// <summary>
    ///   Compiled Regex for translation substitutions.
    /// </summary>
    private static readonly Regex TranslationSubstitutionsRegEx;

    static TranslateTokenViewEngineMatcher()
    {
        // This regex will match strings like:
        // @Translate.Hello_World
        // @Translate.FooBarBaz;
        TranslationSubstitutionsRegEx =
            new Regex(
                @"@Translate\.(?<TranslationKey>[a-zA-Z0-9-_]+);?",
                RegexOptions.Compiled);
    }

    public string Invoke(string content, dynamic model, IViewEngineHost host)
    {
        return TranslationSubstitutionsRegEx.Replace(
            content,
            m =>
            {
                // A match was found!

                string translationResult;

                // Get the translation 'key'.
                var translationKey = m.Groups["TranslationKey"].Value;

                // Load the appropriate translation.  This could farm off to
                // a ResourceManager for example.  The below implementation
                // obviously isn't very useful and is just illustrative. :)
                if (translationKey == "Hello_World")
                {
                    translationResult = "Hello World!";
                }
                else 
                {
                    // We didn't find any translation key matches so we will
                    // use the key itself.
                    translationResult = translationKey;
                }

                return translationResult;
            });
    }
}
Run Code Online (Sandbox Code Playgroud)

好的,所以当上面的匹配器针对我们的视图模板运行时,他们将找到以"@Translate"开头的字符串.紧跟在'@Translate'之后的文字.被认为是我们的翻译密钥.所以在'@ Translate.Hello_World'的例子中,翻译键将是'Hello_world'.

当匹配发生时,将触发replace方法以查找并返回翻译键的相应翻译.我当前的示例只会返回"Hello_World"键的翻译 - 您当然必须填写自己的机制来进行翻译查找,或许可以使用.net的默认资源管理支持?

匹配器不会自动连接到SSVE,你必须使用Nancy支持的IoC功能来注册我之前强调的构造函数参数的匹配器.

为此,您需要覆盖Nancy引导程序中的ConfigureApplicationContainer方法,并添加类似于下面的注册:

public class MyNancyBootstrapper : DefaultNancyBootstrapper
{
    protected override void ConfigureApplicationContainer(TinyIoCContainer container)
    {
        base.ConfigureApplicationContainer(container);

        // Register the custom/additional processors/matchers for our view
        // rendering within the SSVE
        container
            .Register<IEnumerable<ISuperSimpleViewEngineMatcher>>(
                (c, p) =>
                {
                    return new List<ISuperSimpleViewEngineMatcher>()
                    {
                        // This matcher provides support for @Translate. tokens
                        new TranslateTokenViewEngineMatcher()
                    };
                });
    }

    ...
Run Code Online (Sandbox Code Playgroud)

最后一步是将您的翻译代币添加到您的观看中:

<!-- index.sshtml -->
<html>
    <head>
        <title>Translator Test</title>
    </head>
    <body>
        <h1>@Translate.Hello_World;<h1>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

正如我所说,这是一个非常基本的示例,您可以将其用作创建实现以满足您需求的基础.例如,您可以扩展正则表达式匹配器,以考虑您要翻译的目标文化,或者只是简单地使用在您的应用程序中注册的当前线程文化.您可以根据自己的需要灵活地进行操作.:)