How to Golang loop in html with http/template and net/http? - go

I am trying to handle data and then send it into html to be displayed in a specific field.
No expected output into {{.name}}. Works fine with {{.}}. No known structural wrongdoing.
Golang code
package main
import (
"fmt"
"html/template"
"net/http"
"github.com/gorilla/context"
)
var tpl *template.Template
func main() {
tpl, _ = template.ParseGlob("*.html")
http.HandleFunc("/test", testHandler)
http.ListenAndServe(":8080", context.ClearHandler(http.DefaultServeMux))
}
type Data struct {
allData []string
}
func testHandler(w http.ResponseWriter, r *http.Request) {
data := Data{allData: []string{"Add new", "jeff", "ffeej"}}
tpl.ExecuteTemplate(w, "test.html", data)
}
HTML code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test</title>
</head>
<body>
<section>
{{range .allData}}
{{.}}
{{end}}
</section>
</body>
</html>
How does one get the data out of the handler into the html in a specific wanted field?
What am I missing? I am still learning golang.
Thanks in advance.

Related

Prevent overwriting of blocks with same name in Go Template

I'm having difficulty in rendering the correct content using templates in Go. Either case of navigating to /about or / the same content is getting rendered. Below is the current state of code.
I have read that you can parse templates in each handleFunc (for each request) but that seems to be an inefficient way to mitigate the issue.
Code
I have the following templates
base
header
footer
index
about
{{ define "base"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Project Website</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/water.css#2/out/water.css">
</head>
<body>
{{template "header" .}}
{{template "body" .}}
{{template "footer" .}}
</body>
</html>
{{end}}
{{define "header"}}
<h1>Header</h1>
{{end}}
{{define "footer"}}
<h1>Footer</h1>
{{end}}
{{template "base" .}}
{{define "body"}}
<h1>About</h1>
{{end}}
{{template "base" .}}
{{define "body"}}
<h1>Index</h1>
{{end}}
main.go
package main
import (
"html/template"
"log"
"net/http"
)
var tpl *template.Template
func init() {
tpl = template.Must(template.ParseGlob("templates/*"))
}
func main() {
// Connect to database.
// Routes
http.HandleFunc("/about", about)
http.HandleFunc("/", index)
http.HandleFunc("/favicon.ico", doNothing) // TODO Replace with something like do not found
// Listen and serve.
log.Fatal(http.ListenAndServe(":8000", nil))
}
// TODO go away
func doNothing(w http.ResponseWriter, r *http.Request) {}
handlerFunctions.go
package main
import (
"log"
"net/http"
)
func index(rw http.ResponseWriter, req *http.Request) {
log.Println("Index page called")
tpl.ExecuteTemplate(rw, "index.gohtml", nil)
}
func about(rw http.ResponseWriter, req *http.Request) {
log.Println("About page called")
tpl.ExecuteTemplate(rw, "about.gohtml", nil)
}

How to stream a PDF

I use Go and Gin for handle my web service. I want to stream a PDF file.
I tried to use html embed tag and pdf url for tag src, but this method not help me, because browser download the pdf.
For pdf handler I set content-type and someother headers but not work.
GO
func DownloadPdf(c *gin.Context) {
c.Writer.Header().Set("Content-type", "application/pdf")
c.FileAttachment(fmt.Sprintf("%s/order_%v.pdf", fileBasePath, myOrderUrl.OrderId), "bilit_pdf.pdf")
}
func LoadHtml(c *gin.Context) {
t, err := template.ParseFiles("Modules/Pdf/templates/pdf.gohtml")
if err != nil {
panic(err)
}
buf := new(bytes.Buffer)
if err = t.Execute(buf, "http://localhost:3001/v2/pdf/download/YfTgLuPPDc"); err != nil {
panic(err)
}
if _,err:=buf.WriteTo(c.Writer);err!=nil{
panic(err)
}
}
HTLM
<!DOCTYPE html>
<html lang="en" style="height: 100%;width: 100%">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height: 100%;width: 100%;margin: 0;overflow:hidden">
<embed
src="{{.}}"
type="application/pdf"
frameBorder="0"
height="100%"
width="100%">
</embed>
</body>
</html>
I found the answer with adding
c.Writer.Header().Set("Content-type", "application/octet-stream")
into my download code .
and opened PDF file when DownloadPdf route called .

Include css in html, where should I put the css file?

I am trying (unsuccessful) to include my css into my html. I have the files (executable, html and css)in the same directory "/test".
I have done some research over the subject but I can not still include the css in a proper way. For what I already saw if I include the css file starting with "/" it is relative to root folder so to confirm where is the root folder of the program I printed it and it is pointing to "C:\Users\Filipe\Desktop\go\src\test>" where are all my files.
test.go:
package main
import (
"fmt"
"net/http"
"os"
"text/template"
)
type Page struct {
Title string
NavItems []navItem
}
type navItem struct {
Item string
}
func indexHandler(w http.ResponseWriter, r *http.Request) {
page := Page{
Title: "title",
NavItems: []navItem{
{Item: "item1"},
{Item: "item2"},
},
}
t, _ := template.ParseFiles("index.html")
t.Execute(w, page)
}
func testHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "/t directory test")
}
func main() {
http.HandleFunc("/", indexHandler)
fmt.Println(os.Getwd())
http.ListenAndServe(":8080", nil)
}
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" type="text/css" href="/mystyle.css">
<title>{{.Title}}</title>
</head>
<body>
<nav>
{{range .NavItems}}
<a>{{.Item}}<a>
{{end}}
</nav>
</body>
</html>
try to change -
<link rel="stylesheet" type="text/css" href="/mystyle.css">
to
<link rel="stylesheet" type="text/css" href="test/mystyle.css">
That will should solve the problem.

