Personal Blog with HTMX + Go: Part 1 - Golang Templating

This is the first part of the series where I document my journey creating a personal blog using HTMX and Go. This part will cover the basics of Go templating with Labstack Echo.

Prerequisites

Before we start, make sure you have:

  • Go installed (1.21 or later recommended)
  • Basic understanding of Go syntax
  • A text editor of your choice

Setting Up the Project

First, let’s create a new Go project:

mkdir my-blog
cd my-blog
go mod init my-blog

Next, we’ll install Echo, our HTTP framework of choice:

go get github.com/labstack/echo/v4

Understanding Go Templates

Go’s html/template package is powerful yet simple. Templates allow us to:

  • Separate HTML from Go code
  • Inject dynamic data into HTML
  • Create reusable components

Basic Template Syntax

Templates use double curly braces {{}} for dynamic content:

{{define "greeting"}}
<h1>Hello, {{.Name}}!</h1>
{{end}}

The . represents the data passed to the template.

Creating Our First Template

Create a directory structure:

my-blog/
├── main.go
├── public/
│   └── index.html
└── template/
    └── template.go

Let’s create public/index.html:

{{define "index"}}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>My Blog</title>
  </head>
  <body>
    <h1>Welcome to {{.Title}}</h1>
    <p>{{.Description}}</p>
  </body>
</html>
{{end}}

Setting Up the Template Renderer

Create template/template.go:

package template

import (
    "html/template"
    "io"
    "github.com/labstack/echo/v4"
)

type TemplateRenderer struct {
    templates *template.Template
}

func (t *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
    return t.templates.ExecuteTemplate(w, name, data)
}

func NewTemplateRenderer(pattern string) *TemplateRenderer {
    return &TemplateRenderer{
        templates: template.Must(template.ParseGlob(pattern)),
    }
}

Wiring Everything Together

Now let’s create our main.go:

package main

import (
    "net/http"
    "my-blog/template"
    "github.com/labstack/echo/v4"
)

func main() {
    e := echo.New()

    // Set up template renderer
    e.Renderer = template.NewTemplateRenderer("public/*.html")

    // Define routes
    e.GET("/", func(c echo.Context) error {
        data := map[string]interface{}{
            "Title":       "My Blog",
            "Description": "Welcome to my personal blog built with HTMX and Go!",
        }
        return c.Render(http.StatusOK, "index", data)
    })

    // Start server
    e.Logger.Fatal(e.Start(":4040"))
}

Running the Application

Start the server:

go run .

Visit http://localhost:4040 and you should see your rendered template!

Creating Reusable Partials

One of the best features of Go templates is the ability to create partials. Let’s create a name card partial:

Create public/name_card.html:

{{define "name_card"}}
<div>
  <p>User Personal Information:</p>
  <ol>
    <li>Name: {{.Name}}</li>
    <li>Phone: {{.Phone}}</li>
    <li>Email: {{.Email}}</li>
  </ol>
</div>
{{end}}

You can include this in other templates using:

{{template "name_card" .User}}

Introducing HTMX

Now here’s where it gets interesting. HTMX allows us to make AJAX requests directly from HTML attributes. Add HTMX to your page:

<script src="https://unpkg.com/htmx.org@1.9.10"></script>

Now we can create interactive elements:

<button hx-get="/user-info" hx-target="#user-info" hx-swap="innerHTML">Load User Info</button>
<div id="user-info"></div>

When clicked, this button will:

  1. Make a GET request to /user-info
  2. Replace the contents of #user-info with the response

Creating the User Info Endpoint

Add this to your main.go:

e.GET("/user-info", func(c echo.Context) error {
    user := map[string]interface{}{
        "Name":  "Wyndham",
        "Phone": "+62-xxx-xxx-xxxx",
        "Email": "business@mwyndham.dev",
    }
    return c.Render(http.StatusOK, "name_card", user)
})

What’s Next?

In the next part, we’ll integrate TailwindCSS to make our blog look professional. We’ll cover:

  • Setting up TailwindCSS with Go
  • Creating responsive layouts
  • Styling our components

Stay tuned!

#blogging #Golang #Htmx #Tutorial #series

Comments