Support FixedIndent, add tests
This commit is contained in:
parent
5b7e923bd8
commit
c9c7dd1b22
@ -16,11 +16,12 @@ type Hash map[string]interface{}
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
type TemplateNest struct {
|
||||
@ -118,6 +119,7 @@ func (nest *TemplateNest) index(filePath string) (TemplateFileIndex, error) {
|
||||
if err != nil {
|
||||
return TemplateFileIndex{}, fmt.Errorf("error reading file (`%s`): %w", filePath, err)
|
||||
}
|
||||
|
||||
// Capture last modified time
|
||||
fileInfo, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
@ -134,6 +136,7 @@ func (nest *TemplateNest) index(filePath string) (TemplateFileIndex, error) {
|
||||
"%s\\s*(.+?)\\s*%s", regexp.QuoteMeta(delimiterStart), regexp.QuoteMeta(delimiterEnd),
|
||||
))
|
||||
|
||||
contentsStr := string(contents)
|
||||
matches := re.FindAllStringSubmatchIndex(string(contents), -1)
|
||||
for _, match := range matches {
|
||||
if len(match) < 4 {
|
||||
@ -148,15 +151,33 @@ func (nest *TemplateNest) index(filePath string) (TemplateFileIndex, error) {
|
||||
varName := string(contents[nameStartIdx:nameEndIdx])
|
||||
variableNames[varName] = struct{}{}
|
||||
|
||||
// If fixed indent is enabled then record the indent level for this
|
||||
// variable. To get the indent level we look at each character in
|
||||
// reverse from the start position of the variable until we find a
|
||||
// newline character.
|
||||
indentLevel := 0
|
||||
if nest.option.FixedIndent {
|
||||
// If we do not encounter a newline then that means this variable is
|
||||
// on the first line, we take the start position as the indent
|
||||
// level.
|
||||
lineStartIdx := strings.LastIndex(contentsStr[:startIdx], "\n")
|
||||
if lineStartIdx == -1 {
|
||||
indentLevel = startIdx
|
||||
} else {
|
||||
indentLevel = startIdx - lineStartIdx - 1
|
||||
}
|
||||
}
|
||||
|
||||
variables = append(variables, TemplateFileVariable{
|
||||
Name: varName,
|
||||
StartPosition: uint(startIdx),
|
||||
EndPosition: uint(endIdx),
|
||||
IndentLevel: uint(indentLevel),
|
||||
})
|
||||
}
|
||||
|
||||
fileIndex := TemplateFileIndex{
|
||||
Contents: string(contents),
|
||||
Contents: contentsStr,
|
||||
LastModified: fileInfo.ModTime(),
|
||||
VariableNames: variableNames,
|
||||
Variables: variables,
|
||||
@ -261,15 +282,17 @@ func (nest *TemplateNest) Render(toRender interface{}) (string, error) {
|
||||
replacement := ""
|
||||
|
||||
if value, exists := v[variable.Name]; exists {
|
||||
if text, ok := value.(string); ok {
|
||||
replacement = text
|
||||
} else {
|
||||
subRender, err := nest.Render(value)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
replacement = subRender
|
||||
|
||||
if nest.option.FixedIndent && variable.IndentLevel != 0 {
|
||||
indentReplacement := "\n" + strings.Repeat(" ", int(variable.IndentLevel))
|
||||
subRender = strings.ReplaceAll(subRender, "\n", indentReplacement)
|
||||
}
|
||||
|
||||
replacement = subRender
|
||||
}
|
||||
|
||||
// Replace in rendered template
|
||||
|
92
tests/05_fixed_indent_test.go
Normal file
92
tests/05_fixed_indent_test.go
Normal file
@ -0,0 +1,92 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"git.virtual.blue/tomgracey/template-nest-go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestRenderSimplePageWithFixedIndent(t *testing.T) {
|
||||
nest, err := templatenest.New(templatenest.Option{
|
||||
TemplateDir: "templates",
|
||||
FixedIndent: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to initialize TemplateNest: %+v", err)
|
||||
}
|
||||
|
||||
page := templatenest.Hash{
|
||||
"TEMPLATE": "00-simple-page",
|
||||
"variable": "Simple Variable",
|
||||
"simple_component": templatenest.Hash{
|
||||
"TEMPLATE": "02-simple-component-multi-line",
|
||||
},
|
||||
}
|
||||
outputPage := templatenest.Hash{"TEMPLATE": "output/07-simple-page-fixed-indent"}
|
||||
|
||||
render := nest.MustRender(page)
|
||||
outputRender := nest.MustRender(outputPage)
|
||||
|
||||
assert.Equal(t, outputRender, render, "Rendered output does not match expected output")
|
||||
}
|
||||
|
||||
func TestRenderComplexPageWithFixedIndent(t *testing.T) {
|
||||
nest, err := templatenest.New(templatenest.Option{
|
||||
TemplateDir: "templates",
|
||||
FixedIndent: true,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to initialize TemplateNest: %+v", err)
|
||||
}
|
||||
|
||||
page := templatenest.Hash{
|
||||
"TEMPLATE": "10-complex-page",
|
||||
"title": "Complex Page",
|
||||
"pre_body": templatenest.Hash{
|
||||
"TEMPLATE": "18-styles",
|
||||
},
|
||||
"navigation": templatenest.Hash{
|
||||
"TEMPLATE": "11-navigation",
|
||||
"banner": templatenest.Hash{
|
||||
"TEMPLATE": "12-navigation-banner",
|
||||
},
|
||||
"items": []templatenest.Hash{
|
||||
templatenest.Hash{"TEMPLATE": "13-navigation-item-00-services"},
|
||||
templatenest.Hash{"TEMPLATE": "13-navigation-item-01-resources"},
|
||||
},
|
||||
},
|
||||
"hero_section": templatenest.Hash{
|
||||
"TEMPLATE": "14-hero-section",
|
||||
},
|
||||
"main_content": []templatenest.Hash{
|
||||
templatenest.Hash{"TEMPLATE": "15-isdc-card"},
|
||||
templatenest.Hash{
|
||||
"TEMPLATE": "16-vb-brand-cards",
|
||||
"cards": []templatenest.Hash{
|
||||
templatenest.Hash{
|
||||
"TEMPLATE": "17-vb-brand-card-00",
|
||||
"parent_classes": "p-card brand-card col-4",
|
||||
},
|
||||
templatenest.Hash{
|
||||
"TEMPLATE": "17-vb-brand-card-01",
|
||||
"parent_classes": "p-card brand-card col-4",
|
||||
},
|
||||
templatenest.Hash{
|
||||
"TEMPLATE": "17-vb-brand-card-02",
|
||||
"parent_classes": "p-card brand-card col-4",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"post_footer": templatenest.Hash{
|
||||
"TEMPLATE": "19-scripts",
|
||||
},
|
||||
}
|
||||
|
||||
outputPage := templatenest.Hash{"TEMPLATE": "output/08-complex-page-fixed-indent"}
|
||||
|
||||
render := nest.MustRender(page)
|
||||
outputRender := nest.MustRender(outputPage)
|
||||
|
||||
assert.Equal(t, outputRender, render, "Rendered output does not match expected output")
|
||||
}
|
Loading…
Reference in New Issue
Block a user