-1

I have been playing around with numerous go server snippets trying to figure out how I can display an image file within a HTML file or go HTTP template along with an html forms section. Basically, the biggest problem if I use a go template I cannot show an image along with html and still keep the project size small. It seems the only way to get the template to work is by organizing the code into a "typical go HTML project" which I am trying to avoid.

Is there any easy way (with only a couple files and not creating a "typical go web project file structure") to display HTML with an image inside a go template? I believe the problem below is basically with http handlers. Either I can have a text handler or image handler but not both? I need both so I can have user control from HTML form which image will be displayed.

If anyone can help I would really appreciate it.

R Joe

--Revised Sorry about being unclear. I have limited experience with go templates and I have seen many examples where people use go app project file structures that might include directories such as templates, img, etc. These directories are often 10 or more. Then they talk about using routes within apps and other things that I am timid to get into.

I just view what I want to do as much more simple. I have about 70 images. I just want a way where a user can click an html page that displays an image and just provide a number 1,2,3,4 as feedback depending on what image is being displayed.

I imagined that a single go program (1 file) could receive the number and once received change the img on the html page or allow the user to click a next hyperlink or something to bring up the next image and once it is over the program stops.

package main
import (

"fmt"
"html/template"
"log"
"net/http"
//"strings"



func img(w http.ResponseWriter, r *http.Request) {

//http.Handle("/images/", http.StripPrefix("/images/", http.FileServer(http.Dir("images/"))))

fmt.Println("method:", r.Method) //get request method

if r.Method == "GET" {
    t, _ := template.ParseFiles("image.gtpl")
    t.Execute(w, nil)
} else {
    r.ParseForm()
    // logic part of log in
    fmt.Println("previmage:", r.Form["previmage"])
    fmt.Println("nextimage:", r.Form["nextimage"])
}
}

func main() {

//http.HandleFunc("/", sayhelloName) // setting router rule
http.HandleFunc("/login", login)
err := http.ListenAndServe(":9090", nil) // setting listening port
if err != nil {
    log.Fatal("ListenAndServe: ", err)
}
}

<html>
<head>
<title></title>
</head>
<body> //How to Loop Images based on user submit??
<img src="img/question4.png" alt="Cannot load image" style="width: 800px;height: 800px">
    <form action="/login" method="post">
        Username:<input type="text" name="previmage">
        Password:<input type="password" name="nextimage">
        <input type="submit" value="Login">
    </form>
</body>
</html>
djoemart
  • 9
  • 4
  • 1
    It's not clear what you're asking here or what problem you're having. "if I use a go template I cannot show an image along with html and still keep the project size small" doesn't really make sense - using templates has nothing to do with showing images and neither has much to do with the "project size". Can you clarify your question? – Adrian Jun 11 '19 at 21:20
  • OK, I tried to make things a bit more clear. Hopefully it makes more sense now? – djoemart Jun 12 '19 at 02:21
  • There's no mandated file structure. You can do whatever you want. You'll need at a minimum a route to serve the template, and a route to serve the static files (images). It could all be in one, fairly small file, in one directory along with the images, if you wanted to do it that way. It seems like you've got the template working, serving static files is well-documented in net/http and frequently answered on SO. What specifically are you having trouble with other than feeling like you're supposed to have more directories? – Adrian Jun 12 '19 at 13:30
  • My main problem is I cannot display both image and form fields at the same time. I am close I think. Currently, it appears to work with 1 request then I get error: http: panic serving [::1]:55198: http: multiple registrations for /img/. If I use mux: mux.Handle("/img/", http.StripPrefix("/img/", http.FileServer(http.Dir("img")))) I do not get an error but the image never shows only the forms. So my problem is I cannot get both forms and images to load together in a single html page. Maybe I need to add routes but I am so close with just with what I have. Does that make sense? – djoemart Jun 12 '19 at 15:40
  • Can you elaborate with your question? – djoemart Jun 12 '19 at 15:49

1 Answers1

0

You have your http.Handle call, which registers the handler, inside the handler. That means every time a request comes in, it tries to register the handler again. That's not allowed (hence the error, which says explicitly that you cannot re-register the same route). You should be registering it in the same place you're registering the handler for the template, i.e. in main:

func main() {
    http.HandleFunc("/login", login)
    // Register handler correctly
    // I changed the route to /img/ to match what you're using in your HTML
    http.Handle("/img/", http.StripPrefix("/img/", http.FileServer(http.Dir("images/"))))
    err := http.ListenAndServe(":9090", nil) // setting listening port
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}
Adrian
  • 42,911
  • 6
  • 107
  • 99
  • Adrian, many thanks! That certainly seems to have resolved the issue I have had and been stuck on the past few days....I almost was about to just give up so thanks again! – djoemart Jun 12 '19 at 19:06