100 lines
1.8 KiB
Markdown
100 lines
1.8 KiB
Markdown
# Template loader
|
|
|
|
TL works like template.Glob(), but has a few improvements:
|
|
|
|
1. TL loads templates from nested directories.
|
|
2. TL uses relative file path as a template name to avoid collisions.
|
|
3. Optional prefix may be added to a template name.
|
|
4. TL supports shared templates.
|
|
|
|
|
|
## Example
|
|
|
|
- Project structure:
|
|
|
|
```
|
|
.
|
|
├── main.go
|
|
└── templates
|
|
├── icons
|
|
│ └── material
|
|
│ └── favicon.svg
|
|
├── layouts
|
|
│ └── base.html
|
|
└── pages
|
|
└── index.html
|
|
```
|
|
|
|
- main.go:
|
|
|
|
```go
|
|
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"log/slog"
|
|
"os"
|
|
|
|
"code.app-house.ru/go/tl"
|
|
)
|
|
|
|
func main() {
|
|
templates, err := tl.LoadWithOptions(
|
|
// Main templates.
|
|
tl.Collection{
|
|
RootDir: "templates/pages",
|
|
},
|
|
tl.Options{
|
|
SharedCollections: []tl.Collection{
|
|
tl.Collection{
|
|
RootDir: "templates/layouts",
|
|
Prefix: "layouts", // template name prefix, may be omitted.
|
|
},
|
|
tl.Collection{
|
|
RootDir: "templates/icons",
|
|
Prefix: "icons",
|
|
},
|
|
// you can add other collections (e.g. snippets, components...)
|
|
},
|
|
},
|
|
)
|
|
if err != nil {
|
|
slog.Error("can't load templates", "err", err)
|
|
os.Exit(-1)
|
|
}
|
|
|
|
w := bufio.NewWriter(os.Stdout)
|
|
err = templates["index.html"].Execute(w, nil)
|
|
if err != nil {
|
|
slog.Error("can't execute index.html", "err", err)
|
|
os.Exit(-1)
|
|
}
|
|
w.Flush()
|
|
}
|
|
```
|
|
|
|
- layouts/base.html:
|
|
|
|
```html
|
|
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
</head>
|
|
<body>
|
|
{{ block "main" . }}{{ end }}
|
|
</body>
|
|
</html>
|
|
```
|
|
|
|
- pages/index.html:
|
|
|
|
```html
|
|
{{ template "layouts/base.html" . }}
|
|
|
|
{{ define "main" }}
|
|
{{ template "icons/material/favicon.svg" . }}
|
|
<h1>Index</h1>
|
|
{{ end }}
|
|
```
|