summaryrefslogtreecommitdiffstats
path: root/tpl
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-03-19 21:09:31 +0100
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-03-27 15:43:56 +0200
commitbaa29f6534fcd324dbade7dd6c32c90547e3fa4f (patch)
tree71a7524c25365cfc4a7cc1bbaab9d63988525d5e /tpl
parentc7c6b47ba8bb098cf9fac778f7818afba40a1e2f (diff)
output: Rework the base template logic
Extract the logic to a testable function and add support for custom output types. Fixes #2995
Diffstat (limited to 'tpl')
-rw-r--r--tpl/tplimpl/template.go117
1 files changed, 34 insertions, 83 deletions
diff --git a/tpl/tplimpl/template.go b/tpl/tplimpl/template.go
index b625f570b..bf4587e8e 100644
--- a/tpl/tplimpl/template.go
+++ b/tpl/tplimpl/template.go
@@ -14,7 +14,6 @@
package tplimpl
import (
- "fmt"
"html/template"
"io"
"os"
@@ -28,6 +27,7 @@ import (
bp "github.com/spf13/hugo/bufferpool"
"github.com/spf13/hugo/deps"
"github.com/spf13/hugo/helpers"
+ "github.com/spf13/hugo/output"
"github.com/yosssi/ace"
)
@@ -478,80 +478,44 @@ func (t *GoHTMLTemplate) loadTemplates(absPath string, prefix string) {
return nil
}
- tplName := t.GenerateTemplateNameFrom(absPath, path)
+ workingDir := t.PathSpec.WorkingDir()
+ themeDir := t.PathSpec.GetThemeDir()
- if prefix != "" {
- tplName = strings.Trim(prefix, "/") + "/" + tplName
+ if themeDir != "" && strings.HasPrefix(absPath, themeDir) {
+ workingDir = themeDir
}
- var baseTemplatePath string
-
- // Ace and Go templates may have both a base and inner template.
- pathDir := filepath.Dir(path)
- if filepath.Ext(path) != ".amber" && !strings.HasSuffix(pathDir, "partials") && !strings.HasSuffix(pathDir, "shortcodes") {
-
- innerMarkers := goTemplateInnerMarkers
- baseFileName := fmt.Sprintf("%s.html", baseFileBase)
-
- if filepath.Ext(path) == ".ace" {
- innerMarkers = aceTemplateInnerMarkers
- baseFileName = fmt.Sprintf("%s.ace", baseFileBase)
- }
-
- // This may be a view that shouldn't have base template
- // Have to look inside it to make sure
- needsBase, err := helpers.FileContainsAny(path, innerMarkers, t.Fs.Source)
- if err != nil {
- return err
- }
- if needsBase {
-
- layoutDir := t.PathSpec.GetLayoutDirPath()
- currBaseFilename := fmt.Sprintf("%s-%s", helpers.Filename(path), baseFileName)
- templateDir := filepath.Dir(path)
- themeDir := filepath.Join(t.PathSpec.GetThemeDir())
- relativeThemeLayoutsDir := filepath.Join(t.PathSpec.GetRelativeThemeDir(), "layouts")
-
- var baseTemplatedDir string
-
- if strings.HasPrefix(templateDir, relativeThemeLayoutsDir) {
- baseTemplatedDir = strings.TrimPrefix(templateDir, relativeThemeLayoutsDir)
- } else {
- baseTemplatedDir = strings.TrimPrefix(templateDir, layoutDir)
- }
-
- baseTemplatedDir = strings.TrimPrefix(baseTemplatedDir, helpers.FilePathSeparator)
-
- // Look for base template in the follwing order:
- // 1. <current-path>/<template-name>-baseof.<suffix>, e.g. list-baseof.<suffix>.
- // 2. <current-path>/baseof.<suffix>
- // 3. _default/<template-name>-baseof.<suffix>, e.g. list-baseof.<suffix>.
- // 4. _default/baseof.<suffix>
- // For each of the steps above, it will first look in the project, then, if theme is set,
- // in the theme's layouts folder.
-
- pairsToCheck := [][]string{
- []string{baseTemplatedDir, currBaseFilename},
- []string{baseTemplatedDir, baseFileName},
- []string{"_default", currBaseFilename},
- []string{"_default", baseFileName},
- }
-
- Loop:
- for _, pair := range pairsToCheck {
- pathsToCheck := basePathsToCheck(pair, layoutDir, themeDir)
- for _, pathToCheck := range pathsToCheck {
- if ok, err := helpers.Exists(pathToCheck, t.Fs.Source); err == nil && ok {
- baseTemplatePath = pathToCheck
- break Loop
- }
- }
- }
- }
+ li := strings.LastIndex(path, t.PathSpec.LayoutDir()) + len(t.PathSpec.LayoutDir()) + 1
+
+ if li < 0 {
+ // Possibly a theme
+ li = strings.LastIndex(path, "layouts") + 8
+ }
+
+ relPath := path[li:]
+
+ descriptor := output.TemplateLookupDescriptor{
+ WorkingDir: workingDir,
+ LayoutDir: t.PathSpec.LayoutDir(),
+ RelPath: relPath,
+ Prefix: prefix,
+ Theme: t.PathSpec.Theme(),
+ FileExists: func(filename string) (bool, error) {
+ return helpers.Exists(filename, t.Fs.Source)
+ },
+ ContainsAny: func(filename string, subslices [][]byte) (bool, error) {
+ return helpers.FileContainsAny(filename, subslices, t.Fs.Source)
+ },
+ }
+
+ tplID, err := output.CreateTemplateID(descriptor)
+ if err != nil {
+ t.Log.ERROR.Printf("Failed to resolve template in path %q: %s", path, err)
+ return nil
}
- if err := t.AddTemplateFile(tplName, baseTemplatePath, path); err != nil {
- t.Log.ERROR.Printf("Failed to add template %s in path %s: %s", tplName, path, err)
+ if err := t.AddTemplateFile(tplID.Name, tplID.MasterFilename, tplID.OverlayFilename); err != nil {
+ t.Log.ERROR.Printf("Failed to add template %q in path %q: %s", tplID.Name, path, err)
}
}
@@ -562,19 +526,6 @@ func (t *GoHTMLTemplate) loadTemplates(absPath string, prefix string) {
}
}
-func basePathsToCheck(path []string, layoutDir, themeDir string) []string {
- // Always look in the project.
- pathsToCheck := []string{filepath.Join((append([]string{layoutDir}, path...))...)}
-
- // May have a theme
- if themeDir != "" {
- pathsToCheck = append(pathsToCheck, filepath.Join((append([]string{themeDir, "layouts"}, path...))...))
- }
-
- return pathsToCheck
-
-}
-
func (t *GoHTMLTemplate) LoadTemplatesWithPrefix(absPath string, prefix string) {
t.loadTemplates(absPath, prefix)
}