DEV Community

Cover image for How to use Templ with Goravel
Andrei Telteu
Andrei Telteu

Posted on

How to use Templ with Goravel

Install the framework and tools

First let's install Goravel. It's a batteries included Go Web Framework for developers familiar with the Laravel Framework.

Steps from Getting started documentation:

// Download framework
git clone https://github.com/goravel/goravel.git
rm -rf goravel/.git*

// Install dependencies
cd goravel
go mod tidy

// Create .env environment configuration file
cp .env.example .env

// Generate application key
go run . artisan key:generate
Enter fullscreen mode Exit fullscreen mode

Now install templ (for html templates) and air (for hot reloading)

go install github.com/a-h/templ/cmd/templ@latest
go install github.com/cosmtrek/air@latest
Enter fullscreen mode Exit fullscreen mode

Configure a simple frontend template structure

(work in progress - I will update with global variables and script push)

• Add this line in your /.gitignore file: *_templ.go
• Delete resources/views/welcome.tmpl
• Create 2 folders in resources/views, home and parts
• In the folder resources/views/parts create 3 files:
   1. resources/views/parts/header.templ

package parts

templ Header() {
    <h1>Header</h1>
}
Enter fullscreen mode Exit fullscreen mode

   2. resources/views/parts/footer.templ

package parts

templ Footer() {
    <footer>
        <p>&copy; 2024 MyProject</p>
    </footer>
}
Enter fullscreen mode Exit fullscreen mode

   3. resources/views/parts/template.templ

package parts

templ Template() {
    <!DOCTYPE html>
    <html>
        <head>
            <title>My Page</title>
            <meta charset="utf-8"/>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
            <meta name="viewport" content="width=device-width, initial-scale=1"/>
            <!-- Your styles go here -->
        </head>
        <body>
            @Header()
            { children... }
            @Footer()
            <!-- Your scripts go here -->
            <script src="//unpkg.com/alpinejs" defer></script>
        </body>
    </html>
}
Enter fullscreen mode Exit fullscreen mode

• Create your homepage component: resources/views/home/index.templ

package home

import "goravel/resources/views/parts"

templ Index() {
    @parts.Template() {
        <h1>Homepage</h1>
        <div>Templ is awesome</div>
    }
}
Enter fullscreen mode Exit fullscreen mode

Their documentation for children components is here. They have an example for a layout structure but I find this method better.

Use this homepage component in your controller

I made this new file app/http/controllers/controller.go where I can store some helpers available to any controller.

package controllers

import (
    "github.com/a-h/templ"
    "github.com/goravel/framework/contracts/http"
)

func RenderTempl(c http.Context, comp templ.Component) http.Response {
    c.Response().Status(200)
    c.Response().Header("Content-Type", "text/html")
    comp.Render(c, c.Response().Writer())
    return nil
}
Enter fullscreen mode Exit fullscreen mode

This helper renders the provided templ component in the response buffer along with a 200 status header. My first try at this I was using c.Response().Writer().Header().Set() but is does not work ! The only way to set response headers is c.Response().Header(key, val).
Let's use it in app/http/controllers/home_controller.go

package controllers

import (
    "goravel/resources/views/home"
    "github.com/goravel/framework/contracts/http"
)

type HomeController struct {
    //Dependent services
}

func NewHomeController() *HomeController {
    return &HomeController{
        //Inject services
    }
}

func (r *HomeController) Index(ctx http.Context) http.Response {
    // doing awesome stuff here
    return RenderTempl(ctx, home.Index())
}
Enter fullscreen mode Exit fullscreen mode

Now set this new route:

package routes

import (
    "goravel/app/http/controllers"
    "github.com/goravel/framework/facades"
)

func Web() {
    homeController := controllers.NewHomeController()
    facades.Route().Get("/", homeController.Index)
}
Enter fullscreen mode Exit fullscreen mode

Configure hot reloading with Air

Goravel already comes with the configuration file (.air.toml) you need for this, we only need to add the templ generate command in the cmd parameter, like this:

[build]
  bin = "./storage/temp/main"
-  cmd = "go build -o ./storage/temp/main ."
+  cmd = "templ generate && go build -o ./storage/temp/main ."
Enter fullscreen mode Exit fullscreen mode

If you are using Windows add .exe to main in both bin and cmd parameters:

[build]
  bin = "./storage/temp/main.exe"
  cmd = "templ generate && go build -o ./storage/temp/main.exe ."
Enter fullscreen mode Exit fullscreen mode

Done ! Happy coding !

Top comments (2)

Collapse
 
xwero profile image
david duymelinck

As I understand it is that templ has a few benefits over html/template that goravel is using by default.

  • adding variables and functions to the template file instead of binding them when calling the template
  • a nicer way to call nested templates and associated content

Is that correct?

Collapse
 
andreitelteu profile image
Andrei Telteu

The benefits in my opinions are:

  • Type safety over view data ! This is the biggest plus I think. You need the templ vscode extension (vim and neovim plugins available as well). Each view is a simple function that can receive attributes with any type.
  • The same if/for syntax as the go language. You don't have to learn a different syntax like {{range $key, $value := . }}.
  • They have interesting helpers for css-in-go and classes templ.guide/syntax-and-usage/css-s...
  • Some helpers for javascript as well templ.guide/syntax-and-usage/scrip...