diff options
-rw-r--r-- | docs/content/content/multilingual.md | 6 | ||||
-rw-r--r-- | helpers/language.go | 4 | ||||
-rw-r--r-- | helpers/url.go | 32 | ||||
-rw-r--r-- | helpers/url_test.go | 44 | ||||
-rw-r--r-- | hugolib/config.go | 1 | ||||
-rw-r--r-- | hugolib/hugo_sites_test.go | 129 | ||||
-rw-r--r-- | hugolib/node.go | 46 | ||||
-rw-r--r-- | hugolib/page.go | 6 | ||||
-rw-r--r-- | hugolib/site.go | 131 | ||||
-rw-r--r-- | hugolib/site_test.go | 8 | ||||
-rw-r--r-- | hugolib/sitemap_test.go | 14 | ||||
-rw-r--r-- | tpl/template_embedded.go | 2 |
12 files changed, 295 insertions, 128 deletions
diff --git a/docs/content/content/multilingual.md b/docs/content/content/multilingual.md index 35dd1382e..f23a6afcf 100644 --- a/docs/content/content/multilingual.md +++ b/docs/content/content/multilingual.md @@ -14,6 +14,8 @@ Hugo supports multiple languages side-by-side (added in `Hugo 0.17`). Define the Example: ``` +DefaultContentLanguage = "en" + Languages: en: weight: 1 @@ -34,7 +36,9 @@ Anything not defined in a `[lang]:` block will fall back to the global value for that key (like `copyright` for the English (`en`) language in this example). With the config above, all content, sitemap, RSS feeds, paginations -and taxonomy pages will be rendered below `/en` in English, and below `/fr` in French. +and taxonomy pages will be rendered below `/` in English (your default content language), and below `/fr` in French. + +If you want all of the languages to be put below their respective language code, enable `DefaultContentLanguageInSubdir: true` in your configuration. Only the obvious non-global options can be overridden per language. Examples of global options are `BaseURL`, `BuildDrafts`, etc. diff --git a/helpers/language.go b/helpers/language.go index 4ef5edbc4..994129308 100644 --- a/helpers/language.go +++ b/helpers/language.go @@ -31,6 +31,10 @@ type Language struct { paramsInit sync.Once } +func (l *Language) String() string { + return l.Lang +} + func NewLanguage(lang string) *Language { return &Language{Lang: lang, params: make(map[string]interface{})} } diff --git a/helpers/url.go b/helpers/url.go index 83273324d..4d06fb042 100644 --- a/helpers/url.go +++ b/helpers/url.go @@ -168,21 +168,32 @@ func AbsURL(in string, addLanguage bool) string { } if addLanguage { - addSlash := in == "" || strings.HasSuffix(in, "/") - in = path.Join(getLanguagePrefix(), in) + prefix := getLanguagePrefix() - if addSlash { - in += "/" + if prefix != "" { + addSlash := in == "" || strings.HasSuffix(in, "/") + in = path.Join(prefix, in) + + if addSlash { + in += "/" + } } } return MakePermalink(baseURL, in).String() } func getLanguagePrefix() string { + defaultLang := viper.GetString("DefaultContentLanguage") + defaultInSubDir := viper.GetBool("DefaultContentLanguageInSubdir") + if !viper.GetBool("Multilingual") { return "" } - return viper.Get("CurrentContentLanguage").(*Language).Lang + currentLang := viper.Get("CurrentContentLanguage").(*Language).Lang + if currentLang == "" || (currentLang == defaultLang && !defaultInSubDir) { + return "" + } + return currentLang } // IsAbsURL determines whether the given path points to an absolute URL. @@ -211,12 +222,15 @@ func RelURL(in string, addLanguage bool) string { } if addLanguage { - hadSlash := strings.HasSuffix(u, "/") + prefix := getLanguagePrefix() + if prefix != "" { + hadSlash := strings.HasSuffix(u, "/") - u = path.Join(getLanguagePrefix(), u) + u = path.Join(prefix, u) - if hadSlash { - u += "/" + if hadSlash { + u += "/" + } } } diff --git a/helpers/url_test.go b/helpers/url_test.go index f6dd9f9da..d1fadb252 100644 --- a/helpers/url_test.go +++ b/helpers/url_test.go @@ -45,19 +45,24 @@ func TestURLize(t *testing.T) { } func TestAbsURL(t *testing.T) { - for _, addLanguage := range []bool{true, false} { - for _, m := range []bool{true, false} { - for _, l := range []string{"en", "fr"} { - doTestAbsURL(t, addLanguage, m, l) + for _, defaultInSubDir := range []bool{true, false} { + for _, addLanguage := range []bool{true, false} { + for _, m := range []bool{true, false} { + for _, l := range []string{"en", "fr"} { + doTestAbsURL(t, defaultInSubDir, addLanguage, m, l) + } } } } } -func doTestAbsURL(t *testing.T, addLanguage, multilingual bool, lang string) { +func doTestAbsURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool, lang string) { viper.Reset() viper.Set("Multilingual", multilingual) viper.Set("CurrentContentLanguage", NewLanguage(lang)) + viper.Set("DefaultContentLanguage", "en") + viper.Set("DefaultContentLanguageInSubdir", defaultInSubDir) + tests := []struct { input string baseURL string @@ -79,12 +84,17 @@ func doTestAbsURL(t *testing.T, addLanguage, multilingual bool, lang string) { output := AbsURL(test.input, addLanguage) expected := test.expected if multilingual && addLanguage { - expected = strings.Replace(expected, "MULTI", lang+"/", 1) + if !defaultInSubDir && lang == "en" { + expected = strings.Replace(expected, "MULTI", "", 1) + } else { + expected = strings.Replace(expected, "MULTI", lang+"/", 1) + } + } else { expected = strings.Replace(expected, "MULTI", "", 1) } if output != expected { - t.Errorf("Expected %#v, got %#v\n", expected, output) + t.Fatalf("Expected %#v, got %#v\n", expected, output) } } } @@ -106,19 +116,23 @@ func TestIsAbsURL(t *testing.T) { } func TestRelURL(t *testing.T) { - for _, addLanguage := range []bool{true, false} { - for _, m := range []bool{true, false} { - for _, l := range []string{"en", "fr"} { - doTestRelURL(t, addLanguage, m, l) + for _, defaultInSubDir := range []bool{true, false} { + for _, addLanguage := range []bool{true, false} { + for _, m := range []bool{true, false} { + for _, l := range []string{"en", "fr"} { + doTestRelURL(t, defaultInSubDir, addLanguage, m, l) + } } } } } -func doTestRelURL(t *testing.T, addLanguage, multilingual bool, lang string) { +func doTestRelURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool, lang string) { viper.Reset() viper.Set("Multilingual", multilingual) viper.Set("CurrentContentLanguage", NewLanguage(lang)) + viper.Set("DefaultContentLanguage", "en") + viper.Set("DefaultContentLanguageInSubdir", defaultInSubDir) tests := []struct { input string @@ -146,7 +160,11 @@ func doTestRelURL(t *testing.T, addLanguage, multilingual bool, lang string) { expected := test.expected if multilingual && addLanguage { - expected = strings.Replace(expected, "MULTI", "/"+lang, 1) + if !defaultInSubDir && lang == "en" { + expected = strings.Replace(expected, "MULTI", "", 1) + } else { + expected = strings.Replace(expected, "MULTI", "/"+lang, 1) + } } else { expected = strings.Replace(expected, "MULTI", "", 1) } diff --git a/hugolib/config.go b/hugolib/config.go index c4292e81b..17673453e 100644 --- a/hugolib/config.go +++ b/hugolib/config.go @@ -104,4 +104,5 @@ func loadDefaultSettings() { viper.SetDefault("UseModTimeAsFallback", false) viper.SetDefault("Multilingual", false) viper.SetDefault("DefaultContentLanguage", "en") + viper.SetDefault("DefaultContentLanguageInSubdir", false) } diff --git a/hugolib/hugo_sites_test.go b/hugolib/hugo_sites_test.go index 655feba0f..6ab60d9ec 100644 --- a/hugolib/hugo_sites_test.go +++ b/hugolib/hugo_sites_test.go @@ -32,12 +32,134 @@ func testCommonResetState() { viper.SetFs(hugofs.Source()) loadDefaultSettings() + // Default is false, but true is easier to use as default in tests + viper.Set("DefaultContentLanguageInSubdir", true) + if err := hugofs.Source().Mkdir("content", 0755); err != nil { panic("Content folder creation failed.") } } +func TestMultiSitesMainLangInRoot(t *testing.T) { + for _, b := range []bool{false, true} { + doTestMultiSitesMainLangInRoot(t, b) + } +} + +func doTestMultiSitesMainLangInRoot(t *testing.T, defaultInSubDir bool) { + testCommonResetState() + viper.Set("DefaultContentLanguageInSubdir", defaultInSubDir) + + sites := createMultiTestSites(t, multiSiteTomlConfig) + + err := sites.Build(BuildCfg{}) + + if err != nil { + t.Fatalf("Failed to build sites: %s", err) + } + + require.Len(t, sites.Sites, 2) + + enSite := sites.Sites[0] + frSite := sites.Sites[1] + + require.Equal(t, "/en", enSite.Info.LanguagePrefix) + + if defaultInSubDir { + require.Equal(t, "/fr", frSite.Info.LanguagePrefix) + } else { + require.Equal(t, "", frSite.Info.LanguagePrefix) + } + + doc1en := enSite.Pages[0] + doc1fr := frSite.Pages[0] + + enPerm, _ := doc1en.Permalink() + enRelPerm, _ := doc1en.RelPermalink() + require.Equal(t, "http://example.com/blog/en/sect/doc1-slug/", enPerm) + require.Equal(t, "/blog/en/sect/doc1-slug/", enRelPerm) + + frPerm, _ := doc1fr.Permalink() + frRelPerm, _ := doc1fr.RelPermalink() + // Main language in root + require.Equal(t, replaceDefaultContentLanguageValue("http://example.com/blog/fr/sect/doc1/", defaultInSubDir), frPerm) + require.Equal(t, replaceDefaultContentLanguageValue("/blog/fr/sect/doc1/", defaultInSubDir), frRelPerm) + + assertFileContent(t, "public/fr/sect/doc1/index.html", defaultInSubDir, "Single", "Bonjour") + assertFileContent(t, "public/en/sect/doc1-slug/index.html", defaultInSubDir, "Single", "Hello") + + // Check home + if defaultInSubDir { + // should have a redirect on top level. + assertFileContent(t, "public/index.html", true, `<meta http-equiv="refresh" content="0; url=http://example.com/blog/fr" />`) + } + assertFileContent(t, "public/fr/index.html", defaultInSubDir, "Home", "Bonjour") + assertFileContent(t, "public/en/index.html", defaultInSubDir, "Home", "Hello") + + // Check list pages + assertFileContent(t, "public/fr/sect/index.html", defaultInSubDir, "List", "Bonjour") + assertFileContent(t, "public/en/sect/index.html", defaultInSubDir, "List", "Hello") + assertFileContent(t, "public/fr/plaques/frtag1/index.html", defaultInSubDir, "List", "Bonjour") + assertFileContent(t, "public/en/tags/tag1/index.html", defaultInSubDir, "List", "Hello") + + // Check sitemaps + // Sitemaps behaves different: In a multilanguage setup there will always be a index file and + // one sitemap in each lang folder. + assertFileContent(t, "public/sitemap.xml", true, + "<loc>http:/example.com/blog/en/sitemap.xml</loc>", + "<loc>http:/example.com/blog/fr/sitemap.xml</loc>") + + if defaultInSubDir { + assertFileContent(t, "public/fr/sitemap.xml", true, "<loc>http://example.com/blog/fr/</loc>") + } else { + assertFileContent(t, "public/fr/sitemap.xml", true, "<loc>http://example.com/blog/</loc>") + } + assertFileContent(t, "public/en/sitemap.xml", true, "<loc>http://example.com/blog/en/</loc>") + + // Check rss + assertFileContent(t, "public/fr/index.xml", defaultInSubDir, `<atom:link href="http://example.com/blog/fr/index.xml"`) + assertFileContent(t, "public/en/index.xml", defaultInSubDir, `<atom:link href="http://example.com/blog/en/index.xml"`) + assertFileContent(t, "public/fr/sect/index.xml", defaultInSubDir, `<atom:link href="http://example.com/blog/fr/sect/index.xml"`) + assertFileContent(t, "public/en/sect/index.xml", defaultInSubDir, `<atom:link href="http://example.com/blog/en/sect/index.xml"`) + assertFileContent(t, "public/fr/plaques/frtag1/index.xml", defaultInSubDir, `<atom:link href="http://example.com/blog/fr/plaques/frtag1/index.xml"`) + assertFileContent(t, "public/en/tags/tag1/index.xml", defaultInSubDir, `<atom:link href="http://example.com/blog/en/tags/tag1/index.xml"`) + + // Check paginators + assertFileContent(t, "public/fr/page/1/index.html", defaultInSubDir, `refresh" content="0; url=http://example.com/blog/fr/"`) + assertFileContent(t, "public/en/page/1/index.html", defaultInSubDir, `refresh" content="0; url=http://example.com/blog/en/"`) + assertFileContent(t, "public/fr/page/2/index.html", defaultInSubDir, "Home Page 2", "Bonjour", "http://example.com/blog/fr/") + assertFileContent(t, "public/en/page/2/index.html", defaultInSubDir, "Home Page 2", "Hello", "http://example.com/blog/en/") + assertFileContent(t, "public/fr/sect/page/1/index.html", defaultInSubDir, `refresh" content="0; url=http://example.com/blog/fr/sect/"`) + assertFileContent(t, "public/en/sect/page/1/index.html", defaultInSubDir, `refresh" content="0; url=http://example.com/blog/en/sect/"`) + assertFileContent(t, "public/fr/sect/page/2/index.html", defaultInSubDir, "List Page 2", "Bonjour", "http://example.com/blog/fr/sect/") + assertFileContent(t, "public/en/sect/page/2/index.html", defaultInSubDir, "List Page 2", "Hello", "http://example.com/blog/en/sect/") + assertFileContent(t, "public/fr/plaques/frtag1/page/1/index.html", defaultInSubDir, `refresh" content="0; url=http://example.com/blog/fr/plaques/frtag1/"`) + assertFileContent(t, "public/en/tags/tag1/page/1/index.html", defaultInSubDir, `refresh" content="0; url=http://example.com/blog/en/tags/tag1/"`) + assertFileContent(t, "public/fr/plaques/frtag1/page/2/index.html", defaultInSubDir, "List Page 2", "Bonjour", "http://example.com/blog/fr/plaques/frtag1/") + assertFileContent(t, "public/en/tags/tag1/page/2/index.html", defaultInSubDir, "List Page 2", "Hello", "http://example.com/blog/en/tags/tag1/") + +} + +func replaceDefaultContentLanguageValue(value string, defaultInSubDir bool) string { + replace := viper.GetString("DefaultContentLanguage") + "/" + if !defaultInSubDir { + value = strings.Replace(value, replace, "", 1) + + } + return value + +} + +func assertFileContent(t *testing.T, filename string, defaultInSubDir bool, matches ...string) { + filename = replaceDefaultContentLanguageValue(filename, defaultInSubDir) + content := readDestination(t, filename) + for _, match := range matches { + match = replaceDefaultContentLanguageValue(match, defaultInSubDir) + require.True(t, strings.Contains(content, match), fmt.Sprintf("File no match for %q in %q: %s", match, filename, content)) + } +} + func TestMultiSitesBuild(t *testing.T) { testCommonResetState() sites := createMultiTestSites(t, multiSiteTomlConfig) @@ -397,7 +519,7 @@ DisableSitemap = false DisableRSS = false RSSUri = "index.xml" -paginate = 2 +paginate = 1 DefaultContentLanguage = "fr" [permalinks] @@ -435,14 +557,14 @@ func createMultiTestSites(t *testing.T, tomlConfig string) *HugoSites { if err := afero.WriteFile(hugofs.Source(), filepath.Join("layouts", "_default/list.html"), - []byte("List: {{ .Title }}"), + []byte("{{ $p := .Paginator }}List Page {{ $p.PageNumber }}: {{ .Title }}|{{ i18n \"hello\" }}|{{ .Permalink }}"), 0755); err != nil { t.Fatalf("Failed to write layout file: %s", err) } if err := afero.WriteFile(hugofs.Source(), filepath.Join("layouts", "index.html"), - []byte("Home: {{ .Title }}|{{ .IsHome }}"), + []byte("{{ $p := .Paginator }}Home Page {{ $p.PageNumber }}: {{ .Title }}|{{ .IsHome }}|{{ i18n \"hello\" }}|{{ .Permalink }}"), 0755); err != nil { t.Fatalf("Failed to write layout file: %s", err) } @@ -505,6 +627,7 @@ title: doc3 publishdate: "2000-01-03" tags: - tag2 + - tag1 url: /superbob --- # doc3 diff --git a/hugolib/node.go b/hugolib/node.go index 57bd5021f..53c22af13 100644 --- a/hugolib/node.go +++ b/hugolib/node.go @@ -176,7 +176,7 @@ type URLPath struct { } func (n *Node) URL() string { - return n.addMultilingualWebPrefix(n.URLPath.URL) + return n.addLangPathPrefix(n.URLPath.URL) } func (n *Node) Permalink() string { @@ -206,8 +206,27 @@ func (n *Node) Lang() string { return n.lang } +func (n *Node) shouldAddLanguagePrefix() bool { + if !n.Site.IsMultiLingual() { + return false + } + + if n.Lang() == "" { + return false + } + + if !n.Site.defaultContentLanguageInSubdir && n.Lang() == n.Site.multilingual.DefaultLang.Lang { + return false + } + + return true +} + func (n *Node) initLanguage() { n.languageInit.Do(func() { + if n.language != nil { + return + } pageLang := n.lang ml := n.Site.multilingual if ml == nil { @@ -278,29 +297,34 @@ func (n *Node) initTranslations() { }) } -func (n *Node) addMultilingualWebPrefix(outfile string) string { +func (n *Node) addLangPathPrefix(outfile string) string { + return n.addLangPathPrefixIfFlagSet(outfile, n.shouldAddLanguagePrefix()) +} +func (n *Node) addLangPathPrefixIfFlagSet(outfile string, should bool) string { if helpers.IsAbsURL(outfile) { return outfile } - hadSlashSuffix := strings.HasSuffix(outfile, "/") - - lang := n.Lang() - if lang == "" || !n.Site.IsMultiLingual() { + if !should { return outfile } - outfile = "/" + path.Join(lang, outfile) + + hadSlashSuffix := strings.HasSuffix(outfile, "/") + + outfile = "/" + path.Join(n.Lang(), outfile) if hadSlashSuffix { outfile += "/" } return outfile } -func (n *Node) addMultilingualFilesystemPrefix(outfile string) string { - lang := n.Lang() - if lang == "" || !n.Site.IsMultiLingual() { +func (n *Node) addLangFilepathPrefix(outfile string) string { + if outfile == "" { + outfile = helpers.FilePathSeparator + } + if !n.shouldAddLanguagePrefix() { return outfile } - return string(filepath.Separator) + filepath.Join(lang, outfile) + return helpers.FilePathSeparator + filepath.Join(n.Lang(), outfile) } diff --git a/hugolib/page.go b/hugolib/page.go index a15af60bf..74f51c0bb 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -514,7 +514,7 @@ func (p *Page) permalink() (*url.URL, error) { } } - permalink = p.addMultilingualWebPrefix(permalink) + permalink = p.addLangPathPrefix(permalink) return helpers.MakePermalink(baseURL, permalink), nil } @@ -1059,7 +1059,7 @@ func (p *Page) TargetPath() (outfile string) { outfile += "index.html" } outfile = filepath.FromSlash(outfile) - outfile = p.addMultilingualFilesystemPrefix(outfile) + outfile = p.addLangFilepathPrefix(outfile) return } } @@ -1071,5 +1071,5 @@ func (p *Page) TargetPath() (outfile string) { outfile = helpers.ReplaceExtension(p.Source.TranslationBaseName(), p.Extension()) } - return p.addMultilingualFilesystemPrefix(filepath.Join(strings.ToLower(helpers.MakePath(p.Source.Dir())), strings.TrimSpace(outfile))) + return p.addLangFilepathPrefix(filepath.Join(strings.ToLower(helpers.MakePath(p.Source.Dir())), strings.TrimSpace(outfile))) } diff --git a/hugolib/site.go b/hugolib/site.go index 1b92006ff..edcccfe28 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -167,10 +167,11 @@ type SiteInfo struct { paginationPageCount uint64 Data *map[string]interface{} - multilingual *Multilingual - Language *helpers.Language - LanguagePrefix string - Languages helpers.Languages + multilingual *Multilingual + Language *helpers.Language + LanguagePrefix string + Languages helpers.Languages + defaultContentLanguageInSubdir bool } // Used in tests. @@ -864,42 +865,45 @@ func (s *Site) initializeSiteInfo() { permalinks[k] = pathPattern(v) } + defaultContentInSubDir := viper.GetBool("DefaultContentLanguageInSubdir") + defaultContentLanguage := viper.GetString("DefaultContentLanguage") + languagePrefix := "" - if s.multilingualEnabled() { + if s.multilingualEnabled() && (defaultContentInSubDir || lang.Lang != defaultContentLanguage) { languagePrefix = "/" + lang.Lang } var multilingual *Multilingual - if s.owner != nil { multilingual = s.owner.multilingual } s.Info = SiteInfo{ - BaseURL: template.URL(helpers.SanitizeURLKeepTrailingSlash(viper.GetString("BaseURL"))), - Title: lang.GetString("Title"), - Author: lang.GetStringMap("author"), - Social: lang.GetStringMapString("social"), - LanguageCode: lang.GetString("languagecode"), - Copyright: lang.GetString("copyright"), - DisqusShortname: lang.GetString("DisqusShortname"), - multilingual: multilingual, - Language: lang, - LanguagePrefix: languagePrefix, - Languages: languages, - GoogleAnalytics: lang.GetString("GoogleAnalytics"), - RSSLink: permalinkStr(viper.GetString("RSSUri")), - BuildDrafts: viper.GetBool("BuildDrafts"), - canonifyURLs: viper.GetBool("CanonifyURLs"), - preserveTaxonomyNames: viper.GetBool("PreserveTaxonomyNames"), - AllPages: &s.AllPages, - Pages: &s.Pages, - rawAllPages: &s.rawAllPages, - Files: &s.Files, - Menus: &s.Menus, - Params: params, - Permalinks: permalinks, - Data: &s.Data, + BaseURL: template.URL(helpers.SanitizeURLKeepTrailingSlash(viper.GetString("BaseURL"))), + Title: lang.GetString("Title"), + Author: lang.GetStringMap("author"), + Social: lang.GetStringMapString("social"), + LanguageCode: lang.GetString("languagecode"), + Copyright: lang.GetString("copyright"), + DisqusShortname: lang.GetString("DisqusShortname"), + multilingual: multilingual, + Language: lang, + LanguagePrefix: languagePrefix, + Languages: languages, + defaultContentLanguageInSubdir: defaultContentInSubDir, + GoogleAnalytics: lang.GetString("GoogleAnalytics"), + RSSLink: permalinkStr(viper.GetString("RSSUri")), + BuildDrafts: viper.GetBool("BuildDrafts"), + canonifyURLs: viper.GetBool("CanonifyURLs"), + preserveTaxonomyNames: viper.GetBool("PreserveTaxonomyNames"), + AllPages: &s.AllPages, + Pages: &s.Pages, + rawAllPages: &s.rawAllPages, + Files: &s.Files, + Menus: &s.Menus, + Params: params, + Permalinks: permalinks, + Data: &s.Data, } } @@ -1280,7 +1284,7 @@ func (s *Site) assembleMenus() { if p.Section() != "" { me := MenuEntry{Identifier: p.Section(), Name: helpers.MakeTitle(helpers.FirstUpper(p.Section())), - URL: s.Info.createNodeMenuEntryURL(p.addMultilingualWebPrefix("/"+p.Section()) + "/")} + URL: s.Info.createNodeMenuEntryURL(p.addLangPathPrefix("/"+p.Section()) + "/")} if _, ok := flat[twoD{sectionPagesMenu, me.KeyName()}]; ok { // menu with same id defined in config, let that one win continue @@ -1422,7 +1426,7 @@ func (s *Site) renderAliases() error { } } - if s.owner.multilingual.enabled() { + if s.owner.multilingual.enabled() && s.Info.defaultContentLanguageInSubdir { mainLang := s.owner.multilingual.DefaultLang.Lang mainLangURL := helpers.AbsURL(mainLang, false) jww.DEBUG.Printf("Write redirect to main language %s: %s", mainLang, mainLangURL) @@ -1612,19 +1616,6 @@ func (s *Site) newTaxonomyNode(t taxRenderInfo) (*Node, string) { return n, base } -// addMultilingualPrefix adds the `en/` prefix to the path passed as parameter. -// `basePath` must not start with http:// -func (s *Site) addMultilingualPrefix(basePath string) string { - hadPrefix := strings.HasPrefix(basePath, "/") - if s.multilingualEnabled() { - basePath = path.Join(s.Language.Lang, basePath) - if hadPrefix { - basePath = "/" + basePath - } - } - return basePath -} - func taxonomyRenderer(s *Site, taxes <-chan taxRenderInfo, results chan<- error, wg *sync.WaitGroup) { defer wg.Done() @@ -1637,14 +1628,13 @@ func taxonomyRenderer(s *Site, taxes <-chan taxRenderInfo, results chan<- error, []string{"taxonomy/" + t.singular + ".html", "indexes/" + t.singular + ".html", "_default/taxonomy.html", "_default/list.html"}) n, base = s.newTaxonomyNode(t) - - base = s.addMultilingualPrefix(base) + baseWithLanguagePrefix := n.addLangPathPrefix(base) dest := base if viper.GetBool("UglyURLs") { - dest = helpers.Uglify(base + ".html") + dest = helpers.Uglify(baseWithLanguagePrefix + ".html") } else { - dest = helpers.PrettifyPath(base + "/index.html") + dest = helpers.PrettifyPath(baseWithLanguagePrefix + "/index.html") } if err := s.renderAndWritePage("taxonomy "+t.singular, dest, n, layouts...); err != nil { @@ -1657,7 +1647,7 @@ func taxonomyRenderer(s *Site, taxes <-chan taxRenderInfo, results chan<- error, paginatePath := viper.GetString("paginatePath") // write alias for page 1 - s.writeDestAlias(helpers.PaginateAliasPath(base, 1), permalink(base)) + s.writeDestAlias(helpers.PaginateAliasPath(baseWithLanguagePrefix, 1), n.Permalink()) pagers := n.paginator.Pagers() @@ -1675,7 +1665,7 @@ func taxonomyRenderer(s *Site, taxes <-chan taxRenderInfo, results chan<- error, taxonomyPagerNode.Lastmod = first.Lastmod } pageNumber := i + 1 - htmlBase := fmt.Sprintf("/%s/%s/%d", base, paginatePath, pageNumber) + htmlBase := fmt.Sprintf("/%s/%s/%d", baseWithLanguagePrefix, paginatePath, pageNumber) if err := s.renderAndWritePage(fmt.Sprintf("taxonomy %s", t.singular), htmlBase, taxonomyPagerNode, layouts...); err != nil { results <- err continue @@ -1686,11 +1676,10 @@ func taxonomyRenderer(s *Site, taxes <-chan taxRenderInfo, results chan<- error, if !viper.GetBool("DisableRSS") { // XML Feed rssuri := viper.GetString("RSSUri") - n.URLPath.URL = permalinkStr(base + "/" + rssuri) - n.URLPath.Permalink = permalink(base) + s.setURLs(n, base+"/"+rssuri) rssLayouts := []string{"taxonomy/" + t.singular + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"} - if err := s.renderAndWriteXML("taxonomy "+t.singular+" rss", base+"/"+rssuri, n, s.appendThemeTemplates(rssLayouts)...); err != nil { + if err := s.renderAndWriteXML("taxonomy "+t.singular+" rss", baseWithLanguagePrefix+"/"+rssuri, n, s.appendThemeTemplates(rssLayouts)...); err != nil { results <- err continue } @@ -1714,7 +1703,7 @@ func (s *Site) renderListsOfTaxonomyTerms() (err error) { layouts := []string{"taxonomy/" + singular + ".terms.html", "_default/terms.html", "indexes/indexes.html"} layouts = s.appendThemeTemplates(layouts) if s.layoutExists(layouts...) { - if err := s.renderAndWritePage("taxonomy terms for "+singular, s.addMultilingualPrefix(plural+"/index.html"), n, layouts...); err != nil { + if err := s.renderAndWritePage("taxonomy terms for "+singular, n.addLangPathPrefix(plural+"/index.html"), n, layouts...); err != nil { return err } } @@ -1755,9 +1744,9 @@ func (s *Site) renderSectionLists() error { section = helpers.MakePathSanitized(section) } - base := s.addMultilingualPrefix(section) - n := s.newSectionListNode(sectionName, section, data) + base := n.addLangPathPrefix(section) + if err := s.renderAndWritePage(fmt.Sprintf("section %s", section), base, n, s.appendThemeTemplates(layouts)...); err != nil { return err } @@ -1795,10 +1784,9 @@ func (s *Site) renderSectionLists() error { if !viper.GetBool("DisableRSS") && section != "" { // XML Feed rssuri := viper.GetString("RSSUri") - n.URLPath.URL = permalinkStr(base + "/" + rssuri) - n.URLPath.Permalink = permalink(base) + s.setURLs(n, section+"/"+rssuri) rssLayouts := []string{"section/" + section + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"} - if err := s.renderAndWriteXML("section "+section+" rss", base+"/"+rssuri, n, s.appendThemeTemplates(rssLayouts)...); err != nil { + if err := s.renderAndWriteXML("section "+section+" rss", n.addLangPathPrefix(section+"/"+rssuri), n, s.appendThemeTemplates(rssLayouts)...); err != nil { return err } } |