本土化南希没有剃刀视图引擎 [英] Localization in Nancy without the razor viewengine

查看:130
本文介绍了本土化南希没有剃刀视图引擎的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关我用剃刀作为我在南锡视图引擎的那一刻结果
我可以访问我的资源文件这样的剃刀:

  @ Text.text.greeting 

不过,我想切换到不同的视图引擎。结果
是否有其他视图引擎可支持TextResource?结果
如何定位在超级简单视图引擎的工作原理?



还是有利用该模型访问的资源的一种方式?


解决方案

好问题!这是什么,我已经需要做我自己。



我设法@卡尔 - 约翰·舍格伦解决使用你的建议的基础上这一问题 - 即我能创造一个扩展超级简单的查看引擎(SSVE)。






背景



该SSVE已设计,这样你可以注入额外的匹配器,让你做你的视图模板一些处理,因为它们越来越呈现一个请求的输出方式。



您会注意到SSVE中下面的构造(如2014年5月12日)的,允许你在额外通过'匹配器:

 公共SuperSimpleViewEngine(IEnumerable的< ISuperSimpleViewEngineMatcher>的匹配)
{
this.matchers =的匹配? Enumerable.Empty< ISuperSimpleViewEngineMatcher>();

this.processors =新的List<&Func键LT;字符串,对象,IViewEngineHost,串>>
{
PerformSingleSubstitutions,
PerformContextSubstitutions,
PerformEachSubstitutions,
PerformConditionalSubstitutions,
PerformPathSubstitutions,
PerformAntiForgeryTokenSubstitutions,
this.PerformPartialSubstitutions,
this.PerformMasterPageSubstitutions,
};
}

这是大多数模板替换的作品在SSVE的基本方法是做很简单的正则表达式对视图模板匹配。如果正则表达式匹配,则一个替代方法被调用其内相应的替换发生。



例如,附带SSVE默认PerformSingleSubstitutions处理器/匹配是用来做基本的@Model'换人。可能会出现以下处理器的工作流程:




  • 文本@ Model.Name'是一个视图模板内匹配

  • 的替代方法解雇了模型参数替代。

  • 的一些思考,以获得名称属性的值发生针对动态模型。

  • 在名称属性的值,然后用于替换视图模板中的@ Model.Name的字符串。






的实施



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



首先,你需要创建ISuperSimpleViewEngineMatcher的实现。下面是我为说明的目的创建了一个非常基本的例子:

 内部密封类TranslateTokenViewEngineMatcher:
ISuperSimpleViewEngineMatcher
{
///<总结>
///编译正则表达式的翻译换人。
///< /总结>
私人静态只读正则表达式TranslationSubstitutionsRegEx;

静态TranslateTokenViewEngineMatcher()
{
//这个正则表达式会匹配字符串:
// @ Translate.Hello_World
// @ Translate.FooBarBaz ;
TranslationSubstitutionsRegEx =
新正则表达式(
@@ Translate\(小于?TranslationKey> A-ZA-Z0-9 -_] +);?,
RegexOptions.Compiled);
}

公共字符串调用(字符串内容,动态模型,IViewEngineHost主机)
{
返回TranslationSubstitutionsRegEx.Replace(
含量,
M = GT;
{
//找到匹配

串translationResult;!

//获取翻译'键'
VAR translationKey = m.Groups [TranslationKey]值;

//将适当的翻译这可能种田关闭以
//例如一个ResourceManager下面执行
//显然不是非常有用的,只是说明:)
如果(translationKey ==参考hello world)
{
translationResult =的Hello World!。
}
,否则
{
//我们没有发现任何翻译密钥相匹配,所以我们将
//使用密钥本身。
translationResult = translationKey;
}

返回translationResult;
});
}
}



好了,所以当上述匹配器对运行我们他们将会把模板来找到以字符串@Translate。。只是之后的文本@Translate。被认为是我们的翻译键。所以在例如@ Translate.Hello_World'的,翻译的关键是'参考hello world。



在匹配时替换方法烧制查找并返回相应的译名为翻译键。我现在的例子只会返回一个翻译的参考hello world的关键 - 当然你必须填你自己的机制,使做翻译查找,或许耕掉到缺省资源管理支持.NET

的匹配将不会自动挂接到SSVE,你将不得不使用IoC的支持南希的功能,以针对我刚才强调,构造函数的参数注册您的匹配。



