Указание имени поля в анонимных картах - PullRequest
0 голосов
/ 10 ноября 2019

Моя программа получает данные из файла TOML для встроенной структуры с именем Data:

===
[custom]
Data = [                                                                      
  { filename = "fb.jpg", alt = "FB logo", url = "facebook.com" },              
  { filename = "pi.jpg", alt = "Pinterest logo", url = "pinterest.com"},      
  { filename = "twit.jpg", alt = "Twitter logo", url = "twitter.com"},      
]
===

Она объявлена ​​как интерфейс, поэтому я заранее не знаю имен полей. Я хочу перебрать строки и построить изображение в HTML. Я могу повторить это успешно. Это, очевидно, печатает значение каждого столбца за раз:

{{ with .FrontMatter.Custom.Data }}   
        {{ range $_, $value := . }}                                            
                {{ range $_, $t := $value}} {{$t}}, {{end}}
        {{ end }}
{{ end }}

Но из-за жизни я не могу получить доступ к отдельным полям. Я хочу сделать это, но это вызывает ошибку во время выполнения:

            {{ range $_, $t := $value}} {{index $value "filename" }}, {{end}}

Как я могу получить $ value.filename, $ value.alt и так далее?

1 Ответ

1 голос
/ 10 ноября 2019

Трудно быть уверенным в моем ответе, потому что вы не предоставили подробную информацию о используемой вами библиотеке Toml (я предполагаю, что BurntSushi) или структуре данных, которую она генерирует (включая вывод fmt.Printf("%v", outVar), где outVar isинтерфейс с вашим неумелым томлом, был бы полезен).

Однако, если мои предположения верны, тогда проблема, похоже, имеет место;в вашем toml файле у вас есть [custom], но в шаблоне это {{ with .FrontMatter.Custom.Data }} (обратите внимание, что c в custom - это другой случай). Это на самом деле не имеет смысла, поскольку вы говорите, что итерация работает, но с использованием вашего шаблона и предоставленных вами данных все в порядке (я предполагаю, что некоторые детали отсутствуют).

Следующий пример кода работает, как и ожидалось:

package main

import (
    "bytes"
    "fmt"
    "github.com/BurntSushi/toml"
    "html/template"
)

func main() {
    dataToml := `
    [custom]
Data = [                                                                      
  { filename = "fb.jpg", alt = "FB logo", url = "facebook.com" },              
  { filename = "pi.jpg", alt = "Pinterest logo", url = "pinterest.com"},      
  { filename = "twit.jpg", alt = "Twitter logo", url = "twitter.com"},      
]`

    var data interface{}
    if _, err := toml.Decode(dataToml, &data); err != nil {
        panic(err)
    }
    fmt.Printf("data: %v\n", data)

    tmpl := `{{ with .custom.Data }}   
        {{ range $_, $value := . }}         
        {{index $value "filename" }}                                  
        {{ end }}
{{ end }}`

    t := template.Must(template.New("tomlStuff").Parse(tmpl))

    var b bytes.Buffer
    err := t.ExecuteTemplate(&b, "tomlStuff", data)
    if err != nil {
        panic(err)
    }
    fmt.Printf("%v\n", b.String())
}

Вполне возможно, что я что-то упустил;если да, возможно, вы могли бы изменить мой пример на go play так, чтобы он дублировал вашу проблему?

...