Difficulties accessing a switch from a HTML template

Due to my limited knowledge, I can’t understand why the following won’t work:

type objectMapDefinition struct {
	t time.Time
}

func main() {
	switch {
	case t.Hour() < 12:
		t.Format("Good morning!")
	case t.Hour() < 17:
		t.Format("Good afternoon!")
	default:
		t.Format("Good evening!")
	}
	page := Model.Page{
    ObjectMap: objectMapDef{
			t: time.Now(),
		},
	}
}

And then in my HTML template I have used {{ .ObjectMap.t }} to access ‘t’.

I want to be able to print either “Good morning” or “Good afternoon” etc. according to the time on my web page.

Thanks, any help is very much appreciated.

time.Format does not change the formatting of the time, but rather returns the text formatted with a specific layout.

Now there are two ways to fix your problem:

  1. Instead of using time.Time use a string in your template data.
  2. Define a custom template func that formats time as you need.

Hey @lennybeadle, I’m not sure what the rest of your code is doing since you haven’t posted a very big snippet, however it looks like you aren’t using the correct value in your switch statement.

Here’s an example. I’m not using Page here since I don’t know what you are trying to do since you didn’t post it’s definition but this should give you the gist of it:

package main

import (
	"fmt"
	"time"
)

type objectMapDefinition struct {
	t time.Time
}

func main() {
	o := objectMapDefinition{
		t: time.Now(),
	}

	hour := o.t.Hour()
	switch {
	case hour < 12:
		fmt.Println("Good morning!")
	case hour < 17:
		fmt.Println("Good afternoon!")
	default:
		fmt.Println("Good evening!")
	}
}

So basically, right now you are trying to access t.Hour() but aren’t accessing o.t.Hour() or in your case I’m thinking page.ObjectMap.t.Hour().

1 Like

Thanks for your answer! I came up with this solution:

type objectMapDef struct {
	Greeting string
}

func main() {

    T := time.Now()
    var greeting string

	switch {
	case T.Hour() < 12:
		greeting = "Good morning!"
	case T.Hour() < 17:
		greeting = "Good afternoon!"
	default:
		greeting = "Good evening!"
	}

	page := Model.Page{
    ObjectMap: objectMapDef{
			Greeting: greeting,
	    },
	}
}

Here’s probably what you want if you are using something like this for page:

package main

import (
	"fmt"
	"time"
)

type objectMapDefinition struct {
	t time.Time
}

type Page struct {
	o objectMapDefinition
}

func main() {
	page := Page{
		o: objectMapDefinition{
			t: time.Now(),
		},
	}

	hour := page.o.t.Hour()
	switch {
	case hour < 12:
		fmt.Println("Good morning!")
	case hour < 17:
		fmt.Println("Good afternoon!")
	default:
		fmt.Println("Good evening!")
	}
}

Hey @lennybeadle one last post about this since this is already my third one here.

I just thought I’d just quickly let you know about this, if you wanted to re-use that function in lots of your templates, since by using template.Funcs you can pass functions directly to your templates and don’t have to end up passing a greeting string every time you want to display a greeting.

Here’s an example:

package main

import (
	"html/template"
	"log"
	"os"
	"time"
)

// Create the source for the template which calls the greet function.
const tmplSrc = "{{ greet }}"

// greet checks the current hour and returns a greeting string based
// on the time of the day.
func greet() string {
	hour := time.Now().Hour()
	switch {
	case hour < 12:
		return "Good morning!"
	case hour < 17:
		return "Good afternoon!"
	default:
		return "Good evening!"
	}
}

// Create a new template and pass it a `FuncMap` containing
// the function `greet`.
var tmpl = template.Must(template.New("tmpl").Funcs(
	template.FuncMap{
		"greet": greet,
	},
).Parse(tmplSrc))

func main() {
	// Execute the template with no need to pass it any data.
	if err := tmpl.ExecuteTemplate(os.Stdout, "tmpl", nil); err != nil {
		log.Fatalln(err)
	}
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.