Soru Golang HTML şablonlarının içinde veya else / elseif / else tuşlarını kullanın


Bu yapıya sahibim:

const (
    paragraph_hypothesis = 1<<iota
    paragraph_attachment = 1<<iota
    paragraph_menu       = 1<<iota
)

type Paragraph struct {
    Type int // paragraph_hypothesis or paragraph_attachment or paragraph_menu
}

Paragraflarımı bir Type bağımlı yol

Bulduğum tek çözüm, isAttachment test etmek Type Git ve iç içe {{if}} :

{{range .Paragraphs}}
    {{if .IsAttachment}}
        -- attachement presentation code  --
    {{else}}{{if .IsMenu}}
        -- menu --
    {{else}}
        -- default code --
    {{end}}{{end}}
{{end}}

Aslında daha fazla türüm var, bu da onu daha da zorlaştırıyor, hem Go kodunu hem de IsSomething fonksiyonlar ve bunlarla birlikte şablon {{end}}.

Temiz çözüm nedir? Biraz var mı switch veya if/elseif/else Git şablonları çözüm? Veya bu davaları halletmenin tamamen farklı bir yolu var mı?


26
2018-06-07 13:34


Menşei


Html şablonlarını mı kullanıyorsunuz? Örneğiniz Paragraph türü çok açık değil. FuncMap'e işlevler ekleyerek genellikle özel şablon davranışı oluşturabilirsiniz (golang.org/pkg/text/template/#Template.Funcs). Üzgünüm, yapmaya çalıştığın şeyin tam olarak emin değilim. - Intermernet


Cevaplar:


Şablonlar mantıksızdır. Bu tür bir mantığa sahip olmaları gerekmiyor. Sahip olabileceğiniz maksimum mantık bir grup if.

Böyle bir durumda, bunu böyle yapmalısınız:

{{if .IsAttachment}}
    -- attachment presentation code --
{{end}}

{{if .IsMenu}}
    -- menu --
{{end}}

{{if .IsDefault}}
    -- default code --
{{end}}

27
2018-06-07 13:55



Ve test etmenin başka yolu yok Type eklemek daha isSomeValue fonksiyonlar? - Denys Séguret
@dystroy, nokta mantığı şablondan çıkarmaktır. Yani evet, bunun dışında bir yardımcı fonksiyonun olması gerekiyor. Mantıksız şablonlar kullandığınızda diğer teknolojilerde yapmanız gereken şey. - Florian Margaine
Aslında sorun, tanımıyla başlar IsDefault. Sonunda, hem şablonlarda hem de Go kodunda bulunması gereken tüm sunum mantığını kopyalayarak başlayıp, şablonu desteklemek için Go'da büyük ve ayrıntılı bir kodla sona erersiniz ve şablon hiçbir katma değer getirmez. - Denys Séguret
Bu çok katı değil mi? ... Bir koşula karşı değerlendirmek için bir koşul nedir? @FlorianMargaine - Ezeewei
Değiştir: "metin / şablonun bu tür bir mantık olması gerekmez." ile: "metin / şablon daha gelişmiş mantığı desteklemiyor." - Jonathan Mayer


Başarabilirsin switch özel işlevler ekleyerek işlevsellik template.FuncMap.

Aşağıdaki örnekte bir işlev tanımladım printPara (paratype int) string Tanımlanmış paragraf türlerinden birini alır ve buna göre çıktıyı değiştirir.

Lütfen, gerçek şablonda .Paratype içine pipetle printpara işlevi. Bu, parametrelerin şablonlarda nasıl iletileceğidir. Eklenen işlevler için çıktı parametrelerinin sayısı ve biçiminde kısıtlamalar olduğunu lütfen unutmayın. FuncMaps. Bu sayfa ilk bağlantı kadar iyi bazı bilgilere de sahiptir.

package main

import (
    "fmt"
    "os"
    "html/template"
)

func main() {

    const (
        paragraph_hypothesis = 1 << iota
        paragraph_attachment = 1 << iota
        paragraph_menu       = 1 << iota
    )

    const text = "{{.Paratype | printpara}}\n" // A simple test template

    type Paragraph struct {
        Paratype int
    }

    var paralist = []*Paragraph{
        &Paragraph{paragraph_hypothesis},
        &Paragraph{paragraph_attachment},
        &Paragraph{paragraph_menu},
    }

    t := template.New("testparagraphs")

    printPara := func(paratype int) string {
        text := ""
        switch paratype {
        case paragraph_hypothesis:
            text = "This is a hypothesis\n"
        case paragraph_attachment:
            text = "This is an attachment\n"
        case paragraph_menu:
            text = "Menu\n1:\n2:\n3:\n\nPick any option:\n"
        }
        return text
    }

    template.Must(t.Funcs(template.FuncMap{"printpara": printPara}).Parse(text))

    for _, p := range paralist {
        err := t.Execute(os.Stdout, p)
        if err != nil {
            fmt.Println("executing template:", err)
        }
    }
}

üretir:

Bu bir hipotez

Bu bir ek

Menü
  1:
  2:
  3:

Herhangi bir seçenek seçin:

Oyun alanı bağlantısı

Umarım yardımcı olur, kodun biraz temizlenmiş olabileceğine eminim, ancak sağladığınız örnek kodun yakınında kalmaya çalıştım.


6
2018-06-08 02:43



Bu ilginç ancak çözümünüzde HTML'de paragrafın oluşturulması Go ( printPara). Sonra bir şablon kullanmanın bir anlamı yok gibi görünüyor. - Denys Séguret
Baskı sadece bir gösteri. Herhangi bir kodu istediğiniz yere ekleyebilirsiniz. case ifadeler, sadece özel çıktı değil. Değişkenleri işleyebilir, yapı değerlerini değiştirebilirsin. Bu gerçekten nasıl üretebileceğinizi göstermektir. switch şablonlarda işlevsellik gibi. - Intermernet
@Intermernet Ben hem distro ve ben böyle bir şey arıyorlardı düşünüyorum: pastebin.com/QSz0vAxk - Florian Margaine
Tam olarak aradığım şeyler gibiydi. - Denys Séguret
Tamam, okuduktan sonra, standart kütüphaneyi (özellikle golang.org/pkg/text/template/parse/#NodeType Sadece yeni başlayanlar için) gerçek bir anahtar ifadesine sahip olmak. Bir sonraki en iyi şey bir dizi olurdu {{if switch .Type | case 1}}...{{end}} (özel tanımlama Switch() ve Case() FuncMap'teki fonksiyonlar), bu noktada, eğer ifadeler varsa standartla devam edebilirsiniz. Ah, son bir saat içinde lexers ve parsers hakkında çok şey öğrendim. İlgili kaynak, ilgileniyorsanız, golang.org/src/pkg/text/template/parse . - Intermernet


Evet, kullanabilirsiniz {{else if .IsMenu}}


1
2017-07-12 14:36



Bu çalışıyor. Belki bu şablonlar için yeni bir özelliktir. Teşekkürler - openwonk