diff --git a/hugolib/hugo_sites_test.go b/hugolib/hugo_sites_test.go index aa8575075..cbd6bd627 100644 --- a/hugolib/hugo_sites_test.go +++ b/hugolib/hugo_sites_test.go @@ -14,10 +14,10 @@ import ( "github.com/spf13/hugo/helpers" "github.com/spf13/hugo/hugofs" "github.com/spf13/hugo/source" + jww "github.com/spf13/jwalterweatherman" "github.com/spf13/viper" "github.com/stretchr/testify/assert" - - jww "github.com/spf13/jwalterweatherman" + "github.com/stretchr/testify/require" ) func init() { @@ -52,7 +52,7 @@ func TestMultiSites(t *testing.T) { sites := createMultiTestSites(t) - err := sites.Build(BuildCfg{skipRender: true}) + err := sites.Build(BuildCfg{}) if err != nil { t.Fatalf("Failed to build sites: %s", err) @@ -126,6 +126,11 @@ func TestMultiSites(t *testing.T) { assert.Equal(t, "fr", frenchPage.Lang()) } + languageRedirect := readDestination(t, "public/index.html") + + // French is the main content language + require.True(t, strings.Contains(languageRedirect, "0; url=http://example.com/blog/fr"), languageRedirect) + } func TestMultiSitesRebuild(t *testing.T) { @@ -498,7 +503,7 @@ func readFileFromFs(t *testing.T, fs afero.Fs, filename string) string { // Print some debug info root := strings.Split(filename, helpers.FilePathSeparator)[0] afero.Walk(fs, root, func(path string, info os.FileInfo, err error) error { - if !info.IsDir() { + if info != nil && !info.IsDir() { fmt.Println(" ", path) } diff --git a/hugolib/site.go b/hugolib/site.go index cce78f14d..776876980 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -134,10 +134,11 @@ func newSiteFromSources(pathContentPairs ...string) *Site { } type targetList struct { - page target.Output - pageUgly target.Output - file target.Output - alias target.AliasPublisher + page target.Output + pageUgly target.Output + file target.Output + alias target.AliasPublisher + languageAlias target.AliasPublisher } type SiteInfo struct { @@ -1398,6 +1399,16 @@ func (s *Site) renderAliases() error { } } } + + if s.Multilingual.enabled() { + mainLang := s.Multilingual.DefaultLang.Lang + mainLangURL := helpers.AbsURL(mainLang) + jww.DEBUG.Printf("Write redirect to main language %s: %s", mainLang, mainLangURL) + if err := s.publishDestAlias(s.languageAliasTarget(), "/", mainLangURL); err != nil { + return err + } + } + return nil } @@ -2161,6 +2172,11 @@ func (s *Site) aliasTarget() target.AliasPublisher { return s.targets.alias } +func (s *Site) languageAliasTarget() target.AliasPublisher { + s.initTargetList() + return s.targets.languageAlias +} + func (s *Site) initTargetList() { s.targetListInit.Do(func() { if s.targets.page == nil { @@ -2185,6 +2201,12 @@ func (s *Site) initTargetList() { PublishDir: s.absPublishDir(), } } + if s.targets.languageAlias == nil { + s.targets.languageAlias = &target.HTMLRedirectAlias{ + PublishDir: s.absPublishDir(), + AllowRoot: true, + } + } }) } @@ -2198,7 +2220,12 @@ func (s *Site) writeDestPage(path string, publisher target.Publisher, reader io. return publisher.Publish(path, reader) } +// AliasPublisher func (s *Site) writeDestAlias(path string, permalink string) (err error) { + return s.publishDestAlias(s.aliasTarget(), path, permalink) +} + +func (s *Site) publishDestAlias(aliasPublisher target.AliasPublisher, path string, permalink string) (err error) { if viper.GetBool("RelativeURLs") { // convert `permalink` into URI relative to location of `path` baseURL := helpers.SanitizeURLKeepTrailingSlash(viper.GetString("BaseURL")) @@ -2212,7 +2239,7 @@ func (s *Site) writeDestAlias(path string, permalink string) (err error) { permalink = filepath.ToSlash(permalink) } jww.DEBUG.Println("creating alias:", path, "redirecting to", permalink) - return s.aliasTarget().Publish(path, permalink) + return aliasPublisher.Publish(path, permalink) } func (s *Site) draftStats() string { diff --git a/target/htmlredirect.go b/target/htmlredirect.go index d8eac943c..81051589a 100644 --- a/target/htmlredirect.go +++ b/target/htmlredirect.go @@ -45,6 +45,7 @@ type AliasPublisher interface { type HTMLRedirectAlias struct { PublishDir string Templates *template.Template + AllowRoot bool // for the language redirects } func (h *HTMLRedirectAlias) Translate(alias string) (aliasPath string, err error) { @@ -56,7 +57,7 @@ func (h *HTMLRedirectAlias) Translate(alias string) (aliasPath string, err error alias = filepath.Clean(alias) components := strings.Split(alias, helpers.FilePathSeparator) - if alias == helpers.FilePathSeparator { + if !h.AllowRoot && alias == helpers.FilePathSeparator { return "", fmt.Errorf("Alias \"%s\" resolves to website root directory", originalAlias) }