mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
parent
6c9ea022a9
commit
92e86702ea
12 changed files with 154 additions and 101 deletions
|
@ -1042,8 +1042,8 @@ func (c *hugoBuilder) rebuildSites(events []fsnotify.Event) error {
|
||||||
if c.fastRenderMode {
|
if c.fastRenderMode {
|
||||||
c.withConf(func(conf *commonConfig) {
|
c.withConf(func(conf *commonConfig) {
|
||||||
// Make sure we always render the home pages
|
// Make sure we always render the home pages
|
||||||
for _, l := range conf.configs.Languages {
|
for _, l := range conf.configs.ConfigLangs() {
|
||||||
langPath := h.GetLangSubDir(l.Lang)
|
langPath := l.LanguagePrefix()
|
||||||
if langPath != "" {
|
if langPath != "" {
|
||||||
langPath = langPath + "/"
|
langPath = langPath + "/"
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,16 @@ func (c ConfigLanguage) LanguagesDefaultFirst() langs.Languages {
|
||||||
return c.m.LanguagesDefaultFirst
|
return c.m.LanguagesDefaultFirst
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c ConfigLanguage) LanguagePrefix() string {
|
||||||
|
if c.DefaultContentLanguageInSubdir() && c.DefaultContentLanguage() == c.Language().Lang {
|
||||||
|
return c.Language().Lang
|
||||||
|
}
|
||||||
|
if !c.IsMultiLingual() || c.DefaultContentLanguage() == c.Language().Lang {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return c.Language().Lang
|
||||||
|
}
|
||||||
|
|
||||||
func (c ConfigLanguage) BaseURL() urls.BaseURL {
|
func (c ConfigLanguage) BaseURL() urls.BaseURL {
|
||||||
return c.config.C.BaseURL
|
return c.config.C.BaseURL
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ type AllProvider interface {
|
||||||
Language() *langs.Language
|
Language() *langs.Language
|
||||||
Languages() langs.Languages
|
Languages() langs.Languages
|
||||||
LanguagesDefaultFirst() langs.Languages
|
LanguagesDefaultFirst() langs.Languages
|
||||||
|
LanguagePrefix() string
|
||||||
BaseURL() urls.BaseURL
|
BaseURL() urls.BaseURL
|
||||||
BaseURLLiveReload() urls.BaseURL
|
BaseURLLiveReload() urls.BaseURL
|
||||||
Environment() string
|
Environment() string
|
||||||
|
|
|
@ -109,8 +109,16 @@ func doTestAbsURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool,
|
||||||
"weight": 10,
|
"weight": 10,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
|
||||||
v.Set("defaultContentLanguage", "en")
|
v.Set("defaultContentLanguage", "en")
|
||||||
|
} else {
|
||||||
|
v.Set("defaultContentLanguage", lang)
|
||||||
|
v.Set("languages", map[string]any{
|
||||||
|
lang: map[string]interface{}{
|
||||||
|
"weight": 10,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
v.Set("defaultContentLanguageInSubdir", defaultInSubDir)
|
v.Set("defaultContentLanguageInSubdir", defaultInSubDir)
|
||||||
v.Set("baseURL", test.baseURL)
|
v.Set("baseURL", test.baseURL)
|
||||||
|
|
||||||
|
@ -118,16 +126,21 @@ func doTestAbsURL(t *testing.T, defaultInSubDir, addLanguage, multilingual bool,
|
||||||
if multilingual {
|
if multilingual {
|
||||||
configLang = lang
|
configLang = lang
|
||||||
}
|
}
|
||||||
|
defaultContentLanguage := lang
|
||||||
|
if multilingual {
|
||||||
|
defaultContentLanguage = "en"
|
||||||
|
}
|
||||||
|
|
||||||
p := newTestPathSpecFromCfgAndLang(v, configLang)
|
p := newTestPathSpecFromCfgAndLang(v, configLang)
|
||||||
|
|
||||||
output := p.AbsURL(test.input, addLanguage)
|
output := p.AbsURL(test.input, addLanguage)
|
||||||
expected := test.expected
|
expected := test.expected
|
||||||
if multilingual && addLanguage {
|
if addLanguage {
|
||||||
if !defaultInSubDir && lang == "en" {
|
addLanguage = defaultInSubDir && lang == defaultContentLanguage
|
||||||
expected = strings.Replace(expected, "MULTI", "", 1)
|
addLanguage = addLanguage || (lang != defaultContentLanguage && multilingual)
|
||||||
} else {
|
|
||||||
expected = strings.Replace(expected, "MULTI", lang+"/", 1)
|
|
||||||
}
|
}
|
||||||
|
if addLanguage {
|
||||||
|
expected = strings.Replace(expected, "MULTI", lang+"/", 1)
|
||||||
} else {
|
} else {
|
||||||
expected = strings.Replace(expected, "MULTI", "", 1)
|
expected = strings.Replace(expected, "MULTI", "", 1)
|
||||||
}
|
}
|
||||||
|
@ -162,8 +175,16 @@ func doTestRelURL(t testing.TB, defaultInSubDir, addLanguage, multilingual bool,
|
||||||
"weight": 10,
|
"weight": 10,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
|
||||||
v.Set("defaultContentLanguage", "en")
|
v.Set("defaultContentLanguage", "en")
|
||||||
|
} else {
|
||||||
|
v.Set("defaultContentLanguage", lang)
|
||||||
|
v.Set("languages", map[string]any{
|
||||||
|
lang: map[string]interface{}{
|
||||||
|
"weight": 10,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
v.Set("defaultContentLanguageInSubdir", defaultInSubDir)
|
v.Set("defaultContentLanguageInSubdir", defaultInSubDir)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -209,25 +230,25 @@ func doTestRelURL(t testing.TB, defaultInSubDir, addLanguage, multilingual bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
c.Run(fmt.Sprintf("%v/%t%t%t/%s", test, defaultInSubDir, addLanguage, multilingual, lang), func(c *qt.C) {
|
c.Run(fmt.Sprintf("%v/defaultInSubDir=%t;addLanguage=%t;multilingual=%t/%s", test, defaultInSubDir, addLanguage, multilingual, lang), func(c *qt.C) {
|
||||||
|
|
||||||
v.Set("baseURL", test.baseURL)
|
v.Set("baseURL", test.baseURL)
|
||||||
v.Set("canonifyURLs", test.canonify)
|
v.Set("canonifyURLs", test.canonify)
|
||||||
var configLang string
|
defaultContentLanguage := lang
|
||||||
if multilingual {
|
if multilingual {
|
||||||
configLang = lang
|
defaultContentLanguage = "en"
|
||||||
}
|
}
|
||||||
p := newTestPathSpecFromCfgAndLang(v, configLang)
|
p := newTestPathSpecFromCfgAndLang(v, lang)
|
||||||
|
|
||||||
output := p.RelURL(test.input, addLanguage)
|
output := p.RelURL(test.input, addLanguage)
|
||||||
|
|
||||||
expected := test.expected
|
expected := test.expected
|
||||||
if multilingual && addLanguage {
|
if addLanguage {
|
||||||
if !defaultInSubDir && lang == "en" {
|
addLanguage = defaultInSubDir && lang == defaultContentLanguage
|
||||||
expected = strings.Replace(expected, "MULTI", "", 1)
|
addLanguage = addLanguage || (lang != defaultContentLanguage && multilingual)
|
||||||
} else {
|
|
||||||
expected = strings.Replace(expected, "MULTI", "/"+lang, 1)
|
|
||||||
}
|
}
|
||||||
|
if addLanguage {
|
||||||
|
expected = strings.Replace(expected, "MULTI", "/"+lang, 1)
|
||||||
} else {
|
} else {
|
||||||
expected = strings.Replace(expected, "MULTI", "", 1)
|
expected = strings.Replace(expected, "MULTI", "", 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1295,3 +1295,94 @@ Home.
|
||||||
b.Assert(b.H.Configs.LanguageConfigSlice[0].Module.Mounts, qt.HasLen, 7)
|
b.Assert(b.H.Configs.LanguageConfigSlice[0].Module.Mounts, qt.HasLen, 7)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDefaultContentLanguageInSubdirOnlyOneLanguage(t *testing.T) {
|
||||||
|
|
||||||
|
t.Run("One language, default in sub dir", func(t *testing.T) {
|
||||||
|
t.Skip()
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
files := `
|
||||||
|
-- hugo.toml --
|
||||||
|
baseURL = "https://example.com"
|
||||||
|
defaultContentLanguage = "en"
|
||||||
|
defaultContentLanguageInSubdir = true
|
||||||
|
disableKinds = ["taxonomy", "term", "page", "section"]
|
||||||
|
-- content/foo/bar.txt --
|
||||||
|
Foo.
|
||||||
|
-- layouts/index.html --
|
||||||
|
Home.
|
||||||
|
`
|
||||||
|
b := NewIntegrationTestBuilder(
|
||||||
|
IntegrationTestConfig{
|
||||||
|
T: t,
|
||||||
|
TxtarString: files,
|
||||||
|
},
|
||||||
|
).Build()
|
||||||
|
|
||||||
|
b.AssertFileContent("public/en/index.html", "Home.")
|
||||||
|
b.AssertFileContent("public/en/foo/bar.txt", "Foo.")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Two languages, default in sub dir", func(t *testing.T) {
|
||||||
|
t.Skip()
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
files := `
|
||||||
|
-- hugo.toml --
|
||||||
|
baseURL = "https://example.com"
|
||||||
|
defaultContentLanguage = "en"
|
||||||
|
defaultContentLanguageInSubdir = true
|
||||||
|
disableKinds = ["taxonomy", "term", "page", "section"]
|
||||||
|
[languages]
|
||||||
|
[languages.en]
|
||||||
|
title = "English Title"
|
||||||
|
[languages.sv]
|
||||||
|
title = "Swedish Title"
|
||||||
|
-- content/foo/bar.txt --
|
||||||
|
Foo.
|
||||||
|
-- layouts/index.html --
|
||||||
|
Home.
|
||||||
|
`
|
||||||
|
b := NewIntegrationTestBuilder(
|
||||||
|
IntegrationTestConfig{
|
||||||
|
T: t,
|
||||||
|
TxtarString: files,
|
||||||
|
},
|
||||||
|
).Build()
|
||||||
|
|
||||||
|
b.AssertFileContent("public/en/index.html", "Home.")
|
||||||
|
b.AssertFileContent("public/en/foo/bar.txt", "Foo.")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("Two languages, default in root", func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
files := `
|
||||||
|
-- hugo.toml --
|
||||||
|
baseURL = "https://example.com"
|
||||||
|
defaultContentLanguage = "en"
|
||||||
|
defaultContentLanguageInSubdir = false
|
||||||
|
disableKinds = ["taxonomy", "term", "page", "section"]
|
||||||
|
[languages]
|
||||||
|
[languages.en]
|
||||||
|
title = "English Title"
|
||||||
|
[languages.sv]
|
||||||
|
title = "Swedish Title"
|
||||||
|
-- content/foo/bar.txt --
|
||||||
|
Foo.
|
||||||
|
-- layouts/index.html --
|
||||||
|
Home.
|
||||||
|
`
|
||||||
|
b := NewIntegrationTestBuilder(
|
||||||
|
IntegrationTestConfig{
|
||||||
|
T: t,
|
||||||
|
TxtarString: files,
|
||||||
|
},
|
||||||
|
).Build()
|
||||||
|
|
||||||
|
b.AssertFileContent("public/index.html", "Home.")
|
||||||
|
b.AssertFileContent("public/foo/bar.txt", "Foo.")
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ func TestPageBundlerSiteRegular(t *testing.T) {
|
||||||
fs, cfg := newTestBundleSources(c)
|
fs, cfg := newTestBundleSources(c)
|
||||||
cfg.Set("baseURL", baseURL)
|
cfg.Set("baseURL", baseURL)
|
||||||
cfg.Set("canonifyURLs", canonify)
|
cfg.Set("canonifyURLs", canonify)
|
||||||
|
cfg.Set("defaultContentLanguageInSubdir", false)
|
||||||
|
|
||||||
cfg.Set("permalinks", map[string]string{
|
cfg.Set("permalinks", map[string]string{
|
||||||
"a": ":sections/:filename",
|
"a": ":sections/:filename",
|
||||||
|
|
|
@ -102,6 +102,7 @@ func (p *Paths) Lang() string {
|
||||||
return p.Cfg.Language().Lang
|
return p.Cfg.Language().Lang
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO1 check this.
|
||||||
func (p *Paths) GetTargetLanguageBasePath() string {
|
func (p *Paths) GetTargetLanguageBasePath() string {
|
||||||
if len(p.Cfg.Languages()) > 1 {
|
if len(p.Cfg.Languages()) > 1 {
|
||||||
// In a multihost configuration all assets will be published below the language code.
|
// In a multihost configuration all assets will be published below the language code.
|
||||||
|
@ -110,41 +111,8 @@ func (p *Paths) GetTargetLanguageBasePath() string {
|
||||||
return p.GetLanguagePrefix()
|
return p.GetLanguagePrefix()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Paths) GetURLLanguageBasePath() string {
|
|
||||||
if len(p.Cfg.Languages()) > 1 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return p.GetLanguagePrefix()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Paths) GetLanguagePrefix() string {
|
func (p *Paths) GetLanguagePrefix() string {
|
||||||
if len(p.Cfg.Languages()) < 2 {
|
return p.Cfg.LanguagePrefix()
|
||||||
return ""
|
|
||||||
}
|
|
||||||
defaultLang := p.Cfg.DefaultContentLanguage()
|
|
||||||
defaultInSubDir := p.Cfg.DefaultContentLanguageInSubdir()
|
|
||||||
currentLang := p.Cfg.Language().Lang
|
|
||||||
if currentLang == "" || (currentLang == defaultLang && !defaultInSubDir) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return currentLang
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetLangSubDir returns the given language's subdir if needed.
|
|
||||||
func (p *Paths) GetLangSubDir(lang string) string {
|
|
||||||
if len(p.Cfg.Languages()) < 2 {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.Cfg.IsMultihost() {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if lang == "" || (lang == p.Cfg.DefaultContentLanguage() && !p.Cfg.DefaultContentLanguageInSubdir()) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return lang
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AbsPathify creates an absolute path if given a relative path. If already
|
// AbsPathify creates an absolute path if given a relative path. If already
|
||||||
|
|
|
@ -887,21 +887,16 @@ func (s *Site) getLanguageTargetPathLang(alwaysInSubDir bool) string {
|
||||||
|
|
||||||
// get any language code to prefix the relative permalink with.
|
// get any language code to prefix the relative permalink with.
|
||||||
func (s *Site) getLanguagePermalinkLang(alwaysInSubDir bool) string {
|
func (s *Site) getLanguagePermalinkLang(alwaysInSubDir bool) string {
|
||||||
if !s.h.isMultiLingual() || s.h.Conf.IsMultihost() {
|
if s.h.Conf.IsMultihost() {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
if alwaysInSubDir {
|
if s.h.Conf.IsMultiLingual() && alwaysInSubDir {
|
||||||
return s.Language().Lang
|
return s.Language().Lang
|
||||||
}
|
}
|
||||||
|
|
||||||
isDefault := s.Language().Lang == s.conf.DefaultContentLanguage
|
return s.GetLanguagePrefix()
|
||||||
|
|
||||||
if !isDefault || s.conf.DefaultContentLanguageInSubdir {
|
|
||||||
return s.Language().Lang
|
|
||||||
}
|
|
||||||
|
|
||||||
return ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) getTaxonomyKey(key string) string {
|
func (s *Site) getTaxonomyKey(key string) string {
|
||||||
|
|
|
@ -470,16 +470,11 @@ func (s *Site) IsMultiLingual() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) LanguagePrefix() string {
|
func (s *Site) LanguagePrefix() string {
|
||||||
conf := s.s.Conf
|
prefix := s.GetLanguagePrefix()
|
||||||
if !conf.IsMultiLingual() {
|
if prefix == "" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
return "/" + prefix
|
||||||
if !conf.DefaultContentLanguageInSubdir() && s.language.Lang == conf.DefaultContentLanguage() {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
return "/" + s.language.Lang
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the identity of this site.
|
// Returns the identity of this site.
|
||||||
|
|
|
@ -38,35 +38,6 @@ var urlFakeSource = [][2]string{
|
||||||
{filepath.FromSlash("content/blue/doc2.md"), slugDoc2},
|
{filepath.FromSlash("content/blue/doc2.md"), slugDoc2},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPageCount(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
c := qt.New(t)
|
|
||||||
cfg, fs := newTestCfg()
|
|
||||||
cfg.Set("uglyURLs", false)
|
|
||||||
cfg.Set("paginate", 10)
|
|
||||||
configs, err := loadTestConfigFromProvider(cfg)
|
|
||||||
c.Assert(err, qt.IsNil)
|
|
||||||
|
|
||||||
writeSourcesToSource(t, "", fs, urlFakeSource...)
|
|
||||||
s := buildSingleSite(t, deps.DepsCfg{Fs: fs, Configs: configs}, BuildCfg{})
|
|
||||||
|
|
||||||
_, err = s.Fs.WorkingDirReadOnly.Open("public/blue")
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("No indexed rendered.")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, pth := range []string{
|
|
||||||
"public/sd1/foo/index.html",
|
|
||||||
"public/sd2/index.html",
|
|
||||||
"public/sd3/index.html",
|
|
||||||
"public/sd4.html",
|
|
||||||
} {
|
|
||||||
if _, err := s.Fs.WorkingDirReadOnly.Open(filepath.FromSlash(pth)); err != nil {
|
|
||||||
t.Errorf("No alias rendered: %s", pth)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUglyURLsPerSection(t *testing.T) {
|
func TestUglyURLsPerSection(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ func doTestSitemapOutput(t *testing.T, internal bool) {
|
||||||
c := qt.New(t)
|
c := qt.New(t)
|
||||||
cfg, fs := newTestCfg()
|
cfg, fs := newTestCfg()
|
||||||
cfg.Set("baseURL", "http://auth/bub/")
|
cfg.Set("baseURL", "http://auth/bub/")
|
||||||
|
cfg.Set("defaultContentLanguageInSubdir", false)
|
||||||
configs, err := loadTestConfigFromProvider(cfg)
|
configs, err := loadTestConfigFromProvider(cfg)
|
||||||
c.Assert(err, qt.IsNil)
|
c.Assert(err, qt.IsNil)
|
||||||
writeSource(t, fs, "layouts/sitemap.xml", sitemapTemplate)
|
writeSource(t, fs, "layouts/sitemap.xml", sitemapTemplate)
|
||||||
|
|
|
@ -937,8 +937,7 @@ func newTestCfgBasic() (config.Provider, *hugofs.Fs) {
|
||||||
func newTestCfg(withConfig ...func(cfg config.Provider) error) (config.Provider, *hugofs.Fs) {
|
func newTestCfg(withConfig ...func(cfg config.Provider) error) (config.Provider, *hugofs.Fs) {
|
||||||
mm := afero.NewMemMapFs()
|
mm := afero.NewMemMapFs()
|
||||||
cfg := config.New()
|
cfg := config.New()
|
||||||
// Default is false, but true is easier to use as default in tests
|
cfg.Set("defaultContentLanguageInSubdir", false)
|
||||||
cfg.Set("defaultContentLanguageInSubdir", true)
|
|
||||||
cfg.Set("publishDir", "public")
|
cfg.Set("publishDir", "public")
|
||||||
|
|
||||||
fs := hugofs.NewFromOld(hugofs.NewBaseFileDecorator(mm), cfg)
|
fs := hugofs.NewFromOld(hugofs.NewBaseFileDecorator(mm), cfg)
|
||||||
|
|
Loading…
Reference in a new issue