diff --git a/deps/deps.go b/deps/deps.go index de6d8b52a46..b778a07b62b 100644 --- a/deps/deps.go +++ b/deps/deps.go @@ -7,6 +7,7 @@ import ( "github.com/pkg/errors" "github.com/gohugoio/hugo/cache/filecache" + "github.com/gohugoio/hugo/common/hugo" "github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/config" "github.com/gohugoio/hugo/helpers" @@ -62,8 +63,12 @@ type Deps struct { // The translation func to use Translate func(translationID string, args ...interface{}) string `json:"-"` + // The language in use. TODO(bep) consolidate with site Language *langs.Language + // The site building. + Site hugo.Site + // All the output formats available for the current site. OutputFormatsConfig output.Formats @@ -245,7 +250,7 @@ func New(cfg DepsCfg) (*Deps, error) { // ForLanguage creates a copy of the Deps with the language dependent // parts switched out. -func (d Deps) ForLanguage(cfg DepsCfg) (*Deps, error) { +func (d Deps) ForLanguage(cfg DepsCfg, onCreated func(d *Deps) error) (*Deps, error) { l := cfg.Language var err error @@ -271,6 +276,12 @@ func (d Deps) ForLanguage(cfg DepsCfg) (*Deps, error) { d.Cfg = l d.Language = l + if onCreated != nil { + if err = onCreated(&d); err != nil { + return nil, err + } + } + if err := d.translationProvider.Clone(&d); err != nil { return nil, err } diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go index 9cc091927c7..043e049d765 100644 --- a/hugolib/hugo_sites.go +++ b/hugolib/hugo_sites.go @@ -21,12 +21,13 @@ import ( "strings" "sync" + "github.com/gohugoio/hugo/publisher" + "github.com/gohugoio/hugo/common/herrors" "github.com/gohugoio/hugo/common/loggers" "github.com/gohugoio/hugo/deps" "github.com/gohugoio/hugo/helpers" "github.com/gohugoio/hugo/langs" - "github.com/gohugoio/hugo/publisher" "github.com/gohugoio/hugo/i18n" "github.com/gohugoio/hugo/tpl" @@ -224,6 +225,27 @@ func applyDeps(cfg deps.DepsCfg, sites ...*Site) error { continue } + onCreated := func(d *deps.Deps) error { + s.Deps = d + + // Set up the main publishing chain. + s.publisher = publisher.NewDestinationPublisher(d.PathSpec.BaseFs.PublishFs, s.outputFormatsConfig, s.mediaTypesConfig, cfg.Cfg.GetBool("minify")) + + if err := s.initializeSiteInfo(); err != nil { + return err + } + + d.Site = &s.Info + + siteConfig, err := loadSiteConfig(s.Language) + if err != nil { + return err + } + s.siteConfig = siteConfig + s.siteRefLinker, err = newSiteRefLinker(s.Language, s) + return err + } + cfg.Language = s.Language cfg.MediaTypes = s.mediaTypesConfig cfg.OutputFormats = s.outputFormatsConfig @@ -238,37 +260,23 @@ func applyDeps(cfg deps.DepsCfg, sites ...*Site) error { } d.OutputFormatsConfig = s.outputFormatsConfig - s.Deps = d + + if err := onCreated(d); err != nil { + return err + } if err = d.LoadResources(); err != nil { return err } } else { - d, err = d.ForLanguage(cfg) + d, err = d.ForLanguage(cfg, onCreated) if err != nil { return err } d.OutputFormatsConfig = s.outputFormatsConfig - s.Deps = d } - // Set up the main publishing chain. - s.publisher = publisher.NewDestinationPublisher(d.PathSpec.BaseFs.PublishFs, s.outputFormatsConfig, s.mediaTypesConfig, cfg.Cfg.GetBool("minify")) - - if err := s.initializeSiteInfo(); err != nil { - return err - } - - siteConfig, err := loadSiteConfig(s.Language) - if err != nil { - return err - } - s.siteConfig = siteConfig - s.siteRefLinker, err = newSiteRefLinker(s.Language, s) - if err != nil { - return err - } } return nil diff --git a/hugolib/pages_language_merge_test.go b/hugolib/pages_language_merge_test.go index 8a4688f166e..6706af3bce1 100644 --- a/hugolib/pages_language_merge_test.go +++ b/hugolib/pages_language_merge_test.go @@ -66,7 +66,7 @@ func TestMergeLanguages(t *testing.T) { firstNN := nnSite.RegularPages[0] assert.Equal(4, len(firstNN.Sites())) - assert.Equal("en", firstNN.Sites().First().Language.Lang) + assert.Equal("en", firstNN.Sites().First().Language().Lang) nnBundle := nnSite.getPage("page", "bundle") enBundle := enSite.getPage("page", "bundle") diff --git a/hugolib/site.go b/hugolib/site.go index 25eb34f05a6..0fde7d8df7e 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -405,13 +405,17 @@ type SiteInfo struct { Data *map[string]interface{} owner *HugoSites s *Site - Language *langs.Language + language *langs.Language LanguagePrefix string Languages langs.Languages defaultContentLanguageInSubdir bool sectionPagesMenu string } +func (s *SiteInfo) Language() *langs.Language { + return s.language +} + func (s *SiteInfo) Config() SiteConfig { return s.s.siteConfig } @@ -797,7 +801,10 @@ func (s *Site) processPartial(events []fsnotify.Event) (whatChanged, error) { MediaTypes: site.mediaTypesConfig, OutputFormats: site.outputFormatsConfig, } - site.Deps, err = first.Deps.ForLanguage(depsCfg) + site.Deps, err = first.Deps.ForLanguage(depsCfg, func(d *deps.Deps) error { + d.Site = &site.Info + return nil + }) if err != nil { return whatChanged{}, err } @@ -1122,7 +1129,7 @@ func (s *Site) initialize() (err error) { func (s *SiteInfo) HomeAbsURL() string { base := "" if s.IsMultiLingual() { - base = s.Language.Lang + base = s.Language().Lang } return s.owner.AbsURL(base, false) } @@ -1194,7 +1201,7 @@ func (s *Site) initializeSiteInfo() error { Social: lang.GetStringMapString("social"), LanguageCode: lang.GetString("languageCode"), Copyright: lang.GetString("copyright"), - Language: lang, + language: lang, LanguagePrefix: languagePrefix, Languages: languages, defaultContentLanguageInSubdir: defaultContentInSubDir, diff --git a/hugolib/template_test.go b/hugolib/template_test.go index 9cc523cb063..68eeae9a7ea 100644 --- a/hugolib/template_test.go +++ b/hugolib/template_test.go @@ -236,3 +236,21 @@ Page Content b.AssertFileContent("public/page/index.html", "Base: Hi!?") } + +func TestTemplateFuncs(t *testing.T) { + + b := newTestSitesBuilder(t).WithDefaultMultiSiteConfig() + + homeTpl := `Site: {{ site.Language.Lang }} / {{ .Site.Language.Lang }} / {{ site.BaseURL }}` + + b.WithTemplatesAdded( + "index.html", homeTpl, + "index.fr.html", homeTpl, + ) + + b.CreateSites().Build(BuildCfg{}) + + b.AssertFileContent("public/en/index.html", "Site: en / en / http://example.com/blog") + b.AssertFileContent("public/fr/index.html", "Site: fr / fr / http://example.com/blog") + +} diff --git a/tpl/site/init.go b/tpl/site/init.go new file mode 100644 index 00000000000..1957ce0781f --- /dev/null +++ b/tpl/site/init.go @@ -0,0 +1,43 @@ +// Copyright 2018 The Hugo Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package site + +import ( + "github.com/gohugoio/hugo/deps" + "github.com/gohugoio/hugo/tpl/internal" +) + +const name = "site" + +func init() { + f := func(d *deps.Deps) *internal.TemplateFuncsNamespace { + + s := d.Site + ns := &internal.TemplateFuncsNamespace{ + Name: name, + Context: func(args ...interface{}) interface{} { return s }, + } + + if s == nil { + panic("no Site") + } + + // We just add the Site as the namespace here. No method mappings. + + return ns + + } + + internal.AddTemplateFuncsNamespace(f) +} diff --git a/tpl/site/init_test.go b/tpl/site/init_test.go new file mode 100644 index 00000000000..c7e7edf04c5 --- /dev/null +++ b/tpl/site/init_test.go @@ -0,0 +1,40 @@ +// Copyright 2017 The Hugo Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package site + +import ( + "testing" + + "github.com/gohugoio/hugo/common/hugo" + "github.com/gohugoio/hugo/deps" + "github.com/gohugoio/hugo/tpl/internal" + "github.com/stretchr/testify/require" +) + +func TestInit(t *testing.T) { + var found bool + var ns *internal.TemplateFuncsNamespace + var s hugo.Site + + for _, nsf := range internal.TemplateFuncsNamespaceRegistry { + ns = nsf(&deps.Deps{Site: s}) + if ns.Name == name { + found = true + break + } + } + + require.True(t, found) + require.IsType(t, s, ns.Context()) +} diff --git a/tpl/tplimpl/template_funcs.go b/tpl/tplimpl/template_funcs.go index 27ffcd97a75..87b5bfa358d 100644 --- a/tpl/tplimpl/template_funcs.go +++ b/tpl/tplimpl/template_funcs.go @@ -39,6 +39,7 @@ import ( _ "github.com/gohugoio/hugo/tpl/path" _ "github.com/gohugoio/hugo/tpl/resources" _ "github.com/gohugoio/hugo/tpl/safe" + _ "github.com/gohugoio/hugo/tpl/site" _ "github.com/gohugoio/hugo/tpl/strings" _ "github.com/gohugoio/hugo/tpl/templates" _ "github.com/gohugoio/hugo/tpl/time"