how to implement this template ?

1,699 views
Skip to first unread message

Natanael

unread,
Sep 15, 2011, 10:59:34 AM9/15/11
to golang-nuts
I've been reading the doc info about the template package but I'm a
bit puzzled. I wish I had examples to read.
What I want to do is just applying a content map[string]string called
say data to an html template.

<li {{ if data["os"]=="linux" print("class=\"active\"") }} >Linux</li>
<li {{ if data["os"]=="windows" print("class=\"active\"") }} >Windows</
li>
<li {{ if data["os"]=="macosx" print("class=\"active\"") }} >MacOSX</
li>

so if say : data["os"]="macosx"
the parsed template would be:

<li >Linux</li>
<li >Windows</li>
<li class="active" >MacOSX</li>

How can I implement this on a template ?
Thanks

Rob 'Commander' Pike

unread,
Sep 15, 2011, 11:15:37 AM9/15/11
to Natanael, golang-nuts
The template language processes data. It's not a calculator; you have
Go for that.

The most direct way to do what you want is to write the Go function
you need and call it in the template. It could do the lookup and
validate:

</li>{{if osIs "windows"}}class="active"{{end}}Windows</i>

osIs looks up "os" in data. Or there are a myriad of other ways to
factor this. You could even just do an equals function:

</li>{{if index data "os" | equals "windows"}}class="active"{{end}}Windows</i>

Perhaps equals should be pre-installed. I'm taking a slow-and-steady
approach to adding built-ins, though.

-rob

Natanael

unread,
Sep 15, 2011, 1:33:53 PM9/15/11
to golang-nuts
Well, still puzzled.
The example is far difficult, this way:
<li {{ if data["os"]=="linux" print("class=\"active\"") }} >Linux</li>
<li {{ if data["os"]=="windows" print("class=\"active\"") }}
>Windows</
li>
<li {{ if data["os"]=="macosx" print("class=\"active\"") }} >MacOSX</
li>
<li {{ if data["bits"]=="32" print("class=\"active\"") }} >i386</li>
<li {{ if data["bits"]=="64" print("class=\"active\"") }} >x64</
li>
.....................................................
....................................................

Do I have to create a keyIs function for every key in the data map ?
How is the implementation of that function ?
How is the HTML template file parsed using those function/s ?

Thanks
-natanael

Rob 'Commander' Pike

unread,
Sep 15, 2011, 2:01:27 PM9/15/11
to Natanael, golang-nuts

An equals function, as I proposed, makes all these examples trivial.

-rob

tux21b

unread,
Sep 15, 2011, 2:15:19 PM9/15/11
to golan...@googlegroups.com, Natanael
Here is a simple example for such an equals function like rob suggested. This might be a good starting point:

    tmpl := template.Must(template.New("example").Funcs(
        template.FuncMap{
            "eq": func(a, b string) bool {
                return a == b
            },
        }).Parse(`
    <li {{ if eq .data.os "linux" }}class="active"{{ end }}>Linux</li>`))
    tmpl.Execute(os.Stdout, map[string]map[string]string{
        "data": map[string]string{
            "os":   "linux",
            "bits": "64",
        }})

-christoph

Natanael

unread,
Sep 15, 2011, 3:19:46 PM9/15/11
to golang-nuts
OK, perfect.
Thanks to both Rob and Christopher

Regards,
- natanael

George Nava

unread,
Sep 15, 2011, 8:07:24 PM9/15/11
to golang-nuts
Or do the processing first and then just parse this:

<li {{class}}>{{os}}</li>

Whenever you see yourself fighting with a template just stop to think
if you better massage the data first and then pass it to the template
ready for consumption.

Bjorn Tipling

unread,
Mar 4, 2012, 4:54:30 AM3/4/12
to golan...@googlegroups.com
It's absolutely ridiculous that the template engine does not have an equals function built in. Even django templates, notorious for purging logic from its template engine has an {% ifEquals...%} Just do a search on this mailing list on the Google Groups page for people asking again and again as to how one can compare two values in a template. It's not like people are asking how to write a factorial function in their template. No just trying to compare two values to see if I should have an option selected or a radio box checked based on previous values. Unthinkable, I know right. 

