go 56 lines · 8 steps

Rendering HTML pages with Gin handlers

Two Gin handlers fetch data through a repository and render templates, with graceful error pages when something fails.

Explained by highlit
1package handlers
2 
3import (
4 "net/http"
5 "time"
6 
7 "github.com/gin-gonic/gin"
8)
9 
10type ArticleHandler struct {
11 Articles ArticleRepository
12}
13 
14func (h *ArticleHandler) Index(c *gin.Context) {
15 articles, err := h.Articles.Recent(c.Request.Context(), 20)
16 if err != nil {
17 c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{
18 "title": "Something went wrong",
19 "message": "We couldn't load the articles right now.",
20 })
21 return
22 }
23 
24 c.HTML(http.StatusOK, "articles/index.tmpl", gin.H{
25 "title": "Latest Articles",
26 "articles": articles,
27 "year": time.Now().Year(),
28 "flash": flashFrom(c),
29 })
30}
31 
32func (h *ArticleHandler) Show(c *gin.Context) {
33 article, err := h.Articles.BySlug(c.Request.Context(), c.Param("slug"))
34 if err != nil {
35 c.HTML(http.StatusNotFound, "error.tmpl", gin.H{
36 "title": "Not found",
37 "message": "That article has wandered off.",
38 })
39 return
40 }
41 
42 c.HTML(http.StatusOK, "articles/show.tmpl", gin.H{
43 "title": article.Title,
44 "article": article,
45 "year": time.Now().Year(),
46 })
47}
48 
49func flashFrom(c *gin.Context) string {
50 if v, ok := c.Get("flash"); ok {
51 if s, ok := v.(string); ok {
52 return s
53 }
54 }
55 return ""
56}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Holding a repository on the handler struct keeps data access injectable and testable instead of hard-wired.
  2. 2Checking the error before rendering lets each failure return its own status code and friendly page.
  3. 3A small helper that type-asserts context values isolates fragile lookups so handlers stay readable.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Rendering HTML pages with Gin handlers — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code