templatestore_integration_test.go - hugo - [fork] hugo port for 9front
(HTM) git clone https://git.drkhsh.at/hugo.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
templatestore_integration_test.go (37291B)
---
1 package tplimpl_test
2
3 import (
4 "context"
5 "io"
6 "strings"
7 "testing"
8
9 qt "github.com/frankban/quicktest"
10 "github.com/gohugoio/hugo/hugolib"
11 "github.com/gohugoio/hugo/resources/kinds"
12 "github.com/gohugoio/hugo/resources/page"
13 "github.com/gohugoio/hugo/tpl/tplimpl"
14 )
15
16 // Old as in before Hugo v0.146.0.
17 func TestLayoutsOldSetup(t *testing.T) {
18 t.Parallel()
19
20 files := `
21 -- hugo.toml --
22 defaultContentLanguage = "en"
23 defaultContentLanguageInSubdir = true
24 [languages]
25 [languages.en]
26 title = "Title in English"
27 weight = 1
28 [languages.nn]
29 title = "Tittel på nynorsk"
30 weight = 2
31 -- layouts/index.html --
32 Home.
33 {{ template "_internal/twitter_cards.html" . }}
34 -- layouts/_default/single.html --
35 Single.
36 -- layouts/_default/single.nn.html --
37 Single NN.
38 -- layouts/_default/list.html --
39 List HTML.
40 -- layouts/docs/list-baseof.html --
41 Docs Baseof List HTML.
42 {{ block "main" . }}Docs Baseof List HTML main block.{{ end }}
43 -- layouts/docs/list.section.html --
44 {{ define "main" }}
45 Docs List HTML.
46 {{ end }}
47 -- layouts/_default/list.json --
48 List JSON.
49 -- layouts/_default/list.rss.xml --
50 List RSS.
51 -- layouts/_default/list.nn.rss.xml --
52 List NN RSS.
53 -- layouts/_default/baseof.html --
54 Base.
55 -- layouts/partials/mypartial.html --
56 Partial.
57 -- layouts/shortcodes/myshortcode.html --
58 Shortcode.
59 -- content/docs/p1.md --
60 ---
61 title: "P1"
62 ---
63
64 `
65
66 b := hugolib.Test(t, files)
67
68 // b.DebugPrint("", tplimpl.CategoryBaseof)
69
70 b.AssertFileContent("public/en/docs/index.html", "Docs Baseof List HTML.\n\nDocs List HTML.")
71 }
72
73 func TestLayoutsOldSetupBaseofPrefix(t *testing.T) {
74 t.Parallel()
75
76 files := `
77 -- hugo.toml --
78 -- layouts/_default/layout1-baseof.html --
79 Baseof layout1. {{ block "main" . }}{{ end }}
80 -- layouts/_default/layout2-baseof.html --
81 Baseof layout2. {{ block "main" . }}{{ end }}
82 -- layouts/_default/layout1.html --
83 {{ define "main" }}Layout1. {{ .Title }}{{ end }}
84 -- layouts/_default/layout2.html --
85 {{ define "main" }}Layout2. {{ .Title }}{{ end }}
86 -- content/p1.md --
87 ---
88 title: "P1"
89 layout: "layout1"
90 ---
91 -- content/p2.md --
92 ---
93 title: "P2"
94 layout: "layout2"
95 ---
96 `
97
98 b := hugolib.Test(t, files)
99
100 b.AssertFileContent("public/p1/index.html", "Baseof layout1. Layout1. P1")
101 b.AssertFileContent("public/p2/index.html", "Baseof layout2. Layout2. P2")
102 }
103
104 func TestLayoutsOldSetupTaxonomyAndTerm(t *testing.T) {
105 t.Parallel()
106
107 files := `
108 -- hugo.toml --
109 [taxonomies]
110 cat = 'cats'
111 dog = 'dogs'
112 # Templates for term taxonomy, old setup.
113 -- layouts/dogs/terms.html --
114 Dogs Terms. Most specific taxonomy template.
115 -- layouts/taxonomy/terms.html --
116 Taxonomy Terms. Down the list.
117 # Templates for term term, old setup.
118 -- layouts/dogs/term.html --
119 Dogs Term. Most specific term template.
120 -- layouts/term/term.html --
121 Term Term. Down the list.
122 -- layouts/dogs/max/list.html --
123 max: {{ .Title }}
124 -- layouts/_default/list.html --
125 Default list.
126 -- layouts/_default/single.html --
127 Default single.
128 -- content/p1.md --
129 ---
130 title: "P1"
131 dogs: ["luna", "daisy", "max"]
132 ---
133
134 `
135 b := hugolib.Test(t, files, hugolib.TestOptWarn())
136
137 b.AssertLogContains("! WARN")
138
139 b.AssertFileContent("public/dogs/index.html", "Dogs Terms. Most specific taxonomy template.")
140 b.AssertFileContent("public/dogs/luna/index.html", "Dogs Term. Most specific term template.")
141 b.AssertFileContent("public/dogs/max/index.html", "max: Max") // layouts/dogs/max/list.html wins over layouts/term/term.html because of distance.
142 }
143
144 func TestLayoutsOldSetupCustomRSS(t *testing.T) {
145 t.Parallel()
146
147 files := `
148 -- hugo.toml --
149 disableKinds = ["taxonomy", "term", "page"]
150 [outputs]
151 home = ["rss"]
152 -- layouts/_default/list.rss.xml --
153 List RSS.
154 `
155 b := hugolib.Test(t, files)
156 b.AssertFileContent("public/index.xml", "List RSS.")
157 }
158
159 var newSetupTestSites = `
160 -- hugo.toml --
161 defaultContentLanguage = "en"
162 defaultContentLanguageInSubdir = true
163 [languages]
164 [languages.en]
165 title = "Title in English"
166 weight = 1
167 [languages.nn]
168 title = "Tittel på nynorsk"
169 weight = 2
170 [languages.fr]
171 title = "Titre en français"
172 weight = 3
173
174 [outputs]
175 home = ["html", "rss", "redir"]
176
177 [outputFormats]
178 [outputFormats.redir]
179 mediatype = "text/plain"
180 baseName = "_redirects"
181 isPlainText = true
182 -- layouts/404.html --
183 {{ define "main" }}
184 404.
185 {{ end }}
186 -- layouts/home.html --
187 {{ define "main" }}
188 Home: {{ .Title }}|{{ .Content }}|
189 Inline Partial: {{ partial "my-inline-partial.html" . }}
190 {{ end }}
191 {{ define "hero" }}
192 Home hero.
193 {{ end }}
194 {{ define "partials/my-inline-partial.html" }}
195 {{ $value := 32 }}
196 {{ return $value }}
197 {{ end }}
198 -- layouts/index.redir --
199 Redir.
200 -- layouts/single.html --
201 {{ define "main" }}
202 Single needs base.
203 {{ end }}
204 -- layouts/foo/bar/single.html --
205 {{ define "main" }}
206 Single sub path.
207 {{ end }}
208 -- layouts/_markup/render-codeblock.html --
209 Render codeblock.
210 -- layouts/_markup/render-blockquote.html --
211 Render blockquote.
212 -- layouts/_markup/render-codeblock-go.html --
213 Render codeblock go.
214 -- layouts/_markup/render-link.html --
215 Link: {{ .Destination | safeURL }}
216 -- layouts/foo/baseof.html --
217 Base sub path.{{ block "main" . }}{{ end }}
218 -- layouts/foo/bar/baseof.page.html --
219 Base sub path.{{ block "main" . }}{{ end }}
220 -- layouts/list.html --
221 {{ define "main" }}
222 List needs base.
223 {{ end }}
224 -- layouts/section.html --
225 Section.
226 -- layouts/mysectionlayout.section.fr.amp.html --
227 Section with layout.
228 -- layouts/baseof.html --
229 Base.{{ block "main" . }}{{ end }}
230 Hero:{{ block "hero" . }}{{ end }}:
231 {{ with (templates.Defer (dict "key" "global")) }}
232 Defer Block.
233 {{ end }}
234 -- layouts/baseof.fr.html --
235 Base fr.{{ block "main" . }}{{ end }}
236 -- layouts/baseof.term.html --
237 Base term.
238 -- layouts/baseof.section.fr.amp.html --
239 Base with identifiers.{{ block "main" . }}{{ end }}
240 -- layouts/partials/mypartial.html --
241 Partial. {{ partial "_inline/my-inline-partial-in-partial-with-no-ext" . }}
242 {{ define "partials/_inline/my-inline-partial-in-partial-with-no-ext" }}
243 Partial in partial.
244 {{ end }}
245 -- layouts/partials/returnfoo.html --
246 {{ $v := "foo" }}
247 {{ return $v }}
248 -- layouts/shortcodes/myshortcode.html --
249 Shortcode. {{ partial "mypartial.html" . }}|return:{{ partial "returnfoo.html" . }}|
250 -- content/_index.md --
251 ---
252 title: Home sweet home!
253 ---
254
255 {{< myshortcode >}}
256
257 > My blockquote.
258
259
260 Markdown link: [Foo](/foo)
261 -- content/p1.md --
262 ---
263 title: "P1"
264 ---
265 -- content/foo/bar/index.md --
266 ---
267 title: "Foo Bar"
268 ---
269
270 {{< myshortcode >}}
271
272 -- content/single-list.md --
273 ---
274 title: "Single List"
275 layout: "list"
276 ---
277
278 `
279
280 func TestLayoutsType(t *testing.T) {
281 files := `
282 -- hugo.toml --
283 disableKinds = ["taxonomy", "term"]
284 -- layouts/list.html --
285 List.
286 -- layouts/mysection/single.html --
287 mysection/single|{{ .Title }}
288 -- layouts/mytype/single.html --
289 mytype/single|{{ .Title }}
290 -- content/mysection/_index.md --
291 -- content/mysection/mysubsection/_index.md --
292 -- content/mysection/mysubsection/p1.md --
293 ---
294 title: "P1"
295 ---
296 -- content/mysection/mysubsection/p2.md --
297 ---
298 title: "P2"
299 type: "mytype"
300 ---
301
302 `
303
304 b := hugolib.Test(t, files, hugolib.TestOptWarn())
305
306 b.AssertLogContains("! WARN")
307
308 b.AssertFileContent("public/mysection/mysubsection/p1/index.html", "mysection/single|P1")
309 b.AssertFileContent("public/mysection/mysubsection/p2/index.html", "mytype/single|P2")
310 }
311
312 // New, as in from Hugo v0.146.0.
313 func TestLayoutsNewSetup(t *testing.T) {
314 const numIterations = 1
315 for range numIterations {
316
317 b := hugolib.Test(t, newSetupTestSites, hugolib.TestOptWarn())
318
319 b.AssertLogContains("! WARN")
320
321 b.AssertFileContent("public/en/index.html",
322 "Base.\nHome: Home sweet home!|",
323 "|Shortcode.\n|",
324 "<p>Markdown link: Link: /foo</p>",
325 "|return:foo|",
326 "Defer Block.",
327 "Home hero.",
328 "Render blockquote.",
329 )
330
331 b.AssertFileContent("public/en/p1/index.html", "Base.\nSingle needs base.\n\nHero::\n\nDefer Block.")
332 b.AssertFileContent("public/en/404.html", "404.")
333 b.AssertFileContent("public/nn/404.html", "404.")
334 b.AssertFileContent("public/fr/404.html", "404.")
335
336 }
337 }
338
339 func TestHomeRSSAndHTMLWithHTMLOnlyShortcode(t *testing.T) {
340 t.Parallel()
341
342 files := `
343 -- hugo.toml --
344 disableKinds = ["taxonomy", "term"]
345 [outputs]
346 home = ["html", "rss"]
347 -- layouts/home.html --
348 Home: {{ .Title }}|{{ .Content }}|
349 -- layouts/single.html --
350 Single: {{ .Title }}|{{ .Content }}|
351 -- layouts/shortcodes/myshortcode.html --
352 Myshortcode: Count: {{ math.Counter }}|
353 -- content/p1.md --
354 ---
355 title: "P1"
356 ---
357
358 {{< myshortcode >}}
359 `
360
361 b := hugolib.Test(t, files)
362
363 b.AssertFileContent("public/p1/index.html", "Single: P1|Myshortcode: Count: 1|")
364 b.AssertFileContent("public/index.xml", "Myshortcode: Count: 1")
365 }
366
367 func TestHomeRSSAndHTMLWithHTMLOnlyRenderHook(t *testing.T) {
368 t.Parallel()
369
370 files := `
371 -- hugo.toml --
372 disableKinds = ["taxonomy", "term"]
373 [outputs]
374 home = ["html", "rss"]
375 -- layouts/home.html --
376 Home: {{ .Title }}|{{ .Content }}|
377 -- layouts/single.html --
378 Single: {{ .Title }}|{{ .Content }}|
379 -- layouts/_markup/render-link.html --
380 Render Link: {{ math.Counter }}|
381 -- content/p1.md --
382 ---
383 title: "P1"
384 ---
385
386 Link: [Foo](/foo)
387 `
388
389 for range 2 {
390 b := hugolib.Test(t, files)
391 b.AssertFileContent("public/index.xml", "Link: Render Link: 1|")
392 b.AssertFileContent("public/p1/index.html", "Single: P1|<p>Link: Render Link: 1|<")
393 }
394 }
395
396 func TestCodeblockIssue13864(t *testing.T) {
397 t.Parallel()
398
399 files := `
400 -- hugo.toml --
401 disableKinds = ['page','rss','section','sitemap','taxonomy','term']
402 -- content/_index.md --
403 ---
404 title: home
405 ---
406
407 ~~~
408 LANG: none
409 ~~~
410
411 ~~~go
412 LANG: go
413 ~~~
414
415 ~~~go-html-template
416 LANG: go-html-template
417 ~~~
418
419 ~~~xy
420 LANG: xy
421 ~~~
422
423 ~~~x-y
424 LANG: x-y
425 ~~~
426 -- layouts/home.html --
427 {{ .Content }}
428 -- layouts/_markup/render-codeblock.html --
429 {{ .Inner }} LAYOUT: render-codeblock.html|
430 -- layouts/_markup/render-codeblock-go.html --
431 {{ .Inner }} LAYOUT: render-codeblock-go.html|
432 -- layouts/_markup/render-codeblock-go-html-template.html --
433 {{ .Inner }} LAYOUT: render-codeblock-go-html-template.html|
434 -- layouts/_markup/render-codeblock-xy.html --
435 {{ .Inner }} LAYOUT: render-codeblock-xy.html|
436 -- layouts/_markup/render-codeblock-x-y.html.html --
437 {{ .Inner }} LAYOUT: render-codeblock-x-y.html|
438 `
439
440 b := hugolib.Test(t, files)
441
442 b.AssertFileContent("public/index.html",
443 "LANG: none LAYOUT: render-codeblock.html|", // pass
444 "LANG: go LAYOUT: render-codeblock-go.html|", // fail: uses render-codeblock-go-html-template.html
445 "LANG: go-html-template LAYOUT: render-codeblock-go-html-template.html|", // fail: uses render-codeblock.html
446 "LANG: xy LAYOUT: render-codeblock-xy.html|", // pass
447 "LANG: x-y LAYOUT: render-codeblock-x-y.html|", // fail: uses render-codeblock.html
448 )
449 }
450
451 func TestRenderCodeblockSpecificity(t *testing.T) {
452 files := `
453 -- hugo.toml --
454 -- layouts/_markup/render-codeblock.html --
455 Render codeblock.|{{ .Inner }}|
456 -- layouts/_markup/render-codeblock-go.html --
457 Render codeblock go.|{{ .Inner }}|
458 -- layouts/single.html --
459 {{ .Title }}|{{ .Content }}|
460 -- content/p1.md --
461 ---
462 title: "P1"
463 ---
464
465 §§§
466 Basic
467 §§§
468
469 §§§ go
470 Go
471 §§§
472
473 `
474
475 b := hugolib.Test(t, files)
476
477 b.AssertFileContent("public/p1/index.html", "P1|Render codeblock.|Basic|Render codeblock go.|Go|")
478 }
479
480 func TestPrintUnusedTemplates(t *testing.T) {
481 t.Parallel()
482
483 files := `
484 -- config.toml --
485 baseURL = 'http://example.com/'
486 printUnusedTemplates=true
487 -- content/p1.md --
488 ---
489 title: "P1"
490 ---
491 {{< usedshortcode >}}
492 -- layouts/baseof.html --
493 {{ block "main" . }}{{ end }}
494 -- layouts/baseof.json --
495 {{ block "main" . }}{{ end }}
496 -- layouts/index.html --
497 {{ define "main" }}FOO{{ end }}
498 -- layouts/_default/single.json --
499 -- layouts/_default/single.html --
500 {{ define "main" }}MAIN /_default/single.html{{ end }}
501 -- layouts/post/single.html --
502 {{ define "main" }}MAIN{{ end }}
503 -- layouts/_partials/usedpartial.html --
504 -- layouts/_partials/unusedpartial.html --
505 -- layouts/_shortcodes/usedshortcode.html --
506 {{ partial "usedpartial.html" }}
507 -- layouts/shortcodes/unusedshortcode.html --
508
509 `
510
511 b := hugolib.NewIntegrationTestBuilder(
512 hugolib.IntegrationTestConfig{
513 T: t,
514 TxtarString: files,
515 NeedsOsFS: true,
516 },
517 )
518 b.Build()
519
520 b.AssertFileContent("public/p1/index.html", "MAIN /_default/single.html")
521
522 unused := b.H.GetTemplateStore().UnusedTemplates()
523 var names []string
524 for _, tmpl := range unused {
525 if fi := tmpl.Fi; fi != nil {
526 names = append(names, fi.Meta().PathInfo.PathNoLeadingSlash())
527 }
528 }
529
530 b.Assert(names, qt.DeepEquals, []string{"_partials/unusedpartial.html", "shortcodes/unusedshortcode.html", "baseof.json", "post/single.html", "_default/single.json"})
531 b.Assert(len(unused), qt.Equals, 5, qt.Commentf("%#v", names))
532 }
533
534 func TestCreateManyTemplateStores(t *testing.T) {
535 t.Parallel()
536 b := hugolib.Test(t, newSetupTestSites)
537 store := b.H.TemplateStore
538
539 for range 70 {
540 newStore, err := store.NewFromOpts()
541 b.Assert(err, qt.IsNil)
542 b.Assert(newStore, qt.Not(qt.IsNil))
543 }
544 }
545
546 func BenchmarkLookupPagesLayout(b *testing.B) {
547 files := `
548 -- hugo.toml --
549 -- layouts/single.html --
550 {{ define "main" }}
551 Main.
552 {{ end }}
553 -- layouts/baseof.html --
554 baseof: {{ block "main" . }}{{ end }}
555 -- layouts/foo/bar/single.html --
556 {{ define "main" }}
557 Main.
558 {{ end }}
559
560 `
561 bb := hugolib.Test(b, files)
562 store := bb.H.TemplateStore
563
564 b.ResetTimer()
565 b.Run("Single root", func(b *testing.B) {
566 q := tplimpl.TemplateQuery{
567 Path: "/baz",
568 Category: tplimpl.CategoryLayout,
569 Desc: tplimpl.TemplateDescriptor{Kind: kinds.KindPage, LayoutFromTemplate: "single", OutputFormat: "html"},
570 }
571 for i := 0; i < b.N; i++ {
572 store.LookupPagesLayout(q)
573 }
574 })
575
576 b.Run("Single sub folder", func(b *testing.B) {
577 q := tplimpl.TemplateQuery{
578 Path: "/foo/bar",
579 Category: tplimpl.CategoryLayout,
580 Desc: tplimpl.TemplateDescriptor{Kind: kinds.KindPage, LayoutFromTemplate: "single", OutputFormat: "html"},
581 }
582 for i := 0; i < b.N; i++ {
583 store.LookupPagesLayout(q)
584 }
585 })
586 }
587
588 func BenchmarkNewTemplateStore(b *testing.B) {
589 bb := hugolib.Test(b, newSetupTestSites)
590 store := bb.H.TemplateStore
591
592 b.ResetTimer()
593 for i := 0; i < b.N; i++ {
594 newStore, err := store.NewFromOpts()
595 if err != nil {
596 b.Fatal(err)
597 }
598 if newStore == nil {
599 b.Fatal("newStore is nil")
600 }
601 }
602 }
603
604 func TestLayoutsLookupVariants(t *testing.T) {
605 t.Parallel()
606
607 files := `
608 -- hugo.toml --
609 defaultContentLanguage = "en"
610 defaultContentLanguageInSubdir = true
611 [outputs]
612 home = ["html", "rss"]
613 page = ["html", "rss", "amp"]
614 section = ["html", "rss"]
615
616 [languages]
617 [languages.en]
618 title = "Title in English"
619 weight = 1
620 [languages.nn]
621 title = "Tittel på nynorsk"
622 weight = 2
623 -- layouts/list.xml --
624 layouts/list.xml
625 -- layouts/_shortcodes/myshortcode.html --
626 layouts/shortcodes/myshortcode.html
627 -- layouts/foo/bar/_shortcodes/myshortcode.html --
628 layouts/foo/bar/_shortcodes/myshortcode.html
629 -- layouts/_markup/render-codeblock.html --
630 layouts/_markup/render-codeblock.html|{{ .Type }}|
631 -- layouts/_markup/render-codeblock-go.html --
632 layouts/_markup/render-codeblock-go.html|{{ .Type }}|
633 -- layouts/single.xml --
634 layouts/single.xml
635 -- layouts/single.rss.xml --
636 layouts/single.rss.xml
637 -- layouts/single.nn.rss.xml --
638 layouts/single.nn.rss.xml
639 -- layouts/list.html --
640 layouts/list.html
641 -- layouts/single.html --
642 layouts/single.html
643 {{ .Content }}
644 -- layouts/mylayout.html --
645 layouts/mylayout.html
646 -- layouts/mylayout.nn.html --
647 layouts/mylayout.nn.html
648 -- layouts/foo/single.rss.xml --
649 layouts/foo/single.rss.xml
650 -- layouts/foo/single.amp.html --
651 layouts/foo/single.amp.html
652 -- layouts/foo/bar/page.html --
653 layouts/foo/bar/page.html
654 -- layouts/foo/bar/baz/single.html --
655 layouts/foo/bar/baz/single.html
656 {{ .Content }}
657 -- layouts/qux/mylayout.html --
658 layouts/qux/mylayout.html
659 -- layouts/qux/single.xml --
660 layouts/qux/single.xml
661 -- layouts/qux/mylayout.section.html --
662 layouts/qux/mylayout.section.html
663 -- content/p.md --
664 ---
665 ---
666 §§§
667 code
668 §§§
669
670 §§§ go
671 code
672 §§§
673
674 {{< myshortcode >}}
675 -- content/foo/p.md --
676 -- content/foo/p.nn.md --
677 -- content/foo/bar/p.md --
678 -- content/foo/bar/withmylayout.md --
679 ---
680 layout: mylayout
681 ---
682 -- content/foo/bar/_index.md --
683 -- content/foo/bar/baz/p.md --
684 ---
685 ---
686 {{< myshortcode >}}
687 -- content/qux/p.md --
688 -- content/qux/_index.md --
689 ---
690 layout: mylayout
691 ---
692 -- content/qux/quux/p.md --
693 -- content/qux/quux/withmylayout.md --
694 ---
695 layout: mylayout
696 ---
697 -- content/qux/quux/withmylayout.nn.md --
698 ---
699 layout: mylayout
700 ---
701
702
703 `
704
705 b := hugolib.Test(t, files, hugolib.TestOptWarn())
706
707 b.AssertLogContains("! WARN")
708
709 // Single pages.
710 // output format: html.
711 b.AssertFileContent("public/en/p/index.html", "layouts/single.html",
712 "layouts/_markup/render-codeblock.html|",
713 "layouts/_markup/render-codeblock-go.html|go|",
714 "layouts/shortcodes/myshortcode.html",
715 )
716 b.AssertFileContent("public/en/foo/p/index.html", "layouts/single.html")
717 b.AssertFileContent("public/en/foo/bar/p/index.html", "layouts/foo/bar/page.html")
718 b.AssertFileContent("public/en/foo/bar/withmylayout/index.html", "layouts/mylayout.html")
719 b.AssertFileContent("public/en/foo/bar/baz/p/index.html", "layouts/foo/bar/baz/single.html", "layouts/foo/bar/_shortcodes/myshortcode.html")
720 b.AssertFileContent("public/en/qux/quux/withmylayout/index.html", "layouts/qux/mylayout.html")
721 // output format: amp.
722 b.AssertFileContent("public/en/amp/p/index.html", "layouts/single.html")
723 b.AssertFileContent("public/en/amp/foo/p/index.html", "layouts/foo/single.amp.html")
724 // output format: rss.
725 b.AssertFileContent("public/en/p/index.xml", "layouts/single.rss.xml")
726 b.AssertFileContent("public/en/foo/p/index.xml", "layouts/foo/single.rss.xml")
727 b.AssertFileContent("public/nn/foo/p/index.xml", "layouts/single.nn.rss.xml")
728
729 // Note: There is qux/single.xml that's closer, but the one in the root is used becaulse of the output format match.
730 b.AssertFileContent("public/en/qux/p/index.xml", "layouts/single.rss.xml")
731
732 // Note.
733 b.AssertFileContent("public/nn/qux/quux/withmylayout/index.html", "layouts/mylayout.nn.html")
734
735 // Section pages.
736 // output format: html.
737 b.AssertFileContent("public/en/foo/index.html", "layouts/list.html")
738 b.AssertFileContent("public/en/qux/index.html", "layouts/qux/mylayout.section.html")
739 // output format: rss.
740 b.AssertFileContent("public/en/foo/index.xml", "layouts/list.xml")
741 }
742
743 func TestLookupOrderIssue13636(t *testing.T) {
744 t.Parallel()
745
746 filesTemplate := `
747 -- hugo.toml --
748 defaultContentLanguage = "en"
749 defaultContentLanguageInSubdir = true
750 [languages]
751 [languages.en]
752 weight = 1
753 [languages.nn]
754 weight = 2
755 -- content/s1/p1.en.md --
756 ---
757 outputs: ["html", "amp", "json"]
758 ---
759 -- content/s1/p1.nn.md --
760 ---
761 outputs: ["html", "amp", "json"]
762 ---
763 -- layouts/L1 --
764 L1
765 -- layouts/L2 --
766 L2
767 -- layouts/L3 --
768 L3
769
770 `
771
772 tests := []struct {
773 Lang string
774 L1 string
775 L2 string
776 L3 string
777 ExpectHTML string
778 ExpectAmp string
779 ExpectJSON string
780 }{
781 {"en", "all.en.html", "all.html", "single.html", "single.html", "single.html", ""},
782 {"en", "all.amp.html", "all.html", "page.html", "page.html", "all.amp.html", ""},
783 {"en", "all.amp.html", "all.html", "list.html", "all.html", "all.amp.html", ""},
784 {"en", "all.en.html", "all.json", "single.html", "single.html", "single.html", "all.json"},
785 {"en", "all.en.html", "single.json", "single.html", "single.html", "single.html", "single.json"},
786 {"en", "all.en.html", "all.html", "list.html", "all.en.html", "all.en.html", ""},
787 {"en", "list.en.html", "list.html", "list.en.html", "", "", ""},
788 {"nn", "all.en.html", "all.html", "single.html", "single.html", "single.html", ""},
789 {"nn", "all.en.html", "all.nn.html", "single.html", "single.html", "single.html", ""},
790 {"nn", "all.en.html", "all.nn.html", "single.nn.html", "single.nn.html", "single.nn.html", ""},
791 {"nn", "single.json", "single.nn.json", "all.json", "", "", "single.nn.json"},
792 {"nn", "single.json", "single.en.json", "all.nn.json", "", "", "single.json"},
793 }
794
795 for i, test := range tests {
796 if i != 8 {
797 // continue
798 }
799 files := strings.ReplaceAll(filesTemplate, "L1", test.L1)
800 files = strings.ReplaceAll(files, "L2", test.L2)
801 files = strings.ReplaceAll(files, "L3", test.L3)
802 t.Logf("Test %d: %s %s %s %s", i, test.Lang, test.L1, test.L2, test.L3)
803
804 for range 3 {
805 b := hugolib.Test(t, files)
806 b.Assert(len(b.H.Sites), qt.Equals, 2)
807
808 var (
809 pubhHTML = "public/LANG/s1/p1/index.html"
810 pubhAmp = "public/LANG/amp/s1/p1/index.html"
811 pubhJSON = "public/LANG/s1/p1/index.json"
812 )
813
814 pubhHTML = strings.ReplaceAll(pubhHTML, "LANG", test.Lang)
815 pubhAmp = strings.ReplaceAll(pubhAmp, "LANG", test.Lang)
816 pubhJSON = strings.ReplaceAll(pubhJSON, "LANG", test.Lang)
817
818 if test.ExpectHTML != "" {
819 b.AssertFileContent(pubhHTML, test.ExpectHTML)
820 } else {
821 b.AssertFileExists(pubhHTML, false)
822 }
823
824 if test.ExpectAmp != "" {
825 b.AssertFileContent(pubhAmp, test.ExpectAmp)
826 } else {
827 b.AssertFileExists(pubhAmp, false)
828 }
829
830 if test.ExpectJSON != "" {
831 b.AssertFileContent(pubhJSON, test.ExpectJSON)
832 } else {
833 b.AssertFileExists(pubhJSON, false)
834 }
835 }
836 }
837 }
838
839 func TestLookupShortcodeDepth(t *testing.T) {
840 t.Parallel()
841
842 files := `
843 -- hugo.toml --
844 -- layouts/_shortcodes/myshortcode.html --
845 layouts/_shortcodes/myshortcode.html
846 -- layouts/foo/_shortcodes/myshortcode.html --
847 layouts/foo/_shortcodes/myshortcode.html
848 -- layouts/single.html --
849 {{ .Content }}|
850 -- content/p.md --
851 ---
852 ---
853 {{< myshortcode >}}
854 -- content/foo/p.md --
855 ---
856 ---
857 {{< myshortcode >}}
858 -- content/foo/bar/p.md --
859 ---
860 ---
861 {{< myshortcode >}}
862 `
863
864 b := hugolib.Test(t, files)
865
866 b.AssertFileContent("public/p/index.html", "layouts/_shortcodes/myshortcode.html")
867 b.AssertFileContent("public/foo/p/index.html", "layouts/foo/_shortcodes/myshortcode.html")
868 b.AssertFileContent("public/foo/bar/p/index.html", "layouts/foo/_shortcodes/myshortcode.html")
869 }
870
871 func TestLookupShortcodeLayout(t *testing.T) {
872 t.Parallel()
873
874 files := `
875 -- hugo.toml --
876 -- layouts/_shortcodes/myshortcode.single.html --
877 layouts/_shortcodes/myshortcode.single.html
878 -- layouts/_shortcodes/myshortcode.list.html --
879 layouts/_shortcodes/myshortcode.list.html
880 -- layouts/single.html --
881 {{ .Content }}|
882 -- layouts/list.html --
883 {{ .Content }}|
884 -- content/_index.md --
885 ---
886 ---
887 {{< myshortcode >}}
888 -- content/p.md --
889 ---
890 ---
891 {{< myshortcode >}}
892 -- content/foo/p.md --
893 ---
894 ---
895 {{< myshortcode >}}
896 -- content/foo/bar/p.md --
897 ---
898 ---
899 {{< myshortcode >}}
900 `
901
902 b := hugolib.Test(t, files)
903
904 b.AssertFileContent("public/p/index.html", "layouts/_shortcodes/myshortcode.single.html")
905 b.AssertFileContent("public/index.html", "layouts/_shortcodes/myshortcode.list.html")
906 }
907
908 func TestLayoutAll(t *testing.T) {
909 t.Parallel()
910
911 files := `
912 -- hugo.toml --
913 -- layouts/single.html --
914 Single.
915 -- layouts/all.html --
916 All.
917 -- content/p1.md --
918
919 `
920
921 b := hugolib.Test(t, files)
922
923 b.AssertFileContent("public/p1/index.html", "Single.")
924 b.AssertFileContent("public/index.html", "All.")
925 }
926
927 func TestLayoutAllNested(t *testing.T) {
928 t.Parallel()
929
930 files := `
931 -- hugo.toml --
932 disableKinds = ['rss','sitemap','taxonomy','term']
933 -- content/s1/p1.md --
934 ---
935 title: p1
936 ---
937 -- content/s2/p2.md --
938 ---
939 title: p2
940 ---
941 -- layouts/single.html --
942 layouts/single.html
943 -- layouts/list.html --
944 layouts/list.html
945 -- layouts/s1/all.html --
946 layouts/s1/all.html
947 `
948
949 b := hugolib.Test(t, files)
950
951 b.AssertFileContent("public/index.html", "layouts/list.html")
952 b.AssertFileContent("public/s1/index.html", "layouts/s1/all.html")
953 b.AssertFileContent("public/s1/p1/index.html", "layouts/s1/all.html")
954 b.AssertFileContent("public/s2/index.html", "layouts/list.html")
955 b.AssertFileContent("public/s2/p2/index.html", "layouts/single.html")
956 }
957
958 func TestPartialHTML(t *testing.T) {
959 t.Parallel()
960
961 files := `
962 -- hugo.toml --
963 -- layouts/all.html --
964 <html>
965 <head>
966 {{ partial "css.html" .}}
967 </head>
968 </html>
969 -- layouts/partials/css.html --
970 <link rel="stylesheet" href="/css/style.css">
971 `
972
973 b := hugolib.Test(t, files)
974
975 b.AssertFileContent("public/index.html", "<link rel=\"stylesheet\" href=\"/css/style.css\">")
976 }
977
978 func TestPartialPlainTextInHTML(t *testing.T) {
979 t.Parallel()
980
981 files := `
982 -- hugo.toml --
983 -- layouts/all.html --
984 <html>
985 <head>
986 {{ partial "mypartial.txt" . }}
987 </head>
988 </html>
989 -- layouts/partials/mypartial.txt --
990 My <div>partial</div>.
991 `
992
993 b := hugolib.Test(t, files)
994
995 b.AssertFileContent("public/index.html", "My <div>partial</div>.")
996 }
997
998 // Issue #13593.
999 func TestGoatAndNoGoat(t *testing.T) {
1000 t.Parallel()
1001
1002 files := `
1003 -- hugo.toml --
1004 -- content/_index.md --
1005 ---
1006 title: "Home"
1007 ---
1008
1009
1010 §§§
1011 printf "Hello, world!"
1012 §§§
1013
1014
1015 §§§ goat
1016 .---. .-. .-. .-. .---.
1017 | A +--->| 1 |<--->| 2 |<--->| 3 |<---+ B |
1018 '---' '-' '+' '+' '---'
1019 §§§
1020
1021
1022
1023 -- layouts/all.html --
1024 {{ .Content }}
1025
1026 `
1027
1028 b := hugolib.Test(t, files)
1029
1030 // Basic code block.
1031 b.AssertFileContent("public/index.html", "<code>printf "Hello, world!"\n</code>")
1032
1033 // Goat code block.
1034 b.AssertFileContent("public/index.html", "Menlo,Lucida")
1035 }
1036
1037 // Issue #13595.
1038 func TestGoatAndNoGoatCustomTemplate(t *testing.T) {
1039 t.Parallel()
1040
1041 files := `
1042 -- hugo.toml --
1043 -- content/_index.md --
1044 ---
1045 title: "Home"
1046 ---
1047
1048 §§§
1049 printf "Hello, world!"
1050 §§§
1051
1052 §§§ goat
1053 .---. .-. .-. .-. .---.
1054 | A +--->| 1 |<--->| 2 |<--->| 3 |<---+ B |
1055 '---' '-' '+' '+' '---'
1056 §§§
1057
1058
1059
1060 -- layouts/_markup/render-codeblock.html --
1061 _markup/render-codeblock.html
1062 -- layouts/all.html --
1063 {{ .Content }}
1064
1065 `
1066
1067 b := hugolib.Test(t, files)
1068
1069 // Basic code block.
1070 b.AssertFileContent("public/index.html", "_markup/render-codeblock.html")
1071
1072 // Goat code block.
1073 b.AssertFileContent("public/index.html", "Menlo,Lucida")
1074 }
1075
1076 func TestGoatcustom(t *testing.T) {
1077 t.Parallel()
1078
1079 files := `
1080 -- hugo.toml --
1081 -- content/_index.md --
1082 ---
1083 title: "Home"
1084 ---
1085
1086 §§§
1087 printf "Hello, world!"
1088 §§§
1089
1090 §§§ goat
1091 .---. .-. .-. .-. .---.
1092 | A +--->| 1 |<--->| 2 |<--->| 3 |<---+ B |
1093 '---' '-' '+' '+' '---'
1094 §§§
1095
1096
1097
1098 -- layouts/_markup/render-codeblock.html --
1099 _markup/render-codeblock.html
1100 -- layouts/_markup/render-codeblock-goat.html --
1101 _markup/render-codeblock-goat.html
1102 -- layouts/all.html --
1103 {{ .Content }}
1104
1105 `
1106
1107 b := hugolib.Test(t, files)
1108
1109 // Basic code block.
1110 b.AssertFileContent("public/index.html", "_markup/render-codeblock.html")
1111
1112 // Custom Goat code block.
1113 b.AssertFileContent("public/index.html", "_markup/render-codeblock.html_markup/render-codeblock-goat.html")
1114 }
1115
1116 func TestLookupCodeblockIssue13651(t *testing.T) {
1117 t.Parallel()
1118
1119 files := `
1120 -- hugo.toml --
1121 -- layouts/all.html --
1122 {{ .Content }}|
1123 -- layouts/_markup/render-codeblock-foo.html --
1124 render-codeblock-foo.html
1125 -- content/_index.md --
1126 ---
1127 ---
1128
1129 §§§
1130 printf "Hello, world!"
1131 §§§
1132
1133 §§§ foo
1134 printf "Hello, world again!"
1135 §§§
1136 `
1137
1138 b := hugolib.Test(t, files)
1139
1140 content := b.FileContent("public/index.html")
1141 fooCount := strings.Count(content, "render-codeblock-foo.html")
1142 b.Assert(fooCount, qt.Equals, 1)
1143 }
1144
1145 // Issue #13515
1146 func TestPrintPathWarningOnDotRemoval(t *testing.T) {
1147 t.Parallel()
1148
1149 files := `
1150 -- hugo.toml --
1151 baseURL = "https://example.com"
1152 printPathWarnings = true
1153 -- content/v0.124.0.md --
1154 -- content/v0.123.0.md --
1155 -- layouts/all.html --
1156 All.
1157 -- layouts/_default/single.html --
1158 {{ .Title }}|
1159 `
1160
1161 b := hugolib.Test(t, files, hugolib.TestOptWarn())
1162
1163 b.AssertLogContains("! Duplicate content path")
1164 }
1165
1166 // Issue #13577.
1167 func TestPrintPathWarningOnInvalidMarkupFilename(t *testing.T) {
1168 t.Parallel()
1169
1170 files := `
1171 -- hugo.toml --
1172 -- layouts/all.html --
1173 All.
1174 -- layouts/_markup/sitemap.xml --
1175 `
1176 b := hugolib.Test(t, files, hugolib.TestOptWarn())
1177
1178 b.AssertLogContains("unrecognized render hook")
1179 }
1180
1181 func TestLayoutNotFound(t *testing.T) {
1182 t.Parallel()
1183
1184 files := `
1185 -- hugo.toml --
1186 -- layouts/single.html --
1187 Single.
1188 `
1189 b := hugolib.Test(t, files, hugolib.TestOptWarn())
1190 b.AssertLogContains("WARN found no layout file for \"html\" for kind \"home\"")
1191 }
1192
1193 func TestLayoutOverrideThemeWhenThemeOnOldFormatIssue13715(t *testing.T) {
1194 t.Parallel()
1195
1196 files := `
1197 -- hugo.toml --
1198 theme = "mytheme"
1199 -- layouts/list.html --
1200 layouts/list.html
1201 -- themes/mytheme/layouts/_default/list.html --
1202 mytheme/layouts/_default/list.html
1203
1204 `
1205
1206 b := hugolib.Test(t, files)
1207 b.AssertFileContent("public/index.html", "layouts/list.html")
1208 }
1209
1210 func BenchmarkExecuteWithContext(b *testing.B) {
1211 files := `
1212 -- hugo.toml --
1213 disableKinds = ["taxonomy", "term", "home"]
1214 -- layouts/all.html --
1215 {{ .Title }}|
1216 {{ partial "p1.html" . }}
1217 -- layouts/_partials/p1.html --
1218 p1.
1219 {{ partial "p2.html" . }}
1220 {{ partial "p2.html" . }}
1221 {{ partial "p3.html" . }}
1222 {{ partial "p2.html" . }}
1223 {{ partial "p2.html" . }}
1224 {{ partial "p2.html" . }}
1225 {{ partial "p3.html" . }}
1226 -- layouts/_partials/p2.html --
1227 {{ partial "p3.html" . }}
1228 -- layouts/_partials/p3.html --
1229 p3
1230 -- content/p1.md --
1231 `
1232
1233 bb := hugolib.Test(b, files)
1234
1235 store := bb.H.TemplateStore
1236
1237 ti := store.LookupByPath("/all.html")
1238 bb.Assert(ti, qt.Not(qt.IsNil))
1239 p := bb.H.Sites[0].RegularPages()[0]
1240 bb.Assert(p, qt.Not(qt.IsNil))
1241
1242 b.ResetTimer()
1243 for i := 0; i < b.N; i++ {
1244 err := store.ExecuteWithContext(context.Background(), ti, io.Discard, p)
1245 if err != nil {
1246 b.Fatal(err)
1247 }
1248 }
1249 }
1250
1251 func BenchmarkLookupPartial(b *testing.B) {
1252 files := `
1253 -- hugo.toml --
1254 disableKinds = ["taxonomy", "term", "home"]
1255 -- layouts/all.html --
1256 {{ .Title }}|
1257 -- layouts/_partials/p1.html --
1258 -- layouts/_partials/p2.html --
1259 -- layouts/_partials/p2.json --
1260 -- layouts/_partials/p3.html --
1261 `
1262 bb := hugolib.Test(b, files)
1263
1264 store := bb.H.TemplateStore
1265
1266 for i := 0; i < b.N; i++ {
1267 fi := store.LookupPartial("p3.html")
1268 if fi == nil {
1269 b.Fatal("not found")
1270 }
1271 }
1272 }
1273
1274 // Implemented by pageOutput.
1275 type getDescriptorProvider interface {
1276 GetInternalTemplateBasePathAndDescriptor() (string, tplimpl.TemplateDescriptor)
1277 }
1278
1279 func BenchmarkLookupShortcode(b *testing.B) {
1280 files := `
1281 -- hugo.toml --
1282 disableKinds = ["taxonomy", "term", "home"]
1283 -- content/toplevelpage.md --
1284 -- content/a/b/c/nested.md --
1285 -- layouts/all.html --
1286 {{ .Title }}|
1287 -- layouts/_shortcodes/s.html --
1288 s1.
1289 -- layouts/_shortcodes/a/b/s.html --
1290 s2.
1291
1292 `
1293 bb := hugolib.Test(b, files)
1294 store := bb.H.TemplateStore
1295
1296 runOne := func(p page.Page) {
1297 pth, desc := p.(getDescriptorProvider).GetInternalTemplateBasePathAndDescriptor()
1298 q := tplimpl.TemplateQuery{
1299 Path: pth,
1300 Name: "s",
1301 Category: tplimpl.CategoryShortcode,
1302 Desc: desc,
1303 }
1304 v, err := store.LookupShortcode(q)
1305 if v == nil || err != nil {
1306 b.Fatal("not found")
1307 }
1308 }
1309
1310 b.Run("toplevelpage", func(b *testing.B) {
1311 toplevelpage, _ := bb.H.Sites[0].GetPage("/toplevelpage")
1312 for i := 0; i < b.N; i++ {
1313 runOne(toplevelpage)
1314 }
1315 })
1316
1317 b.Run("nestedpage", func(b *testing.B) {
1318 toplevelpage, _ := bb.H.Sites[0].GetPage("/a/b/c/nested")
1319 for i := 0; i < b.N; i++ {
1320 runOne(toplevelpage)
1321 }
1322 })
1323 }
1324
1325 func TestStandardLayoutInFrontMatter13588(t *testing.T) {
1326 t.Parallel()
1327
1328 files := `
1329 -- hugo.toml --
1330 disableKinds = ['home','page','rss','sitemap','taxonomy','term']
1331 -- content/s1/_index.md --
1332 ---
1333 title: s1
1334 ---
1335 -- content/s2/_index.md --
1336 ---
1337 title: s2
1338 layout: list
1339 ---
1340 -- content/s3/_index.md --
1341 ---
1342 title: s3
1343 layout: single
1344 ---
1345 -- layouts/list.html --
1346 list.html
1347 -- layouts/section.html --
1348 section.html
1349 -- layouts/single.html --
1350 single.html
1351 `
1352
1353 b := hugolib.Test(t, files)
1354
1355 b.AssertFileContent("public/s1/index.html", "section.html")
1356 b.AssertFileContent("public/s2/index.html", "list.html") // fail
1357 b.AssertFileContent("public/s3/index.html", "single.html") // fail
1358 }
1359
1360 func TestIssue13605(t *testing.T) {
1361 t.Parallel()
1362
1363 files := `
1364 -- hugo.toml --
1365 disableKinds = ['home','rss','section','sitemap','taxonomy','term']
1366 -- content/s1/p1.md --
1367 ---
1368 title: p1
1369 ---
1370 {{< sc >}}
1371 -- layouts/s1/_shortcodes/sc.html --
1372 layouts/s1/_shortcodes/sc.html
1373 -- layouts/single.html --
1374 {{ .Content }}
1375 `
1376
1377 b := hugolib.Test(t, files)
1378
1379 b.AssertFileContent("public/s1/p1/index.html", "layouts/s1/_shortcodes/sc.html")
1380 }
1381
1382 func TestSkipDotFiles(t *testing.T) {
1383 t.Parallel()
1384
1385 files := `
1386 -- hugo.toml --
1387 -- layouts/all.html --
1388 All.
1389 -- layouts/.DS_Store --
1390 {{ foo }}
1391 `
1392
1393 // Just make sure it doesn't fail.
1394 hugolib.Test(t, files)
1395 }
1396
1397 func TestPartialsLangIssue13612(t *testing.T) {
1398 t.Parallel()
1399
1400 files := `
1401 -- hugo.toml --
1402 disableKinds = ['page','section','sitemap','taxonomy','term']
1403
1404 defaultContentLanguage = 'ru'
1405 defaultContentLanguageInSubdir = true
1406
1407 [languages.ru]
1408 weight = 1
1409
1410 [languages.en]
1411 weight = 2
1412
1413 [outputs]
1414 home = ['html','rss']
1415
1416 -- layouts/_partials/comment.en.html --
1417 layouts/_partials/comment.en.html
1418 -- layouts/_partials/comment.en.xml --
1419 layouts/_partials/comment.en.xml
1420 -- layouts/_partials/comment.ru.html --
1421 layouts/_partials/comment.ru.html
1422 -- layouts/_partials/comment.ru.xml --
1423 layouts/_partials/comment.ru.xml
1424 -- layouts/home.html --
1425 {{ partial (print "comment." (default "ru" .Lang) ".html") . }}
1426 -- layouts/home.rss.xml --
1427 {{ partial (print "comment." (default "ru" .Lang) ".xml") . }}
1428 `
1429
1430 b := hugolib.Test(t, files)
1431
1432 b.AssertFileContent("public/en/index.html", "layouts/_partials/comment.en.html")
1433 b.AssertFileContent("public/en/index.xml", "layouts/_partials/comment.en.xml") // fail
1434 b.AssertFileContent("public/ru/index.html", "layouts/_partials/comment.ru.html") // fail
1435 b.AssertFileContent("public/ru/index.xml", "layouts/_partials/comment.ru.xml") // fail
1436 }
1437
1438 func TestLayoutIssue13628(t *testing.T) {
1439 t.Parallel()
1440
1441 files := `
1442 -- hugo.toml --
1443 disableKinds = ['home','rss','sitemap','taxonomy','term']
1444 -- content/p1.md --
1445 ---
1446 title: p1
1447 layout: foo
1448 ---
1449 -- layouts/single.html --
1450 layouts/single.html
1451 -- layouts/list.html --
1452 layouts/list.html
1453 `
1454
1455 for range 5 {
1456
1457 b := hugolib.Test(t, files)
1458
1459 b.AssertFileContent("public/p1/index.html", "layouts/single.html")
1460 }
1461 }
1462
1463 func TestTemplateLoop(t *testing.T) {
1464 t.Parallel()
1465
1466 files := `
1467 -- hugo.toml --
1468 -- layouts/_partials/p.html --
1469 p: {{ partial "p.html" . }}
1470 -- layouts/all.html --
1471 {{ partial "p.html" . }}
1472
1473 `
1474 b, err := hugolib.TestE(t, files)
1475 b.Assert(err, qt.IsNotNil)
1476 b.Assert(err.Error(), qt.Contains, "error calling partial: maximum template call stack size exceeded")
1477 }
1478
1479 func TestIssue13630(t *testing.T) {
1480 t.Parallel()
1481
1482 files := `
1483 -- hugo.toml --
1484 disableKinds = ['rss','sitemap']
1485 -- content/p1.md --
1486 ---
1487 title: p1
1488 layout: foo
1489 ---
1490 -- layouts/list.html --
1491 layouts/list.html
1492 -- layouts/taxononmy.html.html --
1493 layouts/taxononmy.html.html
1494 `
1495
1496 var b *hugolib.IntegrationTestBuilder
1497
1498 for range 3 {
1499 b = hugolib.Test(t, files)
1500 b.AssertFileExists("public/p1/index.html", false)
1501 }
1502 }
1503
1504 func TestTemplateLoopBlogVsBlogrollIssue13672(t *testing.T) {
1505 t.Parallel()
1506 files := `
1507 -- hugo.toml --
1508 -- layouts/blog/_shortcodes/myshortcode.html --
1509 layouts/blog/_shortcodes/myshortcode.html
1510 -- layouts/blog/baseof.html --
1511 blog/baseof.html {{ block "main" . }}{{ end }}
1512 -- layouts/blog/all.html --
1513 {{ define "main" }}blog/all.html|{{ .Content}}{{ end }}
1514 -- layouts/blogroll/_shortcodes/myshortcode.html --
1515 layouts/blogroll/myshortcode.html
1516 -- layouts/blogroll/baseof.html --
1517 {{ block "main" . }}blogroll/baseof.html{{ end }}
1518 -- layouts/blogroll/all.html --
1519 {{ define "main" }}blogroll/all.html|{{ .Content}}{{ end }}
1520 -- content/blog/p1.md --
1521 ---
1522 title: p1
1523 ---
1524 {{< myshortcode >}}
1525 -- content/blogroll/p1.md --
1526 ---
1527 title: p1
1528 ---
1529 {{< myshortcode >}}
1530 `
1531
1532 b := hugolib.Test(t, files)
1533
1534 b.AssertFileContent("public/blog/p1/index.html", "blog/baseof.html blog/all.html|layouts/blog/_shortcodes/myshortcode.html")
1535 b.AssertFileContent("public/blogroll/p1/index.html", "blogroll/all.html|layouts/blogroll/myshortcode.html")
1536 }
1537
1538 // See issue #13668.
1539 func TestPartialPlainTextVsHTML(t *testing.T) {
1540 t.Parallel()
1541
1542 /*
1543 Note that in the below, there's no output format named txt,
1544 so the isPlainText is fetched from the only output format with that extension.
1545 */
1546 files := `
1547 -- hugo.toml --
1548 -- layouts/_partials/myhtml.html --
1549 <div>myhtml</div>
1550 -- layouts/_partials/mytext.txt --
1551 <div>mytext</div>
1552 -- layouts/all.html --
1553 myhtml: {{ partial "myhtml.html" . }}
1554 mytext: {{ partial "mytext.txt" . }}
1555 mytexts|safeHTML: {{ partial "mytext.txt" . | safeHTML }}
1556 `
1557
1558 b := hugolib.Test(t, files)
1559
1560 b.AssertFileContent("public/index.html",
1561 "myhtml: <div>myhtml</div>",
1562 "mytext: <div>mytext</div>",
1563 "mytexts|safeHTML: <div>mytext</div>",
1564 )
1565 }
1566
1567 func TestIssue13351(t *testing.T) {
1568 t.Parallel()
1569
1570 files := `
1571 -- hugo.toml --
1572 disableKinds = ['page','rss','section','sitemap','taxonomy','term']
1573 [outputs]
1574 home = ['html','json']
1575 [outputFormats.html]
1576 weight = 1
1577 [outputFormats.json]
1578 weight = 2
1579 -- content/_index.md --
1580 ---
1581 title: home
1582 ---
1583 a|b
1584 :--|:--
1585 1|2
1586 -- layouts/index.html --
1587 {{ .Content }}
1588 -- layouts/index.json --
1589 {{ .Content }}
1590 `
1591
1592 b := hugolib.Test(t, files)
1593 b.AssertFileContent("public/index.html", "<table>")
1594 b.AssertFileContent("public/index.json", "<table>")
1595
1596 f := strings.ReplaceAll(files, "weight = 1", "weight = 0")
1597 b = hugolib.Test(t, f)
1598 b.AssertFileContent("public/index.html", "<table>")
1599 b.AssertFileContent("public/index.json", "<table>")
1600
1601 f = strings.ReplaceAll(files, "weight = 1", "")
1602 b = hugolib.Test(t, f)
1603 b.AssertFileContent("public/index.html", "<table>")
1604 b.AssertFileContent("public/index.json", "<table>")
1605 }
1606
1607 func TestPageKindIssue13868(t *testing.T) {
1608 t.Parallel()
1609
1610 files := `
1611 -- hugo.toml --
1612 disableKinds = ['home','rss','section','sitemap','taxonomy','term']
1613 -- content/p1.md --
1614 ---
1615 title: p1
1616 ---
1617 -- layouts/page.html --
1618 layouts/page.html
1619 -- layouts/p1/page.html --
1620 layouts/p1/page.html
1621 `
1622
1623 b := hugolib.Test(t, files)
1624
1625 b.AssertFileContent("public/p1/index.html", "layouts/p1/page.html")
1626 }