menu_test.go - hugo - [fork] hugo port for 9front
HTML git clone https://git.drkhsh.at/hugo.git
DIR Log
DIR Files
DIR Refs
DIR Submodules
DIR README
DIR LICENSE
---
menu_test.go (15089B)
---
1 // Copyright 2019 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 package hugolib
15
16 import (
17 "fmt"
18 "testing"
19
20 qt "github.com/frankban/quicktest"
21 )
22
23 const (
24 menuPageTemplate = `---
25 title: %q
26 weight: %d
27 menu:
28 %s:
29 title: %s
30 weight: %d
31 ---
32 # Doc Menu
33 `
34 )
35
36 func TestMenusSectionPagesMenu(t *testing.T) {
37 t.Parallel()
38
39 siteConfig := `
40 baseurl = "http://example.com/"
41 title = "Section Menu"
42 sectionPagesMenu = "sect"
43 `
44
45 b := newTestSitesBuilder(t).WithConfigFile("toml", siteConfig)
46
47 b.WithTemplates(
48 "partials/menu.html",
49 `{{- $p := .page -}}
50 {{- $m := .menu -}}
51 {{ range (index $p.Site.Menus $m) -}}
52 {{- .URL }}|{{ .Name }}|{{ .Title }}|{{ .Weight -}}|
53 {{- if $p.IsMenuCurrent $m . }}IsMenuCurrent{{ else }}-{{ end -}}|
54 {{- if $p.HasMenuCurrent $m . }}HasMenuCurrent{{ else }}-{{ end -}}|
55 {{- end -}}
56 `,
57 "_default/single.html",
58 `Single|{{ .Title }}
59 Menu Sect: {{ partial "menu.html" (dict "page" . "menu" "sect") }}
60 Menu Main: {{ partial "menu.html" (dict "page" . "menu" "main") }}`,
61 "_default/list.html", "List|{{ .Title }}|{{ .Content }}",
62 )
63
64 b.WithContent(
65 "sect1/p1.md", fmt.Sprintf(menuPageTemplate, "p1", 1, "main", "atitle1", 40),
66 "sect1/p2.md", fmt.Sprintf(menuPageTemplate, "p2", 2, "main", "atitle2", 30),
67 "sect2/p3.md", fmt.Sprintf(menuPageTemplate, "p3", 3, "main", "atitle3", 20),
68 "sect2/p4.md", fmt.Sprintf(menuPageTemplate, "p4", 4, "main", "atitle4", 10),
69 "sect3/p5.md", fmt.Sprintf(menuPageTemplate, "p5", 5, "main", "atitle5", 5),
70 "sect1/_index.md", newTestPage("Section One", "2017-01-01", 100),
71 "sect5/_index.md", newTestPage("Section Five", "2017-01-01", 10),
72 )
73
74 b.Build(BuildCfg{})
75 h := b.H
76
77 s := h.Sites[0]
78
79 b.Assert(len(s.Menus()), qt.Equals, 2)
80
81 p1 := s.RegularPages()[0].Menus()
82
83 // There is only one menu in the page, but it is "member of" 2
84 b.Assert(len(p1), qt.Equals, 1)
85
86 b.AssertFileContent("public/sect1/p1/index.html", "Single",
87 "Menu Sect: "+
88 "/sect5/|Section Five|Section Five|10|-|-|"+
89 "/sect1/|Section One|Section One|100|-|HasMenuCurrent|"+
90 "/sect2/|Sect2s|Sect2s|0|-|-|"+
91 "/sect3/|Sect3s|Sect3s|0|-|-|",
92 "Menu Main: "+
93 "/sect3/p5/|p5|atitle5|5|-|-|"+
94 "/sect2/p4/|p4|atitle4|10|-|-|"+
95 "/sect2/p3/|p3|atitle3|20|-|-|"+
96 "/sect1/p2/|p2|atitle2|30|-|-|"+
97 "/sect1/p1/|p1|atitle1|40|IsMenuCurrent|-|",
98 )
99
100 b.AssertFileContent("public/sect2/p3/index.html", "Single",
101 "Menu Sect: "+
102 "/sect5/|Section Five|Section Five|10|-|-|"+
103 "/sect1/|Section One|Section One|100|-|-|"+
104 "/sect2/|Sect2s|Sect2s|0|-|HasMenuCurrent|"+
105 "/sect3/|Sect3s|Sect3s|0|-|-|")
106 }
107
108 func TestMenusFrontMatter(t *testing.T) {
109 b := newTestSitesBuilder(t).WithSimpleConfigFile()
110
111 b.WithTemplatesAdded("index.html", `
112 Main: {{ len .Site.Menus.main }}
113 Other: {{ len .Site.Menus.other }}
114 {{ range .Site.Menus.main }}
115 * Main|{{ .Name }}: {{ .URL }}
116 {{ end }}
117 {{ range .Site.Menus.other }}
118 * Other|{{ .Name }}: {{ .URL }}
119 {{ end }}
120 `)
121
122 // Issue #5828
123 b.WithContent("blog/page1.md", `
124 ---
125 title: "P1"
126 menu: main
127 ---
128
129 `)
130
131 b.WithContent("blog/page2.md", `
132 ---
133 title: "P2"
134 menu: [main,other]
135 ---
136
137 `)
138
139 b.WithContent("blog/page3.md", `
140 ---
141 title: "P3"
142 menu:
143 main:
144 weight: 30
145 ---
146 `)
147
148 b.Build(BuildCfg{})
149
150 b.AssertFileContent("public/index.html",
151 "Main: 3", "Other: 1",
152 "Main|P1: /blog/page1/",
153 "Other|P2: /blog/page2/",
154 )
155 }
156
157 // https://github.com/gohugoio/hugo/issues/5849
158 func TestMenusPageMultipleOutputFormats(t *testing.T) {
159 config := `
160 baseURL = "https://example.com"
161
162 # DAMP is similar to AMP, but not permalinkable.
163 [outputFormats]
164 [outputFormats.damp]
165 mediaType = "text/html"
166 path = "damp"
167
168 `
169
170 b := newTestSitesBuilder(t).WithConfigFile("toml", config)
171 b.WithContent("_index.md", `
172 ---
173 Title: Home Sweet Home
174 outputs: [ "html", "amp" ]
175 menu: "main"
176 ---
177
178 `)
179
180 b.WithContent("blog/html-amp.md", `
181 ---
182 Title: AMP and HTML
183 outputs: [ "html", "amp" ]
184 menu: "main"
185 ---
186
187 `)
188
189 b.WithContent("blog/html.md", `
190 ---
191 Title: HTML only
192 outputs: [ "html" ]
193 menu: "main"
194 ---
195
196 `)
197
198 b.WithContent("blog/amp.md", `
199 ---
200 Title: AMP only
201 outputs: [ "amp" ]
202 menu: "main"
203 ---
204
205 `)
206
207 b.WithTemplatesAdded("index.html", `{{ range .Site.Menus.main }}{{ .Title }}|{{ .URL }}|{{ end }}`)
208
209 b.Build(BuildCfg{})
210
211 b.AssertFileContent("public/index.html", "AMP and HTML|/blog/html-amp/|AMP only|/amp/blog/amp/|Home Sweet Home|/|HTML only|/blog/html/|")
212 b.AssertFileContent("public/amp/index.html", "AMP and HTML|/amp/blog/html-amp/|AMP only|/amp/blog/amp/|Home Sweet Home|/amp/|HTML only|/blog/html/|")
213 }
214
215 // https://github.com/gohugoio/hugo/issues/5989
216 func TestMenusPageSortByDate(t *testing.T) {
217 b := newTestSitesBuilder(t).WithSimpleConfigFile()
218
219 b.WithContent("blog/a.md", `
220 ---
221 Title: A
222 date: 2019-01-01
223 menu:
224 main:
225 identifier: "a"
226 weight: 1
227 ---
228
229 `)
230
231 b.WithContent("blog/b.md", `
232 ---
233 Title: B
234 date: 2018-01-02
235 menu:
236 main:
237 parent: "a"
238 weight: 100
239 ---
240
241 `)
242
243 b.WithContent("blog/c.md", `
244 ---
245 Title: C
246 date: 2019-01-03
247 menu:
248 main:
249 parent: "a"
250 weight: 10
251 ---
252
253 `)
254
255 b.WithTemplatesAdded("index.html", `{{ range .Site.Menus.main }}{{ .Title }}|Children:
256 {{- $children := sort .Children ".Page.Date" "desc" }}{{ range $children }}{{ .Title }}|{{ end }}{{ end }}
257
258 `)
259
260 b.Build(BuildCfg{})
261
262 b.AssertFileContent("public/index.html", "A|Children:C|B|")
263 }
264
265 // Issue #8825
266 func TestMenuParamsEmptyYaml(t *testing.T) {
267 b := newTestSitesBuilder(t).WithConfigFile("yaml", `
268
269 `)
270
271 b.WithTemplates("index.html", `{{ site.Menus }}`)
272
273 b.WithContent("p1.md", `---
274 menus:
275 main:
276 identity: journal
277 weight: 2
278 params:
279 ---
280 `)
281 b.Build(BuildCfg{})
282 }
283
284 func TestMenuParams(t *testing.T) {
285 b := newTestSitesBuilder(t).WithConfigFile("toml", `
286 [[menus.main]]
287 identifier = "contact"
288 title = "Contact Us"
289 url = "mailto:noreply@example.com"
290 weight = 300
291 [menus.main.params]
292 foo = "foo_config"
293 key2 = "key2_config"
294 camelCase = "camelCase_config"
295 `)
296
297 b.WithTemplatesAdded("index.html", `
298 Main: {{ len .Site.Menus.main }}
299 {{ range .Site.Menus.main }}
300 foo: {{ .Params.foo }}
301 key2: {{ .Params.KEy2 }}
302 camelCase: {{ .Params.camelcase }}
303 {{ end }}
304 `)
305
306 b.WithContent("_index.md", `
307 ---
308 title: "Home"
309 menu:
310 main:
311 weight: 10
312 params:
313 foo: "foo_content"
314 key2: "key2_content"
315 camelCase: "camelCase_content"
316 ---
317 `)
318
319 b.Build(BuildCfg{})
320
321 b.AssertFileContent("public/index.html", `
322 Main: 2
323
324 foo: foo_content
325 key2: key2_content
326 camelCase: camelCase_content
327
328 foo: foo_config
329 key2: key2_config
330 camelCase: camelCase_config
331 `)
332 }
333
334 func TestMenusShadowMembers(t *testing.T) {
335 b := newTestSitesBuilder(t).WithConfigFile("toml", `
336 [[menus.main]]
337 identifier = "contact"
338 pageRef = "contact"
339 title = "Contact Us"
340 url = "mailto:noreply@example.com"
341 weight = 1
342 [[menus.main]]
343 pageRef = "/blog/post3"
344 title = "My Post 3"
345 url = "/blog/post3"
346
347 `)
348
349 commonTempl := `
350 Main: {{ len .Site.Menus.main }}
351 {{ range .Site.Menus.main }}
352 {{ .Title }}|HasMenuCurrent: {{ $.HasMenuCurrent "main" . }}|Page: {{ .Page.Path }}
353 {{ .Title }}|IsMenuCurrent: {{ $.IsMenuCurrent "main" . }}|Page: {{ .Page.Path }}
354 {{ end }}
355 `
356
357 b.WithTemplatesAdded("index.html", commonTempl)
358 b.WithTemplatesAdded("_default/single.html", commonTempl)
359
360 b.WithContent("_index.md", `
361 ---
362 title: "Home"
363 menu:
364 main:
365 weight: 10
366 ---
367 `)
368
369 b.WithContent("blog/_index.md", `
370 ---
371 title: "Blog"
372 menu:
373 main:
374 weight: 20
375 ---
376 `)
377
378 b.WithContent("blog/post1.md", `
379 ---
380 title: "My Post 1: With No Menu Defined"
381 ---
382 `)
383
384 b.WithContent("blog/post2.md", `
385 ---
386 title: "My Post 2: With Menu Defined"
387 menu:
388 main:
389 weight: 30
390 ---
391 `)
392
393 b.WithContent("blog/post3.md", `
394 ---
395 title: "My Post 2: With No Menu Defined"
396 ---
397 `)
398
399 b.WithContent("contact.md", `
400 ---
401 title: "Contact: With No Menu Defined"
402 ---
403 `)
404
405 b.Build(BuildCfg{})
406
407 b.AssertFileContent("public/index.html", `
408 Main: 5
409 Home|HasMenuCurrent: false|Page: /
410 Blog|HasMenuCurrent: false|Page: /blog
411 My Post 2: With Menu Defined|HasMenuCurrent: false|Page: /blog/post2
412 My Post 3|HasMenuCurrent: false|Page: /blog/post3
413 Contact Us|HasMenuCurrent: false|Page: /contact
414 `)
415
416 b.AssertFileContent("public/blog/post1/index.html", `
417 Home|HasMenuCurrent: false|Page: /
418 Blog|HasMenuCurrent: true|Page: /blog
419 `)
420
421 b.AssertFileContent("public/blog/post2/index.html", `
422 Home|HasMenuCurrent: false|Page: /
423 Blog|HasMenuCurrent: true|Page: /blog
424 Blog|IsMenuCurrent: false|Page: /blog
425 `)
426
427 b.AssertFileContent("public/blog/post3/index.html", `
428 Home|HasMenuCurrent: false|Page: /
429 Blog|HasMenuCurrent: true|Page: /blog
430 `)
431
432 b.AssertFileContent("public/contact/index.html", `
433 Contact Us|HasMenuCurrent: false|Page: /contact
434 Contact Us|IsMenuCurrent: true|Page: /contact
435 Blog|HasMenuCurrent: false|Page: /blog
436 Blog|IsMenuCurrent: false|Page: /blog
437 `)
438 }
439
440 // Issue 9846
441 func TestMenuHasMenuCurrentSection(t *testing.T) {
442 t.Parallel()
443
444 files := `
445 -- config.toml --
446 disableKinds = ['RSS','sitemap','taxonomy','term']
447 [[menu.main]]
448 name = 'Home'
449 pageRef = '/'
450 weight = 1
451
452 [[menu.main]]
453 name = 'Tests'
454 pageRef = '/tests'
455 weight = 2
456 [[menu.main]]
457 name = 'Test 1'
458 pageRef = '/tests/test-1'
459 parent = 'Tests'
460 weight = 1
461
462 -- content/tests/test-1.md --
463 ---
464 title: "Test 1"
465 ---
466 -- layouts/_default/list.html --
467 {{ range site.Menus.main }}
468 {{ .Name }}|{{ .URL }}|IsMenuCurrent = {{ $.IsMenuCurrent "main" . }}|HasMenuCurrent = {{ $.HasMenuCurrent "main" . }}|
469 {{ range .Children }}
470 {{ .Name }}|{{ .URL }}|IsMenuCurrent = {{ $.IsMenuCurrent "main" . }}|HasMenuCurrent = {{ $.HasMenuCurrent "main" . }}|
471 {{ end }}
472 {{ end }}
473
474 {{/* Some tests for issue 9925 */}}
475 {{ $page := .Site.GetPage "tests/test-1" }}
476 {{ $section := site.GetPage "tests" }}
477
478 Home IsAncestor Self: {{ site.Home.IsAncestor site.Home }}
479 Home IsDescendant Self: {{ site.Home.IsDescendant site.Home }}
480 Section IsAncestor Self: {{ $section.IsAncestor $section }}
481 Section IsDescendant Self: {{ $section.IsDescendant $section}}
482 Page IsAncestor Self: {{ $page.IsAncestor $page }}
483 Page IsDescendant Self: {{ $page.IsDescendant $page}}
484 `
485
486 b := Test(t, files)
487
488 b.AssertFileContent("public/tests/index.html", `
489 Tests|/tests/|IsMenuCurrent = true|HasMenuCurrent = false
490 Home IsAncestor Self: false
491 Home IsDescendant Self: false
492 Section IsAncestor Self: false
493 Section IsDescendant Self: false
494 Page IsAncestor Self: false
495 Page IsDescendant Self: false
496 `)
497 }
498
499 func TestMenusNewConfigSetup(t *testing.T) {
500 t.Parallel()
501
502 files := `
503 -- hugo.toml --
504 baseURL = "https://example.com"
505 title = "Hugo Menu Test"
506 [menus]
507 [[menus.main]]
508 name = "Home"
509 url = "/"
510 pre = "<span>"
511 post = "</span>"
512 weight = 1
513 -- layouts/index.html --
514 {{ range $i, $e := site.Menus.main }}
515 Menu Item: {{ $i }}: {{ .Pre }}{{ .Name }}{{ .Post }}|{{ .URL }}|
516 {{ end }}
517 `
518
519 b := Test(t, files)
520
521 b.AssertFileContent("public/index.html", `
522 Menu Item: 0: <span>Home</span>|/|
523 `)
524 }
525
526 // Issue #11062
527 func TestMenusSubDirInBaseURL(t *testing.T) {
528 t.Parallel()
529
530 files := `
531 -- hugo.toml --
532 baseURL = "https://example.com/foo/"
533 title = "Hugo Menu Test"
534 [menus]
535 [[menus.main]]
536 name = "Posts"
537 url = "/posts"
538 weight = 1
539 -- layouts/index.html --
540 {{ range $i, $e := site.Menus.main }}
541 Menu Item: {{ $i }}|{{ .URL }}|
542 {{ end }}
543 `
544
545 b := Test(t, files)
546
547 b.AssertFileContent("public/index.html", `
548 Menu Item: 0|/foo/posts|
549 `)
550 }
551
552 func TestSectionPagesMenuMultilingualWarningIssue12306(t *testing.T) {
553 t.Parallel()
554
555 files := `
556 -- hugo.toml --
557 disableKinds = ['section','rss','sitemap','taxonomy','term']
558 defaultContentLanguageInSubdir = true
559 sectionPagesMenu = "main"
560 [languages.en]
561 [languages.fr]
562 -- layouts/_default/home.html --
563 {{- range site.Menus.main -}}
564 <a href="{{ .URL }}">{{ .Name }}</a>
565 {{- end -}}
566 -- layouts/_default/single.html --
567 {{ .Title }}
568 -- content/p1.en.md --
569 ---
570 title: p1
571 menu: main
572 ---
573 -- content/p1.fr.md --
574 ---
575 title: p1
576 menu: main
577 ---
578 -- content/p2.en.md --
579 ---
580 title: p2
581 menu: main
582 ---
583 `
584
585 b := Test(t, files, TestOptWarn())
586
587 b.AssertFileContent("public/en/index.html", `<a href="/en/p1/">p1</a><a href="/en/p2/">p2</a>`)
588 b.AssertFileContent("public/fr/index.html", `<a href="/fr/p1/">p1</a>`)
589 b.AssertLogContains("! WARN")
590 }
591
592 func TestSectionPagesIssue12399(t *testing.T) {
593 t.Parallel()
594
595 files := `
596 -- hugo.toml --
597 disableKinds = ['rss','sitemap','taxonomy','term']
598 capitalizeListTitles = false
599 pluralizeListTitles = false
600 sectionPagesMenu = 'main'
601 -- content/p1.md --
602 ---
603 title: p1
604 ---
605 -- content/s1/p2.md --
606 ---
607 title: p2
608 menus: main
609 ---
610 -- content/s1/p3.md --
611 ---
612 title: p3
613 ---
614 -- layouts/_default/list.html --
615 {{ range site.Menus.main }}<a href="{{ .URL }}">{{ .Name }}</a>{{ end }}
616 -- layouts/_default/single.html --
617 {{ .Title }}
618 `
619
620 b := Test(t, files)
621
622 b.AssertFileExists("public/index.html", true)
623 b.AssertFileContent("public/index.html", `<a href="/s1/p2/">p2</a><a href="/s1/">s1</a>`)
624 }
625
626 // Issue 13161
627 func TestMenuNameAndTitleFallback(t *testing.T) {
628 t.Parallel()
629
630 files := `
631 -- hugo.toml --
632 disableKinds = ['rss','sitemap','taxonomy','term']
633 [[menus.main]]
634 name = 'P1_ME_Name'
635 title = 'P1_ME_Title'
636 pageRef = '/p1'
637 weight = 10
638 [[menus.main]]
639 pageRef = '/p2'
640 weight = 20
641 [[menus.main]]
642 pageRef = '/p3'
643 weight = 30
644 [[menus.main]]
645 name = 'S1_ME_Name'
646 title = 'S1_ME_Title'
647 pageRef = '/s1'
648 weight = 40
649 [[menus.main]]
650 pageRef = '/s2'
651 weight = 50
652 [[menus.main]]
653 pageRef = '/s3'
654 weight = 60
655 -- content/p1.md --
656 ---
657 title: P1_Title
658 ---
659 -- content/p2.md --
660 ---
661 title: P2_Title
662 ---
663 -- content/p3.md --
664 ---
665 title: P3_Title
666 linkTitle: P3_LinkTitle
667 ---
668 -- content/s1/_index.md --
669 ---
670 title: S1_Title
671 ---
672 -- content/s2/_index.md --
673 ---
674 title: S2_Title
675 ---
676 -- content/s3/_index.md --
677 ---
678 title: S3_Title
679 linkTitle: S3_LinkTitle
680 ---
681 -- layouts/_default/single.html --
682 {{ .Content }}
683 -- layouts/_default/list.html --
684 {{ .Content }}
685 -- layouts/_default/home.html --
686 {{- range site.Menus.main }}
687 URL: {{ .URL }}| Name: {{ .Name }}| Title: {{ .Title }}| PageRef: {{ .PageRef }}| Page.Title: {{ .Page.Title }}| Page.LinkTitle: {{ .Page.LinkTitle }}|
688 {{- end }}
689 `
690
691 b := Test(t, files)
692 b.AssertFileContent("public/index.html",
693 `URL: /p1/| Name: P1_ME_Name| Title: P1_ME_Title| PageRef: /p1| Page.Title: P1_Title| Page.LinkTitle: P1_Title|`,
694 `URL: /p2/| Name: P2_Title| Title: P2_Title| PageRef: /p2| Page.Title: P2_Title| Page.LinkTitle: P2_Title|`,
695 `URL: /p3/| Name: P3_LinkTitle| Title: P3_Title| PageRef: /p3| Page.Title: P3_Title| Page.LinkTitle: P3_LinkTitle|`,
696 `URL: /s1/| Name: S1_ME_Name| Title: S1_ME_Title| PageRef: /s1| Page.Title: S1_Title| Page.LinkTitle: S1_Title|`,
697 `URL: /s2/| Name: S2_Title| Title: S2_Title| PageRef: /s2| Page.Title: S2_Title| Page.LinkTitle: S2_Title|`,
698 `URL: /s3/| Name: S3_LinkTitle| Title: S3_Title| PageRef: /s3| Page.Title: S3_Title| Page.LinkTitle: S3_LinkTitle|`,
699 )
700 }