Does gin-gonic support get request?

I am new in gin-gonic framework and i have been trying to read the values from the inputs that i added in a get request from html but i have not been able to read the values that i wrote.
When i submit the request the browser sends this url :
http://localhost:3000/backend?name1=value1&name2=value2&name3=value3
I have been looking in the internet where gin-gonic uses this url type but i have only found that it uses url like this one
http://localhost:3000/backend/value1
html code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form method="GET" action="/backend">
<input id="store" name="name1" type="text">
<input id="razon" name="name2" type="text">
<input id="total" name="name3" type="text">
<input type="submit" value="submit">
</form>
</body>
</html>
golang code:
package main
import(
"net/http"
"fmt"
"github.com/gin-gonic/contrib/static"
"github.com/gin-gonic/gin"
)
func main(){
router := gin.Default()
router.Use(static.Serve("/",static.LocalFile("./views",true)))
router.GET("/backend",func(c *gin.Context){
fmt.Println(c.Param("name1"))
c.JSON(http.StatusOK, gin.H{
"name1" : c.Param("name1"),
})
})
router.Run(":3000")
}
Actual result:
{"name1":""}
Expected result:
{"name1":"value1"}
The function you are looking for is not Param(), it's Query().
https://github.com/gin-gonic/gin#querystring-parameters

Form Always Empty

I've been building a Go todo list and I'm trying to add the ability to add new items, but every time I access the form value, it comes out empty. Here's the handler I built:
func addHandler(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
fmt.Print(err)
}
cook, _ := r.Cookie("userid")
id := cook.Value
r.ParseForm()
text := r.FormValue("todo")
addTodo(text,id) //inserts into database
http.Redirect(w,r,"/todo",http.StatusFound)
}
And here's the html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<table>
{{range .}}
<tr><td>{{printf "%s" .Text}}</td><td>delete</td></tr>
{{end}}
</table>
<form action="/add" method="post"><input type="text" name="todo"><button type="submit">Add</button></form>
</body>
</html>

Resources