要做到这一点,你需要重写你的南希引导程序中的ConfigureApplicationContainer方法,并添加类似下面的一个注册:

 公共类MyNancyBootstrapper:DefaultNancyBootstrapper 
{
保护覆盖无效ConfigureApplicationContainer(TinyIoCContainer容器)
{
base.ConfigureApplicationContainer(集装箱) ;

//注册自定义/额外的处理器/我们的观点
//将SSVE
容器
.Register<内呈现的匹配; IEnumerable的< ISuperSimpleViewEngineMatcher>>(
(C,p)=>
{
返回新的List< ISuperSimpleViewEngineMatcher>()
{
//这个匹配提供支持@Translate令牌$。 b $ b新TranslateTokenViewEngineMatcher()
};
});
}

...



的最后一步是要其实你的翻译标记添加到您的意见!

 <  -  index.sshtml  - > 
< HTML和GT;
< HEAD>
<标题>翻译测试与LT; /标题>
< /头>
<身体GT;
< H1> @ Translate.Hello_World;< H1>
< /身体GT;
< / HTML>






正如我所说,这是一个非常简单的例子它可以为基础用它来创建,以满足您的需求的实现。例如,您可以延长正则表达式匹配也考虑到目标的文化,你想翻译成,或者只是简单地使用当前线程文化在应用程序中注册。您可以灵活请你做的事。 :)


For the moment I'm using razor as my view engine in Nancy.
I can access my resource file like this in razor:

@Text.text.greeting

But I would like to switch to a different view engine.
Are there other view engines available that support the TextResource?
How does localization works in the super simple view engine?

Or is there a way to access the resources using the model?

解决方案

Good question! This is something that I have needed to do myself.

I managed to solve this problem using the basis of the suggestion made to you by @Karl-Johan Sjögren - i.e. I was able to create an extension to the Super Simple View Engine (SSVE).


The Background

The SSVE has been designed in such a way that you can inject additional 'matchers' that allow you to do some processing on your view templates as they are getting rendered for the output of a request.

You will notice the following constructor (as of 2014/05/12) within the SSVE, that allows you to pass in additional 'matchers':

    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,
        };
    }

The basic way that most of the template substitution works in the SSVE is by doing very simple regular expression matches against the view templates. If a regular expression is matched, then a substitution method is invoked within which the appropriate substitution occurs.

For example, the default PerformSingleSubstitutions processor/matcher that comes with the SSVE is used to do your basic '@Model.' substitutions. The following processor workflow could occur:

  • The text '@Model.Name' is matched within a view template.
  • The substitution method is fired for the the Model parameter substitution.
  • Some reflection occurs against the dynamic model in order to get the value of the 'Name' property.
  • The value of the 'Name' property is then used to replace the string of '@Model.Name' within the view template.

The Implementation

Ok, so now that we have the foundation, here is how you can create your very own Translation matcher. :)

First you will need to create an implementation of ISuperSimpleViewEngineMatcher. Below is a really basic example I have created for the purpose of illustration:

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

Okay, so when the above matcher is run against our view templates they will to find strings starting with '@Translate.'. The text just after the '@Translate.' is considered to be our translation key. So in the e.g. of '@Translate.Hello_World', the translation key would be 'Hello_world'.

When a match occurs the replace method is fired to find and return the appropriate translation for the translation key. My current example will only return a translation for the key of 'Hello_World' - you would of course have to fill in your own mechanism with which to do the translation lookups, perhaps farming off to the default resource management support of .net?

The matcher won't get automatically hooked up into the SSVE, you will have to use the IoC supported features of Nancy to register your matcher against that constructor parameter I highlighted earlier.

To do so you will need to override the ConfigureApplicationContainer method within your Nancy bootstrapper and add a registration similar to the one below:

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()
                    };
                });
    }

    ...

The final step is to actually add your translation tokens to your views:

<!-- index.sshtml -->
<html>
    <head>
        <title>Translator Test</title>
    </head>
    <body>
        <h1>@Translate.Hello_World;<h1>
    </body>
</html>


As I said, this is a very basic example which you could use as the basis to create an implementation to suit your needs. You could for example extend the regular expression matcher to also take into account the target culture that you would like to translate into, or just simply use the current thread culture registered within your application. You have the flexibility to do as you please. :)

这篇关于本土化南希没有剃刀视图引擎的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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