Files
donniemarko/internal/render/render.go
adminoo b571588b15 feat(release): v0.2.0
commit 78d6c27c8940da32a6de8e64327c86f74fdaa2eb
Author: adminoo <git@kadath.corp>
Date:   Wed Feb 4 12:59:22 2026 +0100

    feat: freebsd log rotation config thingie

commit 55af4e6c70122e679272ed247c26e04b1247f694
Author: adminoo <git@kadath.corp>
Date:   Wed Feb 4 12:58:43 2026 +0100

    feat: embed templates, static resolution

commit 29c917f929a7378ec29c54315ee2e9f420747787
Author: adminoo <git@kadath.corp>
Date:   Wed Feb 4 10:44:34 2026 +0100

    feat: set log file path

commit 294fd3d1549979eab63587ceec6ff5d0978e9afc
Author: adminoo <git@kadath.corp>
Date:   Wed Feb 4 10:23:53 2026 +0100

    feat: logging HTTP request

commit c9ae80b240d58e1abed7ae3b7b2c3b283a31f1a1
Author: adminoo <git@kadath.corp>
Date:   Wed Feb 4 09:54:05 2026 +0100

    feat: freebsd-specific compile target and scripts

commit 86ca154dedd19aa1fe5f571c445dcf17a8396bfa
Author: adminoo <git@kadath.corp>
Date:   Wed Feb 4 09:25:16 2026 +0100

    feat: mobile friendly CSS

commit 199f4319e0b08a4b6d595d7eb3effb6db6c7beec
Author: adminoo <git@kadath.corp>
Date:   Wed Feb 4 09:25:03 2026 +0100

    feat: persisting rendered note

commit 865e258237e45d7c542685a4653bcad3c5af259d
Author: adminoo <git@kadath.corp>
Date:   Wed Feb 4 08:06:38 2026 +0100

    fix: grouping notes by folder

commit 242d1d074c92461f38212b033c7a9e383f9dc550
Author: adminoo <git@kadath.corp>
Date:   Tue Feb 3 16:52:50 2026 +0100

    feat: storage layer logic

    - Prune notes from db not matching current folder structure at start
    - Detect file system deletion on start by comparing in-db notes
    - Prevent updating of in-db notes at start if modification time is not
      newer
    - Delete by path

commit d75d46bc1ab22bd990d0fdc307e571fe52f0dd99
Author: adminoo <git@kadath.corp>
Date:   Tue Feb 3 15:27:07 2026 +0100

    feat: group notes by root folders

commit e1e25a938e717599332f7b40a449d9bb854b673a
Author: adminoo <git@kadath.corp>
Date:   Tue Feb 3 14:24:37 2026 +0100

    feat: size in kilobytes

commit 61220272a2df2b66c2b8e356ba359ed01de3bd12
Author: adminoo <git@kadath.corp>
Date:   Tue Feb 3 14:19:40 2026 +0100

    feat: styling inputs
2026-02-04 13:17:16 +01:00

123 lines
2.8 KiB
Go

package render
import (
"fmt"
"html/template"
"io/fs"
"net/http"
"os"
"path/filepath"
"sync"
"github.com/russross/blackfriday/v2"
)
type TemplateData struct {
Name string
FileNameSet []string
}
type TemplateManager struct {
templates map[string]*template.Template
mu sync.RWMutex
basePath string
devMode bool
fs fs.FS
}
func NewTemplateManager(basePath string) *TemplateManager {
return NewTemplateManagerFS(os.DirFS("."), basePath)
}
func NewTemplateManagerFS(fsys fs.FS, basePath string) *TemplateManager {
return &TemplateManager{
templates: make(map[string]*template.Template),
basePath: basePath,
devMode: false,
fs: fsys,
}
}
func (tm *TemplateManager) buildTemplatePath(name string) string {
return filepath.Join(tm.basePath, name+".tmpl")
}
func (tm *TemplateManager) GetTemplate(td *TemplateData) (*template.Template, error) {
// Skip cache in dev mode
if !tm.devMode {
tm.mu.RLock()
if tmpl, exists := tm.templates[td.Name]; exists {
tm.mu.RUnlock()
return tmpl, nil
}
tm.mu.RUnlock()
}
// Build file paths
var files []string
for _, file := range td.FileNameSet {
files = append(files, tm.buildTemplatePath(file))
}
// Parse template
tmpl, err := template.ParseFS(tm.fs, files...)
if err != nil {
return nil, fmt.Errorf("parse template %s: %w", td.Name, err)
}
// Cache it (unless in dev mode)
if !tm.devMode {
tm.mu.Lock()
tm.templates[td.Name] = tmpl
tm.mu.Unlock()
}
return tmpl, nil
}
func (tm *TemplateManager) Render(w http.ResponseWriter, name string, data any) error {
// Build the template files - include all necessary templates
var files []string
// Always include base template
files = append(files, tm.buildTemplatePath("base"))
// Include noteList template (used by index)
files = append(files, tm.buildTemplatePath("noteList"))
// Include metadata template (used by index)
files = append(files, tm.buildTemplatePath("metadata"))
// Include metadata template
files = append(files, tm.buildTemplatePath("metadata"))
// Add the specific template
files = append(files, tm.buildTemplatePath(name))
// Parse templates
tmpl, err := template.ParseFS(tm.fs, files...)
if err != nil {
return fmt.Errorf("parse template %s: %w", name, err)
}
// Set content type
w.Header().Set("Content-Type", "text/html; charset=utf-8")
err = tmpl.ExecuteTemplate(w, "base", data)
if err != nil {
return fmt.Errorf("execute template %s: %w", name, err)
}
return nil
}
// Render markdown to HTML with target="_blank" on links
func RenderMarkdown(content []byte) (template.HTML, error) {
renderer := blackfriday.NewHTMLRenderer(blackfriday.HTMLRendererParameters{
Flags: blackfriday.CommonHTMLFlags | blackfriday.HrefTargetBlank,
})
html := blackfriday.Run(content, blackfriday.WithRenderer(renderer))
return template.HTML(html), nil
}