mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
parent
cad2d8cc70
commit
1c0e7c1ae1
6 changed files with 142 additions and 40 deletions
|
@ -60,7 +60,6 @@ type FileMeta struct {
|
||||||
Module string
|
Module string
|
||||||
|
|
||||||
Weight int
|
Weight int
|
||||||
Ordinal int
|
|
||||||
IsOrdered bool
|
IsOrdered bool
|
||||||
IsSymlink bool
|
IsSymlink bool
|
||||||
IsRootFile bool
|
IsRootFile bool
|
||||||
|
|
|
@ -47,10 +47,9 @@ func NewLanguageFs(langs map[string]int, fs afero.Fs) (afero.Fs, error) {
|
||||||
lang := meta.Lang
|
lang := meta.Lang
|
||||||
|
|
||||||
fileLang, translationBaseName, translationBaseNameWithExt := langInfoFrom(langs, fi.Name())
|
fileLang, translationBaseName, translationBaseNameWithExt := langInfoFrom(langs, fi.Name())
|
||||||
weight := 0
|
weight := meta.Weight
|
||||||
|
|
||||||
if fileLang != "" {
|
if fileLang != "" {
|
||||||
weight = 1
|
|
||||||
if fileLang == lang {
|
if fileLang == lang {
|
||||||
// Give priority to myfile.sv.txt inside the sv filesystem.
|
// Give priority to myfile.sv.txt inside the sv filesystem.
|
||||||
weight++
|
weight++
|
||||||
|
@ -63,7 +62,6 @@ func NewLanguageFs(langs map[string]int, fs afero.Fs) (afero.Fs, error) {
|
||||||
&FileMeta{
|
&FileMeta{
|
||||||
Lang: lang,
|
Lang: lang,
|
||||||
Weight: weight,
|
Weight: weight,
|
||||||
Ordinal: langs[lang],
|
|
||||||
TranslationBaseName: translationBaseName,
|
TranslationBaseName: translationBaseName,
|
||||||
TranslationBaseNameWithExt: translationBaseNameWithExt,
|
TranslationBaseNameWithExt: translationBaseNameWithExt,
|
||||||
Classifier: files.ClassifyContentFile(fi.Name(), meta.OpenFunc),
|
Classifier: files.ClassifyContentFile(fi.Name(), meta.OpenFunc),
|
||||||
|
|
|
@ -15,7 +15,6 @@ package hugofs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"path"
|
|
||||||
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
)
|
)
|
||||||
|
@ -56,32 +55,20 @@ func (fs *languageCompositeFs) Open(name string) (afero.File, error) {
|
||||||
// LanguageDirsMerger implements the afero.DirsMerger interface, which is used
|
// LanguageDirsMerger implements the afero.DirsMerger interface, which is used
|
||||||
// to merge two directories.
|
// to merge two directories.
|
||||||
var LanguageDirsMerger = func(lofi, bofi []os.FileInfo) ([]os.FileInfo, error) {
|
var LanguageDirsMerger = func(lofi, bofi []os.FileInfo) ([]os.FileInfo, error) {
|
||||||
m := make(map[string]FileMetaInfo)
|
for _, fi1 := range bofi {
|
||||||
|
fim1 := fi1.(FileMetaInfo)
|
||||||
getKey := func(fim FileMetaInfo) string {
|
var found bool
|
||||||
return path.Join(fim.Meta().Lang, fim.Name())
|
for _, fi2 := range lofi {
|
||||||
}
|
fim2 := fi2.(FileMetaInfo)
|
||||||
|
if fi1.Name() == fi2.Name() && fim1.Meta().Lang == fim2.Meta().Lang {
|
||||||
for _, fi := range lofi {
|
found = true
|
||||||
fim := fi.(FileMetaInfo)
|
break
|
||||||
m[getKey(fim)] = fim
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fi := range bofi {
|
|
||||||
fim := fi.(FileMetaInfo)
|
|
||||||
key := getKey(fim)
|
|
||||||
_, found := m[key]
|
|
||||||
if !found {
|
if !found {
|
||||||
m[key] = fim
|
lofi = append(lofi, fi1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
merged := make([]os.FileInfo, len(m))
|
return lofi, nil
|
||||||
i := 0
|
|
||||||
for _, v := range m {
|
|
||||||
merged[i] = v
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
|
|
||||||
return merged, nil
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -224,13 +224,8 @@ func (w *Walkway) walk(path string, info FileMetaInfo, dirEntries []FileMetaInfo
|
||||||
// to the closest one.
|
// to the closest one.
|
||||||
fiw, fjw := fim.Weight, fjm.Weight
|
fiw, fjw := fim.Weight, fjm.Weight
|
||||||
if fiw != fjw {
|
if fiw != fjw {
|
||||||
return fiw > fjw
|
|
||||||
}
|
|
||||||
|
|
||||||
// Explicit order set.
|
return fiw > fjw
|
||||||
fio, fjo := fim.Ordinal, fjm.Ordinal
|
|
||||||
if fio != fjo {
|
|
||||||
return fio < fjo
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When we walk into a symlink, we keep the reference to
|
// When we walk into a symlink, we keep the reference to
|
||||||
|
|
|
@ -602,6 +602,7 @@ func (b *sourceFilesystemsBuilder) createMainOverlayFs(p *paths.Paths) (*filesys
|
||||||
Module: mod,
|
Module: mod,
|
||||||
dir: dir,
|
dir: dir,
|
||||||
isMainProject: isMainProject,
|
isMainProject: isMainProject,
|
||||||
|
ordinal: j,
|
||||||
}
|
}
|
||||||
j++
|
j++
|
||||||
}
|
}
|
||||||
|
@ -635,12 +636,12 @@ func (b *sourceFilesystemsBuilder) createModFs(
|
||||||
return md.dir, paths.AbsPathify(md.dir, path)
|
return md.dir, paths.AbsPathify(md.dir, path)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, mount := range md.Mounts() {
|
for i, mount := range md.Mounts() {
|
||||||
|
|
||||||
mountWeight := 1
|
// Add more weight to early mounts.
|
||||||
if md.isMainProject {
|
// When two mounts contain the same filename,
|
||||||
mountWeight++
|
// the first entry wins.
|
||||||
}
|
mountWeight := (10 + md.ordinal) * (len(md.Mounts()) - i)
|
||||||
|
|
||||||
inclusionFilter, err := glob.NewFilenameFilter(
|
inclusionFilter, err := glob.NewFilenameFilter(
|
||||||
types.ToStringSlicePreserveString(mount.IncludeFiles),
|
types.ToStringSlicePreserveString(mount.IncludeFiles),
|
||||||
|
@ -829,6 +830,7 @@ type mountsDescriptor struct {
|
||||||
modules.Module
|
modules.Module
|
||||||
dir string
|
dir string
|
||||||
isMainProject bool
|
isMainProject bool
|
||||||
|
ordinal int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *sourceFilesystemsBuilder) createOverlayFs(collector *filesystemsCollector, mounts []mountsDescriptor) error {
|
func (b *sourceFilesystemsBuilder) createOverlayFs(collector *filesystemsCollector, mounts []mountsDescriptor) error {
|
||||||
|
|
|
@ -403,3 +403,124 @@ Page: /fr/event/page2/|ev-fr2
|
||||||
Page: /fr/other/page1/|other-fr1
|
Page: /fr/other/page1/|other-fr1
|
||||||
Page: /fr/other/page2/|other-fr2`)
|
Page: /fr/other/page2/|other-fr2`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Issue 9693
|
||||||
|
func TestContentMountMerge(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
files := `
|
||||||
|
-- config.toml --
|
||||||
|
baseURL = 'https://example.org/'
|
||||||
|
languageCode = 'en-us'
|
||||||
|
title = 'Hugo Forum Topic #37225'
|
||||||
|
theme = 'mytheme'
|
||||||
|
|
||||||
|
disableKinds = ['sitemap','RSS','taxonomy','term']
|
||||||
|
defaultContentLanguage = 'en'
|
||||||
|
defaultContentLanguageInSubdir = true
|
||||||
|
|
||||||
|
[languages.en]
|
||||||
|
languageName = 'English'
|
||||||
|
weight = 1
|
||||||
|
[languages.de]
|
||||||
|
languageName = 'Deutsch'
|
||||||
|
weight = 2
|
||||||
|
[languages.nl]
|
||||||
|
languageName = 'Nederlands'
|
||||||
|
weight = 3
|
||||||
|
|
||||||
|
# EN content
|
||||||
|
[[module.mounts]]
|
||||||
|
source = 'content/en'
|
||||||
|
target = 'content'
|
||||||
|
lang = 'en'
|
||||||
|
|
||||||
|
# DE content
|
||||||
|
[[module.mounts]]
|
||||||
|
source = 'content/de'
|
||||||
|
target = 'content'
|
||||||
|
lang = 'de'
|
||||||
|
|
||||||
|
# This fills in the gaps in DE content with EN content
|
||||||
|
[[module.mounts]]
|
||||||
|
source = 'content/en'
|
||||||
|
target = 'content'
|
||||||
|
lang = 'de'
|
||||||
|
|
||||||
|
# NL content
|
||||||
|
[[module.mounts]]
|
||||||
|
source = 'content/nl'
|
||||||
|
target = 'content'
|
||||||
|
lang = 'nl'
|
||||||
|
|
||||||
|
# This should fill in the gaps in NL content with EN content
|
||||||
|
[[module.mounts]]
|
||||||
|
source = 'content/en'
|
||||||
|
target = 'content'
|
||||||
|
lang = 'nl'
|
||||||
|
|
||||||
|
-- content/de/_index.md --
|
||||||
|
---
|
||||||
|
title: "home (de)"
|
||||||
|
---
|
||||||
|
-- content/de/p1.md --
|
||||||
|
---
|
||||||
|
title: "p1 (de)"
|
||||||
|
---
|
||||||
|
-- content/en/_index.md --
|
||||||
|
---
|
||||||
|
title: "home (en)"
|
||||||
|
---
|
||||||
|
-- content/en/p1.md --
|
||||||
|
---
|
||||||
|
title: "p1 (en)"
|
||||||
|
---
|
||||||
|
-- content/en/p2.md --
|
||||||
|
---
|
||||||
|
title: "p2 (en)"
|
||||||
|
---
|
||||||
|
-- content/en/p3.md --
|
||||||
|
---
|
||||||
|
title: "p3 (en)"
|
||||||
|
---
|
||||||
|
-- content/nl/_index.md --
|
||||||
|
---
|
||||||
|
title: "home (nl)"
|
||||||
|
---
|
||||||
|
-- content/nl/p1.md --
|
||||||
|
---
|
||||||
|
title: "p1 (nl)"
|
||||||
|
---
|
||||||
|
-- content/nl/p3.md --
|
||||||
|
---
|
||||||
|
title: "p3 (nl)"
|
||||||
|
---
|
||||||
|
-- layouts/home.html --
|
||||||
|
{{ .Title }}: {{ site.Language.Lang }}: {{ range site.RegularPages }}{{ .Title }}|{{ end }}:END
|
||||||
|
-- themes/mytheme/config.toml --
|
||||||
|
[[module.mounts]]
|
||||||
|
source = 'content/nlt'
|
||||||
|
target = 'content'
|
||||||
|
lang = 'nl'
|
||||||
|
-- themes/mytheme/content/nlt/p3.md --
|
||||||
|
---
|
||||||
|
title: "p3 theme (nl)"
|
||||||
|
---
|
||||||
|
-- themes/mytheme/content/nlt/p4.md --
|
||||||
|
---
|
||||||
|
title: "p4 theme (nl)"
|
||||||
|
---
|
||||||
|
`
|
||||||
|
|
||||||
|
b := NewIntegrationTestBuilder(
|
||||||
|
IntegrationTestConfig{
|
||||||
|
T: t,
|
||||||
|
TxtarString: files,
|
||||||
|
},
|
||||||
|
).Build()
|
||||||
|
|
||||||
|
b.AssertFileContent("public/nl/index.html", `home (nl): nl: p1 (nl)|p2 (en)|p3 (nl)|p4 theme (nl)|:END`)
|
||||||
|
b.AssertFileContent("public/de/index.html", `home (de): de: p1 (de)|p2 (en)|p3 (en)|:END`)
|
||||||
|
b.AssertFileContent("public/en/index.html", `home (en): en: p1 (en)|p2 (en)|p3 (en)|:END`)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue