skip to Main Content

I’m just starting to use golang and the template system to redevelop my webserver. Now I just want to write constant variables for each website but I don’t even really know what I’m searching. I hope some one can help.

I have this gohtml file for the "base" of every html File

    {{define "topdoc"}}
    <!DOCTYPE html>
    <html lang="en" data-bs-theme="dark">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>{{.title}}</title>
        <!-- Bootstrap -->
        <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
              integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"
              crossorigin="anonymous">
    </head>
    <body>
{{end}}

{{define "botdoc"}}
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
            integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe"
            crossorigin="anonymous"></script>
    </body>
    </html>
{{end}}

Than I want to change the title and later for example meta data description and stuff like that the same way.

{{template "topdoc" .}}
{{template "navbar"}}
HOME

{{template "botdoc"}}

Navbar is defined in another file.

Now I want to give the variable in this file like

{{template "topdoc" .title="Home" .otherParam="Checking..."}}
{{template "navbar"}}
HOME

{{template "botdoc"}}

Maybe someon can help me with this very trivial issue.

When I use this method

{{define "title"}}Home{{end}}
{{template "topdoc"}}
{{template "navbar"}}
HOME

{{template "botdoc"}}

And load the base file first, it shows a blank website.

I load the template files like this:

func main() {
    r := gin.Default()

    tmpl = make(map[string]*template.Template)

    // Load templates files
    templateFiles := []string{}

    fmt.Println("Loading templates...")
    // Walk through the "templates" folder and all its subdirectories
    nerr := filepath.Walk("main/web/assets/templates", func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }

        // Check if the file is an HTML templates
        if !info.IsDir() && strings.HasSuffix(info.Name(), ".gohtml") {
            // Replace backslashes with forward slashes (for Windows compatibility)
            templateName := strings.Replace(path, "\", "/", -1)

            // Parse the file and add it to the "tmpl" map
            templateFiles = append(templateFiles, path)

            //console log
            fmt.Print(templateName + " ")
        }
        return nil
    })

    if nerr != nil {
        panic(nerr)
    }

    fmt.Println("nnLoading sites...")

    // Walk through the "public" folder and all its subdirectories
    err := filepath.Walk("main/web/public", func(path string, info os.FileInfo, err error) error {
        if err != nil {
            return err
        }

        // Check if the file is an HTML templates
        if !info.IsDir() && strings.HasSuffix(info.Name(), ".gohtml") {
            // Get the directory path (relative to the "public" folder)
            relPath, err := filepath.Rel("main/web/public", filepath.Dir(path))
            if err != nil {
                return err
            }
            // Replace backslashes with forward slashes (for Windows compatibility)
            templateName := strings.Replace(relPath, "\", "/", -1)

            // Parse the file and add it to the "tmpl" map
            parsing := []string{}
            parsing = append(parsing, templateFiles...)
            parsing = append(parsing, path)

            fmt.Println(parsing)

            tmpl[templateName] = template.Must(template.ParseFiles(parsing...))

            // If the path is empty, default to "index"
            if templateName == "." {
                templateName = ""
            }

            // Register the templates with the appropriate route
            r.GET("/"+templateName, handler)
        }

        return nil
    })
    if err != nil {
        panic(err)
    }

    r.Run()
}

2

Answers


  1. Chosen as BEST ANSWER

    In order to use "constants" in go templates, its the easiest way to just use a template to define them. Therefor its important to load the base template file at first, so it can be overriten. When doing that, its important to define a "content" template, so that the actual website can be displayed.

    So the base.golang would look like this

    {{define "topdoc"}}
        <!DOCTYPE html>
        <html lang="eng" data-bs-theme="dark">
        <head>
            <meta charset="utf-8">
            <meta http-equiv="X-UA-Compatible" content="IE=edge">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <title>{{template "title"}}</title>
            <!-- Bootstrap -->
            <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
                  integrity="sha384-KK94CHFLLe+nY2dmCWGMq91rCGa5gtU4mk92HdvYe+M/SXH301p5ILy+dN9+nJOZ"
                  crossorigin="anonymous">
        </head>
        <body>
    {{end}}
    
    {{define "title"}} Default Title {{end}}
    {{template "content"}}
    
    {{define "botdoc"}}
        <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
                integrity="sha384-ENjdO4Dr2bkBIFxQpeoTz1HIcje39Wm4jDKdf19U8gI4ddQ3GYNS7NTKfAdVQSZe"
                crossorigin="anonymous"></script>
        </body>
        </html>
    {{end}}
    

    The website file would thant look like this

    {{define "title"}}Home{{end}}
    {{define "content"}}
    {{template "topdoc"}}
    
    
    {{template "navbar"}}
    Home
    
    {{template "botdoc"}}
    {{end}}
    

  2. This is usually achieved using template composition. In your "topdoc" template, simply call other templates:

    {{define "topdoc"}}
    ...
    {{template "title"}}
    ...
    {{end}}
    

    And define the "title" template as

    {{define "title"}}Default title{{end}}
    

    Then, you can override the "title" template with a redefinition of it in a separate file:

    {{define "title"}}New title{{end}}
    {{define "someTemplate}}
    {{template "topdoc"}}
    ...
    {{end}}
    

    You have to compose these different template files so that you load the "topdoc" first (which defines the default "title"), and then load the template redefining the "title".

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search