Using conditions inside templates
Asked Answered
N

1

9

The use of if statements inside templates really is puzzling me.

I'm trying to put a class = "active" inside a nav list made with golang templates, to do a basic tab menu that detects the active tab. Here's my attempt :

{{define "header"}}
<!DOCTYPE html>
<html>
    <head>
        <title>Geoprod</title>
        {{template "stylesheet" .}}
    </head>
    <body>
        <nav class="navbar" role="navigation">
          <div class="navbar-header">
            <a{{if eq .Active "accueil"}} class="active"{{end}} href="/">Geoprod</a>
          </div>
          <div class="navbar-body">
            <ul class="navbar-list">
                <li{{if eq .Active "societe"}} class="active"{{end}}><a href="/societe">Soci&eacutet&eacute</a></li>
                <li{{if eq .Active "dossier"}} class="active"{{end}}><a href="/dossier">Dossier</a></li>
                <li{{if eq .Active "temps"}} class="active"{{end}}><a href="/temps">Temps</a></li>
                <li{{if eq .Active "mails"}} class="active"{{end}}><a href="/mails">Mails</a></li>
            </ul>
          </div>
        </nav>
{{end}}

And in main.go :

var FuncMap = template.FuncMap{
    "eq": func(a, b interface{}) bool {
        return a == b
    },
}
var templates = template.Must(template.ParseGlob("templates/*.html"))

and in func main()

templates.Funcs(FuncMap)

The program compiles, but i've found out adding the {{if eq .Active "something"}} class="active"{{end}} (^^ which I included here) causes the program to not display any text anymore. Any idea why?

Nineveh answered 15/7, 2014 at 10:12 Comment(16)
2 things. Did you check for errors on execute? Also: you have to call the Funcs() before parsing the templates. Otherwise the funcs will not be known. On the other hand: the eq func is already defined golang.org/pkg/text/template/#hdr-FunctionsTiphanie
1: Nope, no errors in the log 2: Strange, i just read this this morning, Rob Pike saying it's up to each one of us to write this function if we need it. Is this a new addition to Go ?Nineveh
if there is no output at all, there has to be an error. Also your implementation of eq is lacking. Please have a look here: golang.org/ref/spec#Comparison_operators Especially the part with comparing interface values.Tiphanie
Are you sure it is the {{if}} expression cause the problem? It looks like you got wrong template name, try change {{define "header"}} to {{define "header.html"}}Incurable
Removing the if causes the page to display as intended (only the code doesn't contain the class="active"). The header template is in the file header.html, should I also change the name of the template ?Nineveh
@Tiphanie How do you call Funcs() before parsing ? All the examples I found were with templates.New("").Funcs(...), but here my templates are already named from within templates, So i can't use templates.New(), can I ? What would be a correct syntax then ?Nineveh
@Tiphanie Let's say i stick to the built-in eq function for now. Is the syntax of my {{if}} statement correct ? Also, where can i find documentation on that .Active ? I copied it from here, but i really can't find anything about it in the official template doc.Nineveh
The dot . is your pipeline (on the top level whatever you passed to the Execute*() methods as the data). If .Active is not set, this might already be your problem. But this indicates you are not checking your Execute error. Please show the code where you Execute().Tiphanie
check this: play.golang.org/p/wr59HYR8gtIncurable
@Tiphanie Indeed, my function where templates are executed doesn't check for errors, because I "just wanted to test something quickly". Mistake I'll remember. I'll fix this and come back with an error log.Nineveh
@Tiphanie So, this is my error log, and it makes my mistake quite clear : executing "header" at <.Active>: Active is not a field of struct type *main.Page . I just thought .Active was some sort of built-in, of course it's not in the doc. I'll replace .Active with a field i actually have, and come back to tell you if that works.Nineveh
@Incurable It's a lot like what you sent me on playground, in the end. Thanks to you too.Nineveh
One more thing : should I write an answer summing up my mistakes just to tag the question as solved ?Nineveh
@NicolasM Please do. This is hard to follow otherwise.Gonroff
Just to check: does my answer do what you want?Milker
I guess no need to add FuncMap. There is in-build function eq in html/template. And what is the value of .Active? Itmust be a string.Briefs
M
5

I tried to convert your code into a minimal working example, and I believe your code and template works as expected. You can see my code (and run it) on the Go Playground.

My guess about what went wrong: Did you notice that {{define ...}} only defines a template for future use. You will still need to tell Go to actually use this template, either by using {{ template "header" }} or similar in a main template, or by using templates.ExecuteTemplate.

Milker answered 11/5, 2015 at 16:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.