Rob 'Commander' Pike

unread,
Mar 4, 2012, 7:32:27 AM3/4/12
to Bjorn Tipling, golan...@googlegroups.com
On Sun, Mar 4, 2012 at 8:54 PM, Bjorn Tipling <bjorn....@gmail.com> wrote:
> It's absolutely ridiculous that the template engine does not have an equals
> function built in. Even django templates, notorious for purging logic from
> its template engine has an {% ifEquals...%} Just do a search on this mailing
> list on the Google Groups page for people asking again and again as to how
> one can compare two values in a template. It's not like people are asking
> how to write a factorial function in their template. No just trying to
> compare two values to see if I should have an option selected or a radio box
> checked based on previous values. Unthinkable, I know right.

Unthinkable and ridiculous to ignore how easy it is to write your own
equality function if you need one. There's a whole programming
language at your disposal, called Go. The template "engine" is
designed to be driven by it, not to replace it.

The problem with building equality in is that one must decide what
equality is. What's right for one user may be wrong for another. (In
fact, Go doesn't even have a full definition itself, because of the
subtleties involved.) You know what form of equality you need, so you
should implement it. chances are, it's one line of code, much less
text than your complaint.

-rob

Rodrigo Moraes

unread,
Mar 4, 2012, 9:19:44 AM3/4/12
to golang-nuts
On Mar 4, 6:54 am, Bjorn Tipling wrote:
> It's absolutely ridiculous that the template engine does not have an equals
> function built in.

Suggestion: take the template package as a raw base to build upon.
Create a package with template helpers, such as different equality
flavors and other stuff. Let us know about it.

-- rodrigo

Bjorn Tipling

unread,
Mar 4, 2012, 11:39:56 AM3/4/12
to Rob 'Commander' Pike, golan...@googlegroups.com
I apologize for my tone, it was late and I was frustrated. What's wrong with including a function that just checks using ==? Maybe that's enough and if that doesn't work, then it makes sense for the developer to build their own.

Again sorry for whining.

Bjorn

ziutek

unread,
Mar 4, 2012, 2:35:03 PM3/4/12
to golang-nuts
There is Kasia template engine for Go (written at a time when there
was no html/template package). I and some other people uses kasia even
now for all Go web projects, because of its different syntax).
Example:

<li $if data["os"]=="linux": class="active" $end>Linux</li>
<li $if data["os"]=="windows": class="active" $end>Windows</li>
<li $if data["os"]=="macosx": class="active" $end>MacOSX</li>

But of course this looks better:

<li $if isLinux(data): class="active" $end>Linux</li>

For web projects I always use Kasia with kview package. Example:

func initView() {
layout := kview.New("layout.kt")
menu := kview.New("menu.kt")

home = layout.Copy()
home.Div("left", menu)
home.Div("right", kview.New("right/home.kt", utils))
}

var utils = map[string]interface{} {
"contains": strings.Contains,
"isLinux": func(c WebCtx) bool { return c.Os() == "linux" },
"isOSX": func(c WebCtx) bool { return c.Os() == "MacOSX" },
}

Rob 'Commander' Pike

unread,
Mar 4, 2012, 3:12:48 PM3/4/12
to Bjorn Tipling, Rob 'Commander' Pike, golan...@googlegroups.com

On Mar 5, 2012, at 3:39 AM, Bjorn Tipling wrote:

> I apologize for my tone, it was late and I was frustrated. What's wrong with including a function that just checks using ==? Maybe that's enough and if that doesn't work, then it makes sense for the developer to build their own.

It's not trivial; one must verify types and comparability and so on. It could use reflect.DeepEqual, and that may be the right answer, but it might not and that's a relatively slow operation.

As is often the case with library design, easy things are easy, difficult things are best delayed it's clear what the right answer is, as long as the user can work out the answer for his own problem without too much burden.

-rob


Andrew Gerrand

unread,
Mar 4, 2012, 11:56:14 PM3/4/12
to golan...@googlegroups.com, Natanael
For an even easier and general equals function, just do this for your
template t:

t.Funcs(template.FuncMap{"eq": reflect.DeepEqual})

Andrew

Reply all
Reply to author
Forward
0 new messages