diff options
-rw-r--r-- | docs/content/content/multilingual.md | 8 | ||||
-rw-r--r-- | helpers/configProvider.go | 25 | ||||
-rw-r--r-- | helpers/content.go | 27 | ||||
-rw-r--r-- | helpers/content_renderer_test.go | 4 | ||||
-rw-r--r-- | helpers/content_test.go | 23 | ||||
-rw-r--r-- | hugolib/config.go | 2 | ||||
-rw-r--r-- | hugolib/embedded_shortcodes_test.go | 8 | ||||
-rw-r--r-- | hugolib/hugo_sites.go | 14 | ||||
-rw-r--r-- | hugolib/hugo_sites_test.go | 18 | ||||
-rw-r--r-- | hugolib/multilingual.go | 29 | ||||
-rw-r--r-- | hugolib/node.go | 37 | ||||
-rw-r--r-- | hugolib/page.go | 21 | ||||
-rw-r--r-- | hugolib/pageSort_test.go | 4 | ||||
-rw-r--r-- | hugolib/page_permalink_test.go | 4 | ||||
-rw-r--r-- | hugolib/page_test.go | 2 | ||||
-rw-r--r-- | hugolib/pagination_test.go | 4 | ||||
-rw-r--r-- | hugolib/shortcode.go | 3 | ||||
-rw-r--r-- | hugolib/shortcode_test.go | 231 | ||||
-rw-r--r-- | hugolib/site.go | 25 | ||||
-rw-r--r-- | hugolib/translations.go | 15 | ||||
-rw-r--r-- | tpl/template_funcs.go | 7 |
21 files changed, 323 insertions, 188 deletions
diff --git a/docs/content/content/multilingual.md b/docs/content/content/multilingual.md index 1f73194ea..f93738f9f 100644 --- a/docs/content/content/multilingual.md +++ b/docs/content/content/multilingual.md @@ -38,16 +38,22 @@ and taxonomy pages will be rendered below `/en` in English, and below `/fr` in F Only the obvious non-global options can be overridden per language. Examples of global options are `BaseURL`, `BuildDrafts`, etc. -Taxonomies configuration can also be set per language, example: +Taxonomies and Blackfriday configuration can also be set per language, example: ``` [Taxonomies] tag = "tags" +[blackfriday] +angledQuotes = true +hrefTargetBlank = true + [Languages] [Languages.en] weight = 1 title = "English" +[Languages.en.blackfriday] +angledQuotes = false [Languages.fr] weight = 2 diff --git a/helpers/configProvider.go b/helpers/configProvider.go new file mode 100644 index 000000000..16a203302 --- /dev/null +++ b/helpers/configProvider.go @@ -0,0 +1,25 @@ +// Copyright 2016-present 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 helpers implements general utility functions that work with +// and on content. The helper functions defined here lay down the +// foundation of how Hugo works with files and filepaths, and perform +// string operations on content. +package helpers + +// ConfigProvider provides the configuration settings for Hugo. +type ConfigProvider interface { + GetString(key string) string + GetStringMap(key string) map[string]interface{} + GetStringMapString(key string) map[string]string +} diff --git a/helpers/content.go b/helpers/content.go index b9281acf4..427d960a1 100644 --- a/helpers/content.go +++ b/helpers/content.go @@ -59,7 +59,7 @@ type Blackfriday struct { } // NewBlackfriday creates a new Blackfriday filled with site config or some sane defaults. -func NewBlackfriday() *Blackfriday { +func NewBlackfriday(c ConfigProvider) *Blackfriday { combinedParam := map[string]interface{}{ "smartypants": true, "angledQuotes": false, @@ -72,7 +72,7 @@ func NewBlackfriday() *Blackfriday { "sourceRelativeLinksProjectFolder": "/docs/content", } - siteParam := viper.GetStringMap("blackfriday") + siteParam := c.GetStringMap("blackfriday") if siteParam != nil { siteConfig := cast.ToStringMap(siteParam) @@ -341,20 +341,25 @@ func ExtractTOC(content []byte) (newcontent []byte, toc []byte) { // RenderingContext holds contextual information, like content and configuration, // for a given content rendering. type RenderingContext struct { - Content []byte - PageFmt string - DocumentID string - Config *Blackfriday - RenderTOC bool - FileResolver FileResolverFunc - LinkResolver LinkResolverFunc - configInit sync.Once + Content []byte + PageFmt string + DocumentID string + Config *Blackfriday + RenderTOC bool + FileResolver FileResolverFunc + LinkResolver LinkResolverFunc + ConfigProvider ConfigProvider + configInit sync.Once +} + +func newViperProvidedRenderingContext() *RenderingContext { + return &RenderingContext{ConfigProvider: viper.GetViper()} } func (c *RenderingContext) getConfig() *Blackfriday { c.configInit.Do(func() { if c.Config == nil { - c.Config = NewBlackfriday() + c.Config = NewBlackfriday(c.ConfigProvider) } }) return c.Config diff --git a/helpers/content_renderer_test.go b/helpers/content_renderer_test.go index 8c8e58604..f96cf0ad5 100644 --- a/helpers/content_renderer_test.go +++ b/helpers/content_renderer_test.go @@ -23,7 +23,7 @@ import ( // Renders a codeblock using Blackfriday func render(input string) string { - ctx := &RenderingContext{} + ctx := newViperProvidedRenderingContext() render := getHTMLRenderer(0, ctx) buf := &bytes.Buffer{} @@ -33,7 +33,7 @@ func render(input string) string { // Renders a codeblock using Mmark func renderWithMmark(input string) string { - ctx := &RenderingContext{} + ctx := newViperProvidedRenderingContext() render := getMmarkHTMLRenderer(0, ctx) buf := &bytes.Buffer{} diff --git a/helpers/content_test.go b/helpers/content_test.go index 8aa645f6b..85e0d7f4f 100644 --- a/helpers/content_test.go +++ b/helpers/content_test.go @@ -22,6 +22,7 @@ import ( "github.com/miekg/mmark" "github.com/russross/blackfriday" + "github.com/spf13/viper" "github.com/stretchr/testify/assert" ) @@ -124,7 +125,7 @@ func TestTruncateWordsByRune(t *testing.T) { } func TestGetHTMLRendererFlags(t *testing.T) { - ctx := &RenderingContext{} + ctx := newViperProvidedRenderingContext() renderer := getHTMLRenderer(blackfriday.HTML_USE_XHTML, ctx) flags := renderer.GetFlags() if flags&blackfriday.HTML_USE_XHTML != blackfriday.HTML_USE_XHTML { @@ -148,7 +149,7 @@ func TestGetHTMLRendererAllFlags(t *testing.T) { {blackfriday.HTML_SMARTYPANTS_LATEX_DASHES}, } defaultFlags := blackfriday.HTML_USE_XHTML - ctx := &RenderingContext{} + ctx := newViperProvidedRenderingContext() ctx.Config = ctx.getConfig() ctx.Config.AngledQuotes = true ctx.Config.Fractions = true @@ -171,7 +172,7 @@ func TestGetHTMLRendererAllFlags(t *testing.T) { } func TestGetHTMLRendererAnchors(t *testing.T) { - ctx := &RenderingContext{} + ctx := newViperProvidedRenderingContext() ctx.DocumentID = "testid" ctx.Config = ctx.getConfig() ctx.Config.PlainIDAnchors = false @@ -195,7 +196,7 @@ func TestGetHTMLRendererAnchors(t *testing.T) { } func TestGetMmarkHTMLRenderer(t *testing.T) { - ctx := &RenderingContext{} + ctx := newViperProvidedRenderingContext() ctx.DocumentID = "testid" ctx.Config = ctx.getConfig() ctx.Config.PlainIDAnchors = false @@ -219,7 +220,7 @@ func TestGetMmarkHTMLRenderer(t *testing.T) { } func TestGetMarkdownExtensionsMasksAreRemovedFromExtensions(t *testing.T) { - ctx := &RenderingContext{} + ctx := newViperProvidedRenderingContext() ctx.Config = ctx.getConfig() ctx.Config.Extensions = []string{"headerId"} ctx.Config.ExtensionsMask = []string{"noIntraEmphasis"} @@ -234,7 +235,7 @@ func TestGetMarkdownExtensionsByDefaultAllExtensionsAreEnabled(t *testing.T) { type data struct { testFlag int } - ctx := &RenderingContext{} + ctx := newViperProvidedRenderingContext() ctx.Config = ctx.getConfig() ctx.Config.Extensions = []string{""} ctx.Config.ExtensionsMask = []string{""} @@ -266,7 +267,7 @@ func TestGetMarkdownExtensionsByDefaultAllExtensionsAreEnabled(t *testing.T) { } func TestGetMarkdownExtensionsAddingFlagsThroughRenderingContext(t *testing.T) { - ctx := &RenderingContext{} + ctx := newViperProvidedRenderingContext() ctx.Config = ctx.getConfig() ctx.Config.Extensions = []string{"definitionLists"} ctx.Config.ExtensionsMask = []string{""} @@ -278,7 +279,7 @@ func TestGetMarkdownExtensionsAddingFlagsThroughRenderingContext(t *testing.T) { } func TestGetMarkdownRenderer(t *testing.T) { - ctx := &RenderingContext{} + ctx := newViperProvidedRenderingContext() ctx.Content = []byte("testContent") ctx.Config = ctx.getConfig() actualRenderedMarkdown := markdownRender(ctx) @@ -289,7 +290,7 @@ func TestGetMarkdownRenderer(t *testing.T) { } func TestGetMarkdownRendererWithTOC(t *testing.T) { - ctx := &RenderingContext{RenderTOC: true} + ctx := &RenderingContext{RenderTOC: true, ConfigProvider: viper.GetViper()} ctx.Content = []byte("testContent") ctx.Config = ctx.getConfig() actualRenderedMarkdown := markdownRender(ctx) @@ -304,7 +305,7 @@ func TestGetMmarkExtensions(t *testing.T) { type data struct { testFlag int } - ctx := &RenderingContext{} + ctx := newViperProvidedRenderingContext() ctx.Config = ctx.getConfig() ctx.Config.Extensions = []string{"tables"} ctx.Config.ExtensionsMask = []string{""} @@ -333,7 +334,7 @@ func TestGetMmarkExtensions(t *testing.T) { } func TestMmarkRender(t *testing.T) { - ctx := &RenderingContext{} + ctx := newViperProvidedRenderingContext() ctx.Content = []byte("testContent") ctx.Config = ctx.getConfig() actualRenderedMarkdown := mmarkRender(ctx) diff --git a/hugolib/config.go b/hugolib/config.go index 285e3567a..c4292e81b 100644 --- a/hugolib/config.go +++ b/hugolib/config.go @@ -94,7 +94,7 @@ func loadDefaultSettings() { viper.SetDefault("NewContentEditor", "") viper.SetDefault("Paginate", 10) viper.SetDefault("PaginatePath", "page") - viper.SetDefault("Blackfriday", helpers.NewBlackfriday()) + viper.SetDefault("Blackfriday", helpers.NewBlackfriday(viper.GetViper())) viper.SetDefault("RSSUri", "index.xml") viper.SetDefault("SectionPagesMenu", "") viper.SetDefault("DisablePathToLower", false) diff --git a/hugolib/embedded_shortcodes_test.go b/hugolib/embedded_shortcodes_test.go index e668ff4c8..cebef0b8b 100644 --- a/hugolib/embedded_shortcodes_test.go +++ b/hugolib/embedded_shortcodes_test.go @@ -15,7 +15,6 @@ package hugolib import ( "fmt" - "html/template" "net/url" "os" "path/filepath" @@ -55,10 +54,9 @@ func doTestShortcodeCrossrefs(t *testing.T, relative bool) { templ := tpl.New() p, _ := pageFromString(simplePageWithURL, path) - p.Node.Site = &SiteInfo{ - rawAllPages: &(Pages{p}), - BaseURL: template.URL(helpers.SanitizeURLKeepTrailingSlash(baseURL)), - } + p.Node.Site = newSiteInfoDefaultLanguage( + helpers.SanitizeURLKeepTrailingSlash(baseURL), + p) output, err := HandleShortcodes(in, p, templ) diff --git a/hugolib/hugo_sites.go b/hugolib/hugo_sites.go index b41334fdc..8fd2a63b9 100644 --- a/hugolib/hugo_sites.go +++ b/hugolib/hugo_sites.go @@ -39,7 +39,7 @@ type HugoSites struct { // NewHugoSites creates a new collection of sites given the input sites, building // a language configuration based on those. -func NewHugoSites(sites ...*Site) (*HugoSites, error) { +func newHugoSites(sites ...*Site) (*HugoSites, error) { langConfig, err := newMultiLingualFromSites(sites...) if err != nil { @@ -55,7 +55,7 @@ func NewHugoSitesFromConfiguration() (*HugoSites, error) { if err != nil { return nil, err } - return NewHugoSites(sites...) + return newHugoSites(sites...) } func createSitesFromConfig() ([]*Site, error) { @@ -461,7 +461,7 @@ func buildAndRenderSite(s *Site, additionalTemplates ...string) error { // Convenience func used in tests to build a single site/language. func doBuildSite(s *Site, render bool, additionalTemplates ...string) error { - sites, err := NewHugoSites(s) + sites, err := newHugoSites(s) if err != nil { return err } @@ -490,7 +490,7 @@ func newHugoSitesFromSourceAndLanguages(input []source.ByteSource, languages Lan Language: languages[0], } if len(languages) == 1 { - return NewHugoSites(first) + return newHugoSites(first) } sites := make([]*Site, len(languages)) @@ -499,7 +499,7 @@ func newHugoSitesFromSourceAndLanguages(input []source.ByteSource, languages Lan sites[i] = &Site{Language: languages[i]} } - return NewHugoSites(sites...) + return newHugoSites(sites...) } @@ -507,3 +507,7 @@ func newHugoSitesFromSourceAndLanguages(input []source.ByteSource, languages Lan func newHugoSitesFromLanguages(languages Languages) (*HugoSites, error) { return newHugoSitesFromSourceAndLanguages(nil, languages) } + +func newHugoSitesDefaultLanguage() (*HugoSites, error) { + return newHugoSitesFromSourceAndLanguages(nil, Languages{newDefaultLanguage()}) +} diff --git a/hugolib/hugo_sites_test.go b/hugolib/hugo_sites_test.go index 158b65124..9ccfed054 100644 --- a/hugolib/hugo_sites_test.go +++ b/hugolib/hugo_sites_test.go @@ -137,6 +137,12 @@ func TestMultiSitesBuild(t *testing.T) { require.NotNil(t, frTags["frtag1"]) readDestination(t, "public/fr/plaques/frtag1/index.html") readDestination(t, "public/en/tags/tag1/index.html") + + // Check Blackfriday config + assert.True(t, strings.Contains(string(doc1fr.Content), "«"), string(doc1fr.Content)) + assert.False(t, strings.Contains(string(doc1en.Content), "«"), string(doc1en.Content)) + assert.True(t, strings.Contains(string(doc1en.Content), "“"), string(doc1en.Content)) + } func TestMultiSitesRebuild(t *testing.T) { @@ -326,7 +332,6 @@ title = "Norsk" // Watching does not work with in-memory fs, so we trigger a reload manually require.NoError(t, viper.ReadInConfig()) - err = sites.Build(BuildCfg{CreateSitesFromConfig: true}) if err != nil { @@ -370,7 +375,10 @@ paginate = 2 DefaultContentLanguage = "fr" [permalinks] - other = "/somewhere/else/:filename" +other = "/somewhere/else/:filename" + +[blackfriday] +angledQuotes = true [Taxonomies] tag = "tags" @@ -379,6 +387,8 @@ tag = "tags" [Languages.en] weight = 10 title = "English" +[Languages.en.blackfriday] +angledQuotes = false [Languages.fr] weight = 20 @@ -441,7 +451,7 @@ tags: publishdate: "2000-01-01" --- # doc1 -*some content* +*some "content"* NOTE: slug should be used as URL `)}, {filepath.FromSlash("sect/doc1.fr.md"), []byte(`--- @@ -452,7 +462,7 @@ plaques: publishdate: "2000-01-04" --- # doc1 -*quelque contenu* +*quelque "contenu"* NOTE: should be in the 'en' Page's 'Translations' field. NOTE: date is after "doc3" `)}, diff --git a/hugolib/multilingual.go b/hugolib/multilingual.go index cc9f607f2..9c5342f99 100644 --- a/hugolib/multilingual.go +++ b/hugolib/multilingual.go @@ -25,9 +25,14 @@ func NewLanguage(lang string) *Language { return &Language{Lang: lang, params: make(map[string]interface{})} } -// TODO(bep) multilingo func newDefaultLanguage() *Language { - return NewLanguage("en") + defaultLang := viper.GetString("DefaultContentLanguage") + + if defaultLang == "" { + defaultLang = "en" + } + + return NewLanguage(defaultLang) } type Languages []*Language @@ -74,16 +79,18 @@ func newMultiLingualFromSites(sites ...*Site) (*Multilingual, error) { languages[i] = s.Language } - defaultLang := viper.GetString("DefaultContentLanguage") + return &Multilingual{Languages: languages, DefaultLang: newDefaultLanguage()}, nil - if defaultLang == "" { - defaultLang = "en" - } - - return &Multilingual{Languages: languages, DefaultLang: NewLanguage(defaultLang)}, nil +} +func newMultiLingualDefaultLanguage() *Multilingual { + return newMultiLingualForLanguage(newDefaultLanguage()) } +func newMultiLingualForLanguage(language *Language) *Multilingual { + languages := Languages{language} + return &Multilingual{Languages: languages, DefaultLang: language} +} func (ml *Multilingual) enabled() bool { return len(ml.Languages) > 1 } @@ -92,6 +99,7 @@ func (l *Language) Params() map[string]interface{} { l.paramsInit.Do(func() { // Merge with global config. // TODO(bep) consider making this part of a constructor func. + globalParams := viper.GetStringMap("Params") for k, v := range globalParams { if _, ok := l.params[k]; !ok { @@ -116,6 +124,9 @@ func (l *Language) GetStringMapString(key string) map[string]string { } func (l *Language) Get(key string) interface{} { + if l == nil { + panic("language not set") + } key = strings.ToLower(key) if v, ok := l.params[key]; ok { return v @@ -159,7 +170,7 @@ func toSortedLanguages(l map[string]interface{}) (Languages, error) { } // Put all into the Params map - // TODO(bep) reconsile with the type handling etc. from other params handlers. + // TODO(bep) ml reconsile with the type handling etc. from other params handlers. language.SetParam(loki, v) } diff --git a/hugolib/node.go b/hugolib/node.go index db1d16631..773573c3c 100644 --- a/hugolib/node.go +++ b/hugolib/node.go @@ -22,6 +22,8 @@ import ( "sync" "time" + jww "github.com/spf13/jwalterweatherman" + "github.com/spf13/hugo/helpers" "github.com/spf13/cast" @@ -45,8 +47,9 @@ type Node struct { paginatorInit sync.Once scratch *Scratch - language *Language - lang string // TODO(bep) multilingo + language *Language + languageInit sync.Once + lang string // TODO(bep) multilingo translations Nodes translationsInit sync.Once @@ -191,6 +194,7 @@ func (n *Node) Scratch() *Scratch { // TODO(bep) multilingo consolidate. See Page. func (n *Node) Language() *Language { + n.initLanguage() return n.language } @@ -204,6 +208,31 @@ func (n *Node) Lang() string { return n.lang } +func (n *Node) initLanguage() { + n.languageInit.Do(func() { + pageLang := n.lang + ml := n.Site.multilingual + if ml == nil { + panic("Multilanguage not set") + } + if pageLang == "" { + n.language = ml.DefaultLang + return + } + + language := ml.Language(pageLang) + + if language == nil { + // TODO(bep) ml + // This may or may not be serious. It can be a file named stefano.chiodino.md. + jww.WARN.Printf("Page language (if it is that) not found in multilang setup: %s.", pageLang) + language = ml.DefaultLang + } + + n.language = language + }) +} + func (n *Node) LanguagePrefix() string { return n.Site.LanguagePrefix } @@ -261,7 +290,7 @@ func (n *Node) addMultilingualWebPrefix(outfile string) string { hadSlashSuffix := strings.HasSuffix(outfile, "/") lang := n.Lang() - if lang == "" || !n.Site.Multilingual { + if lang == "" || !n.Site.IsMultiLingual() { return outfile } outfile = "/" + path.Join(lang, outfile) @@ -273,7 +302,7 @@ func (n *Node) addMultilingualWebPrefix(outfile string) string { func (n *Node) addMultilingualFilesystemPrefix(outfile string) string { lang := n.Lang() - if lang == "" || !n.Site.Multilingual { + if lang == "" || !n.Site.IsMultiLingual() { return outfile } return string(filepath.Separator) + filepath.Join(lang, outfile) diff --git a/hugolib/page.go b/hugolib/page.go index 493e5b512..99aa0db16 100644 --- a/hugolib/page.go +++ b/hugolib/page.go @@ -319,7 +319,8 @@ func (p *Page) setAutoSummary() error { return nil } -func (p *Page) renderBytes(content []byte) []byte { +// TODO(bep) ml not used??? +func (p *Page) _renderBytes(content []byte) []byte { var fn helpers.LinkResolverFunc var fileFn helpers.FileResolverFunc if p.getRenderingConfig().SourceRelativeLinksEval { @@ -331,8 +332,10 @@ func (p *Page) renderBytes(content []byte) []byte { } } return helpers.RenderBytes( - &helpers.RenderingContext{Content: content, PageFmt: p.determineMarkupType(), - DocumentID: p.UniqueID(), Config: p.getRenderingConfig(), LinkResolver: fn, FileResolver: fileFn}) + &helpers.RenderingContext{ + Content: content, PageFmt: p.determineMarkupType(), + ConfigProvider: p.Language(), + DocumentID: p.UniqueID(), Config: p.getRenderingConfig(), LinkResolver: fn, FileResolver: fileFn}) } func (p *Page) renderContent(content []byte) []byte { @@ -346,16 +349,20 @@ func (p *Page) renderContent(content []byte) []byte { return p.Node.Site.SourceRelativeLinkFile(ref, p) } } - return helpers.RenderBytes(&helpers.RenderingContext{Content: content, RenderTOC: true, PageFmt: p.determineMarkupType(), - DocumentID: p.UniqueID(), Config: p.getRenderingConfig(), LinkResolver: fn, FileResolver: fileFn}) + return helpers.RenderBytes(&helpers.RenderingContext{ + Content: content, RenderTOC: true, PageFmt: p.determineMarkupType(), + ConfigProvider: p.Language(), + DocumentID: p.UniqueID(), Config: p.getRenderingConfig(), LinkResolver: fn, FileResolver: fileFn}) } func (p *Page) getRenderingConfig() *helpers.Blackfriday { p.renderingConfigInit.Do(func() { pageParam := cast.ToStringMap(p.GetParam("blackfriday")) - - p.renderingConfig = helpers.NewBlackfriday() + if p.Language() == nil { + panic(fmt.Sprintf("nil language for %s with source lang %s", p.BaseFileName(), p.lang)) + } + p.renderingConfig = helpers.NewBlackfriday(p.Language()) if err := mapstructure.Decode(pageParam, p.renderingConfig); err != nil { jww.FATAL.Printf("Failed to get rendering config for %s:\n%s", p.BaseFileName(), err.Error()) } diff --git a/hugolib/pageSort_test.go b/hugolib/pageSort_test.go index 7f0e89091..1ed99f318 100644 --- a/hugolib/pageSort_test.go +++ b/hugolib/pageSort_test.go @@ -141,9 +141,7 @@ func createSortTestPages(num int) Pages { Section: "z", URL: fmt.Sprintf("http://base/x/y/p%d.html", i), }, - Site: &SiteInfo{ - BaseURL: "http://base/", - }, + Site: newSiteInfoDefaultLanguage("http://base/"), }, Source: Source{File: *source.NewFile(filepath.FromSlash(fmt.Sprintf("/x/y/p%d.md", i)))}, } diff --git a/hugolib/page_permalink_test.go b/hugolib/page_permalink_test.go index a47bad85e..d185bebab 100644 --- a/hugolib/page_permalink_test.go +++ b/hugolib/page_permalink_test.go @@ -69,9 +69,7 @@ func TestPermalink(t *testing.T) { Section: "z", URL: test.url, }, - Site: &SiteInfo{ - BaseURL: test.base, - }, + Site: newSiteInfoDefaultLanguage(string(test.base)), }, Source: Source{File: *source.NewFile(filepath.FromSlash(test.file))}, } diff --git a/hugolib/page_test.go b/hugolib/page_test.go index 6927e6e82..da46151ed 100644 --- a/hugolib/page_test.go +++ b/hugolib/page_test.go @@ -1117,7 +1117,7 @@ func TestPagePaths(t *testing.T) { for _, test := range tests { p, _ := NewPageFrom(strings.NewReader(test.content), filepath.FromSlash(test.path)) - p.Node.Site = &SiteInfo{} + p.Node.Site = newSiteInfoDefaultLanguage("") if test.hasPermalink { p.Node.Site.Permalinks = siteParmalinksSetting diff --git a/hugolib/pagination_test.go b/hugolib/pagination_test.go index b67f5dce5..df2094d63 100644 --- a/hugolib/pagination_test.go +++ b/hugolib/pagination_test.go @@ -460,9 +460,7 @@ func createTestPages(num int) Pages { Section: "z", URL: fmt.Sprintf("http://base/x/y/p%d.html", i), }, - Site: &SiteInfo{ - BaseURL: "http://base/", - }, + Site: newSiteInfoDefaultLanguage("http://base/"), }, Source: Source{File: *source.NewFile(filepath.FromSlash(fmt.Sprintf("/x/y/p%d.md", i)))}, } diff --git a/hugolib/shortcode.go b/hugolib/shortcode.go index b63ba4a49..52cd6893b 100644 --- a/hugolib/shortcode.go +++ b/hugolib/shortcode.go @@ -242,7 +242,8 @@ func renderShortcode(sc shortcode, parent *ShortcodeWithPage, p *Page, t tpl.Tem if sc.doMarkup { newInner := helpers.RenderBytes(&helpers.RenderingContext{ Content: []byte(inner), PageFmt: p.determineMarkupType(), - DocumentID: p.UniqueID(), Config: p.getRenderingConfig()}) + ConfigProvider: p.Language(), + DocumentID: p.UniqueID(), Config: p.getRenderingConfig()}) // If the type is “unknown” or “markdown”, we assume the markdown // generation has been performed. Given the input: `a line`, markdown diff --git a/hugolib/shortcode_test.go b/hugolib/shortcode_test.go index dd16bff07..1b5c6c847 100644 --- a/hugolib/shortcode_test.go +++ b/hugolib/shortcode_test.go @@ -28,29 +28,59 @@ import ( "github.com/spf13/hugo/target" "github.com/spf13/hugo/tpl" "github.com/spf13/viper" + "github.com/stretchr/testify/require" ) +// TODO(bep) remove func pageFromString(in, filename string) (*Page, error) { return NewPageFrom(strings.NewReader(in), filename) } -func CheckShortCodeMatch(t *testing.T, input, expected string, template tpl.Template) { - CheckShortCodeMatchAndError(t, input, expected, template, false) +func CheckShortCodeMatch(t *testing.T, input, expected string, withTemplate func(templ tpl.Template) error) { + CheckShortCodeMatchAndError(t, input, expected, withTemplate, false) } -func CheckShortCodeMatchAndError(t *testing.T, input, expected string, template tpl.Template, expectError bool) { +func CheckShortCodeMatchAndError(t *testing.T, input, expected string, withTemplate func(templ tpl.Template) error, expectError bool) { + testCommonResetState() - p, _ := pageFromString(simplePage, "simple.md") - output, err := HandleShortcodes(input, p, template) + // Need some front matter, see https://github.com/spf13/hugo/issues/2337 + contentFile := `--- +title: "Title" +--- +` + input + + writeSource(t, "content/simple.md", contentFile) + + h, err := newHugoSitesDefaultLanguage() + + if err != nil { + t.Fatalf("Failed to create sites: %s", err) + } + + cfg := BuildCfg{SkipRender: true, withTemplate: withTemplate} + + err = h.Build(cfg) if err != nil && !expectError { - t.Fatalf("Shortcode rendered error %s. Expected: %q, Got: %q", err, expected, output) + t.Fatalf("Shortcode rendered error %s.", err) } if err == nil && expectError { t.Fatalf("No error from shortcode") } + require.Len(t, h.Sites[0].Pages, 1) + + output := strings.TrimSpace(string(h.Sites[0].Pages[0].Content)) + if strings.HasPrefix(output, "<p>") { + output = output[3:] + } + if strings.HasSuffix(output, "</p>") { + output = output[:len(output)-4] + } + + expected = strings.TrimSpace(expected) + if output != expected { t.Fatalf("Shortcode render didn't match. got \n%q but expected \n%q", output, expected) } @@ -86,115 +116,123 @@ func TestShortcodeGoFuzzReports(t *testing.T) { } func TestNonSC(t *testing.T) { - tem := tpl.New() + // notice the syntax diff from 0.12, now comment delims must be added - CheckShortCodeMatch(t, "{{%/* movie 47238zzb */%}}", "{{% movie 47238zzb %}}", tem) + CheckShortCodeMatch(t, "{{%/* movie 47238zzb */%}}", "{{% movie 47238zzb %}}", nil) } // Issue #929 func TestHyphenatedSC(t *testing.T) { - tem := tpl.New() - tem.AddInternalShortcode("hyphenated-video.html", `Playing Video {{ .Get 0 }}`) + wt := func(tem tpl.Template) error { + tem.AddInternalShortcode("hyphenated-video.html", `Playing Video {{ .Get 0 }}`) + return nil + } - CheckShortCodeMatch(t, "{{< hyphenated-video 47238zzb >}}", "Playing Video 47238zzb", tem) + CheckShortCodeMatch(t, "{{< hyphenated-video 47238zzb >}}", "Playing Video 47238zzb", wt) } // Issue #1753 func TestNoTrailingNewline(t *testing.T) { - tem := tpl.New() - tem.AddInternalShortcode("a.html", `{{ .Get 0 }}`) + wt := func(tem tpl.Template) error { + tem.AddInternalShortcode("a.html", `{{ .Get 0 }}`) + return nil + } - CheckShortCodeMatch(t, "ab{{< a c >}}d", "abcd", tem) + CheckShortCodeMatch(t, "ab{{< a c >}}d", "abcd", wt) } func TestPositionalParamSC(t *testing.T) { - tem := tpl.New() - tem.AddInternalShortcode("video.html", `Playing Video {{ .Get 0 }}`) + wt := func(tem tpl.Template) error { + tem.AddInternalShortcode("video.html", `Playing Video {{ .Get 0 }}`) + return nil + } - CheckShortCodeMatch(t, "{{< video 47238zzb >}}", "Playing Video 47238zzb", tem) - CheckShortCodeMatch(t, "{{< video 47238zzb 132 >}}", "Playing Video 47238zzb", tem) - CheckShortCodeMatch(t, "{{<video 47238zzb>}}", "Playing Video 47238zzb", tem) - CheckShortCodeMatch(t, "{{<video 47238zzb >}}", "Playing Video 47238zzb", tem) - CheckShortCodeMatch(t, "{{< video 47238zzb >}}", "Playing Video 47238zzb", tem) + CheckShortCodeMatch(t, "{{< video 47238zzb >}}", "Playing Video 47238zzb", wt) + CheckShortCodeMatch(t, "{{< video 47238zzb 132 >}}", "Playing Video 47238zzb", wt) + CheckShortCodeMatch(t, "{{<video 47238zzb>}}", "Playing Video 47238zzb", wt) + CheckShortCodeMatch(t, "{{<video 47238zzb >}}", "Playing Video 47238zzb", wt) + CheckShortCodeMatch(t, "{{< video 47238zzb >}}", "Playing Video 47238zzb", wt) } func TestPositionalParamIndexOutOfBounds(t *testing.T) { - tem := tpl.New() - tem.AddInternalShortcode("video.html", `Playing Video {{ .Get 1 }}`) - CheckShortCodeMatch(t, "{{< video 47238zzb >}}", "Playing Video error: index out of range for positional param at position 1", tem) + wt := func(tem tpl.Template) error { + tem.AddInternalShortcode("video.html", `Playing Video {{ .Get 1 }}`) + return nil + } + CheckShortCodeMatch(t, "{{< video 47238zzb >}}", "Playing Video error: index out of range for positional param at position 1", wt) } // some repro issues for panics in Go Fuzz testing -func TestShortcodeGoFuzzRepros(t *testing.T) { - tt := tpl.New() - tt.AddInternalShortcode("inner.html", `Shortcode... {{ with .Get 0 }}{{ . }}{{ end }}-- {{ with .Get 1 }}{{ . }}{{ end }}- {{ with .Inner }}{{ . }}{{ end }}`) - // Issue #1337 - CheckShortCodeMatchAndError(t, "{{%inner\"\"\"\"=\"\"", "", tt, true) -} func TestNamedParamSC(t *testing.T) { - tem := tpl.New() - tem.AddInternalShortcode("img.html", `<img{{ with .Get "src" }} src="{{.}}"{{end}}{{with .Get "class"}} class="{{.}}"{{end}}>`) - - CheckShortCodeMatch(t, `{{< img src="one" >}}`, `<img src="one">`, tem) - CheckShortCodeMatch(t, `{{< img class="aspen" >}}`, `<img class="aspen">`, tem) - CheckShortCodeMatch(t, `{{< img src= "one" >}}`, `<img src="one">`, tem) - CheckShortCodeMatch(t, `{{< img src ="one" >}}`, `<img src="one">`, tem) - CheckShortCodeMatch(t, `{{< img src = "one" >}}`, `<img src="one">`, tem) - CheckShortCodeMatch(t, `{{< img src = "one" class = "aspen grove" >}}`, `<img src="one" class="aspen grove">`, tem) + wt := func(tem tpl.Template) error { + tem.AddInternalShortcode("img.html", `<img{{ with .Get "src" }} src="{{.}}"{{end}}{{with .Get "class"}} class="{{.}}"{{end}}>`) + return nil + } + CheckShortCodeMatch(t, `{{< img src="one" >}}`, `<img src="one">`, wt) + CheckShortCodeMatch(t, `{{< img class="aspen" >}}`, `<img class="aspen">`, wt) + CheckShortCodeMatch(t, `{{< img src= "one" >}}`, `<img src="one">`, wt) + CheckShortCodeMatch(t, `{{< img src ="one" >}}`, `<img src="one">`, wt) + CheckShortCodeMatch(t, `{{< img src = "one" >}}`, `<img src="one">`, wt) + CheckShortCodeMatch(t, `{{< img src = "one" class = "aspen grove" >}}`, `<img src="one" class="aspen grove">`, wt) } // Issue #2294 func TestNestedNamedMissingParam(t *testing.T) { - tem := tpl.New() - tem.AddInternalShortcode("acc.html", `<div class="acc">{{ .Inner }}</div>`) - tem.AddInternalShortcode("div.html", `<div {{with .Get "class"}} class="{{ . }}"{{ end }}>{{ .Inner }}</div>`) - tem.AddInternalShortcode("div2.html", `<div {{with .Get 0}} class="{{ . }}"{{ end }}>{{ .Inner }}</div>`) - + wt := func(tem tpl.Template) error { + tem.AddInternalShortcode("acc.html", `<div class="acc">{{ .Inner }}</div>`) + tem.AddInternalShortcode("div.html", `<div {{with .Get "class"}} class="{{ . }}"{{ end }}>{{ .Inner }}</div>`) + tem.AddInternalShortcode("div2.html", `<div {{with .Get 0}} class="{{ . }}"{{ end }}>{{ .Inner }}</div>`) + return nil + } CheckShortCodeMatch(t, `{{% acc %}}{{% div %}}d1{{% /div %}}{{% div2 %}}d2{{% /div2 %}}{{% /acc %}}`, - "<div class=\"acc\"><div >d1</div><div >d2</div>\n</div>", tem) + "<div class=\"acc\"><div >d1</div><div >d2</div>\n</div>", wt) } func TestIsNamedParamsSC(t *testing.T) { - tem := tpl.New() - tem.AddInternalShortcode("byposition.html", `<div id="{{ .Get 0 }}">`) - tem.AddInternalShortcode("byname.html", `<div id="{{ .Get "id" }}">`) - tem.AddInternalShortcode("ifnamedparams.html", `<div id="{{ if .IsNamedParams }}{{ .Get "id" }}{{ else }}{{ .Get 0 }}{{end}}">`) - - CheckShortCodeMatch(t, `{{< ifnamedparams id="name" >}}`, `<div id="name">`, tem) - CheckShortCodeMatch(t, `{{< ifnamedparams position >}}`, `<div id="position">`, tem) - CheckShortCodeMatch(t, `{{< byname id="name" >}}`, `<div id="name">`, tem) - CheckShortCodeMatch(t, `{{< byname position >}}`, `<div id="error: cannot access positional params by string name">`, tem) - CheckShortCodeMatch(t, `{{< byposition position >}}`, `<div id="position">`, tem) - CheckShortCodeMatch(t, `{{< byposition id="name" >}}`, `<div id="error: cannot access named params by position">`, tem) + wt := func(tem tpl.Template) error { + tem.AddInternalShortcode("byposition.html", `<div id="{{ .Get 0 }}">`) + tem.AddInternalShortcode("byname.html", `<div id="{{ .Get "id" }}">`) + tem.AddInternalShortcode("ifnamedparams.html", `<div id="{{ if .IsNamedParams }}{{ .Get "id" }}{{ else }}{{ .Get 0 }}{{end}}">`) + return nil + } + CheckShortCodeMatch(t, `{{< ifnamedparams id="name" >}}`, `<div id="name">`, wt) + CheckShortCodeMatch(t, `{{< ifnamedparams position >}}`, `<div id="position">`, wt) + CheckShortCodeMatch(t, `{{< byname id="name" >}}`, `<div id="name">`, wt) + CheckShortCodeMatch(t, `{{< byname position >}}`, `<div id="error: cannot access positional params by string name">`, wt) + CheckShortCodeMatch(t, `{{< byposition position >}}`, `<div id="position">`, wt) + CheckShortCodeMatch(t, `{{< byposition id="name" >}}`, `<div id="error: cannot access named params by position">`, wt) } func TestInnerSC(t *testing.T) { - tem := tpl.New() - tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`) - - CheckShortCodeMatch(t, `{{< inside class="aspen" >}}`, `<div class="aspen"></div>`, tem) - CheckShortCodeMatch(t, `{{< inside class="aspen" >}}More Here{{< /inside >}}`, "<div class=\"aspen\">More Here</div>", tem) - CheckShortCodeMatch(t, `{{< inside >}}More Here{{< /inside >}}`, "<div>More Here</div>", tem) + wt := func(tem tpl.Template) error { + tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`) + return nil + } + CheckShortCodeMatch(t, `{{< inside class="aspen" >}}`, `<div class="aspen"></div>`, wt) + CheckShortCodeMatch(t, `{{< inside class="aspen" >}}More Here{{< /inside >}}`, "<div class=\"aspen\">More Here</div>", wt) + CheckShortCodeMatch(t, `{{< inside >}}More Here{{< /inside >}}`, "<div>More Here</div>", wt) } func TestInnerSCWithMarkdown(t *testing.T) { - tem := tpl.New() - tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`) - + wt := func(tem tpl.Template) error { + tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`) + return nil + } CheckShortCodeMatch(t, `{{% inside %}} # More Here [link](http://spf13.com) and text -{{% /inside %}}`, "<div><h1 id=\"more-here\">More Here</h1>\n\n<p><a href=\"http://spf13.com\">link</a> and text</p>\n</div>", tem) +{{% /inside %}}`, "<div><h1 id=\"more-here\">More Here</h1>\n\n<p><a href=\"http://spf13.com\">link</a> and text</p>\n</div>", wt) } func TestInnerSCWithAndWithoutMarkdown(t *testing.T) { - tem := tpl.New() - tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`) - + wt := func(tem tpl.Template) error { + tem.AddInternalShortcode("inside.html", `<div{{with .Get "class"}} class="{{.}}"{{end}}>{{ .Inner }}</div>`) + return nil + } CheckShortCodeMatch(t, `{{% inside %}} # More Here @@ -210,54 +248,55 @@ And then: This is **plain** text. {{< /inside >}} -`, "<div><h1 id=\"more-here\">More Here</h1>\n\n<p><a href=\"http://spf13.com\">link</a> and text</p>\n</div>\n\nAnd then:\n\n<div>\n# More Here\n\nThis is **plain** text.\n\n</div>\n", tem) +`, "<div><h1 id=\"more-here\">More Here</h1>\n\n<p><a href=\"http://spf13.com\">link</a> and text</p>\n</div>\n\n<p>And then:</p>\n\n<p><div>\n# More Here\n\nThis is **plain** text.\n\n</div>", wt) } func TestEmbeddedSC(t *testing.T) { - tem := tpl.New() - CheckShortCodeMatch(t, "{{% test %}}", "This is a simple Test", tem) - CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" />\n \n \n</figure>\n", tem) - CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" caption="This is a caption" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"This is a caption\" />\n \n \n <figcaption>\n <p>\n This is a caption\n \n \n \n </p> \n </figcaption>\n \n</figure>\n", tem) + CheckShortCodeMatch(t, "{{% test %}}", "This is a simple Test", nil) + CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" />\n \n \n</figure>\n", nil) + CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" caption="This is a caption" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"This is a caption\" />\n \n \n <figcaption>\n <p>\n This is a caption\n \n \n \n </p> \n </figcaption>\n \n</figure>\n", nil) } func TestNestedSC(t *testing.T) { - tem := tpl.New() - tem.AddInternalShortcode("scn1.html", `<div>Outer, inner is {{ .Inner }}</div>`) - tem.AddInternalShortcode("scn2.html", `<div>SC2</div>`) - - CheckShortCodeMatch(t, `{{% scn1 %}}{{% scn2 %}}{{% /scn1 %}}`, "<div>Outer, inner is <div>SC2</div>\n</div>", tem) + wt := func(tem tpl.Template) error { + tem.AddInternalShortcode("scn1.html", `<div>Outer, inner is {{ .Inner }}</div>`) + tem.AddInternalShortcode("scn2.html", `<div>SC2</div>`) + return nil + } + CheckShortCodeMatch(t, `{{% scn1 %}}{{% scn2 %}}{{% /scn1 %}}`, "<div>Outer, inner is <div>SC2</div>\n</div>", wt) - CheckShortCodeMatch(t, `{{< scn1 >}}{{% scn2 %}}{{< /scn1 >}}`, "<div>Outer, inner is <div>SC2</div></div>", tem) + CheckShortCodeMatch(t, `{{< scn1 >}}{{% scn2 %}}{{< /scn1 >}}`, "<div>Outer, inner is <div>SC2</div></div>", wt) } func TestNestedComplexSC(t *testing.T) { - tem := tpl.New() - tem.AddInternalShortcode("row.html", `-row-{{ .Inner}}-rowStop-`) - tem.AddInternalShortcode("column.html", `-col-{{.Inner }}-colStop-`) - tem.AddInternalShortcode("aside.html", `-aside-{{ .Inner }}-asideStop-`) - + wt := func(tem tpl.Template) error { + tem.AddInternalShortcode("row.html", `-row-{{ .Inner}}-rowStop-`) + tem.AddInternalShortcode("column.html", `-col-{{.Inner }}-colStop-`) + tem.AddInternalShortcode("aside.html", `-aside-{{ .Inner }}-asideStop-`) + return nil + } CheckShortCodeMatch(t, `{{< row >}}1-s{{% column %}}2-**s**{{< aside >}}3-**s**{{< /aside >}}4-s{{% /column %}}5-s{{< /row >}}6-s`, - "-row-1-s-col-2-<strong>s</strong>-aside-3-<strong>s</strong>-asideStop-4-s-colStop-5-s-rowStop-6-s", tem) + "-row-1-s-col-2-<strong>s</strong>-aside-3-<strong>s</strong>-asideStop-4-s-colStop-5-s-rowStop-6-s", wt) // turn around the markup flag CheckShortCodeMatch(t, `{{% row %}}1-s{{< column >}}2-**s**{{% aside %}}3-**s**{{% /aside %}}4-s{{< /column >}}5-s{{% /row %}}6-s`, - "-row-1-s-col-2-<strong>s</strong>-aside-3-<strong>s</strong>-asideStop-4-s-colStop-5-s-rowStop-6-s", tem) + "-row-1-s-col-2-<strong>s</strong>-aside-3-<strong>s</strong>-asideStop-4-s-colStop-5-s-rowStop-6-s", wt) } func TestParentShortcode(t *testing.T) { - tem := tpl.New() - tem.AddInternalShortcode("r1.html", `1: {{ .Get "pr1" }} {{ .Inner }}`) - tem.AddInternalShortcode("r2.html", `2: {{ .Parent.Get "pr1" }}{{ .Get "pr2" }} {{ .Inner }}`) - tem.AddInternalShortcode("r3.html", `3: {{ .Parent.Parent.Get "pr1" }}{{ .Parent.Get "pr2" }}{{ .Get "pr3" }} {{ .Inner }}`) - + wt := func(tem tpl.Template) error { + tem.AddInternalShortcode("r1.html", `1: {{ .Get "pr1" }} {{ .Inner }}`) + tem.AddInternalShortcode("r2.html", `2: {{ .Parent.Get "pr1" }}{{ .Get "pr2" }} {{ .Inner }}`) + tem.AddInternalShortcode("r3.html", `3: {{ .Parent.Parent.Get "pr1" }}{{ .Parent.Get "pr2" }}{{ .Get "pr3" }} {{ .Inner }}`) + return nil + } CheckShortCodeMatch(t, `{{< r1 pr1="p1" >}}1: {{< r2 pr2="p2" >}}2: {{< r3 pr3="p3" >}}{{< /r3 >}}{{< /r2 >}}{{< /r1 >}}`, - "1: p1 1: 2: p1p2 2: 3: p1p2p3 ", tem) + "1: p1 1: 2: p1p2 2: 3: p1p2p3 ", wt) } func TestFigureImgWidth(t *testing.T) { - tem := tpl.New() - CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" alt="apple" width="100px" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"apple\" width=\"100px\" />\n \n \n</figure>\n", tem) + CheckShortCodeMatch(t, `{{% figure src="/found/here" class="bananas orange" alt="apple" width="100px" %}}`, "\n<figure class=\"bananas orange\">\n \n <img src=\"/found/here\" alt=\"apple\" width=\"100px\" />\n \n \n</figure>\n", nil) } func TestHighlight(t *testing.T) { @@ -539,7 +578,7 @@ tags: } - sites, err := NewHugoSites(s) + sites, err := newHugoSites(s) if err != nil { t.Fatalf("Failed to build site: %s", err) diff --git a/hugolib/site.go b/hugolib/site.go index 3abde5d97..fe3285e14 100644 --- a/hugolib/site.go +++ b/hugolib/site.go @@ -107,7 +107,7 @@ func (s *Site) Reset() *Site { // newSite creates a new site in the given language. func newSite(lang *Language) *Site { - return &Site{Language: lang} + return &Site{Language: lang, Info: SiteInfo{multilingual: newMultiLingualForLanguage(lang)}} } // newSite creates a new site in the default language. @@ -172,12 +172,23 @@ type SiteInfo struct { paginationPageCount uint64 Data *map[string]interface{} - Multilingual bool + multilingual *Multilingual Language *Language LanguagePrefix string Languages Languages } +// Used in tests. +func newSiteInfoDefaultLanguage(baseURL string, pages ...*Page) *SiteInfo { + ps := Pages(pages) + + return &SiteInfo{ + BaseURL: template.URL(baseURL), + rawAllPages: &ps, + multilingual: newMultiLingualDefaultLanguage(), + } +} + // SiteSocial is a place to put social details on a site level. These are the // standard keys that themes will expect to have available, but can be // expanded to any others on a per site basis @@ -218,6 +229,10 @@ func (s *SiteInfo) GetParam(key string) interface{} { return nil } +func (s *SiteInfo) IsMultiLingual() bool { + return len(s.Languages) > 1 +} + func (s *SiteInfo) refLink(ref string, page *Page, relative bool) (string, error) { var refURL *url.URL var err error @@ -837,7 +852,7 @@ func (s *Site) initialize() (err error) { // HomeAbsURL is a convenience method giving the absolute URL to the home page. func (s *SiteInfo) HomeAbsURL() string { base := "/" - if s.Multilingual { + if s.IsMultiLingual() { base = s.Language.Lang } return helpers.AbsURL(base) @@ -880,8 +895,8 @@ func (s *Site) initializeSiteInfo() { LanguageCode: lang.GetString("languagecode"), Copyright: lang.GetString("copyright"), DisqusShortname: lang.GetString("DisqusShortname"), - // TODO(bep) multilang, consolidate the below (make into methods etc.) - Multilingual: s.multilingualEnabled(), + // TODO(bep) ml consolidate the below (make into methods etc.) + multilingual: s.Multilingual, Language: lang, LanguagePrefix: languagePrefix, Languages: languages, diff --git a/hugolib/translations.go b/hugolib/translations.go index 267545f37..05dcfb260 100644 --- a/hugolib/translations.go +++ b/hugolib/translations.go @@ -13,10 +13,6 @@ package hugolib -import ( - jww "github.com/spf13/jwalterweatherman" -) - // Translations represent the other translations for a given page. The // string here is the language code, as affected by the `post.LANG.md` // filename. @@ -38,17 +34,6 @@ func pagesToTranslationsMap(ml *Multilingual, pages []*Page) map[string]Translat continue } - language := ml.Language(pageLang) - - if language == nil { - // TODO(bep) ml - // This may or may not be serious. It can be a file named stefano.chiodino.md. - jww.WARN.Printf("Page language (if it is that) not found in multilang setup: %s.", pageLang) - language = ml.DefaultLang - } - - page.language = language - pageTranslation[pageLang] = page out[base] = pageTranslation } diff --git a/tpl/template_funcs.go b/tpl/template_funcs.go index ed931c44b..941115cd9 100644 --- a/tpl/template_funcs.go +++ b/tpl/template_funcs.go @@ -38,6 +38,8 @@ import ( "time" "unicode/utf8" + "github.com/spf13/viper" + "github.com/spf13/afero" "github.com/spf13/hugo/hugofs" @@ -1212,7 +1214,10 @@ func markdownify(in interface{}) (template.HTML, error) { if err != nil { return "", err } - m := helpers.RenderBytes(&helpers.RenderingContext{Content: []byte(text), PageFmt: "markdown"}) + // TODO(bep) ml language + m := helpers.RenderBytes(&helpers.RenderingContext{ + ConfigProvider: viper.GetViper(), + Content: []byte(text), PageFmt: "markdown"}) m = bytes.TrimPrefix(m, markdownTrimPrefix) m = bytes.TrimSuffix(m, markdownTrimSuffix) return template.HTML(m), nil |