Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

dust.js: Using paths in scoped sections

This question is about using the dust.js templating system with paths to data in sub-contexts. My intention is to support i18n using a map of keys to strings.

Given data like this:

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

In dust you can use sections to list each person:

{#people}
    {name}
{/people}

And you can use a path to get access to the firstname i18n string:

{i18n.firstname}

But the following does not work:

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

In fact, the documentation specifically says:

To avoid brittle and confusing references, paths never backtrack up the context stack. If you need to drill into a key available within the parent context, pass the key as a parameter.

So I try and pass the key as a parameter:

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

But this doesn't work. When I experiment with this on the dust homepage, I see the compiled template has this code:

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

Which makes me think the above example should work fine.

So what gives? How can I make this work?

Note: The following does work:

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

But this doesn't work well if you need to access a lot of i18n keys within the people context.

like image 569
JBCP Avatar asked Feb 20 '23 14:02

JBCP


1 Answers

Paths can be used in keys and in sections to specify where you want Dust to look for keys. To understand how and when to use paths, you should first understand how Dust looks for keys when there are no paths. You might want to sit down.

When searching for keys, Dust first looks in the current context, then looks in each parent context until there are no more parents to search in. If no key is found, Dust does nothing (unless you are using an Exists or Not Exists Section). If Dust finds the key, it stops searching and uses the given value. That's not too foreign, right? That's how JavaScript looks for variables in execution environments.

However, instead of looking up the tree toward root, when a path is used, Dust only looks at children. This is best illustrated with an example.

JSON:

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

And the Dust:

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}

[EDIT]: For more info, check out this wiki page from the LinkedIn fork of Dust: https://github.com/linkedin/dustjs/wiki/Where-else-does-Dust-search-if-the-value-is-not-defined%3F-A.K.A.-Dust-Scoping

like image 52
smfoote Avatar answered Mar 06 '23 08:03

smfoote