diff --git a/controller/controller.go b/controller/controller.go
index 000b938..53a0c6e 100644
--- a/controller/controller.go
+++ b/controller/controller.go
@@ -131,11 +131,12 @@ func (t *Controller) cachePage(c echo.Context, p Page, html *bytes.Buffer) {
// 1. The layout/based template specified in Page.Layout
// 2. The content template specified in Page.Name
// 3. All templates within the components directory
+// Also included is the function map provided by the funcmap package
func (t *Controller) parsePageTemplates(p Page) error {
// Check if the template has not yet been parsed or if the app environment is local, so that templates reflect
// changes without having the restart the server
if _, ok := templates.Load(p.Name); !ok || t.Container.Config.App.Environment == config.EnvLocal {
- // Parse the Layout and Name templates
+ // Parse the Layout and Name templates along with the function map
parsed, err :=
template.New(p.Layout+config.TemplateExt).
Funcs(funcMap).
diff --git a/funcmap/funcmap.go b/funcmap/funcmap.go
index f032553..e847b11 100644
--- a/funcmap/funcmap.go
+++ b/funcmap/funcmap.go
@@ -12,14 +12,19 @@ import (
"github.com/labstack/gommon/random"
)
-// CacheKey stores a random string used as a cache key for static files
-var CacheKey = random.String(10)
+var (
+ // CacheBuster stores a random string used as a cache buster for static files.
+ CacheBuster = random.String(10)
+)
+// GetFuncMap provides a template function map
func GetFuncMap() template.FuncMap {
// See http://masterminds.github.io/sprig/ for available funcs
funcMap := sprig.FuncMap()
// Provide a list of custom functions
+ // Expand this as you add more functions to this package
+ // Avoid using a name already in use by sprig
f := template.FuncMap{
"hasField": HasField,
"file": File,
@@ -45,11 +50,12 @@ func HasField(v interface{}, name string) bool {
return rv.FieldByName(name).IsValid()
}
-// File appends a cache key to a given filepath so it can remain cached until the app is restarted
+// File appends a cache buster to a given filepath so it can remain cached until the app is restarted
func File(filepath string) string {
- return fmt.Sprintf("/%s/%s?v=%s", config.StaticPrefix, filepath, CacheKey)
+ return fmt.Sprintf("/%s/%s?v=%s", config.StaticPrefix, filepath, CacheBuster)
}
+// Link outputs HTML for a link element, providing the ability to dynamically set the active class
func Link(url, text, currentPath string, classes ...string) template.HTML {
if currentPath == url {
classes = append(classes, "is-active")
diff --git a/funcmap/funcmap_test.go b/funcmap/funcmap_test.go
new file mode 100644
index 0000000..8c27005
--- /dev/null
+++ b/funcmap/funcmap_test.go
@@ -0,0 +1,39 @@
+package funcmap
+
+import (
+ "fmt"
+ "testing"
+
+ "goweb/config"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestHasField(t *testing.T) {
+ type example struct {
+ name string
+ }
+ var e example
+ assert.True(t, HasField(e, "name"))
+ assert.False(t, HasField(e, "abcd"))
+}
+
+func TestLink(t *testing.T) {
+ link := string(Link("/abc", "Text", "/abc"))
+ expected := `Text`
+ assert.Equal(t, expected, link)
+
+ link = string(Link("/abc", "Text", "/abc", "first", "second"))
+ expected = `Text`
+ assert.Equal(t, expected, link)
+
+ link = string(Link("/abc", "Text", "/def"))
+ expected = `Text`
+ assert.Equal(t, expected, link)
+}
+
+func TestGetFuncMap(t *testing.T) {
+ file := File("test.png")
+ expected := fmt.Sprintf("/%s/test.png?v=%s", config.StaticPrefix, CacheBuster)
+ assert.Equal(t, expected, file)
+}