1

我想知道是否可以使用 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中做到这一点?非常感激任何的帮助。

4

1 回答 1

2

一个相对简单的技巧是注册一个过滤器getName,然后您可以name使用{{ item | getName }}. 过滤器可以写成 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为要访问的每个键编写类似的东西。

于 2019-11-25T21:50:41.337 回答