mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-26 08:18:53 +00:00
Compare commits
9 Commits
github/space
...
v0.18.1
| Author | SHA1 | Date | |
|---|---|---|---|
| dab1303c18 | |||
| 0daceb74e0 | |||
| 7592809527 | |||
| 7b8efedf7c | |||
| 6ab6171ec6 | |||
| 8fea39665b | |||
| a6632c4f35 | |||
| f6d8ffd3e5 | |||
| 25e1590be4 |
+3
-1
@@ -12,4 +12,6 @@ cover.out
|
||||
*~
|
||||
vendor/*/
|
||||
*.bench
|
||||
coverage*.out
|
||||
coverage*.out
|
||||
|
||||
GoBuilds
|
||||
@@ -15,6 +15,8 @@ install:
|
||||
- make govendor
|
||||
script:
|
||||
- make check
|
||||
# Test 64-bit alignment on 32-bit builds
|
||||
- env GOARCH=386 make test
|
||||
- go build -race
|
||||
- ./hugo -s docs/
|
||||
- ./hugo --renderToMemory -s docs/
|
||||
|
||||
@@ -9,6 +9,15 @@ menu:
|
||||
title: Release Notes
|
||||
weight: 10
|
||||
---
|
||||
## **0.18.1** December 30th 2016
|
||||
|
||||
Hugo 0.18.1 is a bug fix release fixing some issues introduced in Hugo 0.18:
|
||||
|
||||
* Fix 32-bit binaries {{<gh 2847 >}}
|
||||
* Fix issues with `preserveTaxonomyNames` {{<gh 2809 >}}
|
||||
* Fix `.URL` for taxonomy pages when `uglyURLs=true` {{<gh 2819 >}}
|
||||
* Fix `IsTranslated` and `Translations` for node pages {{<gh 2812 >}}
|
||||
* Make template error messages more verbose {{<gh 2820 >}}
|
||||
|
||||
## **0.18.0** December 19th 2016
|
||||
|
||||
|
||||
+18
-6
@@ -19,7 +19,13 @@ import (
|
||||
|
||||
// HugoVersionNumber represents the current build version.
|
||||
// This should be the only one
|
||||
const HugoVersionNumber = 0.18
|
||||
const (
|
||||
// Major and minor version.
|
||||
HugoVersionNumber = 0.18
|
||||
|
||||
// Increment this for bug releases
|
||||
HugoPatchVersion = 1
|
||||
)
|
||||
|
||||
// HugoVersionSuffix is the suffix used in the Hugo version string.
|
||||
// It will be blank for release versions.
|
||||
@@ -29,23 +35,29 @@ const HugoVersionSuffix = "" // use this line when doing a release
|
||||
// HugoVersion returns the current Hugo version. It will include
|
||||
// a suffix, typically '-DEV', if it's development version.
|
||||
func HugoVersion() string {
|
||||
return hugoVersion(HugoVersionNumber, HugoVersionSuffix)
|
||||
return hugoVersion(HugoVersionNumber, HugoPatchVersion, HugoVersionSuffix)
|
||||
}
|
||||
|
||||
// HugoReleaseVersion is same as HugoVersion, but no suffix.
|
||||
func HugoReleaseVersion() string {
|
||||
return hugoVersionNoSuffix(HugoVersionNumber)
|
||||
return hugoVersionNoSuffix(HugoVersionNumber, HugoPatchVersion)
|
||||
}
|
||||
|
||||
// NextHugoReleaseVersion returns the next Hugo release version.
|
||||
func NextHugoReleaseVersion() string {
|
||||
return hugoVersionNoSuffix(HugoVersionNumber + 0.01)
|
||||
return hugoVersionNoSuffix(HugoVersionNumber+0.01, 0)
|
||||
}
|
||||
|
||||
func hugoVersion(version float32, suffix string) string {
|
||||
func hugoVersion(version float32, patchVersion int, suffix string) string {
|
||||
if patchVersion > 0 {
|
||||
return fmt.Sprintf("%.2g.%d%s", version, patchVersion, suffix)
|
||||
}
|
||||
return fmt.Sprintf("%.2g%s", version, suffix)
|
||||
}
|
||||
|
||||
func hugoVersionNoSuffix(version float32) string {
|
||||
func hugoVersionNoSuffix(version float32, patchVersion int) string {
|
||||
if patchVersion > 0 {
|
||||
return fmt.Sprintf("%.2g.%d", version, patchVersion)
|
||||
}
|
||||
return fmt.Sprintf("%.2g", version)
|
||||
}
|
||||
|
||||
@@ -14,11 +14,15 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestHugoVersion(t *testing.T) {
|
||||
assert.Equal(t, "0.15-DEV", hugoVersion(0.15, "-DEV"))
|
||||
assert.Equal(t, "0.17", hugoVersionNoSuffix(0.16+0.01))
|
||||
assert.Equal(t, "0.15-DEV", hugoVersion(0.15, 0, "-DEV"))
|
||||
assert.Equal(t, "0.17", hugoVersionNoSuffix(0.16+0.01, 0))
|
||||
|
||||
assert.Equal(t, "0.15.2-DEV", hugoVersion(0.15, 2, "-DEV"))
|
||||
assert.Equal(t, "0.17.3", hugoVersionNoSuffix(0.16+0.01, 3))
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ func (h *HugoSites) assignMissingTranslations() error {
|
||||
// Assign translations
|
||||
for _, t1 := range nodes {
|
||||
for _, t2 := range nodes {
|
||||
if t2.isNewTranslation(t1) {
|
||||
if t1.isNewTranslation(t2) {
|
||||
t1.translations = append(t1.translations, t2)
|
||||
}
|
||||
}
|
||||
@@ -225,6 +225,9 @@ func (h *HugoSites) createMissingPages() error {
|
||||
foundTaxonomyPage := false
|
||||
foundTaxonomyTermsPage := false
|
||||
for key := range tax {
|
||||
if s.Info.preserveTaxonomyNames {
|
||||
key = s.Info.pathSpec.MakePathSanitized(key)
|
||||
}
|
||||
for _, p := range taxonomyPages {
|
||||
if p.sections[0] == plural && p.sections[1] == key {
|
||||
foundTaxonomyPage = true
|
||||
|
||||
@@ -186,6 +186,49 @@ func assertFileContentRegexp(t *testing.T, filename string, defaultInSubDir bool
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultiSitesWithTwoLanguages(t *testing.T) {
|
||||
testCommonResetState()
|
||||
|
||||
viper.Set("defaultContentLanguage", "nn")
|
||||
|
||||
writeSource(t, "config.toml", `
|
||||
[languages]
|
||||
[languages.nn]
|
||||
languageName = "Nynorsk"
|
||||
weight = 1
|
||||
title = "Tittel på Nynorsk"
|
||||
|
||||
[languages.en]
|
||||
title = "Title in English"
|
||||
languageName = "English"
|
||||
weight = 2
|
||||
`,
|
||||
)
|
||||
|
||||
if err := LoadGlobalConfig("", "config.toml"); err != nil {
|
||||
t.Fatalf("Failed to load config: %s", err)
|
||||
}
|
||||
|
||||
// Add some data
|
||||
writeSource(t, "data/hugo.toml", "slogan = \"Hugo Rocks!\"")
|
||||
|
||||
sites, err := NewHugoSitesFromConfiguration()
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create sites: %s", err)
|
||||
}
|
||||
|
||||
require.NoError(t, sites.Build(BuildCfg{}))
|
||||
require.Len(t, sites.Sites, 2)
|
||||
|
||||
nnSite := sites.Sites[0]
|
||||
nnSiteHome := nnSite.getPage(KindHome)
|
||||
require.Len(t, nnSiteHome.AllTranslations(), 2)
|
||||
require.Len(t, nnSiteHome.Translations(), 1)
|
||||
require.True(t, nnSiteHome.IsTranslated())
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
func TestMultiSitesBuild(t *testing.T) {
|
||||
for _, config := range []struct {
|
||||
|
||||
@@ -33,12 +33,14 @@ import (
|
||||
*/
|
||||
|
||||
func TestNodesAsPage(t *testing.T) {
|
||||
for _, ugly := range []bool{false, true} {
|
||||
doTestNodeAsPage(t, ugly)
|
||||
for _, preserveTaxonomyNames := range []bool{false, true} {
|
||||
for _, ugly := range []bool{true, false} {
|
||||
doTestNodeAsPage(t, ugly, preserveTaxonomyNames)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func doTestNodeAsPage(t *testing.T, ugly bool) {
|
||||
func doTestNodeAsPage(t *testing.T, ugly, preserveTaxonomyNames bool) {
|
||||
//jww.SetStdoutThreshold(jww.LevelDebug)
|
||||
jww.SetStdoutThreshold(jww.LevelFatal)
|
||||
|
||||
@@ -55,6 +57,7 @@ func doTestNodeAsPage(t *testing.T, ugly bool) {
|
||||
testCommonResetState()
|
||||
|
||||
viper.Set("uglyURLs", ugly)
|
||||
viper.Set("preserveTaxonomyNames", preserveTaxonomyNames)
|
||||
|
||||
writeLayoutsForNodeAsPageTests(t)
|
||||
writeNodePagesForNodeAsPageTests("", t)
|
||||
@@ -86,6 +89,7 @@ func doTestNodeAsPage(t *testing.T, ugly bool) {
|
||||
|
||||
h := s.owner
|
||||
nodes := h.findAllPagesByKindNotIn(KindPage)
|
||||
|
||||
require.Len(t, nodes, 6)
|
||||
|
||||
home := nodes[5] // oldest
|
||||
@@ -139,6 +143,10 @@ func doTestNodeAsPage(t *testing.T, ugly bool) {
|
||||
"Lastmod: 2009-01-09",
|
||||
)
|
||||
|
||||
web := s.getPage(KindTaxonomy, "categories", "web")
|
||||
require.NotNil(t, web)
|
||||
require.Len(t, web.Data["Pages"].(Pages), 4)
|
||||
|
||||
assertFileContent(t, expectedFilePath(ugly, "public", "categories", "web"), false,
|
||||
"Taxonomy Title: Taxonomy Web",
|
||||
"Taxonomy Web <strong>Content!</strong>",
|
||||
@@ -222,6 +230,19 @@ func doTestNodesWithNoContentFile(t *testing.T, ugly bool) {
|
||||
"Taxonomy Terms Title: Categories",
|
||||
)
|
||||
|
||||
pages := s.findPagesByKind(KindTaxonomyTerm)
|
||||
for _, p := range pages {
|
||||
var want string
|
||||
if ugly {
|
||||
want = "/" + p.Site.pathSpec.URLize(p.Title) + ".html"
|
||||
} else {
|
||||
want = "/" + p.Site.pathSpec.URLize(p.Title) + "/"
|
||||
}
|
||||
if p.URL() != want {
|
||||
t.Errorf("Taxonomy term URL mismatch: want %q, got %q", want, p.URL())
|
||||
}
|
||||
}
|
||||
|
||||
// Sections
|
||||
assertFileContent(t, expectedFilePath(ugly, "public", "sect1"), false,
|
||||
"Section Title: Sect1s",
|
||||
@@ -715,7 +736,7 @@ Lastmod: {{ .Lastmod.Format "2006-01-02" }}
|
||||
Taxonomy Terms Title: {{ .Title }}
|
||||
Taxonomy Terms Content: {{ .Content }}
|
||||
{{ range $key, $value := .Data.Terms }}
|
||||
k/v: {{ $key }} / {{ printf "%s" $value }}
|
||||
k/v: {{ $key | lower }} / {{ printf "%s" $value }}
|
||||
{{ end }}
|
||||
{{ with .Site.Menus.mymenu }}
|
||||
{{ range . }}
|
||||
|
||||
+11
-8
@@ -758,7 +758,7 @@ func (p *Page) createPermalink() (*url.URL, error) {
|
||||
// No permalink config for nodes (currently)
|
||||
pURL := strings.TrimSpace(p.Site.pathSpec.URLize(p.URLPath.URL))
|
||||
pURL = p.addLangPathPrefix(pURL)
|
||||
pURL = p.Site.pathSpec.URLPrep(path.Join(pURL, "index."+p.Extension()))
|
||||
pURL = p.Site.pathSpec.URLPrep(pURL)
|
||||
url := helpers.MakePermalink(baseURL, pURL)
|
||||
return url, nil
|
||||
}
|
||||
@@ -1494,6 +1494,12 @@ func (p *Page) prepareData(s *Site) error {
|
||||
plural := p.sections[0]
|
||||
term := p.sections[1]
|
||||
|
||||
if s.Info.preserveTaxonomyNames {
|
||||
if v, ok := s.taxonomiesOrigKey[fmt.Sprintf("%s-%s", plural, term)]; ok {
|
||||
term = v
|
||||
}
|
||||
}
|
||||
|
||||
singular := s.taxonomiesPluralSingular[plural]
|
||||
taxonomy := s.Taxonomies[plural].Get(term)
|
||||
|
||||
@@ -1626,7 +1632,8 @@ func (p *Page) Lang() string {
|
||||
}
|
||||
|
||||
func (p *Page) isNewTranslation(candidate *Page) bool {
|
||||
if p == candidate || p.Kind != candidate.Kind {
|
||||
|
||||
if p.Kind != candidate.Kind {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -1634,10 +1641,6 @@ func (p *Page) isNewTranslation(candidate *Page) bool {
|
||||
panic("Node type not currently supported for this op")
|
||||
}
|
||||
|
||||
if p.language.Lang == candidate.language.Lang {
|
||||
return false
|
||||
}
|
||||
|
||||
// At this point, we know that this is a traditional Node (home page, section, taxonomy)
|
||||
// It represents the same node, but different language, if the sections is the same.
|
||||
if len(p.sections) != len(candidate.sections) {
|
||||
@@ -1651,8 +1654,8 @@ func (p *Page) isNewTranslation(candidate *Page) bool {
|
||||
}
|
||||
|
||||
// Finally check that it is not already added.
|
||||
for _, translation := range candidate.translations {
|
||||
if p == translation {
|
||||
for _, translation := range p.translations {
|
||||
if candidate == translation {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
+16
-1
@@ -88,6 +88,11 @@ type Site struct {
|
||||
// to get the singular form from that value.
|
||||
taxonomiesPluralSingular map[string]string
|
||||
|
||||
// This is temporary, see https://github.com/spf13/hugo/issues/2835
|
||||
// Maps "actors-gerard-depardieu" to "Gérard Depardieu" when preserveTaxonomyNames
|
||||
// is set.
|
||||
taxonomiesOrigKey map[string]string
|
||||
|
||||
Source source.Input
|
||||
Sections Taxonomy
|
||||
Info SiteInfo
|
||||
@@ -1477,8 +1482,10 @@ func (s *Site) assembleMenus() {
|
||||
func (s *Site) assembleTaxonomies() {
|
||||
s.Taxonomies = make(TaxonomyList)
|
||||
s.taxonomiesPluralSingular = make(map[string]string)
|
||||
s.taxonomiesOrigKey = make(map[string]string)
|
||||
|
||||
taxonomies := s.Language.GetStringMapString("taxonomies")
|
||||
|
||||
jww.INFO.Printf("found taxonomies: %#v\n", taxonomies)
|
||||
|
||||
for singular, plural := range taxonomies {
|
||||
@@ -1496,10 +1503,18 @@ func (s *Site) assembleTaxonomies() {
|
||||
for _, idx := range v {
|
||||
x := WeightedPage{weight.(int), p}
|
||||
s.Taxonomies[plural].add(idx, x, s.Info.preserveTaxonomyNames)
|
||||
if s.Info.preserveTaxonomyNames {
|
||||
// Need to track the original
|
||||
s.taxonomiesOrigKey[fmt.Sprintf("%s-%s", plural, kp(idx))] = idx
|
||||
}
|
||||
}
|
||||
} else if v, ok := vals.(string); ok {
|
||||
x := WeightedPage{weight.(int), p}
|
||||
s.Taxonomies[plural].add(v, x, s.Info.preserveTaxonomyNames)
|
||||
if s.Info.preserveTaxonomyNames {
|
||||
// Need to track the original
|
||||
s.taxonomiesOrigKey[fmt.Sprintf("%s-%s", plural, kp(v))] = v
|
||||
}
|
||||
} else {
|
||||
jww.ERROR.Printf("Invalid %s in %s\n", plural, p.File.Path())
|
||||
}
|
||||
@@ -1808,7 +1823,7 @@ func (s *Site) renderForLayouts(name string, d interface{}, w io.Writer, layouts
|
||||
if err := s.renderThing(d, layout, w); err != nil {
|
||||
|
||||
// Behavior here should be dependent on if running in server or watch mode.
|
||||
distinctErrorLogger.Printf("Error while rendering %s: %.60s…", name, err)
|
||||
distinctErrorLogger.Printf("Error while rendering %q: %s", name, err)
|
||||
if !s.running() && !testMode {
|
||||
// TODO(bep) check if this can be propagated
|
||||
os.Exit(-1)
|
||||
|
||||
@@ -58,7 +58,7 @@ func (s *Site) renderPages() error {
|
||||
|
||||
err := <-errs
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error(s) rendering pages: %.60s…", err)
|
||||
return fmt.Errorf("Error(s) rendering pages: %s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
name: hugo
|
||||
version: "0.18"
|
||||
version: "0.18.1"
|
||||
summary: Fast and Flexible Static Site Generator
|
||||
description: |
|
||||
Hugo is a static HTML and CSS website generator written in Go. It is
|
||||
|
||||
Reference in New Issue
Block a user