LogoPly
Features

Templates

Render HTML templates with html/template.

Templates

Load a directory of .html templates at startup and render them with c.HTML.

app := ply.New()
app.Templates("./templates")

app.Get("/", func(c *core.Context) {
	c.HTML(200, "index.html", map[string]any{
		"Title": "Ply",
		"Items": []string{"one", "two"},
	})
})

How loading works

app.Templates(dir) walks the directory recursively. For every .html file it:

  1. computes the path relative to dir,
  2. converts the path to forward slashes,
  3. parses the file as a template with that relative path as its name.

A file at templates/pages/index.html is available as pages/index.html:

c.HTML(200, "pages/index.html", data)

Loading happens once. Changes to template files require a restart. A read or parse error causes Templates to panic, so load it during startup and let the process fail early.

Template example

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>{{ .Title }}</title>
  </head>
  <body>
    <h1>{{ .Title }}</h1>
    <ul>
      {{ range .Items }}
      <li>{{ . }}</li>
      {{ end }}
    </ul>
  </body>
</html>

html/template escapes values according to their HTML context. Do not cast user input to template.HTML unless it has been sanitized.

Layouts

Use named templates to share a layout:

{{ define "layout" }}
<!doctype html>
<html>
  <body>{{ template "content" . }}</body>
</html>
{{ end }}
{{ define "content" }}
<h1>{{ .Title }}</h1>
{{ end }}

Parse order does not matter. The names come from the define blocks.

Errors

c.HTML returns 500 with a plain text message when:

  • no templates are loaded,
  • the named template does not exist,
  • execution fails.

In production, log the full error on the server and return a generic error page to the client.

Notes

  • Templates are parsed from disk. They are not embedded in the binary.
  • The directory must exist and be readable by the process.
  • Do not load templates per request. Parse once during startup.
  • Rendering happens inside a normal handler, so app.Use middleware applies.