Generate an index of the recipes
This commit is contained in:
parent
482859f212
commit
055358f2db
5 changed files with 42 additions and 3 deletions
|
@ -11,7 +11,7 @@ A simple CLI tool to generate a static website from a
|
||||||
- [ ] Improve the steps rendering logic to avoid doing all of it
|
- [ ] Improve the steps rendering logic to avoid doing all of it
|
||||||
inside a template function.
|
inside a template function.
|
||||||
- [X] Add image support for steps and the recipe.
|
- [X] Add image support for steps and the recipe.
|
||||||
- [ ] Add an `index.html` file that lists all the recipes.
|
- [X] Add an `index.html` file that lists all the recipes.
|
||||||
- [X] Embed the default `style.css` file.
|
- [X] Embed the default `style.css` file.
|
||||||
- [ ] Add command to copy the embedded templates to an external
|
- [ ] Add command to copy the embedded templates to an external
|
||||||
directory.
|
directory.
|
||||||
|
|
1
cmd.go
1
cmd.go
|
@ -4,6 +4,7 @@ type generateCmd struct {
|
||||||
Path string `arg:"" help:"Path to the directory with the recipes."`
|
Path string `arg:"" help:"Path to the directory with the recipes."`
|
||||||
Output string `default:"dist" help:"Path to the directory where the files will be generated."`
|
Output string `default:"dist" help:"Path to the directory where the files will be generated."`
|
||||||
NameKey string `default:"name" short:"n" help:"The metadata key for the recipe name."`
|
NameKey string `default:"name" short:"n" help:"The metadata key for the recipe name."`
|
||||||
|
Title string `default:"Recipes directory" short:"t" help:"The title to use at the recipe index."`
|
||||||
}
|
}
|
||||||
|
|
||||||
var cli struct {
|
var cli struct {
|
||||||
|
|
|
@ -27,6 +27,11 @@ const (
|
||||||
timerSuffix = "</span>"
|
timerSuffix = "</span>"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type RecipeFile struct {
|
||||||
|
Name string
|
||||||
|
Path string
|
||||||
|
}
|
||||||
|
|
||||||
//go:embed templates
|
//go:embed templates
|
||||||
var embedTmpl embed.FS
|
var embedTmpl embed.FS
|
||||||
var imageExtensions = []string{".jpg", ".jpeg", ".png"}
|
var imageExtensions = []string{".jpg", ".jpeg", ".png"}
|
||||||
|
@ -191,6 +196,7 @@ func (g *generateCmd) Run() error {
|
||||||
return fmt.Errorf("cannot create directory on path %q: %w", g.Output, err)
|
return fmt.Errorf("cannot create directory on path %q: %w", g.Output, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
recipeFiles := []*RecipeFile{}
|
||||||
walkErr := filepath.WalkDir(g.Path, func(path string, d fs.DirEntry, err error) error {
|
walkErr := filepath.WalkDir(g.Path, func(path string, d fs.DirEntry, err error) error {
|
||||||
slog.Debug("Walking through file", "path", path)
|
slog.Debug("Walking through file", "path", path)
|
||||||
|
|
||||||
|
@ -248,7 +254,9 @@ func (g *generateCmd) Run() error {
|
||||||
recipeName = name
|
recipeName = name
|
||||||
}
|
}
|
||||||
|
|
||||||
recipeDistPath := filepath.Join(g.Output, filepath.Dir(relpath), fmt.Sprintf("%s.html", filenameWithoutExt))
|
htmlPath := filepath.Join(filepath.Dir(relpath), fmt.Sprintf("%s.html", filenameWithoutExt))
|
||||||
|
recipeFiles = append(recipeFiles, &RecipeFile{Name: recipeName, Path: htmlPath})
|
||||||
|
recipeDistPath := filepath.Join(g.Output, htmlPath)
|
||||||
data := map[string]any{"name": recipeName, "recipe": recipe, "path": path, "relpath": getRelpath(relpath)}
|
data := map[string]any{"name": recipeName, "recipe": recipe, "path": path, "relpath": getRelpath(relpath)}
|
||||||
slog.Debug("Executing template", "recipeName", recipeName, "recipeWebPath", recipeDistPath)
|
slog.Debug("Executing template", "recipeName", recipeName, "recipeWebPath", recipeDistPath)
|
||||||
if err := executeTemplateToFile("recipe", data, recipeDistPath); err != nil {
|
if err := executeTemplateToFile("recipe", data, recipeDistPath); err != nil {
|
||||||
|
@ -261,6 +269,7 @@ func (g *generateCmd) Run() error {
|
||||||
return fmt.Errorf("error while walking directory %q: %w", g.Path, walkErr)
|
return fmt.Errorf("error while walking directory %q: %w", g.Path, walkErr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy styles
|
||||||
styleFile, err := embedTmpl.Open(filepath.Join("templates", "style.css"))
|
styleFile, err := embedTmpl.Open(filepath.Join("templates", "style.css"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot read style.css embed file: %w", err)
|
return fmt.Errorf("cannot read style.css embed file: %w", err)
|
||||||
|
@ -270,5 +279,13 @@ func (g *generateCmd) Run() error {
|
||||||
return fmt.Errorf("cannot copy style.css: %w", err)
|
return fmt.Errorf("cannot copy style.css: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// generate index
|
||||||
|
data := map[string]any{"title": g.Title, "recipes": recipeFiles}
|
||||||
|
indexpath := filepath.Join(g.Output, "index.html")
|
||||||
|
slog.Debug("Executing index template", "title", g.Title, "recipes", len(recipeFiles), "indexpath", indexpath)
|
||||||
|
if err := executeTemplateToFile("index", data, indexpath); err != nil {
|
||||||
|
return fmt.Errorf("cannot execute template \"index\" to file %q: %w", indexpath, err)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
21
templates/index.html.tmpl
Normal file
21
templates/index.html.tmpl
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<title>{{.title}}</title>
|
||||||
|
<link rel="icon" type="image/png" href="{{.relpath}}favicon.png" />
|
||||||
|
<link rel="stylesheet" type="text/css" href="{{.relpath}}style.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>{{.title}}</h1>
|
||||||
|
|
||||||
|
{{if ne (len .recipes) 0}}
|
||||||
|
<ul>
|
||||||
|
{{range .recipes}}
|
||||||
|
<li><a href="{{.Path}}">{{.Name}}</a></li>
|
||||||
|
{{end}}
|
||||||
|
</ul>
|
||||||
|
{{end}}
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -10,7 +10,7 @@ body {
|
||||||
|
|
||||||
.cookware {
|
.cookware {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: red;
|
color: brown;
|
||||||
}
|
}
|
||||||
|
|
||||||
.timer {
|
.timer {
|
||||||
|
|
Loading…
Reference in a new issue