How do I setup templating in Golang Project




Use xtemplate for nested templating

Here the example when I use xtemplate alongside with go-fiber.

Why I use xtemplate if go-fiber already created official html templating with nested feature? This pattern is currently what I’m familiar with. So, for now, I have no issue to keep using it.

But this might not comply with your project needs.

package helpers

import (
    "github.com/dannyvankooten/extemplate"
    "github.com/gofiber/fiber/v2"
)

// Init
var xt = extemplate.New()

// we only need call this once.
func ParseTemplateWithinDir(viewDir string) error {
    return xt.ParseDir(viewDir, []string{".html"})
}

// Render the targeted template
func RenderTemplateWithContext(c *fiber.Ctx, viewDir, name string, data map[string]interface{}) error {

        // In development phase, I want to make it re-parsing the template every time my app render the pages.
        // this is Opt-in. And we can disabled it in production env.
    err := ParseTemplateWithinDir(viewDir)
    if err != nil {
        return err
    }

        // Execute the template.
    return xt.ExecuteTemplate(c.Response().BodyWriter(), name, data)
}

// helper to ensure the response is HTML
func UseHtml(c *fiber.Ctx) {
    c.Response().Header.Add("Content-Type", "text/html; charset=utf-8")
}

Enter fullscreen mode

Exit fullscreen mode



Create the templates

File views/base.html


</span>
 lang="en">

     charset="UTF-8">
    </span>Testing Unpolly<span class="nt"/>
    <span class="nt"><link/> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"https://cdn.jsdelivr.net/npm/unpoly@3.11.0/unpoly.min.css"</span><span class="nt">></span>
    <span class="nt"><link/> <span class="na">rel=</span><span class="s">"stylesheet"</span> <span class="na">href=</span><span class="s">"https://cdn.jsdelivr.net/npm/unpoly@3.11.0/unpoly-bootstrap5.min.css"</span><span class="nt">></span>
<span class="nt"/>
<span class="nt"/>
    {{block "content" .}}From Parent{{end}}
    <span class="nt"/>Another Content!<span class="nt"/>

    <span class="nt"><script><![CDATA[<span class="na">src=]]></script></span><span class="s">"https://cdn.jsdelivr.net/npm/unpoly@3.11.0/unpoly.min.js"</span><span class="nt">></span>
    <span class="nt"><script><![CDATA[<span class="na">src=]]></script></span><span class="s">"https://code.jquery.com/jquery-3.7.1.min.js"</span>
            <span class="na">integrity=</span><span class="s">"sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo="</span>
            <span class="na">crossorigin=</span><span class="s">"anonymous"</span><span class="nt">></span>
<span class="nt"/>
<span class="nt"/>
</span></span></span></span></span></code></pre>
<div class="highlight__panel js-actions-panel">
<div class="highlight__panel-action js-fullscreen-code-action">
    <svg xmlns="http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24" class="highlight-action crayons-icon highlight-action--fullscreen-on"><title>Enter fullscreen mode
    

Exit fullscreen mode

File views/home.html

{{extends "base.html"}}
{{define "content" -}}

From Home template (children)
{{end}}
Enter fullscreen mode

Exit fullscreen mode



Render the Template

Last, render the template.

// handler.go
// ...
app.Get("/app/", func(ctx *fiber.Ctx) error {
    helpers.UseHtml(ctx)
    err := helpers.RenderTemplateWithContext(ctx, ctrl.viewDir, "home.html", map[string]interface{}{
        "someData": "someData to render",
    })
    if err != nil {
        log.Error(err)
    }
    return nil
})
// ...
Enter fullscreen mode

Exit fullscreen mode

Done!



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *