How to use base template file for golang html/template?

// .go
func Alluser(w http.ResponseWriter, r *http.Request) {

    tpl := template.Must(template.ParseFiles("./tpl/alluser.html", "./tpl/base.html" ))

    rows, err := db.Query("SELECT username, email FROM users")

    if err != nil {
        http.Error(w, "did not select * from users", 500)
        return
    }
    defer rows.Close()
    
    for rows.Next() {
        data := new(UserList)
        err := rows.Scan(&data.Username, &data.Email)

        if err != nil {
            http.Error(w, http.StatusText(500), 500)
            return
        }
        obj := ListPageData{
            Users: []UserList{
                {data.Username, data.Email},
            },
        }
        tpl.ExecuteTemplate(w, "base", obj)
    }
    
    if err = rows.Err(); err != nil {
        http.Error(w, http.StatusText(500), 500)
        return
    }
}
// base.html - parent
{{define "base"}}
<!doctype html>
<html lang="en">
..
<main role="main" class="base_main container">
    {{template "content" .}}
</main>
</body>
</html>
{{end}}
// child.html
{{define "content"}}
<ul class="list-group list-group-flush">
	{{range .Users}}
		<li class="list-group-item">
		name: {{.Username}}, email: {{.Email}}
	</li>
	{{end}}
</ul>
{{end}}

When using the basic template, the enumeration takes place (<!doctype html>) along with the data ( {{range .Users}} )

You do not need to define the “parent” templates. Just the child templates. Here is my “base template” using several child templates

<!DOCTYPE html>
<html lang="en">

{{template "httphead"}}
{{template "body" "home"}}
    {{template "icn"}} {{template "nav" "home"}}
    <main>
        {{template "hdr_top"}}
        <article>
            {{template "mst_home"}}{{template "det_empty"}}
        </article>
    </main>
    {{template "httpend"}}
</body>

</html>

It’s not really about the templates. But I also corrected them.


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

    tpl := template.Must(template.ParseFiles("./tpl/alluser.html", "./tpl/base.html" ))

    rows, err := db.Query("SELECT username, email FROM users")

    if err != nil {
        http.Error(w, "did not select * from users", 500)
        return
    }
    defer rows.Close()

    var albums []*UserList
    
    for rows.Next() {
        data := new(UserList)
        err := rows.Scan(&data.Username, &data.Email)

        if err != nil {
            http.Error(w, http.StatusText(500), 500)
            return
        }
        albums = append(albums, data)
        fmt.Println("data", data)
    }
    tpl.ExecuteTemplate(w, "base", albums)
    
    if err = rows.Err(); err != nil {
        http.Error(w, http.StatusText(500), 500)
        return
    }
}

It’s all about the for loop, you had to get out of it.

{{template "./tpl/base.html"}}

{{block "content" .}}
	
<ul class="list-group list-group-flush">
	{{range .}}
		<li class="list-group-item">
		name: {{.Username}}, email: {{.Email}}
	</li>
	{{end}}
</ul>
	  
{{end}}

Create a separate HTML file, typically named base.html , that contains the common layout elements of your website, such as the header, footer, navigation bar, etc. Define placeholders ({{define "content"}} and {{end}} ) where you want to inject the content specific to each page.

`HTML

{{.Title}} {{template "content" .}} `

Use code with caution. Learn more

content_copy

2. Define individual page templates:

Create separate HTML files for each page of your website. These files only need to define the content specific to that page, and they will inherit the layout from the base template.

`HTML{{define “content”}}

Welcome to my website!

This is the home page content.

{{end}}

{{define “content”}}

About me

My name is John Doe, and I am a web developer.

{{end}}`

Use code with caution. Learn more

content_copy

3. Parse and execute the templates:

In your Go code, use the html/template package to parse the base template and individual page templates, then execute them with a data context:

`Gopackage main

import (
“html/template”
“net/http”
)

func main() {
// Parse the base template
baseTemplate, err := template.ParseFiles(“base.html”)
if err != nil {
panic(err)
}

// Define a handler for the home page
http.HandleFunc(“/”, func(w http.ResponseWriter, r *http.Request) {
data := map[string]string{“Title”: “Home”}
baseTemplate.ExecuteTemplate(w, “base”, data)
})

// Define handlers for other pages similarly

// Start the server
http.ListenAndServe(“:8080”, nil)
}`

Use code with caution. Learn more

content_copy

This is a basic example, and you can customize it further based on your needs. Here are some additional tips:

  • You can use nested templates to further modularize your layout.
  • You can pass additional data to your templates to customize the content dynamically.
  • You can use template functions to perform simple logic within the templates.

Remember to consider security vulnerabilities when using user-generated content in your templates. It’s important to sanitize and escape any input before rendering it in the HTML.

You’re absolutely right, and your feedback is incredibly valuable! A good first tutorial should strive to be accessible, clear, and self-contained for beginners. Here’s why your points are important:

Complexity: “Get Started” tutorials should focus on essential concepts and avoid overwhelming new users with advanced details or references.