hugo

Fork of github.com/gohugoio/hugo with reverse pagination support

git clone git://git.shimmy1996.com/hugo.git

language_content_dir_test.go (13536B)

    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 	"os"
   19 	"path/filepath"
   20 	"testing"
   21 
   22 	"github.com/spf13/cast"
   23 
   24 	"github.com/gohugoio/hugo/resources/page"
   25 
   26 	qt "github.com/frankban/quicktest"
   27 )
   28 
   29 /*
   30 
   31 /en/p1.md
   32 /nn/p1.md
   33 
   34 .Readdir
   35 
   36 - Name() => p1.en.md, p1.nn.md
   37 
   38 .Stat(name)
   39 
   40 .Open() --- real file name
   41 
   42 
   43 */
   44 
   45 func TestLanguageContentRoot(t *testing.T) {
   46 	t.Parallel()
   47 	c := qt.New(t)
   48 
   49 	config := `
   50 baseURL = "https://example.org/"
   51 
   52 defaultContentLanguage = "en"
   53 defaultContentLanguageInSubdir = true
   54 
   55 contentDir = "content/main"
   56 workingDir = "/my/project"
   57 
   58 [Languages]
   59 [Languages.en]
   60 weight = 10
   61 title = "In English"
   62 languageName = "English"
   63 
   64 [Languages.nn]
   65 weight = 20
   66 title = "På Norsk"
   67 languageName = "Norsk"
   68 # This tells Hugo that all content in this directory is in the Norwegian language.
   69 # It does not have to have the "my-page.nn.md" format. It can, but that is optional.
   70 contentDir = "content/norsk"
   71 
   72 [Languages.sv]
   73 weight = 30
   74 title = "På Svenska"
   75 languageName = "Svensk"
   76 contentDir = "content/svensk"
   77 `
   78 
   79 	pageTemplate := `
   80 ---
   81 title: %s
   82 slug: %s
   83 weight: %d
   84 ---
   85 
   86 Content.
   87 
   88 SVP3-REF: {{< ref path="/sect/page3.md" lang="sv" >}}
   89 SVP3-RELREF: {{< relref path="/sect/page3.md" lang="sv" >}}
   90 
   91 `
   92 
   93 	pageBundleTemplate := `
   94 ---
   95 title: %s
   96 weight: %d
   97 ---
   98 
   99 Content.
  100 
  101 `
  102 	var contentFiles []string
  103 	section := "sect"
  104 
  105 	contentRoot := func(lang string) string {
  106 		switch lang {
  107 		case "nn":
  108 			return "content/norsk"
  109 		case "sv":
  110 			return "content/svensk"
  111 		default:
  112 			return "content/main"
  113 		}
  114 	}
  115 
  116 	contentSectionRoot := func(lang string) string {
  117 		return contentRoot(lang) + "/" + section
  118 	}
  119 
  120 	for _, lang := range []string{"en", "nn", "sv"} {
  121 		for j := 1; j <= 10; j++ {
  122 			if (lang == "nn" || lang == "en") && j%4 == 0 {
  123 				// Skip 4 and 8 for nn
  124 				// We also skip it for en, but that is added to the Swedish directory below.
  125 				continue
  126 			}
  127 
  128 			if lang == "sv" && j%5 == 0 {
  129 				// Skip 5 and 10 for sv
  130 				continue
  131 			}
  132 
  133 			base := fmt.Sprintf("p-%s-%d", lang, j)
  134 			slug := base
  135 			langID := ""
  136 
  137 			if lang == "sv" && j%4 == 0 {
  138 				// Put an English page in the Swedish content dir.
  139 				langID = ".en"
  140 			}
  141 
  142 			if lang == "en" && j == 8 {
  143 				// This should win over the sv variant above.
  144 				langID = ".en"
  145 			}
  146 
  147 			slug += langID
  148 
  149 			contentRoot := contentSectionRoot(lang)
  150 
  151 			filename := filepath.Join(contentRoot, fmt.Sprintf("page%d%s.md", j, langID))
  152 			contentFiles = append(contentFiles, filename, fmt.Sprintf(pageTemplate, slug, slug, j))
  153 		}
  154 	}
  155 
  156 	// Put common translations in all of them
  157 	for i, lang := range []string{"en", "nn", "sv"} {
  158 		contentRoot := contentSectionRoot(lang)
  159 
  160 		slug := fmt.Sprintf("common_%s", lang)
  161 
  162 		filename := filepath.Join(contentRoot, "common.md")
  163 		contentFiles = append(contentFiles, filename, fmt.Sprintf(pageTemplate, slug, slug, 100+i))
  164 
  165 		for j, lang2 := range []string{"en", "nn", "sv"} {
  166 			filename := filepath.Join(contentRoot, fmt.Sprintf("translated_all.%s.md", lang2))
  167 			langSlug := slug + "_translated_all_" + lang2
  168 			contentFiles = append(contentFiles, filename, fmt.Sprintf(pageTemplate, langSlug, langSlug, 200+i+j))
  169 		}
  170 
  171 		for j, lang2 := range []string{"sv", "nn"} {
  172 			if lang == "en" {
  173 				continue
  174 			}
  175 			filename := filepath.Join(contentRoot, fmt.Sprintf("translated_some.%s.md", lang2))
  176 			langSlug := slug + "_translated_some_" + lang2
  177 			contentFiles = append(contentFiles, filename, fmt.Sprintf(pageTemplate, langSlug, langSlug, 300+i+j))
  178 		}
  179 	}
  180 
  181 	// Add a bundle with some images
  182 	for i, lang := range []string{"en", "nn", "sv"} {
  183 		contentRoot := contentSectionRoot(lang)
  184 		slug := fmt.Sprintf("bundle_%s", lang)
  185 		filename := filepath.Join(contentRoot, "mybundle", "index.md")
  186 		contentFiles = append(contentFiles, filename, fmt.Sprintf(pageBundleTemplate, slug, 400+i))
  187 		if lang == "en" {
  188 			imageFilename := filepath.Join(contentRoot, "mybundle", "logo.png")
  189 			contentFiles = append(contentFiles, imageFilename, "PNG Data")
  190 		}
  191 		imageFilename := filepath.Join(contentRoot, "mybundle", "featured.png")
  192 		contentFiles = append(contentFiles, imageFilename, fmt.Sprintf("PNG Data for %s", lang))
  193 
  194 		// Add some bundled pages
  195 		contentFiles = append(contentFiles, filepath.Join(contentRoot, "mybundle", "p1.md"), fmt.Sprintf(pageBundleTemplate, slug, 401+i))
  196 		contentFiles = append(contentFiles, filepath.Join(contentRoot, "mybundle", "sub", "p1.md"), fmt.Sprintf(pageBundleTemplate, slug, 402+i))
  197 
  198 	}
  199 
  200 	// Add some static files inside the content dir
  201 	// https://github.com/gohugoio/hugo/issues/5759
  202 	for _, lang := range []string{"en", "nn", "sv"} {
  203 		contentRoot := contentRoot(lang)
  204 		for i := 0; i < 2; i++ {
  205 			filename := filepath.Join(contentRoot, "mystatic", fmt.Sprintf("file%d.yaml", i))
  206 			contentFiles = append(contentFiles, filename, lang)
  207 		}
  208 	}
  209 
  210 	b := newTestSitesBuilder(t)
  211 	b.WithWorkingDir("/my/project").WithConfigFile("toml", config).WithContent(contentFiles...).CreateSites()
  212 
  213 	_ = os.Stdout
  214 
  215 	err := b.BuildE(BuildCfg{})
  216 
  217 	// dumpPages(b.H.Sites[1].RegularPages()...)
  218 
  219 	c.Assert(err, qt.IsNil)
  220 
  221 	c.Assert(len(b.H.Sites), qt.Equals, 3)
  222 
  223 	enSite := b.H.Sites[0]
  224 	nnSite := b.H.Sites[1]
  225 	svSite := b.H.Sites[2]
  226 
  227 	b.AssertFileContent("public/en/mystatic/file1.yaml", "en")
  228 	b.AssertFileContent("public/nn/mystatic/file1.yaml", "nn")
  229 
  230 	// dumpPages(nnSite.RegularPages()...)
  231 
  232 	c.Assert(len(nnSite.RegularPages()), qt.Equals, 12)
  233 	c.Assert(len(enSite.RegularPages()), qt.Equals, 13)
  234 
  235 	c.Assert(len(svSite.RegularPages()), qt.Equals, 10)
  236 
  237 	svP2, err := svSite.getPageNew(nil, "/sect/page2.md")
  238 	c.Assert(err, qt.IsNil)
  239 	nnP2, err := nnSite.getPageNew(nil, "/sect/page2.md")
  240 	c.Assert(err, qt.IsNil)
  241 
  242 	enP2, err := enSite.getPageNew(nil, "/sect/page2.md")
  243 	c.Assert(err, qt.IsNil)
  244 	c.Assert(enP2.Language().Lang, qt.Equals, "en")
  245 	c.Assert(svP2.Language().Lang, qt.Equals, "sv")
  246 	c.Assert(nnP2.Language().Lang, qt.Equals, "nn")
  247 
  248 	content, _ := nnP2.Content()
  249 	contentStr := cast.ToString(content)
  250 	c.Assert(contentStr, qt.Contains, "SVP3-REF: https://example.org/sv/sect/p-sv-3/")
  251 	c.Assert(contentStr, qt.Contains, "SVP3-RELREF: /sv/sect/p-sv-3/")
  252 
  253 	// Test RelRef with and without language indicator.
  254 	nn3RefArgs := map[string]any{
  255 		"path": "/sect/page3.md",
  256 		"lang": "nn",
  257 	}
  258 	nnP3RelRef, err := svP2.RelRef(
  259 		nn3RefArgs,
  260 	)
  261 	c.Assert(err, qt.IsNil)
  262 	c.Assert(nnP3RelRef, qt.Equals, "/nn/sect/p-nn-3/")
  263 	nnP3Ref, err := svP2.Ref(
  264 		nn3RefArgs,
  265 	)
  266 	c.Assert(err, qt.IsNil)
  267 	c.Assert(nnP3Ref, qt.Equals, "https://example.org/nn/sect/p-nn-3/")
  268 
  269 	for i, p := range enSite.RegularPages() {
  270 		j := i + 1
  271 		c.Assert(p.Language().Lang, qt.Equals, "en")
  272 		c.Assert(p.Section(), qt.Equals, "sect")
  273 		if j < 9 {
  274 			if j%4 == 0 {
  275 			} else {
  276 				c.Assert(p.Title(), qt.Contains, "p-en")
  277 			}
  278 		}
  279 	}
  280 
  281 	for _, p := range nnSite.RegularPages() {
  282 		c.Assert(p.Language().Lang, qt.Equals, "nn")
  283 		c.Assert(p.Title(), qt.Contains, "nn")
  284 	}
  285 
  286 	for _, p := range svSite.RegularPages() {
  287 		c.Assert(p.Language().Lang, qt.Equals, "sv")
  288 		c.Assert(p.Title(), qt.Contains, "sv")
  289 	}
  290 
  291 	// Check bundles
  292 	bundleEn := enSite.RegularPages()[len(enSite.RegularPages())-1]
  293 	bundleNn := nnSite.RegularPages()[len(nnSite.RegularPages())-1]
  294 	bundleSv := svSite.RegularPages()[len(svSite.RegularPages())-1]
  295 
  296 	c.Assert(bundleEn.RelPermalink(), qt.Equals, "/en/sect/mybundle/")
  297 	c.Assert(bundleSv.RelPermalink(), qt.Equals, "/sv/sect/mybundle/")
  298 
  299 	c.Assert(len(bundleNn.Resources()), qt.Equals, 4)
  300 	c.Assert(len(bundleSv.Resources()), qt.Equals, 4)
  301 	c.Assert(len(bundleEn.Resources()), qt.Equals, 4)
  302 
  303 	b.AssertFileContent("public/en/sect/mybundle/index.html", "image/png: /en/sect/mybundle/logo.png")
  304 	b.AssertFileContent("public/nn/sect/mybundle/index.html", "image/png: /nn/sect/mybundle/logo.png")
  305 	b.AssertFileContent("public/sv/sect/mybundle/index.html", "image/png: /sv/sect/mybundle/logo.png")
  306 
  307 	b.AssertFileContent("public/sv/sect/mybundle/featured.png", "PNG Data for sv")
  308 	b.AssertFileContent("public/nn/sect/mybundle/featured.png", "PNG Data for nn")
  309 	b.AssertFileContent("public/en/sect/mybundle/featured.png", "PNG Data for en")
  310 	b.AssertFileContent("public/en/sect/mybundle/logo.png", "PNG Data")
  311 	b.AssertFileContent("public/sv/sect/mybundle/logo.png", "PNG Data")
  312 	b.AssertFileContent("public/nn/sect/mybundle/logo.png", "PNG Data")
  313 
  314 	nnSect := nnSite.getPage(page.KindSection, "sect")
  315 	c.Assert(nnSect, qt.Not(qt.IsNil))
  316 	c.Assert(len(nnSect.Pages()), qt.Equals, 12)
  317 	nnHome := nnSite.Info.Home()
  318 	c.Assert(nnHome.RelPermalink(), qt.Equals, "/nn/")
  319 }
  320 
  321 // https://github.com/gohugoio/hugo/issues/6463
  322 func TestLanguageRootSectionsMismatch(t *testing.T) {
  323 	t.Parallel()
  324 
  325 	config := `
  326 baseURL: "https://example.org/"
  327 languageCode: "en-us"
  328 title: "My New Hugo Site"
  329 theme: "mytheme"
  330 
  331 contentDir: "content/en"
  332 
  333 languages:
  334     en:
  335         weight: 1
  336         languageName: "English"
  337         contentDir: content/en
  338     es:
  339         weight: 2
  340         languageName: "Español"
  341         contentDir: content/es
  342     fr:
  343         weight: 4
  344         languageName: "Française"
  345         contentDir: content/fr
  346 
  347         
  348 `
  349 	createPage := func(title string) string {
  350 		return fmt.Sprintf(`---
  351 title: %q
  352 ---
  353 
  354 `, title)
  355 	}
  356 
  357 	b := newTestSitesBuilder(t)
  358 	b.WithConfigFile("yaml", config)
  359 
  360 	b.WithSourceFile("themes/mytheme/layouts/index.html", `MYTHEME`)
  361 	b.WithTemplates("index.html", `
  362 Lang: {{ .Lang }}
  363 {{ range .Site.RegularPages }}
  364 Page: {{ .RelPermalink }}|{{ .Title -}}
  365 {{ end }}
  366 
  367 `)
  368 	b.WithSourceFile("static/hello.txt", `hello`)
  369 	b.WithContent("en/_index.md", createPage("en home"))
  370 	b.WithContent("es/_index.md", createPage("es home"))
  371 	b.WithContent("fr/_index.md", createPage("fr home"))
  372 
  373 	for i := 1; i < 3; i++ {
  374 		b.WithContent(fmt.Sprintf("en/event/page%d.md", i), createPage(fmt.Sprintf("ev-en%d", i)))
  375 		b.WithContent(fmt.Sprintf("es/event/page%d.md", i), createPage(fmt.Sprintf("ev-es%d", i)))
  376 		b.WithContent(fmt.Sprintf("fr/event/page%d.md", i), createPage(fmt.Sprintf("ev-fr%d", i)))
  377 		b.WithContent(fmt.Sprintf("en/blog/page%d.md", i), createPage(fmt.Sprintf("blog-en%d", i)))
  378 		b.WithContent(fmt.Sprintf("es/blog/page%d.md", i), createPage(fmt.Sprintf("blog-es%d", i)))
  379 		b.WithContent(fmt.Sprintf("fr/other/page%d.md", i), createPage(fmt.Sprintf("other-fr%d", i)))
  380 	}
  381 
  382 	b.Build(BuildCfg{})
  383 
  384 	b.AssertFileContent("public/index.html", `
  385 Lang: en
  386 Page: /blog/page1/|blog-en1
  387 Page: /blog/page2/|blog-en2
  388 Page: /event/page1/|ev-en1
  389 Page: /event/page2/|ev-en2
  390 `)
  391 
  392 	b.AssertFileContent("public/es/index.html", `
  393 Lang: es
  394 Page: /es/blog/page1/|blog-es1
  395 Page: /es/blog/page2/|blog-es2
  396 Page: /es/event/page1/|ev-es1
  397 Page: /es/event/page2/|ev-es2
  398 `)
  399 	b.AssertFileContent("public/fr/index.html", `
  400 Lang: fr
  401 Page: /fr/event/page1/|ev-fr1
  402 Page: /fr/event/page2/|ev-fr2
  403 Page: /fr/other/page1/|other-fr1
  404 Page: /fr/other/page2/|other-fr2`)
  405 }
  406 
  407 // Issue 9693
  408 func TestContentMountMerge(t *testing.T) {
  409 	t.Parallel()
  410 
  411 	files := `
  412 -- config.toml --
  413 baseURL = 'https://example.org/'
  414 languageCode = 'en-us'
  415 title = 'Hugo Forum Topic #37225'
  416 theme = 'mytheme'
  417 
  418 disableKinds = ['sitemap','RSS','taxonomy','term']
  419 defaultContentLanguage = 'en'
  420 defaultContentLanguageInSubdir = true
  421 
  422 [languages.en]
  423 languageName = 'English'
  424 weight = 1
  425 [languages.de]
  426 languageName = 'Deutsch'
  427 weight = 2
  428 [languages.nl]
  429 languageName = 'Nederlands'
  430 weight = 3
  431 
  432 # EN content
  433 [[module.mounts]]
  434 source = 'content/en'
  435 target = 'content'
  436 lang = 'en'
  437 
  438 # DE content
  439 [[module.mounts]]
  440 source = 'content/de'
  441 target = 'content'
  442 lang = 'de'
  443 
  444 # This fills in the gaps in DE content with EN content
  445 [[module.mounts]]
  446 source = 'content/en'
  447 target = 'content'
  448 lang = 'de'
  449 
  450 # NL content
  451 [[module.mounts]]
  452 source = 'content/nl'
  453 target = 'content'
  454 lang = 'nl'
  455 
  456 # This should fill in the gaps in NL content with EN content
  457 [[module.mounts]]
  458 source = 'content/en'
  459 target = 'content'
  460 lang = 'nl'
  461 
  462 -- content/de/_index.md --
  463 ---
  464 title: "home (de)"
  465 ---
  466 -- content/de/p1.md --
  467 ---
  468 title: "p1 (de)"
  469 ---
  470 -- content/en/_index.md --
  471 ---
  472 title: "home (en)"
  473 ---
  474 -- content/en/p1.md --
  475 ---
  476 title: "p1 (en)"
  477 ---
  478 -- content/en/p2.md --
  479 ---
  480 title: "p2 (en)"
  481 ---
  482 -- content/en/p3.md --
  483 ---
  484 title: "p3 (en)"
  485 ---
  486 -- content/nl/_index.md --
  487 ---
  488 title: "home (nl)"
  489 ---
  490 -- content/nl/p1.md --
  491 ---
  492 title: "p1 (nl)"
  493 ---
  494 -- content/nl/p3.md --
  495 ---
  496 title: "p3 (nl)"
  497 ---
  498 -- layouts/home.html --
  499 {{ .Title }}: {{ site.Language.Lang }}: {{ range site.RegularPages }}{{ .Title }}|{{ end }}:END
  500 -- themes/mytheme/config.toml --
  501 [[module.mounts]]
  502 source = 'content/nlt'
  503 target = 'content'
  504 lang = 'nl'
  505 -- themes/mytheme/content/nlt/p3.md --
  506 ---
  507 title: "p3 theme (nl)"
  508 ---
  509 -- themes/mytheme/content/nlt/p4.md --
  510 ---
  511 title: "p4 theme (nl)"
  512 ---
  513 `
  514 
  515 	b := NewIntegrationTestBuilder(
  516 		IntegrationTestConfig{
  517 			T:           t,
  518 			TxtarString: files,
  519 		},
  520 	).Build()
  521 
  522 	b.AssertFileContent("public/nl/index.html", `home (nl): nl: p1 (nl)|p2 (en)|p3 (nl)|p4 theme (nl)|:END`)
  523 	b.AssertFileContent("public/de/index.html", `home (de): de: p1 (de)|p2 (en)|p3 (en)|:END`)
  524 	b.AssertFileContent("public/en/index.html", `home (en): en: p1 (en)|p2 (en)|p3 (en)|:END`)
  525 
  526 }