6

I am working on a simple todo app in go.

I have determined that all the pages except a user's list of todos can safely be a static html page. * Login form * new account form * index page that talks about the todo app

I see no reason currently for these to be go templates.

My question is how (within go, not using something like nginx) can I have a static html set to return at a specific route most efficiently?

For example index.html to be returned at "/"

I know I could do something like:

func GetNewAccount(res http.ResponseWriter, req *http.Request) {
        body, _ := ioutil.ReadFile("templates/register.html")
        fmt.Fprint(res, string(body))
}

or

var register, _ = string(ioutil.ReadFile("templates/register.html"))
func GetNewAccount(res http.ResponseWriter, req *http.Request) {
        fmt.Fprint(res, register)
}

To me these seems like more roundabout ways to do something seemingly simple.

2 Answers 2

10

If all your static files under the same tree, you could use http.FileServer:

http.Handle("/s/", http.StripPrefix("/s/", http.FileServer(http.Dir("/path/to/static/files/"))))

Otherwise pre-loading the html files you want into a map in func init() then making one handler to fmt.Fprint them based on the request's path should work.

Example of a simple static file handler :

func StaticFilesHandler(path, prefix, suffix string) func(w http.ResponseWriter, req *http.Request) {
    files, err := filepath.Glob(filepath.Join(path, "*", suffix))
    if err != nil {
        panic(err)
    }
    m := make(map[string][]byte, len(files))
    for _, fn := range files {
        if data, err := ioutil.ReadFile(fn); err == nil {
            fn = strings.TrimPrefix(fn, path)
            fn = strings.TrimSuffix(fn, suffix)
            m[fn] = data
        } else {
            panic(err)
        }
    }
    return func(w http.ResponseWriter, req *http.Request) {
        path := strings.TrimPrefix(req.URL.Path, prefix)
        if data := m[path]; data != nil {
            fmt.Fprint(w, data)
        } else {
            http.NotFound(w, req)
        }
    }
}

then you can use it like :

http.Handle("/s/", StaticFilesHandler("/path/to/static/files", "/s/", ".html"))
Sign up to request clarification or add additional context in comments.

2 Comments

That surprises me. It may seem silly but all I am trying to do is be able to server template without the file extension. Obviously in production something like apache or ngnix could do this but I want to keep all that logic in the app.
It's rather easy to implement your own, I added an example.
-2

Or just use third party library and do something like this:

iris.StaticServe("/path/to/static/files","/theroute") //gzip compression enabled

The above code snippet is part of the Iris

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.