While there are other other languages that are more popular for web development like PHP, Python, Javascript, etc., Go language (Golang), which is newer, is also very capable of web development work and it runs amazingly fast. Today, I am going to guide you how to start a Golang HTML template with bootstrap.
I will use Golang v1.16 and gin gonic framework. Gin gonic is a HTTP web framework written in Golang. Gin gonic provides the best perfomance and good productiviy. Basically, they’re good and easy to use.
What I like about web development with Golang is that Golang will compile your code. This will make your application faster and detect bugs earlier.
Table of Contents
Golang Directory Layout
Let’s get started. First we will create a directory layout for our golang files.
G:.
├───bin
├───pkg
└───src
└───web
└───controller
I’m creating three directories: bin, pkg and src in a directory called golang-gin-template. I will call this the GOPATH directory. So, if I call pwd, my absolute directory will be shown below. Note that I am using Windows 10 right now.
pwd
Output
G:\projects\geeksbeginner.com\code\golang-gin-template
Golang Module
A module is a collection of Go packages stored in a file tree. This is the way to import another package in your project in Golang. In this web directory, let’s create file main.go. Then, create a module with this command.
go mod init web
Output
go: creating new go.mod: module web
go: to add module requirements and sums:
go mod tidy
Now, in src/web, the layout looks like this:
Directory: G:\projects\geeksbeginner.com\code\golang-gin-template\src\web
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2/16/2021 9:48 PM controller
-a---- 2/16/2021 9:52 PM 20 go.mod
-a---- 2/16/2021 9:50 PM 191 main.go
Writing Gin Gonic Golang Code
Let’s write our code in main.go.
package main
import (
"log"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.New()
r.Use(gin.Logger())
r.Use(gin.Recovery())
log.Println("Server started")
r.Run()
}
This is a standard boilerplate code with gin gonic. Before we can build it, we need to get the gin gonic code from github repository.
go get github.com/gin-gonic/gin
Output
...
go: downloading github.com/go-playground/locales v0.13.0
go get: added github.com/gin-gonic/gin v1.6.3
After gin project is added, we can try to build the Go project.
go build
If build is successful, a new executable web.exe file will be created.
ls
Output
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2/16/2021 9:48 PM controller
-a---- 2/16/2021 10:22 PM 73 go.mod
-a---- 2/16/2021 10:22 PM 3872 go.sum
-a---- 2/16/2021 9:50 PM 191 main.go
-a---- 2/16/2021 10:23 PM 9351168 web.exe
.\web.exe
If you’re on linux or unix, the executable file will have name web without .exe extension.
Output
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
using env: export GIN_MODE=release
using code: gin.SetMode(gin.ReleaseMode)
2021/02/16 22:25:57 Server started
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080
We don’t have any route, so the applications does nothing except listening on port 8080.
Add Route Controller
Now let’s start writing our route controller to make a web application. We’ll write create a file homepage.go in controller directory.
package controller
import (
"net/http"
"github.com/gin-gonic/gin"
)
func Router(r *gin.Engine) {
r.GET("/", index)
}
func index(c *gin.Context) {
c.String(http.StatusOK, "OK");
}
We need to call controller.Router from main.go, so Gin creates a router for our web.
package main
import (
"log"
"web/controller"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.New()
r.Use(gin.Logger())
r.Use(gin.Recovery())
controller.Router(r)
log.Println("Server started")
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
Our Directory layout will now look like this:
G:.
└───web
│ go.mod
│ go.sum
│ main.go
│ web.exe
│
└───controller
homepage.go
Go to directory web and run build command:
go build
Build command will generate a new web.exe file. Run web.exe file until you see the output lines says Listening and serving HTTP on :8080. Then go to your browser and type address http://localhost:8080/ .
The browser will only says “OK” because that’s our route GET / only response string “OK”. Next we are going to render a HTML files in template.
Golang HTML Templates With Bootstrap
Let’s add more directories and fix our controller code. To make our web beautiful we are going to use a bootstrap theme. I am going to use a free bootstrap theme from https://startbootstrap.com/theme/landing-page.
Startbootstrap.com offers a very nice themes that you can use. In our case we still need to cut the theme into section on separate files.
G:.
├───controller
├───templates
│ ├───views
│ ├───layouts
│ └───homepage
└───static
├───css
├───js
├───img
├───scss
└───vendor
├───bootstrap
│ ├───css
│ └───js
├───fontawesome-free
│ ├───css
│ └───webfonts
├───jquery
└───simple-line-icons
├───css
└───fonts
Now let’s modify our main.go to include our new theme. I put our new theme section in directories template.
package main
import (
"log"
"web/controller"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.New()
r.Use(gin.Logger())
r.Use(gin.Recovery())
r.Static("/css", "./static/css")
r.Static("/img", "./static/img")
r.Static("/scss", "./static/scss")
r.Static("/vendor", "./static/vendor")
r.Static("/js", "./static/js")
r.StaticFile("/favicon.ico", "./img/favicon.ico")
r.LoadHTMLGlob("templates/**/*")
controller.Router(r)
log.Println("Server started")
r.Run() // listen and serve on 0.0.0.0:8080 (for windows "localhost:8080")
}
In lines 15 to line 20, I loaded static files on their path.
In line 22, I loaded the HTML template files in folder template/. Notice the notation /**/* this is means to include all files recursively.
If you load HTML template files recursively using templates/**/*, you cannot place a file in template file. All files must be in the sub folders.
Golang HTML Templates With Bootstrap – The Router
Here is the modified router, I added a controller for index, contact and about. When user click the link on the homepage, the URL link will be served by that router and the router will render the html template.
package controller
import (
"net/http"
"github.com/gin-gonic/gin"
)
func Router(r *gin.Engine) {
r.GET("/", index)
r.GET("/contact", contact)
r.GET("/about", about)
}
func index(c *gin.Context) {
c.HTML(
http.StatusOK,
"views/index.html",
gin.H{
"title": "Geeksbeginner",
},
)
}
func about(c *gin.Context) {
c.HTML(
http.StatusOK,
"views/about.html",
gin.H{},
)
}
func contact(c *gin.Context) {
c.HTML(
http.StatusOK,
"views/contact.html",
gin.H{
"title": "Contact",
},
)
}
Golang HTML Templates With Bootstrap – The Template
In homepage.go, we set our router. This is also where we load our template files. Notice in function index(). I pass a JSON argument {“title”:”Geeksbeginner”}. This how the Golang sends a variable to the template.
{{ define "views/index.html"}}
<!--index.html-->
<!--Embed the header.html template at this location-->
{{ template "layouts/header.html" .}}
{{ template "homepage/master_header.html" .}}
{{ template "homepage/features.html" .}}
{{ template "homepage/image_showcases.html" .}}
{{ template "homepage/testimonials.html" .}}
{{ template "homepage/call_to_action.html" .}}
<!--Embed the footer.html template at this location-->
{{ template "layouts/footer.html" .}}
{{ end }}
Note in line 1 we defined views/index.html. It is recommended to define every file if you are loading the template recursively.
You can download the source code from https://github.com/YZakizon/geeksbeginner in the folder golang-gin-template.