不使用 razor viewengine 进行 Nancy 本地化

2024-05-07

目前我在 Nancy 使用 razor 作为我的视图引擎。
我可以在剃刀中像这样访问我的资源文件:

@Text.text.greeting

但我想切换到不同的视图引擎。
是否有其他支持 TextResource 的视图引擎?
在超级简单的视图引擎中本地化是如何工作的?

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


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

我设法根据@Karl-Johan Sjö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,
        };
    }

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

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

  • 文本“@Model.Name”在视图模板内匹配。
  • 模型参数替换会触发替换方法。
  • 为了获取“名称”属性的值,会对动态模型进行一些反射。
  • 然后,使用“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;
            });
    }
}

好的,所以当上面的匹配器针对我们的视图模板运行时,它们将找到以“@Translate.”开头的字符串。 “@Translate”之后的文本。被认为是我们的翻译关键。所以在例如'@Translate.Hello_World' 的翻译键将为 'Hello_world'。

当发生匹配时,将触发替换方法来查找并返回翻译键的适当翻译。我当前的示例将仅返回“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()
                    };
                });
    }

    ...

最后一步是将翻译标记实际添加到您的视图中:

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

正如我所说,这是一个非常基本的示例,您可以将其用作创建满足您需求的实现的基础。例如,您可以扩展正则表达式匹配器以考虑您想要转换成的目标区域性,或者仅使用在应用程序中注册的当前线程区域性。您可以灵活地做您想做的事。 :)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

不使用 razor viewengine 进行 Nancy 本地化 的相关文章

随机推荐

  • 在哪里可以找到 .net CLR 和 C# 的源代码?

    Microsoft net CLR 和 C 的源代码是否开放 如果是 在哪里可以下载 浏览 您可以借助以下链接下载 NET 的源代码网络海量下载器 http netmassdownloader codeplex com
  • NServiceBus 与 Windows ServiceBus

    有人能够阐明新发布的 Windows ServiceBus 本地 而不是 Azure 和 NServiceBus 之间的差异吗 寻找详细的答案 Windows SB 可能缺少什么 因为我熟悉 NSErviceBus 可以做什么 它是真正的服
  • 字体更改时处理运行时活动配置

    某些设备配置可能会在运行时发生变化 例如屏幕方向 键盘可用性和语言 当发生这样的变化时 Android会重新启动正在运行的Activity 我们可以使用我们自己的配置来处理这个问题 onConfigurationChanged 但是 如果从
  • Android 权限 BIND_NOTIFICATION_LISTENER_SERVICE 不起作用

    我正在 React Native 应用程序中工作 我正在努力在 Android 中使用Notification Services BIND NOTIFICATION LISTENER SERVICE 我正在尝试使用读取传入的通知Notifi
  • pgAdmin 服务器未显示[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 这里总共有n00b 个问题 我正在使用 pgAdmin 尝试管理远程 PostgreSQL 服务器 我单击连接图标 填写表格 然后单击 确定 该表格消
  • 如果变量的值在编译时已知/未知,则进行专门化

    如何在编译时 在实际编译和运行程序之前 其参数之一的值已知 未知的情况下专门化模板函数 我还不知道怎么办 idea 1 include
  • Pygame - 如何使 hitbox 与敌人的移动一起工作?

    我正在用 Pygame 制作一个 Python 游戏 目前正在研究 hitbox 程序应该暂停 设置play False 每当玩家与敌人碰撞时 只有当我注释掉所有敌人的移动 第 56 64 行 时它才 有效 但这显然不是最好的选择 我读过有
  • 如何在点击事件上调用 Angular 组件 [Angular]

    我不是 Angular 方面的专家 我也遵循了互联网上的一些答案 特别this https stackoverflow com questions 17636528 how do i load an html page in a div u
  • 在 Postgres 中以周为单位分割间隔

    这是另一个关于日期的 SQL 问题 我正在使用 PHP 和 Postgres 构建一个日历应用程序 它将显示几天 几周甚至几个月的事件 每个事件都有开始日期和结束日期 按范围选择它们不是问题 然而 如果 Postgres 可以在每周的第一天
  • 使用继承的 ES6 React 类时未触发 componentDidMount 方法

    我试图在 React 中使用 ES6 类 并希望所有组件都继承某些方法 但是一旦我尝试扩展扩展 React Component 类的组件 componentDidMount 方法就不会触发 因此什么也不会发生被渲染 我正在使用的代码 基础组
  • python 和回文

    我最近写了一个循环的方法 usr share dict words并使用我的返回回文列表ispalindrome x 方法 这是一些代码 有什么问题吗 它只会停止 10 分钟 然后返回文件中所有单词的列表 def reverse a ret
  • 不兼容的类型:HomeFragment 无法转换为 Android 中的 Fragment

    我在这部分代码中遇到错误 private void displayView int position update the main content by replacing fragments Fragment fragment null
  • Python:球体的交集

    我对编程非常陌生 但我决定承担一个有趣的项目 因为我最近学会了如何以参数形式表示球体 当三个球体相交时 有两个不同的交点 除非它们仅在一个奇点处重叠 球体的参数表示 我的代码是根据答案修改的Python matplotlib 绘制 3d 立
  • 如何在Redis中进行持久化存储?

    关闭redis服务器后 使用set存储的值被破坏 在这里我找到了使用持久性存储的方法 有人帮助我 如何使用javascript实现这一点 我想将客户端的一些值存储在 redis 数据库中 并且必须在其他客户端中使用该值 您需要配置 Redi
  • 在 Spark Dataframe 中提取数组索引

    我有一个带有数组类型列的数据框 例如 val df List a Array 1d 2d 3d b Array 4d 5d 6d toDF ID DATA df org apache spark sql DataFrame ID strin
  • 是否可以静默运行 .NET Core 控制台应用程序(隐藏控制台窗口)?

    我正在尝试为自己自动化一些任务 并且编写了一些 NET Core 1 0 控制台应用程序 其中之一是 BrowserRouter 一个简单的应用程序 它基于 URL 模式 决定当我单击 HTTP S 链接时要打开哪个浏览器 浏览器配置文件
  • 访问 Linux 线程(pthreads)的本地堆栈

    我目前正在实现一个使用多线程但对总内存消耗有要求的应用程序 我希望有一个主线程执行 I O 并有几个工作线程执行计算 目前 我在主堆栈上有几个可供工作人员访问的数据结构 我使用 OpenMP 进行工作分配 由于主 工作者模式不能很好地与 O
  • cmake MSYS Makefiles 生成器丢失

    我通过 pacman 安装了 cmake 3 2 3 当我尝试从 msys64 shell 中使用它时出现错误 cmake G MSYS Makefiles CMake Error Could not create named genera
  • Winform 没有.NET 框架?

    我必须创建一些表单并将其作为直接 EXE 提供 而不是安装程序 它安装 NET 框架 最终用户对此不满意 他们想要可以直接打开和工作的东西 我知道它可以作为网络完成 但我正在寻找 winforms 吗 请建议哪种工具 技术可以处理这个问题
  • 不使用 razor viewengine 进行 Nancy 本地化

    目前我在 Nancy 使用 razor 作为我的视图引擎 我可以在剃刀中像这样访问我的资源文件 Text text greeting 但我想切换到不同的视图引擎 是否有其他支持 TextResource 的视图引擎 在超级简单的视图引擎中本