有没有一种方法可以计算Go模板?

时间:2020-08-23 21:00:01

标签: go templates

我正在尝试为epub创建一个toc.ncx(只是XML)文件。

在这样的目录中,定义了<navpoint>,每个都有一个ID和一个“播放顺序”。

Go模板有什么方法可以简单地计算导航点吗?

我想到了类似的东西(无效的模板代码)

{{$counter := 0}}
{{define "NAVPOINT"}}
  {{$counter = $counter + 1}}
  <navpoint id="{{.}}" playorder="{{$counter}}">
{{end}}

{{range .TopLevel }}
  {{template "NAVPOINT" .Id}}
  {{range .SecondLevel }}
    {{template "NAVPOINT" .Id}}
    </navpoint>
  {{end}}
  </navpoint>
{{end}}

示例结构

  { TopLevel: [
      { 
        Id: "id-a"
        SecondLevel: [
          {
            Id: "scnd-a"
          }
          {
            Id: "scnd-b"
          }
        ]
      }
      { 
        Id: "id-b"
        SecondLevel: [
          {
            Id: "scnd-c"
          }
          {
            Id: "scnd-d"
          }
        ]
      }
    }

这会给我类似的东西

  <navpoint id="id-a"      playorder="1">
     <navpoint id="scnd-a" playorder="2"></navpoint>
     <navpoint id="scnd-b" playorder="3"></navpoint>
  </navpoint>
  <navpoint id="id-b"      playorder="4">
     <navpoint id="scnd-c" playorder="5"></navpoint>
     <navpoint id="scnd-d" playorder="6"></navpoint>
  </navpoint>

思考我可以使用模板功能,而不是使用模板功能来实现此目的,但不知道如何实现此目的。模板功能可以有计数器吗?

1 个答案:

答案 0 :(得分:0)

由于@icza,我在这里找到了解决方案:Go template remove the last comma in range loop

这就是我现在使用的功能:

"navpoint": func() func(...string) string {
    i := 0
    return func(id ...string) string {
        if len(id) < 1 {
            return "</navPoint>"
        }
        i++
        return `<navPoint id="` + id[0] + `" playorder"` + strconv.Itoa(i) + `">`
    }
},

我在模板中以这种方式使用它:

{{$navpoint := navpoint}}
{{range .TopLevel }}
  {{call $navpoint .Id}}
  {{range .SecondLevel }}
    {{call $navpoint .Id}}
    {{call $navpoint}}
  {{end}}
  {{call $navpoint}}
{{end}}

如果使用id(XX)调用“ navpoint”,则会给出开始标签<navpoint id="XX" playorder="##">。在没有ID的情况下调用时,它会给出结束标记</navpoint>