是否可以从 Dotliquid 访问嵌套字典?

Is it possible to access a nested dictionary from Dotliquid?

我想知道是否可以使用 dotliquid 库访问嵌套字典。

到目前为止我得到的是:

type Document = {
    template : string
    elements : Map<string, obj>
}with  
    static member Test = {
        template = "{% for item in test %} {{ item[\"name\"] }} {% endfor %}"
        elements = 
            Map.empty 
            |> Map.add "test" ([Map.empty |> Map.add "name" "Foo"] :> obj) 
    }

let genTemplate = 
    let doc = Document.Test
    let template = Template.Parse(doc.template)
    template.Render(Hash.FromDictionary(doc.elements |> Map.toSeq |> dict))

预期的结果是:Foo 但不出所料,我只是得到一个空字符串。 如果我只是访问 item 而不是 item["name"],我会得到输出 ["name", "Foo"]。那么在 dotliquid 中有什么办法可以做到这一点吗?任何帮助将不胜感激。

一个相对简单的技巧是注册一个过滤器 getName,然后您可以使用 {{ item | getName }} 访问嵌套字典的 name 属性。过滤器可以写成 F# 方法:

type Filters() = 
  static member getName(map:Map<string, string>) = map.["name"]

Template.RegisterFilter(typeof<Filters>)

如果您现在在测试模板中使用过滤器。请注意,根据您配置的 DotLiquid 命名约定,您可能需要使用 get_name 作为名称(这也是默认名称):

type Document = 
  { template : string
    elements : Map<string, obj> }
  static member Test = 
    { template = "{% for item in test %} {{ item | get_name }} {% endfor %}"
      elements = 
          Map.empty 
          |> Map.add "test" ([Map.empty |> Map.add "name" "Foo"] :> obj) }

有了这个,你得到了你期待的结果:

let genTemplate = 
    let doc = Document.Test
    let template = Template.Parse(doc.template)
    template.Render(Hash.FromDictionary(doc.elements |> Map.toSeq |> dict))

不幸的是,我不确定是否有创建参数化过滤器的方法 - 可能是您必须为要访问的每个键编写类似 getName 的内容。