1
0
Fork 0
hugo/tpl/tplimpl/templatestore_integration_t...

1232 lines
27 KiB
Go

package tplimpl_test
import (
"context"
"io"
"testing"
qt "github.com/frankban/quicktest"
"github.com/gohugoio/hugo/hugolib"
"github.com/gohugoio/hugo/resources/kinds"
"github.com/gohugoio/hugo/resources/page"
"github.com/gohugoio/hugo/tpl/tplimpl"
)
// Old as in before Hugo v0.146.0.
func TestLayoutsOldSetup(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
defaultContentLanguage = "en"
defaultContentLanguageInSubdir = true
[languages]
[languages.en]
title = "Title in English"
weight = 1
[languages.nn]
title = "Tittel på nynorsk"
weight = 2
-- layouts/index.html --
Home.
{{ template "_internal/twitter_cards.html" . }}
-- layouts/_default/single.html --
Single.
-- layouts/_default/single.nn.html --
Single NN.
-- layouts/_default/list.html --
List HTML.
-- layouts/docs/list-baseof.html --
Docs Baseof List HTML.
{{ block "main" . }}Docs Baseof List HTML main block.{{ end }}
-- layouts/docs/list.section.html --
{{ define "main" }}
Docs List HTML.
{{ end }}
-- layouts/_default/list.json --
List JSON.
-- layouts/_default/list.rss.xml --
List RSS.
-- layouts/_default/list.nn.rss.xml --
List NN RSS.
-- layouts/_default/baseof.html --
Base.
-- layouts/partials/mypartial.html --
Partial.
-- layouts/shortcodes/myshortcode.html --
Shortcode.
-- content/docs/p1.md --
---
title: "P1"
---
`
b := hugolib.Test(t, files)
// b.DebugPrint("", tplimpl.CategoryBaseof)
b.AssertFileContent("public/en/docs/index.html", "Docs Baseof List HTML.\n\nDocs List HTML.")
}
func TestLayoutsOldSetupBaseofPrefix(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
-- layouts/_default/layout1-baseof.html --
Baseof layout1. {{ block "main" . }}{{ end }}
-- layouts/_default/layout2-baseof.html --
Baseof layout2. {{ block "main" . }}{{ end }}
-- layouts/_default/layout1.html --
{{ define "main" }}Layout1. {{ .Title }}{{ end }}
-- layouts/_default/layout2.html --
{{ define "main" }}Layout2. {{ .Title }}{{ end }}
-- content/p1.md --
---
title: "P1"
layout: "layout1"
---
-- content/p2.md --
---
title: "P2"
layout: "layout2"
---
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/p1/index.html", "Baseof layout1. Layout1. P1")
b.AssertFileContent("public/p2/index.html", "Baseof layout2. Layout2. P2")
}
func TestLayoutsOldSetupTaxonomyAndTerm(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
[taxonomies]
cat = 'cats'
dog = 'dogs'
# Templates for term taxonomy, old setup.
-- layouts/dogs/terms.html --
Dogs Terms. Most specific taxonomy template.
-- layouts/taxonomy/terms.html --
Taxonomy Terms. Down the list.
# Templates for term term, old setup.
-- layouts/dogs/term.html --
Dogs Term. Most specific term template.
-- layouts/term/term.html --
Term Term. Down the list.
-- layouts/dogs/max/list.html --
max: {{ .Title }}
-- layouts/_default/list.html --
Default list.
-- layouts/_default/single.html --
Default single.
-- content/p1.md --
---
title: "P1"
dogs: ["luna", "daisy", "max"]
---
`
b := hugolib.Test(t, files, hugolib.TestOptWarn())
b.AssertLogContains("! WARN")
b.AssertFileContent("public/dogs/index.html", "Dogs Terms. Most specific taxonomy template.")
b.AssertFileContent("public/dogs/luna/index.html", "Dogs Term. Most specific term template.")
b.AssertFileContent("public/dogs/max/index.html", "max: Max") // layouts/dogs/max/list.html wins over layouts/term/term.html because of distance.
}
func TestLayoutsOldSetupCustomRSS(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ["taxonomy", "term", "page"]
[outputs]
home = ["rss"]
-- layouts/_default/list.rss.xml --
List RSS.
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/index.xml", "List RSS.")
}
var newSetupTestSites = `
-- hugo.toml --
defaultContentLanguage = "en"
defaultContentLanguageInSubdir = true
[languages]
[languages.en]
title = "Title in English"
weight = 1
[languages.nn]
title = "Tittel på nynorsk"
weight = 2
[languages.fr]
title = "Titre en français"
weight = 3
[outputs]
home = ["html", "rss", "redir"]
[outputFormats]
[outputFormats.redir]
mediatype = "text/plain"
baseName = "_redirects"
isPlainText = true
-- layouts/404.html --
{{ define "main" }}
404.
{{ end }}
-- layouts/home.html --
{{ define "main" }}
Home: {{ .Title }}|{{ .Content }}|
Inline Partial: {{ partial "my-inline-partial.html" . }}
{{ end }}
{{ define "hero" }}
Home hero.
{{ end }}
{{ define "partials/my-inline-partial.html" }}
{{ $value := 32 }}
{{ return $value }}
{{ end }}
-- layouts/index.redir --
Redir.
-- layouts/single.html --
{{ define "main" }}
Single needs base.
{{ end }}
-- layouts/foo/bar/single.html --
{{ define "main" }}
Single sub path.
{{ end }}
-- layouts/_markup/render-codeblock.html --
Render codeblock.
-- layouts/_markup/render-blockquote.html --
Render blockquote.
-- layouts/_markup/render-codeblock-go.html --
Render codeblock go.
-- layouts/_markup/render-link.html --
Link: {{ .Destination | safeURL }}
-- layouts/foo/baseof.html --
Base sub path.{{ block "main" . }}{{ end }}
-- layouts/foo/bar/baseof.page.html --
Base sub path.{{ block "main" . }}{{ end }}
-- layouts/list.html --
{{ define "main" }}
List needs base.
{{ end }}
-- layouts/section.html --
Section.
-- layouts/mysectionlayout.section.fr.amp.html --
Section with layout.
-- layouts/baseof.html --
Base.{{ block "main" . }}{{ end }}
Hero:{{ block "hero" . }}{{ end }}:
{{ with (templates.Defer (dict "key" "global")) }}
Defer Block.
{{ end }}
-- layouts/baseof.fr.html --
Base fr.{{ block "main" . }}{{ end }}
-- layouts/baseof.term.html --
Base term.
-- layouts/baseof.section.fr.amp.html --
Base with identifiers.{{ block "main" . }}{{ end }}
-- layouts/partials/mypartial.html --
Partial. {{ partial "_inline/my-inline-partial-in-partial-with-no-ext" . }}
{{ define "partials/_inline/my-inline-partial-in-partial-with-no-ext" }}
Partial in partial.
{{ end }}
-- layouts/partials/returnfoo.html --
{{ $v := "foo" }}
{{ return $v }}
-- layouts/shortcodes/myshortcode.html --
Shortcode. {{ partial "mypartial.html" . }}|return:{{ partial "returnfoo.html" . }}|
-- content/_index.md --
---
title: Home sweet home!
---
{{< myshortcode >}}
> My blockquote.
Markdown link: [Foo](/foo)
-- content/p1.md --
---
title: "P1"
---
-- content/foo/bar/index.md --
---
title: "Foo Bar"
---
{{< myshortcode >}}
-- content/single-list.md --
---
title: "Single List"
layout: "list"
---
`
func TestLayoutsType(t *testing.T) {
files := `
-- hugo.toml --
disableKinds = ["taxonomy", "term"]
-- layouts/list.html --
List.
-- layouts/mysection/single.html --
mysection/single|{{ .Title }}
-- layouts/mytype/single.html --
mytype/single|{{ .Title }}
-- content/mysection/_index.md --
-- content/mysection/mysubsection/_index.md --
-- content/mysection/mysubsection/p1.md --
---
title: "P1"
---
-- content/mysection/mysubsection/p2.md --
---
title: "P2"
type: "mytype"
---
`
b := hugolib.Test(t, files, hugolib.TestOptWarn())
b.AssertLogContains("! WARN")
b.AssertFileContent("public/mysection/mysubsection/p1/index.html", "mysection/single|P1")
b.AssertFileContent("public/mysection/mysubsection/p2/index.html", "mytype/single|P2")
}
// New, as in from Hugo v0.146.0.
func TestLayoutsNewSetup(t *testing.T) {
const numIterations = 1
for range numIterations {
b := hugolib.Test(t, newSetupTestSites, hugolib.TestOptWarn())
b.AssertLogContains("! WARN")
b.AssertFileContent("public/en/index.html",
"Base.\nHome: Home sweet home!|",
"|Shortcode.\n|",
"<p>Markdown link: Link: /foo</p>",
"|return:foo|",
"Defer Block.",
"Home hero.",
"Render blockquote.",
)
b.AssertFileContent("public/en/p1/index.html", "Base.\nSingle needs base.\n\nHero::\n\nDefer Block.")
b.AssertFileContent("public/en/404.html", "404.")
b.AssertFileContent("public/nn/404.html", "404.")
b.AssertFileContent("public/fr/404.html", "404.")
}
}
func TestHomeRSSAndHTMLWithHTMLOnlyShortcode(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ["taxonomy", "term"]
[outputs]
home = ["html", "rss"]
-- layouts/home.html --
Home: {{ .Title }}|{{ .Content }}|
-- layouts/single.html --
Single: {{ .Title }}|{{ .Content }}|
-- layouts/shortcodes/myshortcode.html --
Myshortcode: Count: {{ math.Counter }}|
-- content/p1.md --
---
title: "P1"
---
{{< myshortcode >}}
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/p1/index.html", "Single: P1|Myshortcode: Count: 1|")
b.AssertFileContent("public/index.xml", "Myshortcode: Count: 1")
}
func TestHomeRSSAndHTMLWithHTMLOnlyRenderHook(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ["taxonomy", "term"]
[outputs]
home = ["html", "rss"]
-- layouts/home.html --
Home: {{ .Title }}|{{ .Content }}|
-- layouts/single.html --
Single: {{ .Title }}|{{ .Content }}|
-- layouts/_markup/render-link.html --
Render Link: {{ math.Counter }}|
-- content/p1.md --
---
title: "P1"
---
Link: [Foo](/foo)
`
for range 2 {
b := hugolib.Test(t, files)
b.AssertFileContent("public/index.xml", "Link: Render Link: 1|")
b.AssertFileContent("public/p1/index.html", "Single: P1|<p>Link: Render Link: 1|<")
}
}
func TestRenderCodeblockSpecificity(t *testing.T) {
files := `
-- hugo.toml --
-- layouts/_markup/render-codeblock.html --
Render codeblock.|{{ .Inner }}|
-- layouts/_markup/render-codeblock-go.html --
Render codeblock go.|{{ .Inner }}|
-- layouts/single.html --
{{ .Title }}|{{ .Content }}|
-- content/p1.md --
---
title: "P1"
---
§§§
Basic
§§§
§§§ go
Go
§§§
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/p1/index.html", "P1|Render codeblock.|Basic|Render codeblock go.|Go|")
}
func TestPrintUnusedTemplates(t *testing.T) {
t.Parallel()
files := `
-- config.toml --
baseURL = 'http://example.com/'
printUnusedTemplates=true
-- content/p1.md --
---
title: "P1"
---
{{< usedshortcode >}}
-- layouts/baseof.html --
{{ block "main" . }}{{ end }}
-- layouts/baseof.json --
{{ block "main" . }}{{ end }}
-- layouts/index.html --
{{ define "main" }}FOO{{ end }}
-- layouts/_default/single.json --
-- layouts/_default/single.html --
{{ define "main" }}MAIN /_default/single.html{{ end }}
-- layouts/post/single.html --
{{ define "main" }}MAIN{{ end }}
-- layouts/_partials/usedpartial.html --
-- layouts/_partials/unusedpartial.html --
-- layouts/_shortcodes/usedshortcode.html --
{{ partial "usedpartial.html" }}
-- layouts/shortcodes/unusedshortcode.html --
`
b := hugolib.NewIntegrationTestBuilder(
hugolib.IntegrationTestConfig{
T: t,
TxtarString: files,
NeedsOsFS: true,
},
)
b.Build()
b.AssertFileContent("public/p1/index.html", "MAIN /_default/single.html")
unused := b.H.GetTemplateStore().UnusedTemplates()
var names []string
for _, tmpl := range unused {
if fi := tmpl.Fi; fi != nil {
names = append(names, fi.Meta().PathInfo.PathNoLeadingSlash())
}
}
b.Assert(names, qt.DeepEquals, []string{"_partials/unusedpartial.html", "shortcodes/unusedshortcode.html", "baseof.json", "post/single.html", "_default/single.json"})
b.Assert(len(unused), qt.Equals, 5, qt.Commentf("%#v", names))
}
func TestCreateManyTemplateStores(t *testing.T) {
t.Parallel()
b := hugolib.Test(t, newSetupTestSites)
store := b.H.TemplateStore
for range 70 {
newStore, err := store.NewFromOpts()
b.Assert(err, qt.IsNil)
b.Assert(newStore, qt.Not(qt.IsNil))
}
}
func BenchmarkLookupPagesLayout(b *testing.B) {
files := `
-- hugo.toml --
-- layouts/single.html --
{{ define "main" }}
Main.
{{ end }}
-- layouts/baseof.html --
baseof: {{ block "main" . }}{{ end }}
-- layouts/foo/bar/single.html --
{{ define "main" }}
Main.
{{ end }}
`
bb := hugolib.Test(b, files)
store := bb.H.TemplateStore
b.ResetTimer()
b.Run("Single root", func(b *testing.B) {
q := tplimpl.TemplateQuery{
Path: "/baz",
Category: tplimpl.CategoryLayout,
Desc: tplimpl.TemplateDescriptor{Kind: kinds.KindPage, LayoutFromTemplate: "single", OutputFormat: "html"},
}
for i := 0; i < b.N; i++ {
store.LookupPagesLayout(q)
}
})
b.Run("Single sub folder", func(b *testing.B) {
q := tplimpl.TemplateQuery{
Path: "/foo/bar",
Category: tplimpl.CategoryLayout,
Desc: tplimpl.TemplateDescriptor{Kind: kinds.KindPage, LayoutFromTemplate: "single", OutputFormat: "html"},
}
for i := 0; i < b.N; i++ {
store.LookupPagesLayout(q)
}
})
}
func BenchmarkNewTemplateStore(b *testing.B) {
bb := hugolib.Test(b, newSetupTestSites)
store := bb.H.TemplateStore
b.ResetTimer()
for i := 0; i < b.N; i++ {
newStore, err := store.NewFromOpts()
if err != nil {
b.Fatal(err)
}
if newStore == nil {
b.Fatal("newStore is nil")
}
}
}
func TestLayoutsLookupVariants(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
defaultContentLanguage = "en"
defaultContentLanguageInSubdir = true
[outputs]
home = ["html", "rss"]
page = ["html", "rss", "amp"]
section = ["html", "rss"]
[languages]
[languages.en]
title = "Title in English"
weight = 1
[languages.nn]
title = "Tittel på nynorsk"
weight = 2
-- layouts/list.xml --
layouts/list.xml
-- layouts/_shortcodes/myshortcode.html --
layouts/shortcodes/myshortcode.html
-- layouts/foo/bar/_shortcodes/myshortcode.html --
layouts/foo/bar/_shortcodes/myshortcode.html
-- layouts/_markup/render-codeblock.html --
layouts/_markup/render-codeblock.html|{{ .Type }}|
-- layouts/_markup/render-codeblock-go.html --
layouts/_markup/render-codeblock-go.html|{{ .Type }}|
-- layouts/single.xml --
layouts/single.xml
-- layouts/single.rss.xml --
layouts/single.rss.xml
-- layouts/single.nn.rss.xml --
layouts/single.nn.rss.xml
-- layouts/list.html --
layouts/list.html
-- layouts/single.html --
layouts/single.html
{{ .Content }}
-- layouts/mylayout.html --
layouts/mylayout.html
-- layouts/mylayout.nn.html --
layouts/mylayout.nn.html
-- layouts/foo/single.rss.xml --
layouts/foo/single.rss.xml
-- layouts/foo/single.amp.html --
layouts/foo/single.amp.html
-- layouts/foo/bar/page.html --
layouts/foo/bar/page.html
-- layouts/foo/bar/baz/single.html --
layouts/foo/bar/baz/single.html
{{ .Content }}
-- layouts/qux/mylayout.html --
layouts/qux/mylayout.html
-- layouts/qux/single.xml --
layouts/qux/single.xml
-- layouts/qux/mylayout.section.html --
layouts/qux/mylayout.section.html
-- content/p.md --
---
---
§§§
code
§§§
§§§ go
code
§§§
{{< myshortcode >}}
-- content/foo/p.md --
-- content/foo/p.nn.md --
-- content/foo/bar/p.md --
-- content/foo/bar/withmylayout.md --
---
layout: mylayout
---
-- content/foo/bar/_index.md --
-- content/foo/bar/baz/p.md --
---
---
{{< myshortcode >}}
-- content/qux/p.md --
-- content/qux/_index.md --
---
layout: mylayout
---
-- content/qux/quux/p.md --
-- content/qux/quux/withmylayout.md --
---
layout: mylayout
---
-- content/qux/quux/withmylayout.nn.md --
---
layout: mylayout
---
`
b := hugolib.Test(t, files, hugolib.TestOptWarn())
b.AssertLogContains("! WARN")
// Single pages.
// output format: html.
b.AssertFileContent("public/en/p/index.html", "layouts/single.html",
"layouts/_markup/render-codeblock.html|",
"layouts/_markup/render-codeblock-go.html|go|",
"layouts/shortcodes/myshortcode.html",
)
b.AssertFileContent("public/en/foo/p/index.html", "layouts/single.html")
b.AssertFileContent("public/en/foo/bar/p/index.html", "layouts/foo/bar/page.html")
b.AssertFileContent("public/en/foo/bar/withmylayout/index.html", "layouts/mylayout.html")
b.AssertFileContent("public/en/foo/bar/baz/p/index.html", "layouts/foo/bar/baz/single.html", "layouts/foo/bar/_shortcodes/myshortcode.html")
b.AssertFileContent("public/en/qux/quux/withmylayout/index.html", "layouts/qux/mylayout.html")
// output format: amp.
b.AssertFileContent("public/en/amp/p/index.html", "layouts/single.html")
b.AssertFileContent("public/en/amp/foo/p/index.html", "layouts/foo/single.amp.html")
// output format: rss.
b.AssertFileContent("public/en/p/index.xml", "layouts/single.rss.xml")
b.AssertFileContent("public/en/foo/p/index.xml", "layouts/foo/single.rss.xml")
b.AssertFileContent("public/nn/foo/p/index.xml", "layouts/single.nn.rss.xml")
// Note: There is qux/single.xml that's closer, but the one in the root is used becaulse of the output format match.
b.AssertFileContent("public/en/qux/p/index.xml", "layouts/single.rss.xml")
// Note.
b.AssertFileContent("public/nn/qux/quux/withmylayout/index.html", "layouts/mylayout.nn.html")
// Section pages.
// output format: html.
b.AssertFileContent("public/en/foo/index.html", "layouts/list.html")
b.AssertFileContent("public/en/qux/index.html", "layouts/qux/mylayout.section.html")
// output format: rss.
b.AssertFileContent("public/en/foo/index.xml", "layouts/list.xml")
}
func TestLookupShortcodeDepth(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
-- layouts/_shortcodes/myshortcode.html --
layouts/_shortcodes/myshortcode.html
-- layouts/foo/_shortcodes/myshortcode.html --
layouts/foo/_shortcodes/myshortcode.html
-- layouts/single.html --
{{ .Content }}|
-- content/p.md --
---
---
{{< myshortcode >}}
-- content/foo/p.md --
---
---
{{< myshortcode >}}
-- content/foo/bar/p.md --
---
---
{{< myshortcode >}}
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/p/index.html", "layouts/_shortcodes/myshortcode.html")
b.AssertFileContent("public/foo/p/index.html", "layouts/foo/_shortcodes/myshortcode.html")
b.AssertFileContent("public/foo/bar/p/index.html", "layouts/foo/_shortcodes/myshortcode.html")
}
func TestLookupShortcodeLayout(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
-- layouts/_shortcodes/myshortcode.single.html --
layouts/_shortcodes/myshortcode.single.html
-- layouts/_shortcodes/myshortcode.list.html --
layouts/_shortcodes/myshortcode.list.html
-- layouts/single.html --
{{ .Content }}|
-- layouts/list.html --
{{ .Content }}|
-- content/_index.md --
---
---
{{< myshortcode >}}
-- content/p.md --
---
---
{{< myshortcode >}}
-- content/foo/p.md --
---
---
{{< myshortcode >}}
-- content/foo/bar/p.md --
---
---
{{< myshortcode >}}
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/p/index.html", "layouts/_shortcodes/myshortcode.single.html")
b.AssertFileContent("public/index.html", "layouts/_shortcodes/myshortcode.list.html")
}
func TestLayoutAll(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
-- layouts/single.html --
Single.
-- layouts/all.html --
All.
-- content/p1.md --
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/p1/index.html", "Single.")
b.AssertFileContent("public/index.html", "All.")
}
func TestLayoutAllNested(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['rss','sitemap','taxonomy','term']
-- content/s1/p1.md --
---
title: p1
---
-- content/s2/p2.md --
---
title: p2
---
-- layouts/single.html --
layouts/single.html
-- layouts/list.html --
layouts/list.html
-- layouts/s1/all.html --
layouts/s1/all.html
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/index.html", "layouts/list.html")
b.AssertFileContent("public/s1/index.html", "layouts/s1/all.html")
b.AssertFileContent("public/s1/p1/index.html", "layouts/s1/all.html")
b.AssertFileContent("public/s2/index.html", "layouts/list.html")
b.AssertFileContent("public/s2/p2/index.html", "layouts/single.html")
}
func TestPartialHTML(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
-- layouts/all.html --
<html>
<head>
{{ partial "css.html" .}}
</head>
</html>
-- layouts/partials/css.html --
<link rel="stylesheet" href="/css/style.css">
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/index.html", "<link rel=\"stylesheet\" href=\"/css/style.css\">")
}
// Issue #13593.
func TestGoatAndNoGoat(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
-- content/_index.md --
---
title: "Home"
---
§§§
printf "Hello, world!"
§§§
§§§ goat
.---. .-. .-. .-. .---.
| A +--->| 1 |<--->| 2 |<--->| 3 |<---+ B |
'---' '-' '+' '+' '---'
§§§
-- layouts/all.html --
{{ .Content }}
`
b := hugolib.Test(t, files)
// Basic code block.
b.AssertFileContent("public/index.html", "<code>printf &#34;Hello, world!&#34;\n</code>")
// Goat code block.
b.AssertFileContent("public/index.html", "Menlo,Lucida")
}
// Issue #13595.
func TestGoatAndNoGoatCustomTemplate(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
-- content/_index.md --
---
title: "Home"
---
§§§
printf "Hello, world!"
§§§
§§§ goat
.---. .-. .-. .-. .---.
| A +--->| 1 |<--->| 2 |<--->| 3 |<---+ B |
'---' '-' '+' '+' '---'
§§§
-- layouts/_markup/render-codeblock.html --
_markup/render-codeblock.html
-- layouts/all.html --
{{ .Content }}
`
b := hugolib.Test(t, files)
// Basic code block.
b.AssertFileContent("public/index.html", "_markup/render-codeblock.html")
// Goat code block.
b.AssertFileContent("public/index.html", "Menlo,Lucida")
}
func TestGoatcustom(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
-- content/_index.md --
---
title: "Home"
---
§§§
printf "Hello, world!"
§§§
§§§ goat
.---. .-. .-. .-. .---.
| A +--->| 1 |<--->| 2 |<--->| 3 |<---+ B |
'---' '-' '+' '+' '---'
§§§
-- layouts/_markup/render-codeblock.html --
_markup/render-codeblock.html
-- layouts/_markup/render-codeblock-goat.html --
_markup/render-codeblock-goat.html
-- layouts/all.html --
{{ .Content }}
`
b := hugolib.Test(t, files)
// Basic code block.
b.AssertFileContent("public/index.html", "_markup/render-codeblock.html")
// Custom Goat code block.
b.AssertFileContent("public/index.html", "_markup/render-codeblock.html_markup/render-codeblock-goat.html")
}
// Issue #13515
func TestPrintPathWarningOnDotRemoval(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
baseURL = "https://example.com"
printPathWarnings = true
-- content/v0.124.0.md --
-- content/v0.123.0.md --
-- layouts/all.html --
All.
-- layouts/_default/single.html --
{{ .Title }}|
`
b := hugolib.Test(t, files, hugolib.TestOptWarn())
b.AssertLogContains("Duplicate content path")
}
// Issue #13577.
func TestPrintPathWarningOnInvalidMarkupFilename(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
-- layouts/all.html --
All.
-- layouts/_markup/sitemap.xml --
`
b := hugolib.Test(t, files, hugolib.TestOptWarn())
b.AssertLogContains("unrecognized render hook")
}
func BenchmarkExecuteWithContext(b *testing.B) {
files := `
-- hugo.toml --
disableKinds = ["taxonomy", "term", "home"]
-- layouts/all.html --
{{ .Title }}|
{{ partial "p1.html" . }}
-- layouts/_partials/p1.html --
p1.
{{ partial "p2.html" . }}
{{ partial "p2.html" . }}
{{ partial "p3.html" . }}
{{ partial "p2.html" . }}
{{ partial "p2.html" . }}
{{ partial "p2.html" . }}
{{ partial "p3.html" . }}
-- layouts/_partials/p2.html --
{{ partial "p3.html" . }}
-- layouts/_partials/p3.html --
p3
-- content/p1.md --
`
bb := hugolib.Test(b, files)
store := bb.H.TemplateStore
ti := store.LookupByPath("/all.html")
bb.Assert(ti, qt.Not(qt.IsNil))
p := bb.H.Sites[0].RegularPages()[0]
bb.Assert(p, qt.Not(qt.IsNil))
b.ResetTimer()
for i := 0; i < b.N; i++ {
err := store.ExecuteWithContext(context.Background(), ti, io.Discard, p)
if err != nil {
b.Fatal(err)
}
}
}
func BenchmarkLookupPartial(b *testing.B) {
files := `
-- hugo.toml --
disableKinds = ["taxonomy", "term", "home"]
-- layouts/all.html --
{{ .Title }}|
-- layouts/_partials/p1.html --
-- layouts/_partials/p2.html --
-- layouts/_partials/p2.json --
-- layouts/_partials/p3.html --
`
bb := hugolib.Test(b, files)
store := bb.H.TemplateStore
for i := 0; i < b.N; i++ {
fi := store.LookupPartial("p3.html")
if fi == nil {
b.Fatal("not found")
}
}
}
// Implemented by pageOutput.
type getDescriptorProvider interface {
GetInternalTemplateBasePathAndDescriptor() (string, tplimpl.TemplateDescriptor)
}
func BenchmarkLookupShortcode(b *testing.B) {
files := `
-- hugo.toml --
disableKinds = ["taxonomy", "term", "home"]
-- content/toplevelpage.md --
-- content/a/b/c/nested.md --
-- layouts/all.html --
{{ .Title }}|
-- layouts/_shortcodes/s.html --
s1.
-- layouts/_shortcodes/a/b/s.html --
s2.
`
bb := hugolib.Test(b, files)
store := bb.H.TemplateStore
runOne := func(p page.Page) {
pth, desc := p.(getDescriptorProvider).GetInternalTemplateBasePathAndDescriptor()
q := tplimpl.TemplateQuery{
Path: pth,
Name: "s",
Category: tplimpl.CategoryShortcode,
Desc: desc,
}
v := store.LookupShortcode(q)
if v == nil {
b.Fatal("not found")
}
}
b.Run("toplevelpage", func(b *testing.B) {
toplevelpage, _ := bb.H.Sites[0].GetPage("/toplevelpage")
for i := 0; i < b.N; i++ {
runOne(toplevelpage)
}
})
b.Run("nestedpage", func(b *testing.B) {
toplevelpage, _ := bb.H.Sites[0].GetPage("/a/b/c/nested")
for i := 0; i < b.N; i++ {
runOne(toplevelpage)
}
})
}
func TestStandardLayoutInFrontMatter13588(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['home','page','rss','sitemap','taxonomy','term']
-- content/s1/_index.md --
---
title: s1
---
-- content/s2/_index.md --
---
title: s2
layout: list
---
-- content/s3/_index.md --
---
title: s3
layout: single
---
-- layouts/list.html --
list.html
-- layouts/section.html --
section.html
-- layouts/single.html --
single.html
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/s1/index.html", "section.html")
b.AssertFileContent("public/s2/index.html", "list.html") // fail
b.AssertFileContent("public/s3/index.html", "single.html") // fail
}
func TestIssue13605(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['home','rss','section','sitemap','taxonomy','term']
-- content/s1/p1.md --
---
title: p1
---
{{< sc >}}
-- layouts/s1/_shortcodes/sc.html --
layouts/s1/_shortcodes/sc.html
-- layouts/single.html --
{{ .Content }}
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/s1/p1/index.html", "layouts/s1/_shortcodes/sc.html")
}
func TestSkipDotFiles(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
-- layouts/all.html --
All.
-- layouts/.DS_Store --
{{ foo }}
`
// Just make sure it doesn't fail.
hugolib.Test(t, files)
}
func TestPartialsLangIssue13612(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['page','section','sitemap','taxonomy','term']
defaultContentLanguage = 'ru'
defaultContentLanguageInSubdir = true
[languages.ru]
weight = 1
[languages.en]
weight = 2
[outputs]
home = ['html','rss']
-- layouts/_partials/comment.en.html --
layouts/_partials/comment.en.html
-- layouts/_partials/comment.en.xml --
layouts/_partials/comment.en.xml
-- layouts/_partials/comment.ru.html --
layouts/_partials/comment.ru.html
-- layouts/_partials/comment.ru.xml --
layouts/_partials/comment.ru.xml
-- layouts/home.html --
{{ partial (print "comment." (default "ru" .Lang) ".html") . }}
-- layouts/home.rss.xml --
{{ partial (print "comment." (default "ru" .Lang) ".xml") . }}
`
b := hugolib.Test(t, files)
b.AssertFileContent("public/en/index.html", "layouts/_partials/comment.en.html")
b.AssertFileContent("public/en/index.xml", "layouts/_partials/comment.en.xml") // fail
b.AssertFileContent("public/ru/index.html", "layouts/_partials/comment.ru.html") // fail
b.AssertFileContent("public/ru/index.xml", "layouts/_partials/comment.ru.xml") // fail
}
func TestLayoutIssue13628(t *testing.T) {
t.Parallel()
files := `
-- hugo.toml --
disableKinds = ['home','rss','sitemap','taxonomy','term']
-- content/p1.md --
---
title: p1
layout: foo
---
-- layouts/single.html --
layouts/single.html
-- layouts/list.html --
layouts/list.html
`
for range 5 {
b := hugolib.Test(t, files)
b.AssertFileContent("public/p1/index.html", "layouts/single.html")
}
}