-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
97 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package templatereloader | ||
|
||
import ( | ||
"html/template" | ||
"io/fs" | ||
"path" | ||
"time" | ||
|
||
"github.com/linkdata/deadlock" | ||
"github.com/linkdata/jaws" | ||
) | ||
|
||
// A TemplateReloader reloads and reparses templates if more than one second | ||
// has passed since the last Lookup. | ||
type TemplateReloader struct { | ||
Path string // the file path we are loading from | ||
mu deadlock.RWMutex | ||
when time.Time | ||
curr *template.Template | ||
} | ||
|
||
// New returns a jaws.TemplateLookuper. | ||
// | ||
// If deadlock.Debug is false, it calls template.New("").ParseFS(fsys, fpath). | ||
// | ||
// If deadlock.Debug is true, fsys is ignored and it returns a TemplateReloader | ||
// that loads the templates using ParseGlob(relpath/fpath). | ||
func New(fsys fs.FS, fpath, relpath string) (jtl jaws.TemplateLookuper, err error) { | ||
return create(deadlock.Debug, fsys, fpath, relpath) | ||
} | ||
|
||
func create(debug bool, fsys fs.FS, fpath, relpath string) (tl jaws.TemplateLookuper, err error) { | ||
if !debug { | ||
return template.New("").ParseFS(fsys, fpath) | ||
} | ||
var tmpl *template.Template | ||
fpath = path.Join(relpath, fpath) | ||
if tmpl, err = template.New("").ParseGlob(fpath); err == nil { | ||
tl = &TemplateReloader{ | ||
Path: fpath, | ||
when: time.Now(), | ||
curr: tmpl, | ||
} | ||
} | ||
return | ||
} | ||
|
||
func (tr *TemplateReloader) Lookup(name string) *template.Template { | ||
tr.mu.RLock() | ||
tl := tr.curr | ||
d := time.Since(tr.when) | ||
tr.mu.RUnlock() | ||
if d > time.Second { | ||
tr.mu.Lock() | ||
defer tr.mu.Unlock() | ||
tr.curr = template.Must(template.New("").ParseGlob(tr.Path)) | ||
tr.when = tr.when.Add(d) | ||
tl = tr.curr | ||
} | ||
return tl.Lookup(name) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package templatereloader | ||
|
||
import ( | ||
"embed" | ||
"testing" | ||
"time" | ||
) | ||
|
||
//go:embed assets | ||
var assetsFS embed.FS | ||
|
||
func TestNew(t *testing.T) { | ||
tl, err := New(assetsFS, "assets/*.html", "") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
tr := tl.(*TemplateReloader) | ||
tr.when = tr.when.Add(-time.Second * 2) | ||
|
||
tmpl := tl.Lookup("test.html") | ||
if tmpl == nil { | ||
t.Fail() | ||
} | ||
} | ||
|
||
func Test_create_no_debug(t *testing.T) { | ||
tl, err := create(false, assetsFS, "assets/*.html", "") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
tmpl := tl.Lookup("test.html") | ||
if tmpl == nil { | ||
t.Fail() | ||
} | ||
} |