Creating Reusable Templates

Our application will display a web page using its template. However, there will be several parts such as the header, menu, sidebar, and footer, which will be common across all pages. Go allows us to create reusable template snippets that can be imported in other templates.

The header and the footer will be the common pieces that will be reused across all templates. We will also create the menu in its own template file which will be used by the header template. Finally, we'll create the template for the index page which will import the header and the footer. All the template files will be placed in the templates directory within the project directory.

Let's start by creating the template for the menu in templates/menu.html as follows:

<!--menu.html-->

<nav class="navbar navbar-default">
  <div class="container">
    <div class="navbar-header">
      <a class="navbar-brand" href="/">
        Home
      </a>
    </div>
  </div>
</nav>

Initially, the menu contains only the link to the home page. We will add to this as we add more functionality to the application. The template for the header will be placed in the templates/header.html file as follows:

<!--header.html-->

<!doctype html>
<html>

  <head>
    <!--Use the `title` variable to set the title of the page-->
    <title>{{ .title }}</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="UTF-8">

    <!--Use bootstrap to make the application look nice-->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
    <script async src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
  </head>

  <body class="container">
    <!--Embed the menu.html template at this location-->
    {{ template "menu.html" . }}

As you can see, we are using the open source Bootstrap framework. Most of this file is standard HTML. However, take note of two lines. The line containing <title>{{ .title }}</title> is used to dynamically set the title of the page using the .title variable that must be set inside the application. Secondly, the line containing {{ template "menu.html" . }} is used to import the menu template from the menu.html file. This is how Go lets you import one template in another.

The template for the footer contains static HTML. The template for the index page makes use of the header and the footer and displays a simple Hello Gin message:

<!--index.html-->

<!--Embed the header.html template at this location-->
{{ template "header.html" .}}

  <h1>Hello Gin!</h1>

<!--Embed the footer.html template at this location-->
{{ template "footer.html" .}}

Like the index template, templates for other pages will reuse the templates for the header and the footer in a similar manner.

Completing and Validating the Setup

Once you have created the templates, it's time to create the entry file for your application. We'll create the main.go file for this with the simplest possible web application that will use the index template. We can do this using Gin in four steps:

1. Create the router

The default way to create a router in Gin is as follows:

router := gin.Default()

This creates a router which can be used to define the build of the application.

2. Load the templates

Once you have created the router, you can load all the templates like this:

router.LoadHTMLGlob("templates/*")

This loads all the template files located in the templates folder. Once loaded, these don't have to be read again on every request making Gin web applications very fast.

3. Define the route handler

At the heart of Gin is how you divide the application into various routes and define handlers for each route. We will create a route for the index page and an inline route handler.

router.GET("/", func(c *gin.Context) {

  // Call the HTML method of the Context to render a template
  c.HTML(
      // Set the HTTP status to 200 (OK)
      http.StatusOK,
      // Use the index.html template
      "index.html",
      // Pass the data that the page uses (in this case, 'title')
      gin.H{
          "title": "Home Page",
      },
  )

})

The router.GET method is used to define a route handler for a GET request. It takes in as parameters the route (/) and one or more route handlers which are just functions.

The route handler has a pointer to the context (gin.Context) as its parameter. This context contains all the information about the request that the handler might need to process it. For example, it includes information about the headers, cookies, etc.

The Context also has methods to render a response in HTML, text, JSON and XML formats. In this case, we use the context.HTML method to render an HTML template (index.html). The call to this method includes additional data in which the value of title is set to Home Page. This is a value that the HTML template can make use of. In this case, we use this value in the <title>tag in the header's template.

4. Start the application

To start the application, you can use the Run method of the router:

router.Run()

This starts the application on localhost and serves on the 8080 port by default.

The complete main.go file looks as follows:

// main.go

package main

import (
  "net/http"

  "github.com/gin-gonic/gin"
)

var router *gin.Engine

func main() {

  // Set the router as the default one provided by Gin
  router = gin.Default()

  // Process the templates at the start so that they don't have to be loaded
  // from the disk again. This makes serving HTML pages very fast.
  router.LoadHTMLGlob("templates/*")

  // Define the route for the index page and display the index.html template
  // To start with, we'll use an inline route handler. Later on, we'll create
  // standalone functions that will be used as route handlers.
  router.GET("/", func(c *gin.Context) {

    // Call the HTML method of the Context to render a template
    c.HTML(
      // Set the HTTP status to 200 (OK)
      http.StatusOK,
      // Use the index.html template
      "index.html",
      // Pass the data that the page uses (in this case, 'title')
      gin.H{
        "title": "Home Page",
      },
    )

  })

  // Start serving the application
  router.Run()

}

To execute the application from the command line, go to your application directory and execute the following command:

go build -o app

This will build your application and create an executable named app which you can run as follows:

./app

If all goes well, you should be able to access your application at http://localhost:8080 and it should look like this:

Gin Hello World

The directory structure of your application at this stage should be as follows:

├── main.go
└── templates
    ├── footer.html
    ├── header.html
    ├── index.html
    └── menu.html

results matching ""

    No results matching ""