mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-07 20:30:36 -05:00
Add Translations and AllTranslations to Node
This commit also consolidates URLs on Node vs Page, so now .Permalink should be interoperable. Note that this implementations should be fairly short-livded, waiting for #2297, but the API should be stable.
This commit is contained in:
parent
52bf8f9095
commit
3a02807970
7 changed files with 162 additions and 74 deletions
|
@ -554,7 +554,7 @@ func TestHomeNodeMenu(t *testing.T) {
|
||||||
s := setupMenuTests(t, menuPageSources)
|
s := setupMenuTests(t, menuPageSources)
|
||||||
|
|
||||||
home := s.newHomeNode()
|
home := s.newHomeNode()
|
||||||
homeMenuEntry := &MenuEntry{Name: home.Title, URL: home.URL}
|
homeMenuEntry := &MenuEntry{Name: home.Title, URL: home.URL()}
|
||||||
|
|
||||||
for i, this := range []struct {
|
for i, this := range []struct {
|
||||||
menu string
|
menu string
|
||||||
|
|
109
hugolib/node.go
109
hugolib/node.go
|
@ -15,6 +15,9 @@ package hugolib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"html/template"
|
"html/template"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -38,6 +41,27 @@ type Node struct {
|
||||||
paginator *Pager
|
paginator *Pager
|
||||||
paginatorInit sync.Once
|
paginatorInit sync.Once
|
||||||
scratch *Scratch
|
scratch *Scratch
|
||||||
|
|
||||||
|
language *Language
|
||||||
|
lang string // TODO(bep) multilingo
|
||||||
|
|
||||||
|
translations Nodes
|
||||||
|
translationsInit sync.Once
|
||||||
|
}
|
||||||
|
|
||||||
|
// The Nodes type is temporary until we get https://github.com/spf13/hugo/issues/2297 fixed.
|
||||||
|
type Nodes []*Node
|
||||||
|
|
||||||
|
func (n Nodes) Len() int {
|
||||||
|
return len(n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n Nodes) Less(i, j int) bool {
|
||||||
|
return n[i].language.Weight < n[j].language.Weight
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n Nodes) Swap(i, j int) {
|
||||||
|
n[i], n[j] = n[j], n[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Now() time.Time {
|
func (n *Node) Now() time.Time {
|
||||||
|
@ -46,7 +70,7 @@ func (n *Node) Now() time.Time {
|
||||||
|
|
||||||
func (n *Node) HasMenuCurrent(menuID string, inme *MenuEntry) bool {
|
func (n *Node) HasMenuCurrent(menuID string, inme *MenuEntry) bool {
|
||||||
if inme.HasChildren() {
|
if inme.HasChildren() {
|
||||||
me := MenuEntry{Name: n.Title, URL: n.URL}
|
me := MenuEntry{Name: n.Title, URL: n.URL()}
|
||||||
|
|
||||||
for _, child := range inme.Children {
|
for _, child := range inme.Children {
|
||||||
if me.IsSameResource(child) {
|
if me.IsSameResource(child) {
|
||||||
|
@ -63,7 +87,7 @@ func (n *Node) HasMenuCurrent(menuID string, inme *MenuEntry) bool {
|
||||||
|
|
||||||
func (n *Node) IsMenuCurrent(menuID string, inme *MenuEntry) bool {
|
func (n *Node) IsMenuCurrent(menuID string, inme *MenuEntry) bool {
|
||||||
|
|
||||||
me := MenuEntry{Name: n.Title, URL: n.Site.createNodeMenuEntryURL(n.URL)}
|
me := MenuEntry{Name: n.Title, URL: n.Site.createNodeMenuEntryURL(n.URL())}
|
||||||
|
|
||||||
if !me.IsSameResource(inme) {
|
if !me.IsSameResource(inme) {
|
||||||
return false
|
return false
|
||||||
|
@ -138,6 +162,7 @@ func (n *Node) RelRef(ref string) (string, error) {
|
||||||
return n.Site.RelRef(ref, nil)
|
return n.Site.RelRef(ref, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(bep) multilingo some of these are now hidden. Consider unexport.
|
||||||
type URLPath struct {
|
type URLPath struct {
|
||||||
URL string
|
URL string
|
||||||
Permalink string
|
Permalink string
|
||||||
|
@ -145,6 +170,14 @@ type URLPath struct {
|
||||||
Section string
|
Section string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Node) URL() string {
|
||||||
|
return n.addMultilingualWebPrefix(n.URLPath.URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Permalink() string {
|
||||||
|
return permalink(n.URL())
|
||||||
|
}
|
||||||
|
|
||||||
// Scratch returns the writable context associated with this Node.
|
// Scratch returns the writable context associated with this Node.
|
||||||
func (n *Node) Scratch() *Scratch {
|
func (n *Node) Scratch() *Scratch {
|
||||||
if n.scratch == nil {
|
if n.scratch == nil {
|
||||||
|
@ -152,3 +185,75 @@ func (n *Node) Scratch() *Scratch {
|
||||||
}
|
}
|
||||||
return n.scratch
|
return n.scratch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(bep) multilingo consolidate. See Page.
|
||||||
|
func (n *Node) Language() *Language {
|
||||||
|
return n.language
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Lang() string {
|
||||||
|
if n.Language() != nil {
|
||||||
|
return n.Language().Lang
|
||||||
|
}
|
||||||
|
return n.lang
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllTranslations returns all translations, including the current Node.
|
||||||
|
// Note that this and the one below is kind of a temporary hack before #2297 is solved.
|
||||||
|
func (n *Node) AllTranslations() Nodes {
|
||||||
|
n.initTranslations()
|
||||||
|
return n.translations
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translations returns the translations excluding the current Node.
|
||||||
|
func (n *Node) Translations() Nodes {
|
||||||
|
n.initTranslations()
|
||||||
|
translations := make(Nodes, 0)
|
||||||
|
|
||||||
|
for _, t := range n.translations {
|
||||||
|
|
||||||
|
if t != n {
|
||||||
|
translations = append(translations, t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return translations
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) initTranslations() {
|
||||||
|
n.translationsInit.Do(func() {
|
||||||
|
if n.translations != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
n.translations = make(Nodes, 0)
|
||||||
|
for _, l := range n.Site.Languages {
|
||||||
|
if l == n.language {
|
||||||
|
n.translations = append(n.translations, n)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
translation := *n
|
||||||
|
translation.language = l
|
||||||
|
translation.translations = n.translations
|
||||||
|
n.translations = append(n.translations, &translation)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Sort(n.translations)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) addMultilingualWebPrefix(outfile string) string {
|
||||||
|
lang := n.Lang()
|
||||||
|
if lang == "" || !n.Site.Multilingual {
|
||||||
|
return outfile
|
||||||
|
}
|
||||||
|
return "/" + path.Join(lang, outfile)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) addMultilingualFilesystemPrefix(outfile string) string {
|
||||||
|
lang := n.Lang()
|
||||||
|
if lang == "" || !n.Site.Multilingual {
|
||||||
|
return outfile
|
||||||
|
}
|
||||||
|
return string(filepath.Separator) + filepath.Join(lang, outfile)
|
||||||
|
}
|
||||||
|
|
|
@ -64,8 +64,6 @@ type Page struct {
|
||||||
translations Pages
|
translations Pages
|
||||||
extension string
|
extension string
|
||||||
contentType string
|
contentType string
|
||||||
lang string
|
|
||||||
language *Language
|
|
||||||
renderable bool
|
renderable bool
|
||||||
Layout string
|
Layout string
|
||||||
layoutsCalculated []string
|
layoutsCalculated []string
|
||||||
|
@ -431,7 +429,7 @@ func (p *Page) permalink() (*url.URL, error) {
|
||||||
baseURL := string(p.Site.BaseURL)
|
baseURL := string(p.Site.BaseURL)
|
||||||
dir := strings.TrimSpace(helpers.MakePath(filepath.ToSlash(strings.ToLower(p.Source.Dir()))))
|
dir := strings.TrimSpace(helpers.MakePath(filepath.ToSlash(strings.ToLower(p.Source.Dir()))))
|
||||||
pSlug := strings.TrimSpace(helpers.URLize(p.Slug))
|
pSlug := strings.TrimSpace(helpers.URLize(p.Slug))
|
||||||
pURL := strings.TrimSpace(helpers.URLize(p.URL))
|
pURL := strings.TrimSpace(helpers.URLize(p.URLPath.URL))
|
||||||
var permalink string
|
var permalink string
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -467,14 +465,6 @@ func (p *Page) Extension() string {
|
||||||
return viper.GetString("DefaultExtension")
|
return viper.GetString("DefaultExtension")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bep) multilingo consolidate
|
|
||||||
func (p *Page) Language() *Language {
|
|
||||||
return p.language
|
|
||||||
}
|
|
||||||
func (p *Page) Lang() string {
|
|
||||||
return p.lang
|
|
||||||
}
|
|
||||||
|
|
||||||
// AllTranslations returns all translations, including the current Page.
|
// AllTranslations returns all translations, including the current Page.
|
||||||
func (p *Page) AllTranslations() Pages {
|
func (p *Page) AllTranslations() Pages {
|
||||||
return p.translations
|
return p.translations
|
||||||
|
@ -591,7 +581,7 @@ func (p *Page) update(f interface{}) error {
|
||||||
if url := cast.ToString(v); strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
|
if url := cast.ToString(v); strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
|
||||||
return fmt.Errorf("Only relative URLs are supported, %v provided", url)
|
return fmt.Errorf("Only relative URLs are supported, %v provided", url)
|
||||||
}
|
}
|
||||||
p.URL = cast.ToString(v)
|
p.URLPath.URL = cast.ToString(v)
|
||||||
case "type":
|
case "type":
|
||||||
p.contentType = cast.ToString(v)
|
p.contentType = cast.ToString(v)
|
||||||
case "extension", "ext":
|
case "extension", "ext":
|
||||||
|
@ -1008,8 +998,8 @@ func (p *Page) FullFilePath() string {
|
||||||
|
|
||||||
func (p *Page) TargetPath() (outfile string) {
|
func (p *Page) TargetPath() (outfile string) {
|
||||||
// Always use URL if it's specified
|
// Always use URL if it's specified
|
||||||
if len(strings.TrimSpace(p.URL)) > 2 {
|
if len(strings.TrimSpace(p.URLPath.URL)) > 2 {
|
||||||
outfile = strings.TrimSpace(p.URL)
|
outfile = strings.TrimSpace(p.URLPath.URL)
|
||||||
|
|
||||||
if strings.HasSuffix(outfile, "/") {
|
if strings.HasSuffix(outfile, "/") {
|
||||||
outfile = outfile + "index.html"
|
outfile = outfile + "index.html"
|
||||||
|
@ -1042,17 +1032,3 @@ func (p *Page) TargetPath() (outfile string) {
|
||||||
|
|
||||||
return p.addMultilingualFilesystemPrefix(filepath.Join(strings.ToLower(helpers.MakePath(p.Source.Dir())), strings.TrimSpace(outfile)))
|
return p.addMultilingualFilesystemPrefix(filepath.Join(strings.ToLower(helpers.MakePath(p.Source.Dir())), strings.TrimSpace(outfile)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Page) addMultilingualWebPrefix(outfile string) string {
|
|
||||||
if p.Lang() == "" {
|
|
||||||
return outfile
|
|
||||||
}
|
|
||||||
return "/" + path.Join(p.Lang(), outfile)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Page) addMultilingualFilesystemPrefix(outfile string) string {
|
|
||||||
if p.Lang() == "" {
|
|
||||||
return outfile
|
|
||||||
}
|
|
||||||
return string(filepath.Separator) + filepath.Join(p.Lang(), outfile)
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,14 +16,15 @@ package hugolib
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/spf13/cast"
|
|
||||||
"github.com/spf13/hugo/helpers"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"math"
|
"math"
|
||||||
"path"
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/spf13/cast"
|
||||||
|
"github.com/spf13/hugo/helpers"
|
||||||
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Pager represents one of the elements in a paginator.
|
// Pager represents one of the elements in a paginator.
|
||||||
|
@ -274,7 +275,7 @@ func (n *Node) Paginator(options ...interface{}) (*Pager, error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pagers, err := paginatePages(n.Data["Pages"], pagerSize, n.URL)
|
pagers, err := paginatePages(n.Data["Pages"], pagerSize, n.URL())
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
initError = err
|
initError = err
|
||||||
|
@ -324,7 +325,7 @@ func (n *Node) Paginate(seq interface{}, options ...interface{}) (*Pager, error)
|
||||||
if n.paginator != nil {
|
if n.paginator != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pagers, err := paginatePages(seq, pagerSize, n.URL)
|
pagers, err := paginatePages(seq, pagerSize, n.URL())
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
initError = err
|
initError = err
|
||||||
|
|
|
@ -117,19 +117,20 @@ type targetList struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type SiteInfo struct {
|
type SiteInfo struct {
|
||||||
BaseURL template.URL
|
BaseURL template.URL
|
||||||
Taxonomies TaxonomyList
|
Taxonomies TaxonomyList
|
||||||
Authors AuthorList
|
Authors AuthorList
|
||||||
Social SiteSocial
|
Social SiteSocial
|
||||||
Sections Taxonomy
|
Sections Taxonomy
|
||||||
Pages *Pages // Includes only pages in this language
|
Pages *Pages // Includes only pages in this language
|
||||||
AllPages *Pages // Includes other translated pages, excluding those in this language.
|
AllPages *Pages // Includes other translated pages, excluding those in this language.
|
||||||
Files *[]*source.File
|
Files *[]*source.File
|
||||||
Menus *Menus
|
Menus *Menus
|
||||||
Hugo *HugoInfo
|
Hugo *HugoInfo
|
||||||
Title string
|
Title string
|
||||||
RSSLink string
|
RSSLink string
|
||||||
Author map[string]interface{}
|
Author map[string]interface{}
|
||||||
|
// TODO(bep) multilingo
|
||||||
LanguageCode string
|
LanguageCode string
|
||||||
DisqusShortname string
|
DisqusShortname string
|
||||||
GoogleAnalytics string
|
GoogleAnalytics string
|
||||||
|
@ -885,7 +886,7 @@ func (s *Site) initializeSiteInfo() {
|
||||||
LanguagePrefix: languagePrefix,
|
LanguagePrefix: languagePrefix,
|
||||||
Languages: languages,
|
Languages: languages,
|
||||||
GoogleAnalytics: viper.GetString("GoogleAnalytics"),
|
GoogleAnalytics: viper.GetString("GoogleAnalytics"),
|
||||||
RSSLink: s.permalinkStr(viper.GetString("RSSUri")),
|
RSSLink: permalinkStr(viper.GetString("RSSUri")),
|
||||||
BuildDrafts: viper.GetBool("BuildDrafts"),
|
BuildDrafts: viper.GetBool("BuildDrafts"),
|
||||||
canonifyURLs: viper.GetBool("CanonifyURLs"),
|
canonifyURLs: viper.GetBool("CanonifyURLs"),
|
||||||
preserveTaxonomyNames: viper.GetBool("PreserveTaxonomyNames"),
|
preserveTaxonomyNames: viper.GetBool("PreserveTaxonomyNames"),
|
||||||
|
@ -1672,7 +1673,7 @@ func taxonomyRenderer(s *Site, taxes <-chan taxRenderInfo, results chan<- error,
|
||||||
paginatePath := viper.GetString("paginatePath")
|
paginatePath := viper.GetString("paginatePath")
|
||||||
|
|
||||||
// write alias for page 1
|
// write alias for page 1
|
||||||
s.writeDestAlias(helpers.PaginateAliasPath(base, 1), s.permalink(base))
|
s.writeDestAlias(helpers.PaginateAliasPath(base, 1), permalink(base))
|
||||||
|
|
||||||
pagers := n.paginator.Pagers()
|
pagers := n.paginator.Pagers()
|
||||||
|
|
||||||
|
@ -1701,8 +1702,8 @@ func taxonomyRenderer(s *Site, taxes <-chan taxRenderInfo, results chan<- error,
|
||||||
if !viper.GetBool("DisableRSS") {
|
if !viper.GetBool("DisableRSS") {
|
||||||
// XML Feed
|
// XML Feed
|
||||||
rssuri := viper.GetString("RSSUri")
|
rssuri := viper.GetString("RSSUri")
|
||||||
n.URL = s.permalinkStr(base + "/" + rssuri)
|
n.URLPath.URL = permalinkStr(base + "/" + rssuri)
|
||||||
n.Permalink = s.permalink(base)
|
n.URLPath.Permalink = permalink(base)
|
||||||
rssLayouts := []string{"taxonomy/" + t.singular + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"}
|
rssLayouts := []string{"taxonomy/" + t.singular + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"}
|
||||||
|
|
||||||
if err := s.renderAndWriteXML("taxonomy "+t.singular+" rss", base+"/"+rssuri, n, s.appendThemeTemplates(rssLayouts)...); err != nil {
|
if err := s.renderAndWriteXML("taxonomy "+t.singular+" rss", base+"/"+rssuri, n, s.appendThemeTemplates(rssLayouts)...); err != nil {
|
||||||
|
@ -1782,7 +1783,7 @@ func (s *Site) renderSectionLists() error {
|
||||||
paginatePath := viper.GetString("paginatePath")
|
paginatePath := viper.GetString("paginatePath")
|
||||||
|
|
||||||
// write alias for page 1
|
// write alias for page 1
|
||||||
s.writeDestAlias(helpers.PaginateAliasPath(base, 1), s.permalink(base))
|
s.writeDestAlias(helpers.PaginateAliasPath(base, 1), permalink(base))
|
||||||
|
|
||||||
pagers := n.paginator.Pagers()
|
pagers := n.paginator.Pagers()
|
||||||
|
|
||||||
|
@ -1810,8 +1811,8 @@ func (s *Site) renderSectionLists() error {
|
||||||
if !viper.GetBool("DisableRSS") && section != "" {
|
if !viper.GetBool("DisableRSS") && section != "" {
|
||||||
// XML Feed
|
// XML Feed
|
||||||
rssuri := viper.GetString("RSSUri")
|
rssuri := viper.GetString("RSSUri")
|
||||||
n.URL = s.permalinkStr(base + "/" + rssuri)
|
n.URLPath.URL = permalinkStr(base + "/" + rssuri)
|
||||||
n.Permalink = s.permalink(base)
|
n.URLPath.Permalink = permalink(base)
|
||||||
rssLayouts := []string{"section/" + section + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"}
|
rssLayouts := []string{"section/" + section + ".rss.xml", "_default/rss.xml", "rss.xml", "_internal/_default/rss.xml"}
|
||||||
if err := s.renderAndWriteXML("section "+section+" rss", base+"/"+rssuri, n, s.appendThemeTemplates(rssLayouts)...); err != nil {
|
if err := s.renderAndWriteXML("section "+section+" rss", base+"/"+rssuri, n, s.appendThemeTemplates(rssLayouts)...); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -1834,7 +1835,7 @@ func (s *Site) renderHomePage() error {
|
||||||
paginatePath := viper.GetString("paginatePath")
|
paginatePath := viper.GetString("paginatePath")
|
||||||
|
|
||||||
// write alias for page 1
|
// write alias for page 1
|
||||||
s.writeDestAlias(s.addMultilingualPrefix(helpers.PaginateAliasPath("", 1)), s.permalink("/"))
|
s.writeDestAlias(s.addMultilingualPrefix(helpers.PaginateAliasPath("", 1)), permalink("/"))
|
||||||
|
|
||||||
pagers := n.paginator.Pagers()
|
pagers := n.paginator.Pagers()
|
||||||
|
|
||||||
|
@ -1862,7 +1863,7 @@ func (s *Site) renderHomePage() error {
|
||||||
|
|
||||||
if !viper.GetBool("DisableRSS") {
|
if !viper.GetBool("DisableRSS") {
|
||||||
// XML Feed
|
// XML Feed
|
||||||
n.URL = s.permalinkStr(viper.GetString("RSSUri"))
|
n.URLPath.URL = permalinkStr(viper.GetString("RSSUri"))
|
||||||
n.Title = ""
|
n.Title = ""
|
||||||
high := 50
|
high := 50
|
||||||
if len(s.Pages) < high {
|
if len(s.Pages) < high {
|
||||||
|
@ -1886,10 +1887,10 @@ func (s *Site) renderHomePage() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(bep) reusing the Home Node smells trouble
|
// TODO(bep) reusing the Home Node smells trouble
|
||||||
n.URL = helpers.URLize("404.html")
|
n.URLPath.URL = helpers.URLize("404.html")
|
||||||
n.IsHome = false
|
n.IsHome = false
|
||||||
n.Title = "404 Page not found"
|
n.Title = "404 Page not found"
|
||||||
n.Permalink = s.permalink("404.html")
|
n.URLPath.Permalink = permalink("404.html")
|
||||||
n.scratch = newScratch()
|
n.scratch = newScratch()
|
||||||
|
|
||||||
nfLayouts := []string{"404.html"}
|
nfLayouts := []string{"404.html"}
|
||||||
|
@ -1929,7 +1930,7 @@ func (s *Site) renderSitemap() error {
|
||||||
page.Date = s.Info.LastChange
|
page.Date = s.Info.LastChange
|
||||||
page.Lastmod = s.Info.LastChange
|
page.Lastmod = s.Info.LastChange
|
||||||
page.Site = &s.Info
|
page.Site = &s.Info
|
||||||
page.URL = "/"
|
page.URLPath.URL = "/"
|
||||||
page.Sitemap.ChangeFreq = sitemapDefault.ChangeFreq
|
page.Sitemap.ChangeFreq = sitemapDefault.ChangeFreq
|
||||||
page.Sitemap.Priority = sitemapDefault.Priority
|
page.Sitemap.Priority = sitemapDefault.Priority
|
||||||
|
|
||||||
|
@ -2002,24 +2003,25 @@ func (s *Site) Stats(t0 time.Time) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) setURLs(n *Node, in string) {
|
func (s *Site) setURLs(n *Node, in string) {
|
||||||
in = s.addMultilingualPrefix(in)
|
n.URLPath.URL = helpers.URLizeAndPrep(in)
|
||||||
n.URL = helpers.URLizeAndPrep(in)
|
n.URLPath.Permalink = permalink(n.URLPath.URL)
|
||||||
n.Permalink = s.permalink(n.URL)
|
// TODO(bep) multilingo
|
||||||
n.RSSLink = template.HTML(s.permalink(in + ".xml"))
|
n.RSSLink = template.HTML(permalink(in + ".xml"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) permalink(plink string) string {
|
func permalink(plink string) string {
|
||||||
return s.permalinkStr(plink)
|
return permalinkStr(plink)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) permalinkStr(plink string) string {
|
func permalinkStr(plink string) string {
|
||||||
return helpers.MakePermalink(viper.GetString("BaseURL"), helpers.URLizeAndPrep(plink)).String()
|
return helpers.MakePermalink(viper.GetString("BaseURL"), helpers.URLizeAndPrep(plink)).String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Site) newNode() *Node {
|
func (s *Site) newNode() *Node {
|
||||||
return &Node{
|
return &Node{
|
||||||
Data: make(map[string]interface{}),
|
Data: make(map[string]interface{}),
|
||||||
Site: &s.Info,
|
Site: &s.Info,
|
||||||
|
language: s.Lang,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2075,7 +2077,7 @@ func (s *Site) renderAndWritePage(name string, dest string, d interface{}, layou
|
||||||
|
|
||||||
var pageTarget target.Output
|
var pageTarget target.Output
|
||||||
|
|
||||||
if p, ok := d.(*Page); ok && path.Ext(p.URL) != "" {
|
if p, ok := d.(*Page); ok && path.Ext(p.URLPath.URL) != "" {
|
||||||
// user has explicitly set a URL with extension for this page
|
// user has explicitly set a URL with extension for this page
|
||||||
// make sure it sticks even if "ugly URLs" are turned off.
|
// make sure it sticks even if "ugly URLs" are turned off.
|
||||||
pageTarget = s.pageUglyTarget()
|
pageTarget = s.pageUglyTarget()
|
||||||
|
|
|
@ -1448,7 +1448,10 @@ NOTE: should use the "permalinks" configuration with :filename
|
||||||
permalink, err = doc3.Permalink()
|
permalink, err = doc3.Permalink()
|
||||||
assert.NoError(t, err, "permalink call failed")
|
assert.NoError(t, err, "permalink call failed")
|
||||||
assert.Equal(t, "http://example.com/blog/superbob", permalink, "invalid doc3 permalink")
|
assert.Equal(t, "http://example.com/blog/superbob", permalink, "invalid doc3 permalink")
|
||||||
assert.Equal(t, "/superbob", doc3.URL, "invalid url, was specified on doc3")
|
|
||||||
|
// TODO(bep) multilingo. Check this case. This has url set in frontmatter, but we must split into lang folders
|
||||||
|
// The assertion below was missing the /en prefix.
|
||||||
|
assert.Equal(t, "/en/superbob", doc3.URL(), "invalid url, was specified on doc3 TODO(bep)")
|
||||||
|
|
||||||
assert.Equal(t, doc2.Next, doc3, "doc3 should follow doc2, in .Next")
|
assert.Equal(t, doc2.Next, doc3, "doc3 should follow doc2, in .Next")
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@ func SetTranslateLang(lang string) error {
|
||||||
translater.current = f
|
translater.current = f
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return fmt.Errorf("Translation func for language %v not found", lang)
|
jww.WARN.Printf("Translation func for language %v not found", lang)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetI18nTfuncs(bndl *bundle.Bundle) {
|
func SetI18nTfuncs(bndl *bundle.Bundle) {
|
||||||
|
@ -58,7 +59,7 @@ func SetI18nTfuncs(bndl *bundle.Bundle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func I18nTranslate(id string, args ...interface{}) (string, error) {
|
func I18nTranslate(id string, args ...interface{}) (string, error) {
|
||||||
if translater == nil {
|
if translater == nil || translater.current == nil {
|
||||||
return "", fmt.Errorf("i18n not initialized, have you configured everything properly?")
|
return "", fmt.Errorf("i18n not initialized, have you configured everything properly?")
|
||||||
}
|
}
|
||||||
return translater.current(id, args...), nil
|
return translater.current(id, args...), nil
|
||||||
|
|
Loading…
Reference in a new issue