Support defaults, add tests
This commit is contained in:
parent
decc220bfc
commit
0acc608e47
@ -14,15 +14,18 @@ type Hash map[string]interface{}
|
||||
|
||||
// Option holds configuration for TemplateNest
|
||||
type Option struct {
|
||||
Delimiters [2]string
|
||||
NameLabel string // Identify the template to be used
|
||||
TemplateDir string // Directory where templates are located
|
||||
TemplateExtension string // Appended on the label to idenfity the template
|
||||
DieOnBadParams bool // Attempt to populate a variable that doesn't exist should result in an error
|
||||
ShowLabels bool // Prepend & Append a string to every template, helpful in debugging
|
||||
CommentDelimiters [2]string // Used in conjunction with ShowLabels, if HTML then use '<!--', '-->'
|
||||
FixedIndent bool // Intended to improve readability when inspecting nested templates
|
||||
TokenEscapeChar string // Escapes a token delimiter, i.e. if set to '\' then variables that have '\' prefix won't be replaced
|
||||
Delimiters [2]string
|
||||
NameLabel string // Identify the template to be used
|
||||
TemplateDir string // Directory where templates are located
|
||||
TemplateExtension string // Appended on the label to idenfity the template
|
||||
DieOnBadParams bool // Attempt to populate a variable that doesn't exist should result in an error
|
||||
ShowLabels bool // Prepend & Append a string to every template, helpful in debugging
|
||||
CommentDelimiters [2]string // Used in conjunction with ShowLabels, if HTML then use '<!--', '-->'
|
||||
FixedIndent bool // Intended to improve readability when inspecting nested templates
|
||||
TokenEscapeChar string // Escapes a token delimiter, i.e. if set to '\' then variables that have '\' prefix won't be replaced
|
||||
DefaultsNamespaceChar string
|
||||
Defaults Hash // Provide a hash of default values that are substituted if template hash does not provide a value
|
||||
defaultsFlat Hash
|
||||
}
|
||||
|
||||
type TemplateNest struct {
|
||||
@ -73,6 +76,14 @@ func New(opts Option) (*TemplateNest, error) {
|
||||
if opts.TemplateExtension == "" {
|
||||
opts.TemplateExtension = "html"
|
||||
}
|
||||
if opts.DefaultsNamespaceChar == "" {
|
||||
opts.DefaultsNamespaceChar = "."
|
||||
}
|
||||
if opts.Defaults == nil {
|
||||
opts.Defaults = make(map[string]interface{})
|
||||
}
|
||||
|
||||
opts.defaultsFlat = FlattenMap(opts.Defaults, "", opts.DefaultsNamespaceChar)
|
||||
|
||||
// Initialize TemplateNest with the final options.
|
||||
nest := &TemplateNest{
|
||||
@ -115,6 +126,28 @@ func New(opts Option) (*TemplateNest, error) {
|
||||
return nest, nil
|
||||
}
|
||||
|
||||
// FlattenMap flattens a nested map[string]interface{} into a flat map with
|
||||
// dot-separated keys.
|
||||
func FlattenMap(input Hash, parentKey string, separator string) Hash {
|
||||
result := make(map[string]interface{})
|
||||
for key, value := range input {
|
||||
fullKey := key
|
||||
if parentKey != "" {
|
||||
fullKey = parentKey + separator + key
|
||||
}
|
||||
|
||||
// Check if the value is a nested map
|
||||
if nestedMap, ok := value.(Hash); ok {
|
||||
for k, v := range FlattenMap(nestedMap, fullKey, separator) {
|
||||
result[k] = v
|
||||
}
|
||||
} else {
|
||||
result[fullKey] = value
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func (nest *TemplateNest) index(filePath string) (TemplateFileIndex, error) {
|
||||
contents, err := ioutil.ReadFile(filePath)
|
||||
if err != nil {
|
||||
@ -303,7 +336,14 @@ func (nest *TemplateNest) Render(toRender interface{}) (string, error) {
|
||||
// with an empty string.
|
||||
replacement := ""
|
||||
|
||||
if value, exists := v[variable.Name]; exists {
|
||||
value, exists := v[variable.Name]
|
||||
defaultValue, defaultExists := nest.option.defaultsFlat[variable.Name]
|
||||
|
||||
if exists || defaultExists {
|
||||
if !exists {
|
||||
value = defaultValue
|
||||
}
|
||||
|
||||
subRender, err := nest.Render(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
51
tests/08_defaults_test.go
Normal file
51
tests/08_defaults_test.go
Normal file
@ -0,0 +1,51 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"git.virtual.blue/tomgracey/template-nest-go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRenderWithDefaults(t *testing.T) {
|
||||
nest, err := templatenest.New(templatenest.Option{
|
||||
TemplateDir: "templates",
|
||||
Defaults: templatenest.Hash{
|
||||
"variable": "Simple Variable",
|
||||
"space": templatenest.Hash{
|
||||
"inside": "A variable inside a space.",
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to initialize TemplateNest: %+v", err)
|
||||
}
|
||||
|
||||
page := templatenest.Hash{
|
||||
"TEMPLATE": "00-simple-page",
|
||||
"simple_component": []templatenest.Hash{
|
||||
templatenest.Hash{
|
||||
"TEMPLATE": "01-simple-component",
|
||||
"variable": "Simple Variable in Simple Component",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
outputPage := templatenest.Hash{"TEMPLATE": "output/01-simple-page"}
|
||||
|
||||
assert.Equal(
|
||||
t,
|
||||
nest.MustRender(outputPage),
|
||||
nest.MustRender(page),
|
||||
"Rendered output does not match expected output",
|
||||
)
|
||||
|
||||
spacePage := templatenest.Hash{"TEMPLATE": "03-namespace-page"}
|
||||
spaceOutputPage := templatenest.Hash{"TEMPLATE": "output/11-namespace-page"}
|
||||
|
||||
assert.Equal(
|
||||
t,
|
||||
nest.MustRender(spaceOutputPage),
|
||||
nest.MustRender(spacePage),
|
||||
"Rendered output does not match expected output",
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue
Block a user