dust.js:在作用域部分中使用路径

dust.js: Using paths in scoped sections

本文关键字:路径 作用域部 js dust      更新时间:2023-09-26

这个问题是关于使用dust.js模板系统以及子上下文中的数据路径。我的目的是使用键到字符串的映射来支持 i18n。

给定如下数据:

{i18n : { firstname : "First Name" },
 people : [
    {"name" : "Moe"},
    {"name" : "Curly"}
 ]}

在灰尘中,您可以使用部分列出每个人:

{#people}
    {name}
{/people}

您可以使用路径来访问名字 i18n 字符串:

{i18n.firstname}

但以下方法不起作用:

{#people}
    {i18n.firstname}: {name}
{/people}

事实上,文档特别指出:

为避免引用脆弱和混乱,路径永远不会回溯 上下文堆栈。如果需要钻取到 中可用的密钥 父上下文中,将键作为参数传递。

所以我尝试将密钥作为参数传递:

{#people i18n=i18n}
    {i18n.firstname}: {name}
{/people}

但这行不通。当我在 dust 主页上对此进行实验时,我看到编译的模板包含以下代码:

"i18n": ctx.get("i18n")

这让我认为上面的例子应该可以正常工作。

那么什么给了呢?我怎样才能做到这一点?

注意:以下方法有效

{#people firstname=i18n.firstname}
    {firstname}: {name}
{/people}

但是,如果您需要在人员上下文中访问大量 i18n 键,则这效果不佳。

路径可以在键和部分中使用,以指定您希望 Dust 查找键的位置。要了解如何以及何时使用路径,您应该首先了解 Dust 在没有路径时如何查找键。你可能想坐下来。

搜索键时,Dust 首先在当前上下文中查找,然后在每个父上下文中查找,直到没有更多的父上下文可供搜索。如果未找到键,则 Dust 不执行任何操作(除非您使用的是"存在"或"不存在"部分)。如果 Dust 找到密钥,它将停止搜索并使用给定的值。这不会太陌生,对吧?这就是 JavaScript 在执行环境中寻找变量的方式。

然而,当使用路径时,Dust不是朝树根看,而是只看孩子。最好用一个例子来说明这一点。

JSON:
{
  "i18n": {
    "firstname": "First Name"
  },
  "name": "My Dust Template",
  "firstname": "Surprise!",
  "people": [
    {
      "name": {
        "firstname": "Moe",
        "lastname": "Howard"
      }
    },
    {
      "name": {
        "firstname": "Curly",
        "lastname": "Howard"
      }
    }
  ]
}

和尘埃:

Dust Template:
{! Show the name of the template !}
{name}{~n}
{#people}
  {! 
     As you noted, the following will not work, because 
     when using a path, Dust only searches
     deeper into the JSON. The output will be:
     ": Surprise!"
  !}
  {i18n.firstname}: {firstname}{~n}
  {!
     To get your i18n string, you need to look up the 
     stack instead of down. This can be done by using a
     section without a path, as follows. The output will be:
     "First Name: Moe"
     "First Name: Curly"
  !}
  {#i18n}{firstname}{/i18n}: {name.firstname}{~n}
  {! 
     Note that we successfully used the path to 
     get the firstname of each of the people.
  !}
{/people}

[编辑]:有关更多信息,请查看来自Dust:https://github.com/linkedin/dustjs/wiki/Where-else-does-Dust-search-if-the-value-is-not-defined%3F-A.K.A.-Dust-Scoping LinkedIn分支的维基页面

如果这是你的模板:

{#people i18n=i18n}
  {i18n.firstname}: {name}
{/people}

下面是上下文堆栈遍历"name"数组时的样子

{ your original context}
i18n -> firstname: "First Name"
name -> "Moe" 

发生的情况是,当您定义参数时,Dust 会将您定义的所有参数推送到上下文堆栈中。 然后,当它在您的上下文中找到一个数组时,Dust 会一次一个地推送到堆栈中,数组中的所有项目。

所以现在当你在本节中定义一个路径上下文时,即使你已经将 i18n 作为参数传入,i18n 上下文仍然在上下文堆栈中,当你尝试使用路径访问 i18n,如 {i18n.firstname},dust 不会找到它,因为它必须回溯才能找到它,而 getPath 不会做回溯。 获取方法, 另一方面,确实会回溯,所以这就是为什么当你这样做时:

{#people firstname=i18n.firstname}
  {firstname}: {name}
{/people}

它有效,因为它使用 get 方法访问部分中的名字。 希望你明白我想说什么。

我要做的是定义一个帮助程序方法,该方法采用如下部分:

{#people}
  {#i18n}{firstname}{/i18n}: {name}{~n}
{/people}

并在上下文中定义方法(或将其推送到全局上下文[使用 makeBase 定义]以使其成为全局帮助程序),如下所示:

i18n: function(chunk, context, bodies, params){
  var trans = context.get(translation); //or whatever name you give to your i18n list
  chunk.render(bodies.block, context.push(trans));
  return chunk;
}

在尘埃网站上对此进行了测试,它可以工作。 这种方法的优点是,您现在可以在该部分的范围内格式化 i18n 输出。 此外,最好在全局上下文中同时定义帮助程序和 i18n 列表,因此请使用 makeBase。 万事如意。