Templates within Echo

The Echo framework does provide a facility for custom rendering which is based on the echo.Renderer interface. This interface stipulates that implementations have a method Render which will perform the rendering of data. With this convention, we are able to take what we learned about Go templates and apply those templates to implement a custom echo.Renderer that is capable of rendering HTML templates back to the caller. The following is a very minimal example of an echo.Renderer implementation that we have implemented in $GOPATH/src/github.com/PacktPublishing/Echo-Essentials/chapter8/handlers/reminder.go:

type CustomTemplate struct {
        *template.Template
}

func (ct *CustomTemplate) Render(w io.Writer, name string, data interface{},
        ctx echo.Context) error {
        return ct.ExecuteTemplate(w, name, data)
}

Within this code block, we are creating a CustomTemplate structure which is a template.Template type. Within the Render method, that is required of the echo.Renderer interface, we are performing an execute on the template which is named name with the pipeline of data. Since template.Template is capable of handling multiple named templates, we can parse all of our templates into this structure, and reference them by name in our handler code.

For the purposes of our example, I have moved the template we used from the exploration in the previous section into the handler file located at $GOPATH/src/github.com/PacktPublishing/Echo-Essentials/chapter8/handlers/reminder.go , seen as follows:

const RemindersTmpl = `
<html>
        <head>
                <title>{{.Title}}</title>
        </head>
        <body>
                <table>
                        <th>
                                <td>Reminder Name</td>
                                <td>Reminder ID</td>
                                <td>Reminder Due</td>
                        </th>
                        {{ range .Reminders }}
                        <tr>
                                <td>{{ .Name }}</td>
                                <td>{{ .ID }}</td>
                                <td>{{ .Due }}</td>
                        </tr>
                        {{ else }}
                        <tr>
                                <td colspan=3>No rows!</td>
                        </tr>
                        {{ end }}
        </body>
</html>
`

With this template constant created, and our custom echo.Renderer implemented, we are now able to register our custom echo.Renderer with Echo itself. This is achieved by the following code in $GOPATH/src/github.com/PacktPublishing/Echo-Essentials/chapter8/cmd/service/main.go:

   t, err := template.New("reminders").Parse(handlers.RemindersTmpl)
   if err != nil {
       panic(err.Error())
   }

   e.Renderer = &handlers.CustomTemplate{t}

The preceding code first creates a new html/template.Template instance named reminders and parses our handler's template constant. We then wrap the template in our handlers.CustomTemplate structure which has the echo.Renderer implementation, and assign our echo.Echo instance's Renderer attribute to our custom renderer implementation. At this point, we have all of the scaffolding in place to render a template in our handler code, which can be seen in the following code snippet taken from $GOPATH/src/github.com/PacktPublishing/Echo-Essentials/chapter8/handlers/reminder.go:

func RenderReminders(c echo.Context) error {
        reminders := []Reminder{
                Reminder{
                        ID:   uuid.NewV4(),
                        Name: "Oil Change",
                        Due:  time.Now().Add(30 * 3 * 24 * time.Hour),
                },
                Reminder{
                        ID:   uuid.NewV4(),
                        Name: "Birthday Party",
                        Due:  mustTime(time.Parse("2006-01-02", "2020-01-01")),
                },
        }

        tmplData := struct {
                Reminders []Reminder
                Title     string
        }{reminders, "Reminders Page"}

        return c.Render(http.StatusOK, "reminders", tmplData)
}

Within our handler, we are creating two reminders, putting these reminders into a template data structure, and then calling c.Render. The arguments to c.Render are the response status code, then the name of the template to render, and then the template data to populate the template with. When exercised by calling this handler, we get the following populated template rendered back to the caller:

<html>
        <head>
                <title>Reminders Page</title>
        </head>
        <body>
                <table>
                        <th>
                                <td>Reminder Name</td>
                                <td>Reminder ID</td>
                                <td>Reminder Due</td>
                        </th>
                        
                        <tr>
                                <td>Oil Change</td>
                                <td>1c37a3b7-04b6-4920-bd69-ff591ed13cb8</td>
                                <td>2018-07-24 09:11:29.038822676 -0400 EDT m=+7776004.143317695</td>
                        </tr>
                        
                        <tr>
                                <td>Birthday Party</td>
                                <td>f729272f-aecb-4a84-9909-53cbdf5d5af2</td>
                                <td>2020-01-01 00:00:00 +0000 UTC</td>
                        </tr>
                        
        </body>
</html>

As you can see, implementing templates within your Echo project is very simple. There are few moving parts and only one interface to implement (echo.Renderer) in order to produce template-driven renderings to your callers. When married to the functionality of the html/template and text/template capabilities built into the Go standard library, you will be able to produce server-rendered templates very easily. Within the next section, we will discuss how to reach back into Echo from templates.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.218.157