Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/gohugoio/hugo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/output
diff options
context:
space:
mode:
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-04-12 21:40:36 +0300
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>2017-04-13 12:19:54 +0300
commit077005e514b1ed50d84ceb90c7c72f184cb04521 (patch)
tree4154c7825764929c4c2b3a07e4cef8e971957982 /output
parentefc0e05c4ef974414b010b3fba5e40dab0d43876 (diff)
output: Fix base theme vs project base template logic
Fixes #3323
Diffstat (limited to 'output')
-rw-r--r--output/layout_base.go50
-rw-r--r--output/layout_base_test.go47
2 files changed, 60 insertions, 37 deletions
diff --git a/output/layout_base.go b/output/layout_base.go
index a0d2bc4eb..876746556 100644
--- a/output/layout_base.go
+++ b/output/layout_base.go
@@ -38,7 +38,11 @@ type TemplateNames struct {
}
type TemplateLookupDescriptor struct {
- // The full path to the site or theme root.
+ // TemplateDir is the project or theme root of the current template.
+ // This will be the same as WorkingDir for non-theme templates.
+ TemplateDir string
+
+ // The full path to the site root.
WorkingDir string
// Main project layout dir, defaults to "layouts"
@@ -51,8 +55,8 @@ type TemplateLookupDescriptor struct {
// The template name prefix to look for, i.e. "theme".
Prefix string
- // The theme name if active.
- Theme string
+ // The theme dir if theme active.
+ ThemeDir string
// All the output formats in play. This is used to decide if text/template or
// html/template.
@@ -64,16 +68,29 @@ type TemplateLookupDescriptor struct {
func CreateTemplateNames(d TemplateLookupDescriptor) (TemplateNames, error) {
- var id TemplateNames
-
name := filepath.ToSlash(d.RelPath)
if d.Prefix != "" {
name = strings.Trim(d.Prefix, "/") + "/" + name
}
- baseLayoutDir := filepath.Join(d.WorkingDir, d.LayoutDir)
- fullPath := filepath.Join(baseLayoutDir, d.RelPath)
+ var (
+ id TemplateNames
+
+ // This is the path to the actual template in process. This may
+ // be in the theme's or the project's /layouts.
+ baseLayoutDir = filepath.Join(d.TemplateDir, d.LayoutDir)
+ fullPath = filepath.Join(baseLayoutDir, d.RelPath)
+
+ // This is always the project's layout dir.
+ baseWorkLayoutDir = filepath.Join(d.WorkingDir, d.LayoutDir)
+
+ baseThemeLayoutDir string
+ )
+
+ if d.ThemeDir != "" {
+ baseThemeLayoutDir = filepath.Join(d.ThemeDir, "layouts")
+ }
// The filename will have a suffix with an optional type indicator.
// Examples:
@@ -140,8 +157,8 @@ func CreateTemplateNames(d TemplateLookupDescriptor) (TemplateNames, error) {
currBaseFilename := fmt.Sprintf("%s-%s", filenameNoSuffix, baseFilename)
templateDir := filepath.Dir(fullPath)
- themeDir := filepath.Join(d.WorkingDir, d.Theme)
+ // Find the base, e.g. "_default".
baseTemplatedDir := strings.TrimPrefix(templateDir, baseLayoutDir)
baseTemplatedDir = strings.TrimPrefix(baseTemplatedDir, helpers.FilePathSeparator)
@@ -162,7 +179,7 @@ func CreateTemplateNames(d TemplateLookupDescriptor) (TemplateNames, error) {
Loop:
for _, pair := range pairsToCheck {
- pathsToCheck := basePathsToCheck(pair, baseLayoutDir, themeDir)
+ pathsToCheck := basePathsToCheck(pair, baseLayoutDir, baseWorkLayoutDir, baseThemeLayoutDir)
for _, pathToCheck := range pathsToCheck {
if ok, err := d.FileExists(pathToCheck); err == nil && ok {
@@ -177,13 +194,18 @@ func CreateTemplateNames(d TemplateLookupDescriptor) (TemplateNames, error) {
}
-func basePathsToCheck(path []string, layoutDir, themeDir string) []string {
- // Always look in the project.
- pathsToCheck := []string{filepath.Join((append([]string{layoutDir}, path...))...)}
+func basePathsToCheck(path []string, layoutDir, workLayoutDir, themeLayoutDir string) []string {
+ // workLayoutDir will always be the most specific, so start there.
+ pathsToCheck := []string{filepath.Join((append([]string{workLayoutDir}, path...))...)}
+
+ if layoutDir != "" && layoutDir != workLayoutDir {
+ pathsToCheck = append(pathsToCheck, filepath.Join((append([]string{layoutDir}, path...))...))
+ }
// May have a theme
- if themeDir != "" {
- pathsToCheck = append(pathsToCheck, filepath.Join((append([]string{themeDir, "layouts"}, path...))...))
+ if themeLayoutDir != "" && themeLayoutDir != layoutDir {
+ pathsToCheck = append(pathsToCheck, filepath.Join((append([]string{themeLayoutDir}, path...))...))
+
}
return pathsToCheck
diff --git a/output/layout_base_test.go b/output/layout_base_test.go
index 16be615f2..b78f31352 100644
--- a/output/layout_base_test.go
+++ b/output/layout_base_test.go
@@ -25,6 +25,7 @@ func TestLayoutBase(t *testing.T) {
var (
workingDir = "/sites/mysite/"
+ themeDir = "/themes/mytheme/"
layoutBase1 = "layouts"
layoutPath1 = "_default/single.html"
layoutPathAmp = "_default/single.amp.html"
@@ -38,76 +39,76 @@ func TestLayoutBase(t *testing.T) {
basePathMatchStrings string
expect TemplateNames
}{
- {"No base", TemplateLookupDescriptor{WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPath1}, false, "",
+ {"No base", TemplateLookupDescriptor{TemplateDir: workingDir, WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPath1}, false, "",
TemplateNames{
Name: "_default/single.html",
OverlayFilename: "/sites/mysite/layouts/_default/single.html",
}},
- {"Base", TemplateLookupDescriptor{WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPath1}, true, "",
+ {"Base", TemplateLookupDescriptor{TemplateDir: workingDir, WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPath1}, true, "",
TemplateNames{
Name: "_default/single.html",
OverlayFilename: "/sites/mysite/layouts/_default/single.html",
MasterFilename: "/sites/mysite/layouts/_default/single-baseof.html",
}},
- {"Base in theme", TemplateLookupDescriptor{WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPath1, Theme: "mytheme"}, true,
+ {"Base in theme", TemplateLookupDescriptor{TemplateDir: workingDir, WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPath1, ThemeDir: themeDir}, true,
"mytheme/layouts/_default/baseof.html",
TemplateNames{
Name: "_default/single.html",
OverlayFilename: "/sites/mysite/layouts/_default/single.html",
- MasterFilename: "/sites/mysite/mytheme/layouts/_default/baseof.html",
+ MasterFilename: "/themes/mytheme/layouts/_default/baseof.html",
}},
- {"Template in theme, base in theme", TemplateLookupDescriptor{WorkingDir: filepath.Join(workingDir, "mytheme"), LayoutDir: layoutBase1, RelPath: layoutPath1, Theme: "mytheme"}, true,
+ {"Template in theme, base in theme", TemplateLookupDescriptor{TemplateDir: themeDir, WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPath1, ThemeDir: themeDir}, true,
"mytheme/layouts/_default/baseof.html",
TemplateNames{
Name: "_default/single.html",
- OverlayFilename: "/sites/mysite/mytheme/layouts/_default/single.html",
- MasterFilename: "/sites/mysite/mytheme/layouts/_default/baseof.html",
+ OverlayFilename: "/themes/mytheme/layouts/_default/single.html",
+ MasterFilename: "/themes/mytheme/layouts/_default/baseof.html",
}},
- {"Template in theme, base in site", TemplateLookupDescriptor{WorkingDir: filepath.Join(workingDir, "mytheme"), LayoutDir: layoutBase1, RelPath: layoutPath1, Theme: "mytheme"}, true,
- "mytheme/layouts/_default/baseof.html",
+ {"Template in theme, base in site", TemplateLookupDescriptor{TemplateDir: themeDir, WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPath1, ThemeDir: themeDir}, true,
+ "/sites/mysite/layouts/_default/baseof.html",
TemplateNames{
Name: "_default/single.html",
- OverlayFilename: "/sites/mysite/mytheme/layouts/_default/single.html",
- MasterFilename: "/sites/mysite/mytheme/layouts/_default/baseof.html",
+ OverlayFilename: "/themes/mytheme/layouts/_default/single.html",
+ MasterFilename: "/sites/mysite/layouts/_default/baseof.html",
}},
- {"Template in site, base in theme", TemplateLookupDescriptor{WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPath1, Theme: "mytheme"}, true,
- "/sites/mysite/mytheme/layouts/_default/baseof.html",
+ {"Template in site, base in theme", TemplateLookupDescriptor{TemplateDir: workingDir, WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPath1, ThemeDir: themeDir}, true,
+ "/themes/mytheme",
TemplateNames{
Name: "_default/single.html",
OverlayFilename: "/sites/mysite/layouts/_default/single.html",
- MasterFilename: "/sites/mysite/mytheme/layouts/_default/baseof.html",
+ MasterFilename: "/themes/mytheme/layouts/_default/single-baseof.html",
}},
- {"With prefix, base in theme", TemplateLookupDescriptor{WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPath1,
- Theme: "mytheme", Prefix: "someprefix"}, true,
+ {"With prefix, base in theme", TemplateLookupDescriptor{TemplateDir: workingDir, WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPath1,
+ ThemeDir: themeDir, Prefix: "someprefix"}, true,
"mytheme/layouts/_default/baseof.html",
TemplateNames{
Name: "someprefix/_default/single.html",
OverlayFilename: "/sites/mysite/layouts/_default/single.html",
- MasterFilename: "/sites/mysite/mytheme/layouts/_default/baseof.html",
+ MasterFilename: "/themes/mytheme/layouts/_default/baseof.html",
}},
- {"Partial", TemplateLookupDescriptor{WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: "partials/menu.html"}, true,
+ {"Partial", TemplateLookupDescriptor{TemplateDir: workingDir, WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: "partials/menu.html"}, true,
"mytheme/layouts/_default/baseof.html",
TemplateNames{
Name: "partials/menu.html",
OverlayFilename: "/sites/mysite/layouts/partials/menu.html",
}},
- {"AMP, no base", TemplateLookupDescriptor{WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPathAmp}, false, "",
+ {"AMP, no base", TemplateLookupDescriptor{TemplateDir: workingDir, WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPathAmp}, false, "",
TemplateNames{
Name: "_default/single.amp.html",
OverlayFilename: "/sites/mysite/layouts/_default/single.amp.html",
}},
- {"JSON, no base", TemplateLookupDescriptor{WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPathJSON}, false, "",
+ {"JSON, no base", TemplateLookupDescriptor{TemplateDir: workingDir, WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPathJSON}, false, "",
TemplateNames{
Name: "_default/single.json",
OverlayFilename: "/sites/mysite/layouts/_default/single.json",
}},
- {"AMP with base", TemplateLookupDescriptor{WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPathAmp}, true, "single-baseof.html|single-baseof.amp.html",
+ {"AMP with base", TemplateLookupDescriptor{TemplateDir: workingDir, WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPathAmp}, true, "single-baseof.html|single-baseof.amp.html",
TemplateNames{
Name: "_default/single.amp.html",
OverlayFilename: "/sites/mysite/layouts/_default/single.amp.html",
MasterFilename: "/sites/mysite/layouts/_default/single-baseof.amp.html",
}},
- {"AMP with no match in base", TemplateLookupDescriptor{WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPathAmp}, true, "single-baseof.html",
+ {"AMP with no match in base", TemplateLookupDescriptor{TemplateDir: workingDir, WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPathAmp}, true, "single-baseof.html",
TemplateNames{
Name: "_default/single.amp.html",
OverlayFilename: "/sites/mysite/layouts/_default/single.amp.html",
@@ -115,7 +116,7 @@ func TestLayoutBase(t *testing.T) {
MasterFilename: "",
}},
- {"JSON with base", TemplateLookupDescriptor{WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPathJSON}, true, "single-baseof.json",
+ {"JSON with base", TemplateLookupDescriptor{TemplateDir: workingDir, WorkingDir: workingDir, LayoutDir: layoutBase1, RelPath: layoutPathJSON}, true, "single-baseof.json",
TemplateNames{
Name: "_default/single.json",
OverlayFilename: "/sites/mysite/layouts/_default/single.json",