Compare commits

..

45 Commits

Author SHA1 Message Date
hugoreleaser 58ac83a98c releaser: Add release notes to /docs for release of 0.76.1
[ci skip]
2020-10-07 07:33:10 +00:00
hugoreleaser 2b8e8e6d96 releaser: Bump versions for release of 0.76.1
[ci skip]
2020-10-07 07:33:10 +00:00
hugoreleaser aef8369865 releaser: Add release notes for 0.76.1
[ci skip]
2020-10-07 07:33:10 +00:00
Bjørn Erik Pedersen f9e798e8c4 langs/i18n: Fix i18n .Count regression
Fixes #7787
2020-10-07 00:32:21 +02:00
digitalcraftsman ee56efffcb Fix typo in 0.76.0 release note 2020-10-06 19:03:36 +02:00
hugoreleaser 2c4e76e962 releaser: Prepare repository for 0.77.0-DEV
[ci skip]
2020-10-06 15:42:25 +00:00
hugoreleaser 9c7d6e475c releaser: Add release notes to /docs for release of 0.76.0
[ci skip]
2020-10-06 15:29:25 +00:00
hugoreleaser 4482958f96 releaser: Bump versions for release of 0.76.0
[ci skip]
2020-10-06 15:29:25 +00:00
Bjørn Erik Pedersen e1ec3bc2b2 Release 0.76.0 2020-10-06 17:21:35 +02:00
hugoreleaser 1cfa63b9ec releaser: Add release notes for 0.76.0
Rename to *-ready.md to continue.
[ci skip]
2020-10-06 17:21:23 +02:00
Bjørn Erik Pedersen b9318e4315 docs: Regen docshelper 2020-10-06 16:25:23 +02:00
Bjørn Erik Pedersen 5e39eb20a6 Merge commit 'e5568488051a571df48401e03f1304b95dbc9028' 2020-10-06 16:24:00 +02:00
Bjørn Erik Pedersen e556848805 Squashed 'docs/' changes from 4895c29c5..9abd3043a
9abd3043a Add docs for shimming JS libraries
6a1c8dcd7 Update sitemap-template.md (#1245)
37c397332 Update frontends.md
a0f86f6df Update configuration.md
bb00cb2c1 Update page-bundles.md
773212de6 Restructure and simplify
fcba7dddf Some minor clarifications of weight sorting
759b967fc Update configuration-markup.md
56708f0b7 module import path remove slash at end
59f4f4acd Doc: Fix typo in hugo command
faacf2e97 Clarify pagination documentation (#1208)
d8eb60887 netlify: Bump to 0.75.1
8cedf6231 Merge branch 'temp751'
188e2bf56 releaser: Add release notes to /docs for release of 0.75.1
c96d4b7a3 Update index.md
1a9d192f7 Update index.md
32731b916 Update index.md
a5bfa0c9a Restore the ... home page
b6850bf96 Release 0.75.0
d6e5e624f releaser: Add release notes to /docs for release of 0.75.0
8cd6b4f47 typo: already -> already
2cb2b22bb Merge commit '534ae9c57a902aea9ed6e62390dec11fa74b7122'
e3525de23 docs: Regen docs helper
fd746dd83 docs: Regenerate CLI docs
e20127980 Add "hugo mod npm pack"
8e82c7ce1 markup/highlight: Add support to linkable line anchors on Chroma
21e94911b markup/asciidocext: Fix AsciiDoc TOC with code
50b8dace5 modules: Add noVendor to module config
d05b541fe modules: Make ignoreVendor a glob pattern
c946082e7 docs: Update replaceRE func
149054341 docs: Update replace func
d917567df docs: Update merge function
f1e093c92 docs: Regen CLI docs
c7bac967d docs: Regen docs helper
7a38f7a45 Merge commit '7d7771b673e5949f554515a2c236b23192c765c8'
1a5a7263a markup/asciidoc: Add support for .TableOfContents

git-subtree-dir: docs
git-subtree-split: 9abd3043a9
2020-10-06 16:22:20 +02:00
Bjørn Erik Pedersen 634938908e pagemeta: Make BuildConfig.Render an enum
Allowing links on pages without rendering them.

Fixes #7783
2020-10-06 14:06:10 +02:00
Bjørn Erik Pedersen c63db7f1f6 Allow cascade to be a slice with a _target discriminator
Fixes #7782
2020-10-06 14:06:10 +02:00
Bjørn Erik Pedersen 5e2a547cb5 Add force flag to server redirects config
Fixes #7778
2020-10-05 22:20:00 +02:00
dependabot[bot] ee090c0940 build(deps): bump github.com/evanw/esbuild from 0.7.8 to 0.7.9
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.7.8 to 0.7.9.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.7.8...v0.7.9)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-05 12:13:46 +02:00
Josh Gerdes edc5c4741c tpl: Add Do Not Track (dnt) option to Vimeo shortcode
Added a Vimeo EnableDNT privacy option to the Hugo config. This will enable the Vimeo 'Do Not Track' flag when either Vimeo shortcode tempalte options are used. When enabled, it will force the Vimeo player to be blocked from tracking any session data, including all cookies and stats.

Fixes #7700
2020-10-02 23:02:38 +02:00
dependabot[bot] 05e358fd33 build(deps): bump github.com/tdewolff/minify/v2 from 2.9.5 to 2.9.7
Bumps [github.com/tdewolff/minify/v2](https://github.com/tdewolff/minify) from 2.9.5 to 2.9.7.
- [Release notes](https://github.com/tdewolff/minify/releases)
- [Commits](https://github.com/tdewolff/minify/compare/v2.9.5...v2.9.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-02 14:09:16 +02:00
dependabot[bot] a2e85d9a75 build(deps): bump github.com/aws/aws-sdk-go from 1.34.34 to 1.35.0
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.34.34 to 1.35.0.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.34.34...v1.35.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-01 12:13:53 +02:00
dependabot[bot] 4fba78dd0e build(deps): bump github.com/getkin/kin-openapi from 0.22.0 to 0.22.1
Bumps [github.com/getkin/kin-openapi](https://github.com/getkin/kin-openapi) from 0.22.0 to 0.22.1.
- [Release notes](https://github.com/getkin/kin-openapi/releases)
- [Commits](https://github.com/getkin/kin-openapi/compare/v0.22.0...v0.22.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-01 12:13:30 +02:00
dependabot[bot] c011b4667f build(deps): bump github.com/aws/aws-sdk-go from 1.34.33 to 1.34.34
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.34.33 to 1.34.34.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.34.33...v1.34.34)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-30 12:13:40 +02:00
dependabot[bot] 35348b4b34 build(deps): bump github.com/evanw/esbuild from 0.7.7 to 0.7.8
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.7.7 to 0.7.8.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.7.7...v0.7.8)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-30 12:13:00 +02:00
dependabot[bot] 34915777c2 build(deps): bump github.com/aws/aws-sdk-go from 1.34.27 to 1.34.33
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.34.27 to 1.34.33.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.34.27...v1.34.33)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-29 19:48:58 +02:00
dependabot[bot] 0f4a837ed1 build(deps): bump github.com/evanw/esbuild from 0.7.4 to 0.7.7
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.7.4 to 0.7.7.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.7.4...v0.7.7)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-29 19:48:21 +02:00
dependabot[bot] b395d686e9 build(deps): bump github.com/tdewolff/minify/v2 from 2.9.4 to 2.9.5
Bumps [github.com/tdewolff/minify/v2](https://github.com/tdewolff/minify) from 2.9.4 to 2.9.5.
- [Release notes](https://github.com/tdewolff/minify/releases)
- [Commits](https://github.com/tdewolff/minify/compare/v2.9.4...v2.9.5)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-29 19:47:59 +02:00
Bjørn Erik Pedersen 97987e5c02 langs/i18n: Upgrade to go-i18n v2
Fixes #5242
2020-09-29 17:48:07 +02:00
Bjørn Erik Pedersen 111344113b publisher: Fix writeStats with quote inside quotes
Fixes #7746
2020-09-28 22:17:36 +02:00
dependabot[bot] 4855c186d8 build(deps): bump github.com/evanw/esbuild from 0.7.2 to 0.7.4
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.7.2 to 0.7.4.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.7.2...v0.7.4)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-24 10:36:14 +02:00
Andrey Sitnik 0c3d2b67e0 Fix CLI example for PostCSS 8 2020-09-22 19:31:02 +02:00
dependabot[bot] 6f07ec7e9e build(deps): bump github.com/aws/aws-sdk-go from 1.34.26 to 1.34.27
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.34.26 to 1.34.27.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.34.26...v1.34.27)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-21 13:24:10 +02:00
dependabot[bot] 4318dc72f8 build(deps): bump github.com/alecthomas/chroma from 0.8.0 to 0.8.1
Bumps [github.com/alecthomas/chroma](https://github.com/alecthomas/chroma) from 0.8.0 to 0.8.1.
- [Release notes](https://github.com/alecthomas/chroma/releases)
- [Changelog](https://github.com/alecthomas/chroma/blob/master/.goreleaser.yml)
- [Commits](https://github.com/alecthomas/chroma/compare/v0.8.0...v0.8.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-21 13:23:46 +02:00
dependabot[bot] acdc27a32d build(deps): bump github.com/evanw/esbuild from 0.7.1 to 0.7.2
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.7.1 to 0.7.2.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.7.1...v0.7.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-21 13:23:01 +02:00
Bjørn Erik Pedersen 3acde9ae04 Make sure CSS is rebuilt when postcss.config.js or tailwind.config.js changes
Fixes #7715
2020-09-20 13:35:41 +02:00
Joe Mooring 473b6610d5 Fix typo in redirect error message 2020-09-19 22:06:54 +02:00
dependabot[bot] 0bce97703c build(deps): bump github.com/aws/aws-sdk-go from 1.34.22 to 1.34.26
Bumps [github.com/aws/aws-sdk-go](https://github.com/aws/aws-sdk-go) from 1.34.22 to 1.34.26.
- [Release notes](https://github.com/aws/aws-sdk-go/releases)
- [Changelog](https://github.com/aws/aws-sdk-go/blob/master/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-go/compare/v1.34.22...v1.34.26)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-19 21:18:16 +02:00
Bjørn Erik Pedersen b254532b52 deps: Update to github.com/tdewolff/minify v2.9.4 2020-09-19 21:17:02 +02:00
Anthony Fok 05a2289292 snap: Bump bundled Node.js from v12.18.3 to v12.18.4
due to CVE-2020-8201, CVE-2020-8251 and CVE-2020-8252,
see https://nodejs.org/en/blog/vulnerability/september-2020-security-releases/
2020-09-18 12:13:31 -06:00
Helder Pereira 8e553dcdef markup/asciidocext: Add preserveTOC option 2020-09-17 10:50:25 +02:00
dependabot[bot] d4fc70a3b3 build(deps): bump github.com/frankban/quicktest from 1.10.2 to 1.11.0
Bumps [github.com/frankban/quicktest](https://github.com/frankban/quicktest) from 1.10.2 to 1.11.0.
- [Release notes](https://github.com/frankban/quicktest/releases)
- [Commits](https://github.com/frankban/quicktest/compare/v1.10.2...v1.11.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-17 09:55:45 +02:00
dependabot[bot] d905abc002 build(deps): bump github.com/evanw/esbuild from 0.6.32 to 0.7.1
Bumps [github.com/evanw/esbuild](https://github.com/evanw/esbuild) from 0.6.32 to 0.7.1.
- [Release notes](https://github.com/evanw/esbuild/releases)
- [Changelog](https://github.com/evanw/esbuild/blob/master/CHANGELOG.md)
- [Commits](https://github.com/evanw/esbuild/compare/v0.6.32...v0.7.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-16 20:52:20 +02:00
dependabot[bot] 8f3946746d build(deps): bump github.com/rogpeppe/go-internal from 1.5.1 to 1.6.2
Bumps [github.com/rogpeppe/go-internal](https://github.com/rogpeppe/go-internal) from 1.5.1 to 1.6.2.
- [Release notes](https://github.com/rogpeppe/go-internal/releases)
- [Commits](https://github.com/rogpeppe/go-internal/compare/v1.5.1...v1.6.2)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-16 20:50:54 +02:00
dependabot[bot] b01b2564ee build(deps): bump github.com/jdkato/prose from 1.1.1 to 1.2.0
Bumps [github.com/jdkato/prose](https://github.com/jdkato/prose) from 1.1.1 to 1.2.0.
- [Release notes](https://github.com/jdkato/prose/releases)
- [Commits](https://github.com/jdkato/prose/compare/v1.1.1...v1.2.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-16 20:50:25 +02:00
dependabot[bot] 9fa5ebe2c4 build(deps): bump github.com/spf13/afero from 1.2.2 to 1.4.0
Bumps [github.com/spf13/afero](https://github.com/spf13/afero) from 1.2.2 to 1.4.0.
- [Release notes](https://github.com/spf13/afero/releases)
- [Commits](https://github.com/spf13/afero/compare/v1.2.2...v1.4.0)

Signed-off-by: dependabot[bot] <support@github.com>
2020-09-16 20:48:25 +02:00
hugoreleaser efaed306b1 releaser: Prepare repository for 0.76.0-DEV
[ci skip]
2020-09-15 07:00:54 +00:00
69 changed files with 1243 additions and 278 deletions
+27 -9
View File
@@ -376,17 +376,36 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, erro
}
if redirect := f.c.serverConfig.MatchRedirect(requestURI); !redirect.IsZero() {
doRedirect := true
// This matches Netlify's behaviour and is needed for SPA behaviour.
// See https://docs.netlify.com/routing/redirects/rewrites-proxies/
if redirect.Status == 200 {
if r2 := f.rewriteRequest(r, strings.TrimPrefix(redirect.To, u.Path)); r2 != nil {
requestURI = redirect.To
r = r2
if !redirect.Force {
path := filepath.Clean(strings.TrimPrefix(requestURI, u.Path))
fi, err := f.c.hugo().BaseFs.PublishFs.Stat(path)
if err == nil {
if fi.IsDir() {
// There will be overlapping directories, so we
// need to check for a file.
_, err = f.c.hugo().BaseFs.PublishFs.Stat(filepath.Join(path, "index.html"))
doRedirect = err != nil
} else {
doRedirect = false
}
}
}
if doRedirect {
if redirect.Status == 200 {
if r2 := f.rewriteRequest(r, strings.TrimPrefix(redirect.To, u.Path)); r2 != nil {
requestURI = redirect.To
r = r2
}
} else {
w.Header().Set("Content-Type", "")
http.Redirect(w, r, redirect.To, redirect.Status)
return
}
} else {
w.Header().Set("Content-Type", "")
http.Redirect(w, r, redirect.To, redirect.Status)
return
}
}
@@ -416,7 +435,6 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, erro
fileserver := decorate(http.FileServer(fs))
mu := http.NewServeMux()
if u.Path == "" || u.Path == "/" {
mu.Handle("/", fileserver)
} else {
+36
View File
@@ -22,6 +22,42 @@ import (
"github.com/gohugoio/hugo/common/types"
)
// TODO(bep) replace the private versions in /tpl with these.
// IsInt returns whether the given kind is a number.
func IsNumber(kind reflect.Kind) bool {
return IsInt(kind) || IsUint(kind) || IsFloat(kind)
}
// IsInt returns whether the given kind is an int.
func IsInt(kind reflect.Kind) bool {
switch kind {
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return true
default:
return false
}
}
// IsUint returns whether the given kind is an uint.
func IsUint(kind reflect.Kind) bool {
switch kind {
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return true
default:
return false
}
}
// IsFloat returns whether the given kind is a float.
func IsFloat(kind reflect.Kind) bool {
switch kind {
case reflect.Float32, reflect.Float64:
return true
default:
return false
}
}
// IsTruthful returns whether in represents a truthful value.
// See IsTruthfulValue
func IsTruthful(in interface{}) bool {
+1 -1
View File
@@ -16,7 +16,7 @@ package hugo
// CurrentVersion represents the current build version.
// This should be the only one.
var CurrentVersion = Version{
Number: 0.75,
Number: 0.76,
PatchLevel: 1,
Suffix: "",
}
+2 -1
View File
@@ -184,6 +184,7 @@ type Redirect struct {
From string
To string
Status int
Force bool
}
func (r Redirect) IsZero() bool {
@@ -206,7 +207,7 @@ func DecodeServer(cfg Provider) (*Server, error) {
// There are some tricky infinite loop situations when dealing
// when the target does not have a trailing slash.
// This can certainly be handled better, but not time for that now.
return nil, errors.Errorf("unspported redirect to value %q in server config; currently this must be either a remote destination or a local folder, e.g. \"/blog/\" or \"/blog/index.html\"", redir.To)
return nil, errors.Errorf("unsupported redirect to value %q in server config; currently this must be either a remote destination or a local folder, e.g. \"/blog/\" or \"/blog/index.html\"", redir.To)
}
s.Redirects[i] = redir
}
+4
View File
@@ -80,6 +80,10 @@ type Twitter struct {
type Vimeo struct {
Service `mapstructure:",squash"`
// When set to true, the Vimeo player will be blocked from tracking any session data,
// including all cookies and stats.
EnableDNT bool
// If simple mode is enabled, only a thumbnail is fetched from i.vimeocdn.com and
// shown with a play button overlaid. If a user clicks the button, he/she will
// be taken to the video page on vimeo.com in a new browser tab.
+2 -1
View File
@@ -45,6 +45,7 @@ enableDNT = true
simple = true
[privacy.vimeo]
disable = true
enableDNT = true
simple = true
[privacy.youtube]
disable = true
@@ -63,7 +64,7 @@ simple = true
pc.GoogleAnalytics.RespectDoNotTrack, pc.GoogleAnalytics.AnonymizeIP,
pc.GoogleAnalytics.UseSessionStorage, pc.Instagram.Disable,
pc.Instagram.Simple, pc.Twitter.Disable, pc.Twitter.EnableDNT,
pc.Twitter.Simple, pc.Vimeo.Disable, pc.Vimeo.Simple,
pc.Twitter.Simple, pc.Vimeo.Disable, pc.Vimeo.EnableDNT, pc.Vimeo.Simple,
pc.YouTube.PrivacyEnhanced, pc.YouTube.Disable,
}
+1 -1
View File
@@ -66,7 +66,7 @@ type Deps struct {
FileCaches filecache.Caches
// The translation func to use
Translate func(translationID string, args ...interface{}) string `json:"-"`
Translate func(translationID string, templateData interface{}) string `json:"-"`
// The language in use. TODO(bep) consolidate with site
Language *langs.Language
+4
View File
@@ -51,6 +51,7 @@ enableDNT = false
simple = false
[privacy.vimeo]
disable = false
enableDNT = false
simple = false
[privacy.youtube]
disable = false
@@ -128,6 +129,9 @@ privacyEnhanced
### Vimeo
enableDNT
: Enabling this for the vimeo shortcode, the Vimeo player will be blocked from tracking any session data, including all cookies and stats.
simple
: If simple mode is enabled, the video thumbnail is fetched from Vimeo's servers and it is overlayed with a play button. If the user clicks to play the video, it will open in a new tab directly on Vimeo's website.
@@ -20,13 +20,24 @@ They are stored in a reserved Front Matter object named `_build` with the follow
```yaml
_build:
render: true
render: always
list: always
publishResources: true
```
#### render
If true, the page will be treated as a published page, holding its dedicated output files (`index.html`, etc...) and permalink.
If `always`, the page will be treated as a published page, holding its dedicated output files (`index.html`, etc...) and permalink.
{{< new-in "0.76.0" >}} We extended this property from a boolean to an enum in Hugo 0.76.0. Valid values are:
never
: The page will not be included in any page collection.
always (default)
: The page will be rendered to disk and get a `RelPermalink` etc.
link
: The page will be not be rendered to disk, but will get a `RelPermalink`.
#### list
+34 -19
View File
@@ -43,7 +43,7 @@ The `markup identifier` is fetched from either the `markup` variable in front ma
## External Helpers
Some of the formats in the table above needs external helpers installed on your PC. For example, for AsciiDoc files,
Some of the formats in the table above need external helpers installed on your PC. For example, for AsciiDoc files,
Hugo will try to call the `asciidoctor` command. This means that you will have to install the associated
tool on your machine to be able to use these formats.
@@ -69,33 +69,48 @@ The Asciidoctor community offers a wide set of tools for the AsciiDoc format tha
[See the Asciidoctor docs for installation instructions](https://asciidoctor.org/docs/install-toolchain/). Make sure that also all
optional extensions like `asciidoctor-diagram` or `asciidoctor-html5s` are installed if required.
Asciidoctor parameters can be customized in Hugo:
{{% note %}}
External `asciidoctor` command requires Hugo rendering to _disk_ to a specific destination directory. It is required to run Hugo with the command option `--destination`.
{{% /note %}}
Parameter | Default | Comment
--- | --- | ---
backend | `html5` | Don't change this unless you know what you are doing.
doctype | `article` | Currently supported Document type is `article`.
extensions | | Possible extensions are `asciidoctor-html5s`, `asciidoctor-bibtex`, `asciidoctor-diagram`, `asciidoctor-interdoc-reftext`, `asciidoctor-katex`, `asciidoctor-latex`, `asciidoctor-mathematical`, `asciidoctor-question`, `asciidoctor-rouge`.
attributes | | Variables to be referenced in your `adoc` file. This is a list of variable name/value maps. See [Asciidoctor#attributes](https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#attributes-and-substitutions).
noheaderorfooter | true | Output an embeddable document, which excludes the header, the footer, and everything outside the body of the document. Don't change this unless you know what you are doing.
safemode | `unsafe` | Safe mode level `unsafe`, `safe`, `server` or `secure`. Don't change this unless you know what you are doing.
sectionnumbers | `false` | Auto-number section titles.
verbose | `false` | Verbosely print processing information and configuration file checks to stderr.
trace | `false` | Include backtrace information on errors.
failurelevel | `fatal` | The minimum logging level that triggers a non-zero exit code (failure).
workingfoldercurrent | `false` | Set the working folder to the rendered `adoc` file, so [include](https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#include-files) will work with relative paths. This setting uses the `asciidoctor` cli parameter `--base-dir` and attribute `outdir=`. For rendering [asciidoctor-diagram](https://asciidoctor.org/docs/asciidoctor-diagram/) `workingfoldercurrent` must be set to `true`.
Some [Asciidoctor](https://asciidoctor.org/man/asciidoctor/) parameters can be customized in Hugo:
Parameter | Comment
--- | ---
backend | Don't change this unless you know what you are doing.
doctype | Currently, the only document type supported in Hugo is `article`.
extensions | Possible extensions are `asciidoctor-html5s`, `asciidoctor-bibtex`, `asciidoctor-diagram`, `asciidoctor-interdoc-reftext`, `asciidoctor-katex`, `asciidoctor-latex`, `asciidoctor-mathematical`, `asciidoctor-question`, `asciidoctor-rouge`.
attributes | Variables to be referenced in your AsciiDoc file. This is a list of variable name/value maps. See [Asciidoctor's attributes](https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#attributes-and-substitutions).
noHeaderOrFooter | Output an embeddable document, which excludes the header, the footer, and everything outside the body of the document. Don't change this unless you know what you are doing.
safeMode | Safe mode level `unsafe`, `safe`, `server` or `secure`. Don't change this unless you know what you are doing.
sectionNumbers | Auto-number section titles.
verbose | Verbosely print processing information and configuration file checks to stderr.
trace | Include backtrace information on errors.
failureLevel | The minimum logging level that triggers a non-zero exit code (failure).
Hugo provides additional settings that don't map directly to Asciidoctor's CLI options:
workingFolderCurrent
: Sets the working directory to be the same as that of the AsciiDoc file being processed, so that [include](https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#include-files) will work with relative paths. This setting uses the `asciidoctor` cli parameter `--base-dir` and attribute `outdir=`. For rendering diagrams with [asciidoctor-diagram](https://asciidoctor.org/docs/asciidoctor-diagram/), `workingFolderCurrent` must be set to `true`.
preserveTOC
: By default, Hugo removes the table of contents generated by Asciidoctor and provides it through the built-in variable [`.TableOfContents`](/content-management/toc/) to enable further customization and better integration with the various Hugo themes. This option can be set to `true` to preserve Asciidoctor's TOC in the generated page.
Below are all the AsciiDoc related settings in Hugo with their default values:
{{< code-toggle config="markup.asciidocExt" />}}
Example of how to set extensions and attributes:
```
[markup.asciidocext]
[markup.asciidocExt]
extensions = ["asciidoctor-html5s", "asciidoctor-diagram"]
workingFolderCurrent = true
[markup.asciidocext.attributes]
[markup.asciidocExt.attributes]
my-base-url = "https://example.com/"
my-attribute-name = "my value"
```
Important: External `asciidoctor` requires Hugo rendering to _disk_ to a specific destination folder. It is required to run Hugo with the command option `--destination`!
In a complex Asciidoctor environment it is sometimes helpful to debug the exact call to your external helper with all
parameters. Run Hugo with `-v`. You will get an output like
@@ -159,6 +159,39 @@ show_comments: false
Any node or section can pass down to descendents a set of Front Matter values as long as defined underneath the reserved `cascade` Front Matter key.
### Target Specific Pages
{{< new-in "0.76.0" >}}
Since Hugo 0.76 the `cascade` block can be a slice with a optional `_target` keyword, allowing for multiple `cascade` values targeting different page sets.
{{< code-toggle copy="false" >}}
title ="Blog"
[[cascade]]
background = "yosemite.jpg"
[cascade._target]
path="/blog/**"
lang="en"
kind="page"
[[cascade]]
background = "goldenbridge.jpg"
[cascade._target]
kind="section"
{{</ code-toggle >}}
Keywords available for `_target`:
path
: A [Glob](https://github.com/gobwas/glob) pattern matching the content path below /content. Expects Unix-styled slashes. Note that this is the virtual path, so it starts at the mount root.
kind
: A Glob pattern matching the Page's Kind(s), e.g. "{home,section}".
lang
: A Glob pattern matching the Page's language, e.g. "{en,sv}".
Any of the above can be omitted.
### Example
In `content/blog/_index.md`
@@ -174,6 +207,8 @@ With the above example the Blog section page and its descendents will return `im
- Said descendent has its own `banner` value set
- Or a closer ancestor node has its own `cascade.banner` value set.
## Order Content Through Front Matter
You can assign content-specific `weight` in the front matter of your content. These values are especially useful for [ordering][ordering] in list views. You can use `weight` for ordering of content and the convention of [`<TAXONOMY>_weight`][taxweight] for ordering content within a taxonomy. See [Ordering and Grouping Hugo Lists][lists] to see how `weight` can be used to organize your content in list views.
@@ -135,10 +135,6 @@ A leaf bundle can be made headless by adding below in the Front Matter
headless = true
```
{{% note %}}
Only leaf bundles can be made headless.
{{% /note %}}
There are many use cases of such headless page bundles:
- Shared media galleries
+2 -3
View File
@@ -96,14 +96,13 @@ With the preceding example, even pages with > 400 words *and* `toc` not set to `
Hugo supports table of contents with AsciiDoc content format.
In the header of your content file, specify the AsciiDoc TOC directives, by using the macro or auto style:
In the header of your content file, specify the AsciiDoc TOC directives necessary to ensure that the table of contents is generated. Hugo will use the generated TOC to populate the page variable `.TableOfContents` in the same way as described for Markdown. See example below:
```asciidoc
// <!-- Your front matter up here -->
:toc: macro
:toc:
// Set toclevels to be at least your hugo [markup.tableOfContents.endLevel] config key
:toclevels: 4
toc::[]
== Introduction
@@ -30,6 +30,8 @@ This is the default configuration:
{{< code-toggle config="markup.goldmark" />}}
For details on the extensions, refer to [this section](https://github.com/yuin/goldmark/#built-in-extensions) of the Goldmark documentation
Some settings explained:
unsafe
@@ -67,7 +67,7 @@ In addition to using a single site config file, one can use the `configDir` dire
Considering the structure above, when running `hugo --environment staging`, Hugo will use every settings from `config/_default` and merge `staging`'s on top of those.
{{% note %}}
Default environments are __development__ with `hugo serve` and __production__ with `hugo`.
Default environments are __development__ with `hugo server` and __production__ with `hugo`.
{{%/ note %}}
## All Configuration Settings
@@ -360,10 +360,10 @@ Note that a `status` code of 200 will trigger a [URL rewrite](https://docs.netli
from = "/myspa/**"
to = "/myspa/"
status = 200
force = false
{{< /code-toggle >}}
{{< new-in "0.76.0" >}} Setting `force=true` will make a redirect even if there is existing content in the path. Note that before Hugo 0.76 `force` was the default behaviour, but this is inline with how Netlify does it.
## Configure Title Case
@@ -88,7 +88,7 @@ ignoreConfig
: If enabled, any module configuration file, e.g. `config.toml`, will not be loaded. Note that this will also stop the loading of any transitive module dependencies.
disable
: Set to `true` to disable the module off while keeping any version info in the `go.*` files.
: Set to `true` to disable the module while keeping any version info in the `go.*` files.
{{< gomodules-info >}}
+1 -1
View File
@@ -41,7 +41,7 @@ The easiest way to use a Module for a theme is to import it in the config.
```toml
[module]
[[module.imports]]
path = "github.com/spf13/hyde/"
path = "github.com/spf13/hyde"
```
## Update Modules
+28
View File
@@ -38,6 +38,8 @@ externals [slice]
{{ $externals := slice "react" "react-dom" }}
```
> Marking a package as external doesn't imply that the library can be loaded from a CDN. It simply tells Hugo not to expand/include the package in the JS file.
defines [map]
: Allow to define a set of string replacement to be performed when building. Should be a map where each key is to be replaced by its value.
@@ -66,3 +68,29 @@ Or with options:
{{ $built := resources.Get "scripts/main.js" | js.Build $opts }}
<script type="text/javascript" src="{{ $built.RelPermalink }}" defer></script>
```
#### Shimming a JS library
It's a very common practice to load external libraries using CDN rather than importing all packages in a single JS file, making it bulky. To do the same with Hugo, you'll need to shim the libraries as follows. In this example, `algoliasearch` and `instantsearch.js` will be shimmed.
Firstly, add the following to your project's `package.json`:
```json
{
"browser": {
"algoliasearch/lite": "./public/js/shims/algoliasearch.js",
"instantsearch.js/es/lib/main": "./public/js/shims/instantsearch.js"
}
}
```
What this does is it tells Hugo to look for the listed packages somewhere else. Here we're telling Hugo to look for `algoliasearch/lite` and `instantsearch.js/es/lib/main` in the project's `public/js/shims` folder.
Now we'll need to create the shim JS files which export the global JS variables `module.exports = window.something`. You can create a separate shim JS file in your `assets` directory, and redirect the import paths there if you wish, but a much cleaner way is to create these files on the go, by having the following before your JS is built.
```go-html-template
{{ $a := "module.exports = window.algoliasearch" | resources.FromString "js/shims/algoliasearch.js" }}
{{ $i := "module.exports = window.instantsearch" | resources.FromString "js/shims/instantsearch.js" }}
{{/* Call RelPermalink unnecessarily to generate JS files */}}
{{ $placebo := slice $a.RelPermalink $i.RelPermalink }}
```
That's it! You should now have a browser-friendly JS which can use external JS libraries.
+2 -2
View File
@@ -27,7 +27,7 @@ The resource will be processed using the project's or theme's own `postcss.confi
```
{{% note %}}
Hugo Pipe's PostCSS requires the `postcss-cli` JavaScript package to be installed in the environment (`npm install -g postcss-cli`) along with any PostCSS plugin(s) used (e.g., `npm install -g autoprefixer`).
Hugo Pipe's PostCSS requires the `postcss-cli` JavaScript package to be installed in the environment (`npm install -g postcss postcss-cli`) along with any PostCSS plugin(s) used (e.g., `npm install -g autoprefixer`).
If you are using the Hugo Snap package, PostCSS and plugin(s) need to be installed locally within your Hugo site directory, e.g., `npm install postcss-cli` without the `-g` flag.
{{% /note %}}
@@ -78,4 +78,4 @@ module.exports = {
: []
]
}
```
```
Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

@@ -1,16 +1,15 @@
---
date: 2020-09-14
title: "0.75.0"
description: "0.75.0"
title: "NPM Pack"
description: "Hugo 0.75 comes with a new \"hugo mod npm pack\" command, several improvements re. Hugo Modules and the Node tools, and more."
categories: ["Releases"]
---
Hugo `0.75.0` brings several improvements to Hugo Modules, a new CLI command to bridge the JavaScript dependencies into Hugo, a refresh of the versions of the most important upstream dependencies, and more.
Hugo `0.75.0` brings several improvements to Hugo Modules, a new CLI command to bridge the JavaScript dependencies into Hugo, a refresh of the versions of the most important upstream dependencies, and more. There are also some good bug fixes in this release. One notable one is covered by [this commit](https://github.com/gohugoio/hugo/commit/4055c121847847d8bd6b95a928185daee065091b) -- which covers a "stale content scenario in server" when you include content or page data via `GetPage` from a shortcode.
## NPM Pack
The new CLI command is called `hugo mod npm pack`. We have marked it as experimental. It works great, go ahead and use it, but we need to test this out in real projects to get a feel of it; it is likely that it will change/improve in the upcoming versions of Hugo. The command creates a consolidated `package.json` from the project and all of its [theme components](https://gohugo.io/hugo-modules/theme-components/). On version conflicts, the version closest to the project is selected. We may revise that strategy in the future ([minimal version selection](https://about.sourcegraph.com/blog/the-pain-that-minimal-version-selection-solves/) maybe?), but this should give both control and the least amount of surprise for the site owner.
So, why did we do this? JavaScript is often a background actor in a Hugo project, and it doesn't make sense to publish it to a NPM registry. The JS dependencies are mostly build tools (PostCSS, TailwindCSS, Babel), `devDependencies`. This has been working fine as long as you kept the JS config files (including `package.json`) in the project, adding duplication/work when using ready-to-use theme components. These tools work best when you have everything below a single file tree, which is very much different to how [Hugo Modules](https://gohugo.io/hugo-modules/) work. An example of a module with TailwindCSS:
@@ -44,7 +43,7 @@ const tailwind = require('tailwindcss')(tailwindConfig);
* We have added a `noVendor` Glob pattern config to the module config [d4611c43](https://github.com/gohugoio/hugo/commit/d4611c4322dabfd8d2520232be578388029867db) [@bep](https://github.com/bep) [#7647](https://github.com/gohugoio/hugo/issues/7647). This allows you to only vendor a subset of your dependencies.
* We have added `ignoreImports` option to module imports config [20af9a07](https://github.com/gohugoio/hugo/commit/20af9a078189ce1e92a1d2047c90fba2a4e91827) [@bep](https://github.com/bep) [#7646](https://github.com/gohugoio/hugo/issues/7646), which allows you to import a module and load its config, but not follow its imports.
* We have deprecated `--ignoreVendor` in favour of a `--ignoreVendor`, a patch matching Glob pattern [9a1e6d15](https://github.com/gohugoio/hugo/commit/9a1e6d15a31ec667b2ff9cf20e43b1daca61e004) [@bep](https://github.com/bep). A typical use for this would be when you have vendored your dependencies, but want to edit one of them.
* We have deprecated `--ignoreVendor` in favour of a `--ignoreVendorPaths`, a patch matching Glob pattern [9a1e6d15](https://github.com/gohugoio/hugo/commit/9a1e6d15a31ec667b2ff9cf20e43b1daca61e004) [@bep](https://github.com/bep). A typical use for this would be when you have vendored your dependencies, but want to edit one of them.
## Statistics
@@ -62,6 +61,10 @@ Hugo now has:
* 438+ [contributors](https://github.com/gohugoio/hugo/graphs/contributors)
* 352+ [themes](http://themes.gohugo.io/)
## Notes
* We now build with Go 1.15, which means that we no longer build release binaries for MacOS 32-bit.
* You may now get an error message about "error calling partial: partials that returns a value needs a non-zero argument.". This error situation was not caught earlier, and comes from a limitation in Go's templates: If you use the `return` keyword in a partial, the argument you pass to that partial (e.g. the ".") cannot be zero (and 0 and "" is considered a zero argument).
## Enhancements
### Templates
@@ -0,0 +1,111 @@
---
date: 2020-10-06
title: "0.76.0"
description: "0.76.0"
categories: ["Releases"]
---
In **Hugo 0.76.0** you can now have a list of [cascade](https://gohugo.io/content-management/front-matter#front-matter-cascade) blocks per page and a new `_target` keyword where you can select which pages to _cascade_ upon using [Glob](https://github.com/gobwas/glob) patterns for a `Page`'s `Kind`, `Lang` and/or `Path`:
```toml
title ="Blog"
[[cascade]]
background = "yosemite.jpg"
[cascade._target]
path="/blog/**"
lang="en"
kind="page"
[[cascade]]
background = "goldenbridge.jpg"
[cascade._target]
kind="section"
```
Tasks that were earlier hard/borderline impossible to do are now simple. One common example would to apply a different template set to nested sections; you can now apply a custom `Type` to these sections using `path="/blog/*/**"` and similar.
A related improvement is that the [build option](https://gohugo.io/content-management/build-options/#readout) `render` is now an enum. In addition to turning on/off rendering of a given page you can tell Hugo to not render, but you want to preserve the `.Permalink`, useful for SPA applications.
This release represents **35 contributions by 8 contributors** to the main Hugo code base.[@dependabot[bot]](https://github.com/apps/dependabot) leads the Hugo development with a significant amount of contributions, but also a big shoutout to [@bep](https://github.com/bep), [@ai](https://github.com/ai), and [@jmooring](https://github.com/jmooring) for their ongoing contributions.
And a big thanks to [@digitalcraftsman](https://github.com/digitalcraftsman) for his relentless work on keeping the themes site in pristine condition and to [@davidsneighbour](https://github.com/davidsneighbour), [@coliff](https://github.com/coliff) and [@kaushalmodi](https://github.com/kaushalmodi) for all the great work on the documentation site.
Many have also been busy writing and fixing the documentation in [hugoDocs](https://github.com/gohugoio/hugoDocs),
which has received **11 contributions by 6 contributors**. A special thanks to [@amdw](https://github.com/amdw), [@davidsneighbour](https://github.com/davidsneighbour), [@samrobbins85](https://github.com/samrobbins85), and [@yaythomas](https://github.com/yaythomas) for their work on the documentation site.
Hugo now has:
* 47025+ [stars](https://github.com/gohugoio/hugo/stargazers)
* 438+ [contributors](https://github.com/gohugoio/hugo/graphs/contributors)
* 354+ [themes](http://themes.gohugo.io/)
## Notes
We have added a `force` flag to the [server redirects](https://gohugo.io/getting-started/configuration/#configure-server) configuration, configuring whether to override any existing content in the path or not. This is inline with how [Netlify](https://docs.netlify.com/routing/redirects/#syntax-for-the-netlify-configuration-file) does it.
This is set to default `false`. If you want the old behaviour you need to add this flag to your configuration:
```toml
[[redirects]]
from = "/myspa/**"
to = "/myspa/"
status = 200
force = true
```
## Enhancements
### Templates
* Add Do Not Track (dnt) option to Vimeo shortcode [edc5c474](https://github.com/gohugoio/hugo/commit/edc5c4741caaee36ba4d42b5947c195a3e02e6aa) [@joshgerdes](https://github.com/joshgerdes) [#7700](https://github.com/gohugoio/hugo/issues/7700)
### Other
* Regen docshelper [b9318e43](https://github.com/gohugoio/hugo/commit/b9318e4315d9112f727140c0950d8836bf26eb87) [@bep](https://github.com/bep)
* Make BuildConfig.Render an enum [63493890](https://github.com/gohugoio/hugo/commit/634938908ec8f393b9a05d26b4cfe19ca7abb0d0) [@bep](https://github.com/bep) [#7783](https://github.com/gohugoio/hugo/issues/7783)
* Allow cascade to be a slice with a _target discriminator [c63db7f1](https://github.com/gohugoio/hugo/commit/c63db7f1f6774a2d661af1d8197c6fe377e3ad25) [@bep](https://github.com/bep) [#7782](https://github.com/gohugoio/hugo/issues/7782)
* Add force flag to server redirects config [5e2a547c](https://github.com/gohugoio/hugo/commit/5e2a547cb594b31ecb0f089b08db2e15c6dc381a) [@bep](https://github.com/bep) [#7778](https://github.com/gohugoio/hugo/issues/7778)
* bump github.com/evanw/esbuild from 0.7.8 to 0.7.9 [ee090c09](https://github.com/gohugoio/hugo/commit/ee090c0940cdbf636e3a55a40b41612d92b9c62d) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/tdewolff/minify/v2 from 2.9.5 to 2.9.7 [05e358fd](https://github.com/gohugoio/hugo/commit/05e358fd335bcb5c7bdc2783ab0c17ec42667df6) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/aws/aws-sdk-go from 1.34.34 to 1.35.0 [a2e85d9a](https://github.com/gohugoio/hugo/commit/a2e85d9a75aca59fd720cce6561ff64997858cd2) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/getkin/kin-openapi from 0.22.0 to 0.22.1 [4fba78dd](https://github.com/gohugoio/hugo/commit/4fba78dd0e950742132954a5d24629e4adfa1bb1) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/aws/aws-sdk-go from 1.34.33 to 1.34.34 [c011b466](https://github.com/gohugoio/hugo/commit/c011b4667f3e1e3c6ecea2fe8f251578884c53b6) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/evanw/esbuild from 0.7.7 to 0.7.8 [35348b4b](https://github.com/gohugoio/hugo/commit/35348b4b343600ec24b1eb1a06f4d3c59199df25) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/aws/aws-sdk-go from 1.34.27 to 1.34.33 [34915777](https://github.com/gohugoio/hugo/commit/34915777c2e8bc1457ff90d09cf814d494d9eece) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/evanw/esbuild from 0.7.4 to 0.7.7 [0f4a837e](https://github.com/gohugoio/hugo/commit/0f4a837ed1fd903bb6740b512683528ddb917918) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/tdewolff/minify/v2 from 2.9.4 to 2.9.5 [b395d686](https://github.com/gohugoio/hugo/commit/b395d686e9a77bf4e0d587ee9a3af4ae6e1aee02) [@dependabot[bot]](https://github.com/apps/dependabot)
* Upgrade to go-i18n v2 [97987e5c](https://github.com/gohugoio/hugo/commit/97987e5c0254e35668dca7f89e67b79553e617c8) [@bep](https://github.com/bep) [#5242](https://github.com/gohugoio/hugo/issues/5242)
* bump github.com/evanw/esbuild from 0.7.2 to 0.7.4 [4855c186](https://github.com/gohugoio/hugo/commit/4855c186d8f05e5e1b0f681b4aa6482a033df241) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/aws/aws-sdk-go from 1.34.26 to 1.34.27 [6f07ec7e](https://github.com/gohugoio/hugo/commit/6f07ec7e9ec5c43f78100aa36b82786ba0260d75) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/alecthomas/chroma from 0.8.0 to 0.8.1 [4318dc72](https://github.com/gohugoio/hugo/commit/4318dc72f8c562b3bc106cd953d9fce58a93455d) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/evanw/esbuild from 0.7.1 to 0.7.2 [acdc27a3](https://github.com/gohugoio/hugo/commit/acdc27a32de83f32557e7a108797ddbebe4eb464) [@dependabot[bot]](https://github.com/apps/dependabot)
* Make sure CSS is rebuilt when postcss.config.js or tailwind.config.js changes [3acde9ae](https://github.com/gohugoio/hugo/commit/3acde9ae04fbf4a8c635d404608cb87218a8b803) [@bep](https://github.com/bep) [#7715](https://github.com/gohugoio/hugo/issues/7715)
* bump github.com/aws/aws-sdk-go from 1.34.22 to 1.34.26 [0bce9770](https://github.com/gohugoio/hugo/commit/0bce97703c17318b13b95d78ba41f40efb06aea7) [@dependabot[bot]](https://github.com/apps/dependabot)
* Update to github.com/tdewolff/minify v2.9.4 [b254532b](https://github.com/gohugoio/hugo/commit/b254532b52785954c98a473a635b9cea016d8565) [@bep](https://github.com/bep)
* Bump bundled Node.js from v12.18.3 to v12.18.4 [05a22892](https://github.com/gohugoio/hugo/commit/05a22892921bd4618efe6135ce0d6fe2be545607) [@anthonyfok](https://github.com/anthonyfok)
* Add preserveTOC option [8e553dcd](https://github.com/gohugoio/hugo/commit/8e553dcdefe50ab534f1199c006ae7754e14bee5) [@helfper](https://github.com/helfper)
* bump github.com/frankban/quicktest from 1.10.2 to 1.11.0 [d4fc70a3](https://github.com/gohugoio/hugo/commit/d4fc70a3b320a55c4f571eed806d5ad5fdf1ef14) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/evanw/esbuild from 0.6.32 to 0.7.1 [d905abc0](https://github.com/gohugoio/hugo/commit/d905abc002aa6fd260e82063ef1edb8876aa76fd) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/rogpeppe/go-internal from 1.5.1 to 1.6.2 [8f394674](https://github.com/gohugoio/hugo/commit/8f3946746dda444f183ba235288c2b39d0d6a943) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/jdkato/prose from 1.1.1 to 1.2.0 [b01b2564](https://github.com/gohugoio/hugo/commit/b01b2564eefe342c9bf9767ffc256ebd04b94c71) [@dependabot[bot]](https://github.com/apps/dependabot)
* bump github.com/spf13/afero from 1.2.2 to 1.4.0 [9fa5ebe2](https://github.com/gohugoio/hugo/commit/9fa5ebe2c42fbb37d066ffcd36bad4d08efe879a) [@dependabot[bot]](https://github.com/apps/dependabot)
* Preserve the original package.json if it exists [214afe4c](https://github.com/gohugoio/hugo/commit/214afe4c1bb9c37bc6159e659d66ba9a268a2849) [@bep](https://github.com/bep) [#7690](https://github.com/gohugoio/hugo/issues/7690)
## Fixes
### Templates
* Fix grammar in the new 'requires non-zero' error message [cd830bb0](https://github.com/gohugoio/hugo/commit/cd830bb0275fc39240861627ef26e146985b5c86) [@nekr0z](https://github.com/nekr0z)
### Other
* Fix writeStats with quote inside quotes [11134411](https://github.com/gohugoio/hugo/commit/111344113bf8c16ae45528d67ff408da15961727) [@bep](https://github.com/bep) [#7746](https://github.com/gohugoio/hugo/issues/7746)
* Fix CLI example for PostCSS 8 [0c3d2b67](https://github.com/gohugoio/hugo/commit/0c3d2b67e0af38a4c3935fb04f722a73ec1d3f8b) [@ai](https://github.com/ai)
* Fix typo in redirect error message [473b6610](https://github.com/gohugoio/hugo/commit/473b6610d51d4a33ba35917f95b0d97ea78dad2b) [@jmooring](https://github.com/jmooring)
* Fix nilpointer for images with no Exif [cd00f7f9](https://github.com/gohugoio/hugo/commit/cd00f7f9661d67951ef16c5198541f09f1c058b4) [@bep](https://github.com/bep) [#7688](https://github.com/gohugoio/hugo/issues/7688)
@@ -0,0 +1,20 @@
---
date: 2020-10-07
title: "Hugo 0.76.1: A couple of Bug Fixes"
description: "This version fixes a couple of bugs introduced in 0.76.0."
categories: ["Releases"]
images:
- images/blog/hugo-bug-poster.png
---
This is a bug-fix release with a couple of important fixes.
* langs/i18n: Fix i18n .Count regression [f9e798e8](https://github.com/gohugoio/hugo/commit/f9e798e8c4234bd60277e3cb10663ba254d4ecb7) [@bep](https://github.com/bep) [#7787](https://github.com/gohugoio/hugo/issues/7787)
* Fix typo in 0.76.0 release note [ee56efff](https://github.com/gohugoio/hugo/commit/ee56efffcb3f81120b0d3e0297b4fb5966124354) [@digitalcraftsman](https://github.com/digitalcraftsman)
+7 -1
View File
@@ -43,10 +43,16 @@ Setting `Paginate` to a positive value will split the list pages for the homepag
There are two ways to configure and use a `.Paginator`:
1. The simplest way is just to call `.Paginator.Pages` from a template. It will contain the pages for *that page*.
2. Select a subset of the pages with the available template functions and ordering options, and pass the slice to `.Paginate`, e.g. `{{ range (.Paginate ( first 50 .Pages.ByTitle )).Pages }}`.
2. Select another set of pages with the available template functions and ordering options, and pass the slice to `.Paginate`, e.g.
* `{{ range (.Paginate ( first 50 .Pages.ByTitle )).Pages }}` or
* `{{ range (.Paginate .RegularPagesRecursive).Pages }}`.
For a given **Page**, it's one of the options above. The `.Paginator` is static and cannot change once created.
If you call `.Paginator` or `.Paginate` multiple times on the same page, you should ensure all the calls are identical. Once *either* `.Paginator` or `.Paginate` is called while generating a page, its result is cached, and any subsequent similar call will reuse the cached result. This means that any such calls which do not match the first one will not behave as written.
(Remember that function arguments are eagerly evaluated, so a call like `$paginator := cond x .Paginator (.Paginate .RegularPagesRecursive)` is an example of what you should *not* do. Use `if`/`else` instead to ensure exactly one evaluation.)
The global page size setting (`Paginate`) can be overridden by providing a positive integer as the last argument. The examples below will give five items per page:
* `{{ range (.Paginator 5).Pages }}`
@@ -43,7 +43,7 @@ For multilingual sites, we also create a Sitemap index. You can provide a custom
## Hugos sitemap.xml
This template respects the version 0.9 of the [Sitemap Protocol](https://www.sitemaps.org/protocol.html).
This template respects the version 1.0 of the [Sitemap Protocol](https://www.sitemaps.org/protocol.html).
```xml
{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\" ?>" | safeHTML }}
@@ -158,11 +158,11 @@ Hugo uses both `date` and `weight` to order content within taxonomies.
Each piece of content in Hugo can optionally be assigned a date. It can also be assigned a weight for each taxonomy it is assigned to.
When iterating over content within taxonomies, the default sort is the same as that used for section and list pages first by weight then by date. This means that if the weights for two pieces of content are the same, then the more recent content will be displayed first.
When iterating over content within taxonomies, the default sort is the same as that used for section and list pages: first by weight, then by date. This means that if the weights for two pieces of content are the same, then the more recent content will be displayed first.
The default weight for any piece of content is 0.
The default weight for any piece of content is 0. Zero means "does not have a weight", not "has a weight of numerical value zero".
Weights of zero are treated specially: if two pages have unequal weights, and one of them is zero, then the zero-weighted page will always appear after the other one, regardless of the other's weight. Zero weights should thus be used with care: for example, if both positive and negative weights are used to extend a sequence in both directions, a zero-weighted page will appear not in the middle of the list, but at the end.
Weights of zero are thus treated specially: if two pages have unequal weights, and one of them is zero, then the zero-weighted page will always appear after the other one, regardless of the other's weight. Zero weights should thus be used with care: for example, if both positive and negative weights are used to extend a sequence in both directions, a zero-weighted page will appear not in the middle of the list, but at the end.
### Assign Weight
+1 -2
View File
@@ -30,5 +30,4 @@ toc: false
* **Features:** inline PageDown editor, visual tree view, image upload and digital asset management with Cloudinary, site preview, continuous integration with GitHub, atomic deploy and hosting, Git and Hugo integration, autosave, custom domain, project syncing, theme cloning and management. Developers have complete control over the source code and can manage it with GitHubs deceptively simple workflow.
* [DATOCMS](https://www.datocms.com) DatoCMS is a fully customizable administrative area for your static websites. Use your favorite website generator, let your clients publish new content independently, and the host the site anywhere you like.
* [Forestry.io](https://forestry.io/). Forestry is a git-backed CMS for Hugo, Gatsby, Jekyll and VuePress websites with support for GitHub, GitLab, Bitbucket and Azure Devops. Forestry provides a nice user interface to edit and model content for non technical editors. It supports S3, Cloudinary and Netlify Large Media integrations for storing media. Every time an update is made via the CMS, Forestry will commit changes back to your repo and vice-versa.
* [Netlify.com](https://www.netlify.com). Netlify builds, deploys, and hosts your static website or app (Hugo, Jekyll, etc). Netlify offers a drag-and-drop interface and automatic deployments from GitHub or Bitbucket.
* **Features:** global CDN, atomic deploys, ultra-fast DNS, instant cache invalidation, high availability, automated hosting, Git integration, form submission hooks, authentication providers, and custom domains. Developers have complete control over the source code and can manage it with GitHub or Bitbucket's deceptively simple workflow.
+12 -6
View File
@@ -1535,7 +1535,8 @@
"verbose": false,
"trace": false,
"failureLevel": "fatal",
"workingFolderCurrent": false
"workingFolderCurrent": false,
"preserveTOC": false
}
},
"minify": {
@@ -1556,13 +1557,18 @@
"keepWhitespace": false
},
"css": {
"decimals": -1,
"keepCSS2": true
"keepCSS2": true,
"precision": 0
},
"js": {
"precision": 0,
"keepVarNames": false
},
"json": {
"precision": 0
},
"js": {},
"json": {},
"svg": {
"decimals": -1
"precision": 0
},
"xml": {
"keepWhitespace": false
+4 -4
View File
@@ -3,7 +3,7 @@ publish = "public"
command = "hugo --gc --minify"
[context.production.environment]
HUGO_VERSION = "0.74.3"
HUGO_VERSION = "0.75.1"
HUGO_ENV = "production"
HUGO_ENABLEGITINFO = "true"
@@ -11,20 +11,20 @@ HUGO_ENABLEGITINFO = "true"
command = "hugo --gc --minify --enableGitInfo"
[context.split1.environment]
HUGO_VERSION = "0.74.3"
HUGO_VERSION = "0.75.1"
HUGO_ENV = "production"
[context.deploy-preview]
command = "hugo --gc --minify --buildFuture -b $DEPLOY_PRIME_URL"
[context.deploy-preview.environment]
HUGO_VERSION = "0.74.3"
HUGO_VERSION = "0.75.1"
[context.branch-deploy]
command = "hugo --gc --minify -b $DEPLOY_PRIME_URL"
[context.branch-deploy.environment]
HUGO_VERSION = "0.74.3"
HUGO_VERSION = "0.75.1"
[context.next.environment]
HUGO_ENABLEGITINFO = "true"
+10 -10
View File
@@ -5,27 +5,27 @@ require (
github.com/BurntSushi/toml v0.3.1
github.com/PuerkitoBio/purell v1.1.1
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
github.com/alecthomas/chroma v0.8.0
github.com/alecthomas/chroma v0.8.1
github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1 // indirect
github.com/armon/go-radix v1.0.0
github.com/aws/aws-sdk-go v1.34.22
github.com/aws/aws-sdk-go v1.35.0
github.com/bep/debounce v1.2.0
github.com/bep/gitmap v1.1.2
github.com/bep/golibsass v0.7.0
github.com/bep/tmc v0.5.1
github.com/disintegration/gift v1.2.1
github.com/dustin/go-humanize v1.0.0
github.com/evanw/esbuild v0.6.32
github.com/evanw/esbuild v0.7.9
github.com/fortytw2/leaktest v1.3.0
github.com/frankban/quicktest v1.10.2
github.com/frankban/quicktest v1.11.0
github.com/fsnotify/fsnotify v1.4.9
github.com/getkin/kin-openapi v0.22.0
github.com/getkin/kin-openapi v0.22.1
github.com/ghodss/yaml v1.0.0
github.com/gobwas/glob v0.2.3
github.com/gohugoio/testmodBuilder/mods v0.0.0-20190520184928-c56af20f2e95
github.com/google/go-cmp v0.5.2
github.com/gorilla/websocket v1.4.2
github.com/jdkato/prose v1.1.1
github.com/jdkato/prose v1.2.0
github.com/kyokomi/emoji v2.2.4+incompatible
github.com/magefile/mage v1.10.0
github.com/markbates/inflect v1.0.4
@@ -35,23 +35,23 @@ require (
github.com/mitchellh/mapstructure v1.3.3
github.com/muesli/smartcrop v0.3.0
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect
github.com/nicksnyder/go-i18n v1.10.1
github.com/nicksnyder/go-i18n/v2 v2.1.1
github.com/niklasfasching/go-org v1.3.2
github.com/olekukonko/tablewriter v0.0.4
github.com/pelletier/go-toml v1.6.0 // indirect
github.com/pkg/errors v0.9.1
github.com/rogpeppe/go-internal v1.5.1
github.com/rogpeppe/go-internal v1.6.2
github.com/russross/blackfriday v1.5.3-0.20200218234912-41c5fccfd6f6
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd
github.com/sanity-io/litter v1.3.0
github.com/spf13/afero v1.2.2
github.com/spf13/afero v1.4.0
github.com/spf13/cast v1.3.1
github.com/spf13/cobra v0.0.7
github.com/spf13/fsync v0.9.0
github.com/spf13/jwalterweatherman v1.1.0
github.com/spf13/pflag v1.0.5
github.com/spf13/viper v1.7.1
github.com/tdewolff/minify/v2 v2.6.2
github.com/tdewolff/minify/v2 v2.9.7
github.com/yuin/goldmark v1.2.1
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691
gocloud.dev v0.15.0
+65
View File
@@ -57,6 +57,8 @@ github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyV
github.com/alecthomas/chroma v0.7.2-0.20200305040604-4f3623dce67a/go.mod h1:fv5SzZPFJbwp2NXJWpFIX7DZS4HgV1K4ew4Pc2OZD9s=
github.com/alecthomas/chroma v0.8.0 h1:HS+HE97sgcqjQGu5uVr8jIE55Mmh5UeQ7kckAhHg2pY=
github.com/alecthomas/chroma v0.8.0/go.mod h1:sko8vR34/90zvl5QdcUdvzL3J8NKjAUx9va9jPuFNoM=
github.com/alecthomas/chroma v0.8.1 h1:ym20sbvyC6RXz45u4qDglcgr8E313oPROshcuCHqiEE=
github.com/alecthomas/chroma v0.8.1/go.mod h1:sko8vR34/90zvl5QdcUdvzL3J8NKjAUx9va9jPuFNoM=
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo=
github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0=
github.com/alecthomas/kong v0.1.17-0.20190424132513-439c674f7ae0/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI=
@@ -86,6 +88,16 @@ github.com/aws/aws-sdk-go v1.34.21 h1:M97FXuiJgDHwD4mXhrIZ7RJ4xXV6uZVPvIC2qb+HfY
github.com/aws/aws-sdk-go v1.34.21/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.34.22 h1:7V2sKilVVgHqdjbW+O/xaVWYfnmuLwZdF/+6JuUh6Cw=
github.com/aws/aws-sdk-go v1.34.22/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.34.26 h1:tw4nsSfGvCDnXt2xPe8NkxIrDui+asAWinMknPLEf80=
github.com/aws/aws-sdk-go v1.34.26/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.34.27 h1:qBqccUrlz43Zermh0U1O502bHYZsgMlBm+LUVabzBPA=
github.com/aws/aws-sdk-go v1.34.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/aws/aws-sdk-go v1.34.33 h1:ymkFm0rNPEOlgjyX3ojEd4zqzW6kGICBkqWs7LqgHtU=
github.com/aws/aws-sdk-go v1.34.33/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
github.com/aws/aws-sdk-go v1.34.34 h1:5dC0ZU0xy25+UavGNEkQ/5MOQwxXDA2YXtjCL1HfYKI=
github.com/aws/aws-sdk-go v1.34.34/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
github.com/aws/aws-sdk-go v1.35.0 h1:Pxqn1MWNfBCNcX7jrXCCTfsKpg5ms2IMUMmmcGtYJuo=
github.com/aws/aws-sdk-go v1.35.0/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bep/debounce v1.2.0 h1:wXds8Kq8qRfwAOpAxHrJDbCXgC5aHSzgQb/0gKsHQqo=
@@ -112,6 +124,7 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E=
@@ -137,6 +150,18 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/evanw/esbuild v0.6.32 h1:hVuqC+IgEENPWnr0gic01EFgGCmyW8dUPnr78zC7K5k=
github.com/evanw/esbuild v0.6.32/go.mod h1:mptxmSXIzBIKKCe4jo9A5SToEd1G+AKZ9JmY85dYRJ0=
github.com/evanw/esbuild v0.7.1 h1:bkC9MpDxHPCLESOf3AQzK1QiyaxbnxFa3XLPnyARLSI=
github.com/evanw/esbuild v0.7.1/go.mod h1:mptxmSXIzBIKKCe4jo9A5SToEd1G+AKZ9JmY85dYRJ0=
github.com/evanw/esbuild v0.7.2 h1:LBY35Gw3fKs7jVpsbQwOmw7pJLDHdpliI1Mc/DqP0Hs=
github.com/evanw/esbuild v0.7.2/go.mod h1:mptxmSXIzBIKKCe4jo9A5SToEd1G+AKZ9JmY85dYRJ0=
github.com/evanw/esbuild v0.7.4 h1:mLb2tQ9315u23ulh/5Gg8xejOfgqHs2zm7bDNtNnNcM=
github.com/evanw/esbuild v0.7.4/go.mod h1:mptxmSXIzBIKKCe4jo9A5SToEd1G+AKZ9JmY85dYRJ0=
github.com/evanw/esbuild v0.7.7 h1:l/M5wHuU738LEX8RyGDP7Zkdrw84j3bpCPrJbKX33Ks=
github.com/evanw/esbuild v0.7.7/go.mod h1:mptxmSXIzBIKKCe4jo9A5SToEd1G+AKZ9JmY85dYRJ0=
github.com/evanw/esbuild v0.7.8 h1:DyCpTDLRAtjqRixfXFslGSsYaoKRQfYi+gwGkzW1FHI=
github.com/evanw/esbuild v0.7.8/go.mod h1:mptxmSXIzBIKKCe4jo9A5SToEd1G+AKZ9JmY85dYRJ0=
github.com/evanw/esbuild v0.7.9 h1:jXSoYpNpGkOK1VNx3tvd/KnbVbn5ULRYzvkumXaSkxo=
github.com/evanw/esbuild v0.7.9/go.mod h1:mptxmSXIzBIKKCe4jo9A5SToEd1G+AKZ9JmY85dYRJ0=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fortytw2/leaktest v1.2.0 h1:cj6GCiwJDH7l3tMHLjZDo0QqPtrXJiWSI9JgpeQKw+Q=
github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
@@ -148,6 +173,8 @@ github.com/frankban/quicktest v1.7.2 h1:2QxQoC1TS09S7fhCPsrvqYdvP1H5M1P1ih5ABm3B
github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o=
github.com/frankban/quicktest v1.10.2 h1:19ARM85nVi4xH7xPXuc5eM/udya5ieh7b/Sv+d844Tk=
github.com/frankban/quicktest v1.10.2/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s=
github.com/frankban/quicktest v1.11.0 h1:Yyrghcw93e1jKo4DTZkRFTTFvBsVhzbblBUPNU1vW6Q=
github.com/frankban/quicktest v1.11.0/go.mod h1:K+q6oSqb0W0Ininfk863uOk1lMy69l/P6txr3mVT54s=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
@@ -156,6 +183,8 @@ github.com/getkin/kin-openapi v0.14.0 h1:hqwQL7kze/adt0wB+0UJR2nJm+gfUHqM0Gu4D8n
github.com/getkin/kin-openapi v0.14.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw=
github.com/getkin/kin-openapi v0.22.0 h1:J5IFyKd/5yuB6AZAgwK0CMBKnabWcmkowtsl6bRkz4s=
github.com/getkin/kin-openapi v0.22.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw=
github.com/getkin/kin-openapi v0.22.1 h1:ODA1olTp175o//NfHko/uCAAhwUSfm5P4+K52XvTg4w=
github.com/getkin/kin-openapi v0.22.1/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@@ -258,12 +287,17 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jdkato/prose v1.1.1 h1:r6CwY09U97IZNgNQEHoeCh2nvg2e8WCOGjPH/b7lowI=
github.com/jdkato/prose v1.1.1/go.mod h1:jkF0lkxaX5PFSlk9l4Gh9Y+T57TqUZziWT7uZbW5ADg=
github.com/jdkato/prose v1.2.0 h1:t/R3H6xOrVuIgNevWiOSJf1kEoeF2VWlrN6w76Tkzow=
github.com/jdkato/prose v1.2.0/go.mod h1:WC4YKHtBdAMgBdmfdqBmEuVbBD0U5c9HQ6l1U8Cq0ts=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.3.0 h1:OS12ieG61fsCg5+qLJ+SsW9NicxNkg3b25OyT2yCeUc=
github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@@ -274,6 +308,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -326,6 +361,7 @@ github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8
github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/montanaflynn/stats v0.6.3/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/muesli/smartcrop v0.3.0 h1:JTlSkmxWg/oQ1TcLDoypuirdE8Y/jzNirQeLkxpA6Oc=
github.com/muesli/smartcrop v0.3.0/go.mod h1:i2fCI/UorTfgEpPPLWiFBv4pye+YAG78RwcQLUkocpI=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@@ -333,6 +369,8 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
github.com/nicksnyder/go-i18n v1.10.1 h1:isfg77E/aCD7+0lD/D00ebR2MV5vgeQ276WYyDaCRQc=
github.com/nicksnyder/go-i18n v1.10.1/go.mod h1:e4Di5xjP9oTVrC6y3C7C0HoSYXjSbhh/dU0eUV32nB4=
github.com/nicksnyder/go-i18n/v2 v2.1.1 h1:ATCOanRDlrfKVB4WHAdJnLEqZtDmKYsweqsOUYflnBU=
github.com/nicksnyder/go-i18n/v2 v2.1.1/go.mod h1:d++QJC9ZVf7pa48qrsRWhMJ5pSHIPmS3OLqK1niyLxs=
github.com/niklasfasching/go-org v1.3.2 h1:ZKTSd+GdJYkoZl1pBXLR/k7DRiRXnmB96TRiHmHdzwI=
github.com/niklasfasching/go-org v1.3.2/go.mod h1:AsLD6X7djzRIz4/RFZu8vwRL0VGjUvGZCCH1Nz0VdrU=
github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E=
@@ -356,6 +394,7 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
@@ -378,6 +417,8 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.5.1 h1:asQ0uD7BN9RU5Im41SEEZTwCi/zAXdMOLS3npYaos2g=
github.com/rogpeppe/go-internal v1.5.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.6.2 h1:aIihoIOHCiLZHxyoNQ+ABL4NKhFTgKLBdMLyEAh98m0=
github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/russross/blackfriday v1.5.3-0.20200218234912-41c5fccfd6f6 h1:tlXG832s5pa9x9Gs3Rp2rTvEqjiDEuETUOSfBEiTcns=
github.com/russross/blackfriday v1.5.3-0.20200218234912-41c5fccfd6f6/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
@@ -390,6 +431,7 @@ github.com/sanity-io/litter v1.3.0/go.mod h1:5Z71SvaYy5kcGtyglXOC9rrUi3c1E8CamFW
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/shogo82148/go-shuffle v0.0.0-20180218125048-27e6095f230d/go.mod h1:2htx6lmL0NGLHlO8ZCf+lQBGBHIbEujyywxJArf+2Yc=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
@@ -403,6 +445,8 @@ github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/afero v1.4.0 h1:jsLTaI1zwYO3vjrzHalkVcIHXTNmdQFepW4OI8H3+x8=
github.com/spf13/afero v1.4.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
@@ -432,14 +476,28 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tdewolff/minify/v2 v2.6.2 h1:Jaod6aSABWmhftvnxvXogxcEoQt6yogfFeZgIQEMPOw=
github.com/tdewolff/minify/v2 v2.6.2/go.mod h1:BkDSm8aMMT0ALGmpt7j3Ra7nLUgZL0qhyrAHXwxcy5w=
github.com/tdewolff/minify/v2 v2.9.4 h1:sOqgmowmkZWmHZ0AqIFS300VvCCkgDNTw1eWw1tnNCY=
github.com/tdewolff/minify/v2 v2.9.4/go.mod h1:4SrPavRSPLpv4U4jqV8jzSjiEuq2BH+BPgxorMkGrhc=
github.com/tdewolff/minify/v2 v2.9.5 h1:+fHvqLencVdv14B+zgxQGhetF9qXl/nRTN/1mcyQwpM=
github.com/tdewolff/minify/v2 v2.9.5/go.mod h1:jshtBj/uUJH6JX1fuxTLnnHOA1RVJhF5MM+leJzDKb4=
github.com/tdewolff/minify/v2 v2.9.7 h1:r8ewdcX8VYUoNj+s9WSy4FtNNNqNPevWOkb/MksAtzQ=
github.com/tdewolff/minify/v2 v2.9.7/go.mod h1:AcJ/ggtHex5N/QiafLI8rlIO3qwSlgbPNLi27VZSYz8=
github.com/tdewolff/parse/v2 v2.4.2 h1:Bu2Qv6wepkc+Ou7iB/qHjAhEImlAP5vedzlQRUdj3BI=
github.com/tdewolff/parse/v2 v2.4.2/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
github.com/tdewolff/parse/v2 v2.5.2 h1:OIUAejEkj9Oj6N1q18xg7ByYkpQ0xf4nA1aAH5nqxks=
github.com/tdewolff/parse/v2 v2.5.2/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
github.com/tdewolff/parse/v2 v2.5.3 h1:fnPIstKgEfxd3+wwHnH73sAYydsR0o/jYhcQ6c5PkrA=
github.com/tdewolff/parse/v2 v2.5.3/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
github.com/tdewolff/parse/v2 v2.5.4 h1:ggaQ1SVE8wErRrZwUs49I6iQ1zL/tFlb7KtYsk2I8Yk=
github.com/tdewolff/parse/v2 v2.5.4/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
github.com/tdewolff/test v1.0.6 h1:76mzYJQ83Op284kMT+63iCNCI7NEERsIN8dLM+RiKr4=
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
github.com/tidwall/pretty v0.0.0-20190325153808-1166b9ac2b65/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
@@ -448,6 +506,7 @@ github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex
github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
github.com/uber/jaeger-lib v1.5.0/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I=
@@ -483,6 +542,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20190422183909-d864b10871cd/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -573,6 +633,8 @@ golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 h1:opSr2sbRXk5X5/givKrrKj9HX
golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3 h1:5B6i6EAiSYyejWfvc5Rc9BbI3rzIsrrXfAQBWnYfn+w=
golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c h1:UIcGWL6/wpCfyGuJnRFJRurA+yj8RrW7Q6x2YMCXt6c=
golang.org/x/sys v0.0.0-20200724161237-0e2f3a69832c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
@@ -662,6 +724,7 @@ gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.51.1 h1:GyboHr4UqMiLUybYjd22ZjQIKEJEpgtLXtuGbR21Oho=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/neurosnap/sentences.v1 v1.0.6/go.mod h1:YlK+SN+fLQZj+kY3r8DkGDhDr91+S3JmTb5LSxFRQo0=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
@@ -670,8 +733,10 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+20 -14
View File
@@ -23,30 +23,36 @@ import (
"github.com/gobwas/glob/syntax"
)
type globErr struct {
glob glob.Glob
err error
}
var (
globCache = make(map[string]glob.Glob)
globCache = make(map[string]globErr)
globMu sync.RWMutex
)
func GetGlob(pattern string) (glob.Glob, error) {
var g glob.Glob
var eg globErr
globMu.RLock()
g, found := globCache[pattern]
var found bool
eg, found = globCache[pattern]
globMu.RUnlock()
if !found {
var err error
g, err = glob.Compile(strings.ToLower(pattern), '/')
if err != nil {
return nil, err
}
globMu.Lock()
globCache[pattern] = g
globMu.Unlock()
if found {
return eg.glob, eg.err
}
return g, nil
var err error
g, err := glob.Compile(strings.ToLower(pattern), '/')
eg = globErr{g, err}
globMu.Lock()
globCache[pattern] = eg
globMu.Unlock()
return eg.glob, eg.err
}
+9
View File
@@ -73,5 +73,14 @@ func TestGetGlob(t *testing.T) {
g, err := GetGlob("**.JSON")
c.Assert(err, qt.IsNil)
c.Assert(g.Match("data/my.json"), qt.Equals, true)
}
func BenchmarkGetGlob(b *testing.B) {
for i := 0; i < b.N; i++ {
_, err := GetGlob("**/foo")
if err != nil {
b.Fatal(err)
}
}
}
+69 -1
View File
@@ -229,7 +229,7 @@ Banner: post.jpg`,
counters := &testCounters{}
b.Build(BuildCfg{testCounters: counters})
// As we only changed the content, not the cascade front matter, make
// As we only changed the content, not the cascade front matter,
// only the home page is re-rendered.
b.Assert(int(counters.contentRenderCounter), qt.Equals, 1)
@@ -392,3 +392,71 @@ defaultContentLanguageInSubDir = false
return b
}
func TestCascadeTarget(t *testing.T) {
t.Parallel()
c := qt.New(t)
newBuilder := func(c *qt.C) *sitesBuilder {
b := newTestSitesBuilder(c)
b.WithTemplates("index.html", `
{{ $p1 := site.GetPage "s1/p1" }}
{{ $s1 := site.GetPage "s1" }}
P1|p1:{{ $p1.Params.p1 }}|p2:{{ $p1.Params.p2 }}|
S1|p1:{{ $s1.Params.p1 }}|p2:{{ $s1.Params.p2 }}|
`)
b.WithContent("s1/_index.md", "---\ntitle: s1 section\n---")
b.WithContent("s1/p1/index.md", "---\ntitle: p1\n---")
b.WithContent("s1/p2/index.md", "---\ntitle: p2\n---")
b.WithContent("s2/p1/index.md", "---\ntitle: p1_2\n---")
return b
}
c.Run("slice", func(c *qt.C) {
b := newBuilder(c)
b.WithContent("_index.md", `+++
title = "Home"
[[cascade]]
p1 = "p1"
[[cascade]]
p2 = "p2"
+++
`)
b.Build(BuildCfg{})
b.AssertFileContent("public/index.html", "P1|p1:p1|p2:p2")
})
c.Run("slice with _target", func(c *qt.C) {
b := newBuilder(c)
b.WithContent("_index.md", `+++
title = "Home"
[[cascade]]
p1 = "p1"
[cascade._target]
path="**p1**"
[[cascade]]
p2 = "p2"
[cascade._target]
kind="section"
+++
`)
b.Build(BuildCfg{})
b.AssertFileContent("public/index.html", `
P1|p1:p1|p2:|
S1|p1:|p2:p2|
`)
})
}
+1 -1
View File
@@ -789,7 +789,7 @@ func (m *pageMaps) withMaps(fn func(pm *pageMap) error) error {
type pagesMapBucket struct {
// Cascading front matter.
cascade maps.Params
cascade map[page.PageMatcher]maps.Params
owner *pageState // The branch node
+23 -1
View File
@@ -54,7 +54,15 @@ title: No List
_build:
render: false
---
`, "sect/no-publishresources/index.md", `
`,
"sect/no-render-link.md", `
---
title: No Render Link
_build:
render: link
---
`,
"sect/no-publishresources/index.md", `
---
title: No Publish Resources
_build:
@@ -303,6 +311,20 @@ title: Headless Local Lists Sub
b.Assert(getPageInPagePages(sect, ref), qt.Not(qt.IsNil))
})
c.Run("Build config, no render link", func(c *qt.C) {
b := newSitesBuilder(c, disableKind)
b.Build(BuildCfg{})
ref := "/sect/no-render-link.md"
b.Assert(b.CheckExists("public/sect/no-render/index.html"), qt.Equals, false)
p := getPage(b, ref)
b.Assert(p, qt.Not(qt.IsNil))
b.Assert(p.RelPermalink(), qt.Equals, "/blog/sect/no-render-link/")
b.Assert(p.OutputFormats(), qt.HasLen, 0)
b.Assert(getPageInSitePages(b, ref), qt.Not(qt.IsNil))
sect := getPage(b, "/sect")
b.Assert(getPageInPagePages(sect, ref), qt.Not(qt.IsNil))
})
c.Run("Build config, no publish resources", func(c *qt.C) {
b := newSitesBuilder(c, disableKind)
b.Build(BuildCfg{})
+59 -10
View File
@@ -308,12 +308,22 @@ func (p *pageMeta) Weight() int {
func (pm *pageMeta) mergeBucketCascades(b1, b2 *pagesMapBucket) {
if b1.cascade == nil {
b1.cascade = make(map[string]interface{})
b1.cascade = make(map[page.PageMatcher]maps.Params)
}
if b2 != nil && b2.cascade != nil {
for k, v := range b2.cascade {
if _, found := b1.cascade[k]; !found {
vv, found := b1.cascade[k]
if !found {
b1.cascade[k] = v
} else {
// Merge
for ck, cv := range v {
if _, found := vv[ck]; !found {
vv[ck] = cv
}
}
}
}
}
@@ -332,14 +342,44 @@ func (pm *pageMeta) setMetadata(parentBucket *pagesMapBucket, p *pageState, fron
if p.bucket != nil {
// Check for any cascade define on itself.
if cv, found := frontmatter["cascade"]; found {
p.bucket.cascade = maps.ToStringMap(cv)
switch v := cv.(type) {
case []map[string]interface{}:
p.bucket.cascade = make(map[page.PageMatcher]maps.Params)
for _, vv := range v {
var m page.PageMatcher
if mv, found := vv["_target"]; found {
err := page.DecodePageMatcher(mv, &m)
if err != nil {
return err
}
}
c, found := p.bucket.cascade[m]
if found {
// Merge
for k, v := range vv {
if _, found := c[k]; !found {
c[k] = v
}
}
} else {
p.bucket.cascade[m] = vv
}
}
default:
p.bucket.cascade = map[page.PageMatcher]maps.Params{
page.PageMatcher{}: maps.ToStringMap(cv),
}
}
}
}
} else {
frontmatter = make(map[string]interface{})
}
var cascade map[string]interface{}
var cascade map[page.PageMatcher]maps.Params
if p.bucket != nil {
if parentBucket != nil {
@@ -351,9 +391,14 @@ func (pm *pageMeta) setMetadata(parentBucket *pagesMapBucket, p *pageState, fron
cascade = parentBucket.cascade
}
for k, v := range cascade {
if _, found := frontmatter[k]; !found {
frontmatter[k] = v
for m, v := range cascade {
if !m.Matches(p) {
continue
}
for kk, vv := range v {
if _, found := frontmatter[kk]; !found {
frontmatter[kk] = vv
}
}
}
@@ -461,12 +506,12 @@ func (pm *pageMeta) setMetadata(parentBucket *pagesMapBucket, p *pageState, fron
pm.params[loki] = isHeadless
if p.File().TranslationBaseName() == "index" && isHeadless {
pm.buildConfig.List = pagemeta.Never
pm.buildConfig.Render = false
pm.buildConfig.Render = pagemeta.Never
}
case "outputs":
o := cast.ToStringSlice(v)
if len(o) > 0 {
// Output formats are exlicitly set in front matter, use those.
// Output formats are explicitly set in front matter, use those.
outFormats, err := p.s.outputFormatsConfig.GetByNames(o...)
if err != nil {
@@ -638,7 +683,11 @@ func (p *pageMeta) getListFilter(local bool) contentTreeNodeCallback {
}
func (p *pageMeta) noRender() bool {
return !p.buildConfig.Render
return p.buildConfig.Render != pagemeta.Always
}
func (p *pageMeta) noLink() bool {
return p.buildConfig.Render == pagemeta.Never
}
func (p *pageMeta) applyDefaultValues(n *contentNode) error {
+4 -2
View File
@@ -51,9 +51,11 @@ func newPagePaths(
var relPermalink, permalink string
// If a page is headless or marked as "no render", or bundled in another,
// If a page is headless or bundled in another,
// it will not get published on its own and it will have no links.
if !pm.noRender() && !pm.bundled {
// We also check the build options if it's set to not render or have
// a link.
if !pm.noLink() && !pm.bundled {
relPermalink = paths.RelPermalink(s.PathSpec)
permalink = paths.PermalinkForOutputFormat(s.PathSpec, f)
}
+21
View File
@@ -1757,3 +1757,24 @@ $$$
`<pre><code class="language-bash {hl_lines=[1]}" data-lang="bash {hl_lines=[1]}">SHORT`,
)
}
func TestPageCaseIssues(t *testing.T) {
t.Parallel()
b := newTestSitesBuilder(t)
b.WithConfigFile("toml", `defaultContentLanguage = "no"
[languages]
[languages.NO]
title = "Norsk"
`)
b.WithContent("a/B/C/Page1.md", "---\ntitle: Page1\n---")
b.WithTemplates("index.html", `
{{ $p1 := site.GetPage "a/B/C/Page1" }}
Lang: {{ .Lang }}
Page1: {{ $p1.Path }}
`)
b.Build(BuildCfg{})
b.AssertFileContent("public/index.html", "Lang: no", filepath.FromSlash("Page1: a/B/C/Page1.md"))
}
+8 -1
View File
@@ -137,6 +137,7 @@ func (c *pagesCollector) isCascadingEdit(dir contentDirKey) (bool, string) {
hasCascade := n.p.bucket.cascade != nil && len(n.p.bucket.cascade) > 0
if !ok {
isCascade = hasCascade
return true
}
@@ -145,7 +146,12 @@ func (c *pagesCollector) isCascadingEdit(dir contentDirKey) (bool, string) {
return true
}
isCascade = !reflect.DeepEqual(cascade1, n.p.bucket.cascade)
for _, v := range n.p.bucket.cascade {
isCascade = !reflect.DeepEqual(cascade1, v)
if isCascade {
break
}
}
return true
@@ -187,6 +193,7 @@ func (c *pagesCollector) Collect() (collectErr error) {
collectErr = c.collectDir(dir.dirname, true, nil)
case bundleBranch:
isCascading, section := c.isCascadingEdit(dir)
if isCascading {
c.contentMap.deleteSection(section)
}
+1 -1
View File
@@ -489,7 +489,7 @@ Min HTML: {{ ( resources.Get "mydata/html1.html" | resources.Minify ).Content |
`)
}, func(b *sitesBuilder) {
b.AssertFileContent("public/index.html", `Min CSS: h1{font-style:bold}`)
b.AssertFileContent("public/index.html", `Min JS: var x;x=5;document.getElementById(&#34;demo&#34;).innerHTML=x*10;`)
b.AssertFileContent("public/index.html", `Min JS: var x;x=5,document.getElementById(&#34;demo&#34;).innerHTML=x*10`)
b.AssertFileContent("public/index.html", `Min JSON: {"employees":[{"firstName":"John","lastName":"Doe"},{"firstName":"Anna","lastName":"Smith"},{"firstName":"Peter","lastName":"Jones"}]}`)
b.AssertFileContent("public/index.html", `Min XML: <hello><world>Hugo Rocks!</<world></hello>`)
b.AssertFileContent("public/index.html", `Min SVG: <svg height="100" width="100"><path d="M1e2 1e2H3e2 2e2z"/></svg>`)
+13
View File
@@ -23,6 +23,7 @@ import (
"os"
"path"
"path/filepath"
"regexp"
"sort"
"strconv"
"strings"
@@ -1027,11 +1028,20 @@ func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) erro
logger = helpers.NewDistinctFeedbackLogger()
)
var isCSSConfigRe = regexp.MustCompile(`(postcss|tailwind)\.config\.js`)
var isCSSFileRe = regexp.MustCompile(`\.(css|scss|sass)`)
var cachePartitions []string
// Special case
// TODO(bep) I have a ongoing branch where I have redone the cache. Consider this there.
var isCSSChange bool
for _, ev := range events {
if assetsFilename := s.BaseFs.Assets.MakePathRelative(ev.Name); assetsFilename != "" {
cachePartitions = append(cachePartitions, resources.ResourceKeyPartitions(assetsFilename)...)
if !isCSSChange {
isCSSChange = isCSSFileRe.MatchString(assetsFilename) || isCSSConfigRe.MatchString(assetsFilename)
}
}
id, found := s.eventToIdentity(ev)
@@ -1078,6 +1088,9 @@ func (s *Site) processPartial(config *BuildCfg, init func(config *BuildCfg) erro
// These in memory resource caches will be rebuilt on demand.
for _, s := range s.h.Sites {
s.ResourceSpec.ResourceCache.DeletePartitions(cachePartitions...)
if isCSSChange {
s.ResourceSpec.ResourceCache.DeleteContains("css", "scss", "sass")
}
}
if tmplChanged || i18nChanged {
+46 -47
View File
@@ -14,35 +14,40 @@
package i18n
import (
"reflect"
"strings"
"github.com/gohugoio/hugo/common/hreflect"
"github.com/gohugoio/hugo/common/loggers"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/helpers"
"github.com/nicksnyder/go-i18n/i18n/bundle"
"github.com/nicksnyder/go-i18n/i18n/translation"
"github.com/nicksnyder/go-i18n/v2/i18n"
)
type translateFunc func(translationID string, templateData interface{}) string
var (
i18nWarningLogger = helpers.NewDistinctFeedbackLogger()
)
// Translator handles i18n translations.
type Translator struct {
translateFuncs map[string]bundle.TranslateFunc
translateFuncs map[string]translateFunc
cfg config.Provider
logger *loggers.Logger
}
// NewTranslator creates a new Translator for the given language bundle and configuration.
func NewTranslator(b *bundle.Bundle, cfg config.Provider, logger *loggers.Logger) Translator {
t := Translator{cfg: cfg, logger: logger, translateFuncs: make(map[string]bundle.TranslateFunc)}
func NewTranslator(b *i18n.Bundle, cfg config.Provider, logger *loggers.Logger) Translator {
t := Translator{cfg: cfg, logger: logger, translateFuncs: make(map[string]translateFunc)}
t.initFuncs(b)
return t
}
// Func gets the translate func for the given language, or for the default
// configured language if not found.
func (t Translator) Func(lang string) bundle.TranslateFunc {
func (t Translator) Func(lang string) translateFunc {
if f, ok := t.translateFuncs[lang]; ok {
return f
}
@@ -50,68 +55,62 @@ func (t Translator) Func(lang string) bundle.TranslateFunc {
if f, ok := t.translateFuncs[t.cfg.GetString("defaultContentLanguage")]; ok {
return f
}
t.logger.INFO.Println("i18n not initialized; if you need string translations, check that you have a bundle in /i18n that matches the site language or the default language.")
return func(translationID string, args ...interface{}) string {
return func(translationID string, args interface{}) string {
return ""
}
}
func (t Translator) initFuncs(bndl *bundle.Bundle) {
defaultContentLanguage := t.cfg.GetString("defaultContentLanguage")
defaultT, err := bndl.Tfunc(defaultContentLanguage)
if err != nil {
t.logger.INFO.Printf("No translation bundle found for default language %q", defaultContentLanguage)
}
translations := bndl.Translations()
func (t Translator) initFuncs(bndl *i18n.Bundle) {
enableMissingTranslationPlaceholders := t.cfg.GetBool("enableMissingTranslationPlaceholders")
for _, lang := range bndl.LanguageTags() {
currentLang := lang
currentLangStr := currentLang.String()
currentLangKey := strings.TrimPrefix(currentLangStr, artificialLangTagPrefix)
localizer := i18n.NewLocalizer(bndl, currentLangStr)
t.translateFuncs[currentLang] = func(translationID string, args ...interface{}) string {
tFunc, err := bndl.Tfunc(currentLang)
if err != nil {
t.logger.WARN.Printf("could not load translations for language %q (%s), will use default content language.\n", lang, err)
t.translateFuncs[currentLangKey] = func(translationID string, templateData interface{}) string {
var pluralCount interface{}
if templateData != nil {
tp := reflect.TypeOf(templateData)
if hreflect.IsNumber(tp.Kind()) {
pluralCount = templateData
// This was how go-i18n worked in v1.
templateData = map[string]interface{}{
"Count": templateData,
}
}
}
translated := tFunc(translationID, args...)
if translated != translationID {
translated, translatedLang, err := localizer.LocalizeWithTag(&i18n.LocalizeConfig{
MessageID: translationID,
TemplateData: templateData,
PluralCount: pluralCount,
})
if err == nil && currentLang == translatedLang {
return translated
}
// If there is no translation for translationID,
// then Tfunc returns translationID itself.
// But if user set same translationID and translation, we should check
// if it really untranslated:
if isIDTranslated(translations, currentLang, translationID) {
return translated
if _, ok := err.(*i18n.MessageNotFoundErr); !ok {
t.logger.WARN.Printf("Failed to get translated string for language %q and ID %q: %s", currentLangStr, translationID, err)
}
if t.cfg.GetBool("logI18nWarnings") {
i18nWarningLogger.Printf("i18n|MISSING_TRANSLATION|%s|%s", currentLang, translationID)
i18nWarningLogger.Printf("i18n|MISSING_TRANSLATION|%s|%s", currentLangStr, translationID)
}
if enableMissingTranslationPlaceholders {
return "[i18n] " + translationID
}
if defaultT != nil {
translated := defaultT(translationID, args...)
if translated != translationID {
return translated
}
if isIDTranslated(translations, defaultContentLanguage, translationID) {
return translated
}
}
return ""
return translated
}
}
}
// If the translation map contains translationID for specified currentLang,
// then the translationID is actually translated.
func isIDTranslated(translations map[string]map[string]translation.Translation, lang, id string) bool {
_, contains := translations[lang][id]
return contains
}
+39 -7
View File
@@ -14,6 +14,7 @@
package i18n
import (
"fmt"
"path/filepath"
"testing"
@@ -125,6 +126,35 @@ var i18nTests = []i18nTest{
expected: "¡Hola, 50 gente!",
expectedFlag: "¡Hola, 50 gente!",
},
// https://github.com/gohugoio/hugo/issues/7787
{
name: "readingTime-one",
data: map[string][]byte{
"en.toml": []byte(`[readingTime]
one = "One minute to read"
other = "{{ .Count }} minutes to read"
`),
},
args: 1,
lang: "en",
id: "readingTime",
expected: "One minute to read",
expectedFlag: "One minute to read",
},
{
name: "readingTime-many",
data: map[string][]byte{
"en.toml": []byte(`[readingTime]
one = "One minute to read"
other = "{{ .Count }} minutes to read"
`),
},
args: 21,
lang: "en",
id: "readingTime",
expected: "21 minutes to read",
expectedFlag: "21 minutes to read",
},
// Same id and translation in current language
// https://github.com/gohugoio/hugo/issues/2607
{
@@ -242,13 +272,15 @@ func TestI18nTranslate(t *testing.T) {
v.Set("enableMissingTranslationPlaceholders", enablePlaceholders)
for _, test := range i18nTests {
if enablePlaceholders {
expected = test.expectedFlag
} else {
expected = test.expected
}
actual = doTestI18nTranslate(t, test, v)
c.Assert(actual, qt.Equals, expected)
c.Run(fmt.Sprintf("%s-%t", test.name, enablePlaceholders), func(c *qt.C) {
if enablePlaceholders {
expected = test.expectedFlag
} else {
expected = test.expected
}
actual = doTestI18nTranslate(t, test, v)
c.Assert(actual, qt.Equals, expected)
})
}
}
}
+28 -30
View File
@@ -14,16 +14,19 @@
package i18n
import (
"errors"
"encoding/json"
"github.com/gohugoio/hugo/common/herrors"
"golang.org/x/text/language"
yaml "gopkg.in/yaml.v2"
"github.com/BurntSushi/toml"
"github.com/gohugoio/hugo/helpers"
"github.com/nicksnyder/go-i18n/v2/i18n"
"github.com/gohugoio/hugo/deps"
"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/hugofs"
"github.com/gohugoio/hugo/source"
"github.com/nicksnyder/go-i18n/i18n/bundle"
"github.com/nicksnyder/go-i18n/i18n/language"
_errors "github.com/pkg/errors"
)
@@ -42,13 +45,10 @@ func NewTranslationProvider() *TranslationProvider {
func (tp *TranslationProvider) Update(d *deps.Deps) error {
spec := source.NewSourceSpec(d.PathSpec, nil)
i18nBundle := bundle.New()
en := language.GetPluralSpec("en")
if en == nil {
return errors.New("the English language has vanished like an old oak table")
}
var newLangs []string
bundle := i18n.NewBundle(language.English)
bundle.RegisterUnmarshalFunc("toml", toml.Unmarshal)
bundle.RegisterUnmarshalFunc("yaml", yaml.Unmarshal)
bundle.RegisterUnmarshalFunc("json", json.Unmarshal)
// The source dirs are ordered so the most important comes first. Since this is a
// last key win situation, we have to reverse the iteration order.
@@ -56,33 +56,18 @@ func (tp *TranslationProvider) Update(d *deps.Deps) error {
for i := len(dirs) - 1; i >= 0; i-- {
dir := dirs[i]
src := spec.NewFilesystemFromFileMetaInfo(dir)
files, err := src.Files()
if err != nil {
return err
}
for _, r := range files {
currentSpec := language.GetPluralSpec(r.BaseFileName())
if currentSpec == nil {
// This may is a language code not supported by go-i18n, it may be
// Klingon or ... not even a fake language. Make sure it works.
newLangs = append(newLangs, r.BaseFileName())
}
}
if len(newLangs) > 0 {
language.RegisterPluralSpec(newLangs, en)
}
for _, file := range files {
if err := addTranslationFile(i18nBundle, file); err != nil {
if err := addTranslationFile(bundle, file); err != nil {
return err
}
}
}
tp.t = NewTranslator(i18nBundle, d.Cfg, d.Log)
tp.t = NewTranslator(bundle, d.Cfg, d.Log)
d.Translate = tp.t.Func(d.Language.Lang)
@@ -90,16 +75,29 @@ func (tp *TranslationProvider) Update(d *deps.Deps) error {
}
func addTranslationFile(bundle *bundle.Bundle, r source.File) error {
const artificialLangTagPrefix = "art-x-"
func addTranslationFile(bundle *i18n.Bundle, r source.File) error {
f, err := r.FileInfo().Meta().Open()
if err != nil {
return _errors.Wrapf(err, "failed to open translations file %q:", r.LogicalName())
}
err = bundle.ParseTranslationFileBytes(r.LogicalName(), helpers.ReaderToBytes(f))
b := helpers.ReaderToBytes(f)
f.Close()
name := r.LogicalName()
lang := helpers.Filename(name)
tag := language.Make(lang)
if tag == language.Und {
name = artificialLangTagPrefix + name
}
_, err = bundle.ParseMessageFileBytes(b, name)
if err != nil {
return errWithFileContext(_errors.Wrapf(err, "failed to load translations"), r)
}
return nil
}
@@ -27,6 +27,7 @@ var (
Trace: false,
FailureLevel: "fatal",
WorkingFolderCurrent: false,
PreserveTOC: false,
}
// CliDefault holds Asciidoctor CLI defaults (see https://asciidoctor.org/docs/user-manual/)
@@ -86,4 +87,5 @@ type Config struct {
Trace bool
FailureLevel string
WorkingFolderCurrent bool
PreserveTOC bool
}
+7 -7
View File
@@ -18,7 +18,6 @@ package asciidocext
import (
"bytes"
"io"
"os/exec"
"path/filepath"
@@ -64,7 +63,7 @@ type asciidocConverter struct {
}
func (a *asciidocConverter) Convert(ctx converter.RenderContext) (converter.Result, error) {
content, toc, err := extractTOC(a.getAsciidocContent(ctx.Src, a.ctx))
content, toc, err := a.extractTOC(a.getAsciidocContent(ctx.Src, a.ctx))
if err != nil {
return nil, err
}
@@ -204,7 +203,7 @@ func getAsciidoctorExecPath() string {
// extractTOC extracts the toc from the given src html.
// It returns the html without the TOC, and the TOC data
func extractTOC(src []byte) ([]byte, tableofcontents.Root, error) {
func (a *asciidocConverter) extractTOC(src []byte) ([]byte, tableofcontents.Root, error) {
var buf bytes.Buffer
buf.Write(src)
node, err := html.Parse(&buf)
@@ -219,7 +218,9 @@ func extractTOC(src []byte) ([]byte, tableofcontents.Root, error) {
f = func(n *html.Node) bool {
if n.Type == html.ElementNode && n.Data == "div" && attr(n, "id") == "toc" {
toc = parseTOC(n)
n.Parent.RemoveChild(n)
if !a.cfg.MarkupConfig.AsciidocExt.PreserveTOC {
n.Parent.RemoveChild(n)
}
return true
}
if n.FirstChild != nil {
@@ -285,7 +286,7 @@ func parseTOC(doc *html.Node) tableofcontents.Root {
f(n.NextSibling, row, level)
}
}
f(doc.FirstChild, 0, 0)
f(doc.FirstChild, -1, 0)
return toc
}
@@ -300,9 +301,8 @@ func attr(node *html.Node, key string) string {
func nodeContent(node *html.Node) string {
var buf bytes.Buffer
w := io.Writer(&buf)
for c := node.FirstChild; c != nil; c = c.NextSibling {
html.Render(w, c)
html.Render(&buf, c)
}
return buf.String()
}
+112 -19
View File
@@ -277,11 +277,17 @@ func TestTableOfContents(t *testing.T) {
t.Skip("asciidoctor not installed")
}
c := qt.New(t)
p, err := Provider.New(converter.ProviderConfig{Logger: loggers.NewErrorLogger()})
mconf := markup_config.Default
p, err := Provider.New(
converter.ProviderConfig{
MarkupConfig: mconf,
Logger: loggers.NewErrorLogger(),
},
)
c.Assert(err, qt.IsNil)
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
b, err := conv.Convert(converter.RenderContext{Src: []byte(`:toc: macro
r, err := conv.Convert(converter.RenderContext{Src: []byte(`:toc: macro
:toclevels: 4
toc::[]
@@ -300,11 +306,52 @@ testContent
== Section 2
`)})
c.Assert(err, qt.IsNil)
toc, ok := b.(converter.TableOfContentsProvider)
toc, ok := r.(converter.TableOfContentsProvider)
c.Assert(ok, qt.Equals, true)
root := toc.TableOfContents()
c.Assert(root.ToHTML(2, 4, false), qt.Equals, "<nav id=\"TableOfContents\">\n <ul>\n <li><a href=\"#_introduction\">Introduction</a></li>\n <li><a href=\"#_section_1\">Section 1</a>\n <ul>\n <li><a href=\"#_section_1_1\">Section 1.1</a>\n <ul>\n <li><a href=\"#_section_1_1_1\">Section 1.1.1</a></li>\n </ul>\n </li>\n <li><a href=\"#_section_1_2\">Section 1.2</a></li>\n </ul>\n </li>\n <li><a href=\"#_section_2\">Section 2</a></li>\n </ul>\n</nav>")
c.Assert(root.ToHTML(2, 3, false), qt.Equals, "<nav id=\"TableOfContents\">\n <ul>\n <li><a href=\"#_introduction\">Introduction</a></li>\n <li><a href=\"#_section_1\">Section 1</a>\n <ul>\n <li><a href=\"#_section_1_1\">Section 1.1</a></li>\n <li><a href=\"#_section_1_2\">Section 1.2</a></li>\n </ul>\n </li>\n <li><a href=\"#_section_2\">Section 2</a></li>\n </ul>\n</nav>")
expected := tableofcontents.Root{
Headers: tableofcontents.Headers{
{
ID: "",
Text: "",
Headers: tableofcontents.Headers{
{
ID: "_introduction",
Text: "Introduction",
Headers: nil,
},
{
ID: "_section_1",
Text: "Section 1",
Headers: tableofcontents.Headers{
{
ID: "_section_1_1",
Text: "Section 1.1",
Headers: tableofcontents.Headers{
{
ID: "_section_1_1_1",
Text: "Section 1.1.1",
Headers: nil,
},
},
},
{
ID: "_section_1_2",
Text: "Section 1.2",
Headers: nil,
},
},
},
{
ID: "_section_2",
Text: "Section 2",
Headers: nil,
},
},
},
},
}
c.Assert(toc.TableOfContents(), qt.DeepEquals, expected)
c.Assert(string(r.Bytes()), qt.Not(qt.Contains), "<div id=\"toc\" class=\"toc\">")
}
func TestTableOfContentsWithCode(t *testing.T) {
@@ -322,26 +369,72 @@ func TestTableOfContentsWithCode(t *testing.T) {
c.Assert(err, qt.IsNil)
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
b, err := conv.Convert(converter.RenderContext{Src: []byte(`:toc: auto
r, err := conv.Convert(converter.RenderContext{Src: []byte(`:toc: auto
== Some ` + "`code`" + ` in the title
`)})
c.Assert(err, qt.IsNil)
toc, ok := b.(converter.TableOfContentsProvider)
toc, ok := r.(converter.TableOfContentsProvider)
c.Assert(ok, qt.Equals, true)
expected := tableofcontents.Headers{
{},
{
ID: "",
Text: "",
Headers: tableofcontents.Headers{
{
ID: "_some_code_in_the_title",
Text: "Some <code>code</code> in the title",
Headers: nil,
expected := tableofcontents.Root{
Headers: tableofcontents.Headers{
{
ID: "",
Text: "",
Headers: tableofcontents.Headers{
{
ID: "_some_code_in_the_title",
Text: "Some <code>code</code> in the title",
Headers: nil,
},
},
},
},
}
c.Assert(toc.TableOfContents().Headers, qt.DeepEquals, expected)
c.Assert(toc.TableOfContents(), qt.DeepEquals, expected)
c.Assert(string(r.Bytes()), qt.Not(qt.Contains), "<div id=\"toc\" class=\"toc\">")
}
func TestTableOfContentsPreserveTOC(t *testing.T) {
if !Supports() {
t.Skip("asciidoctor not installed")
}
c := qt.New(t)
mconf := markup_config.Default
mconf.AsciidocExt.PreserveTOC = true
p, err := Provider.New(
converter.ProviderConfig{
MarkupConfig: mconf,
Logger: loggers.NewErrorLogger(),
},
)
c.Assert(err, qt.IsNil)
conv, err := p.New(converter.DocumentContext{})
c.Assert(err, qt.IsNil)
r, err := conv.Convert(converter.RenderContext{Src: []byte(`:toc:
:idprefix:
:idseparator: -
== Some title
`)})
c.Assert(err, qt.IsNil)
toc, ok := r.(converter.TableOfContentsProvider)
c.Assert(ok, qt.Equals, true)
expected := tableofcontents.Root{
Headers: tableofcontents.Headers{
{
ID: "",
Text: "",
Headers: tableofcontents.Headers{
{
ID: "some-title",
Text: "Some title",
Headers: nil,
},
},
},
},
}
c.Assert(toc.TableOfContents(), qt.DeepEquals, expected)
c.Assert(string(r.Bytes()), qt.Contains, "<div id=\"toc\" class=\"toc\">")
}
+21 -6
View File
@@ -18,6 +18,7 @@ import (
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/docshelper"
"github.com/gohugoio/hugo/parser"
"github.com/spf13/cast"
"github.com/mitchellh/mapstructure"
"github.com/tdewolff/minify/v2/css"
@@ -35,18 +36,16 @@ var defaultTdewolffConfig = tdewolffConfig{
KeepEndTags: true,
KeepDefaultAttrVals: true,
KeepWhitespace: false,
// KeepQuotes: false, >= v2.6.2
KeepQuotes: false,
},
CSS: css.Minifier{
Decimals: -1, // will be deprecated
// Precision: 0, // use Precision with >= v2.7.0
KeepCSS2: true,
Precision: 0,
KeepCSS2: true,
},
JS: js.Minifier{},
JSON: json.Minifier{},
SVG: svg.Minifier{
Decimals: -1, // will be deprecated
// Precision: 0, // use Precision with >= v2.7.0
Precision: 0,
},
XML: xml.Minifier{
KeepWhitespace: false,
@@ -99,6 +98,22 @@ func decodeConfig(cfg config.Provider) (conf minifyConfig, err error) {
m := maps.ToStringMap(v)
// Handle upstream renames.
if td, found := m["tdewolff"]; found {
tdm := cast.ToStringMap(td)
for _, key := range []string{"css", "svg"} {
if v, found := tdm[key]; found {
vm := cast.ToStringMap(v)
if vv, found := vm["decimal"]; found {
vvi := cast.ToInt(vv)
if vvi > 0 {
vm["precision"] = vvi
}
}
}
}
}
err = mapstructure.WeakDecode(m, &conf)
if err != nil {
+24 -1
View File
@@ -34,7 +34,7 @@ func TestNew(t *testing.T) {
var rawJS string
var minJS string
rawJS = " var foo =1 ; foo ++ ; "
minJS = "var foo=1;foo++;"
minJS = "var foo=1;foo++"
var rawJSON string
var minJSON string
@@ -168,3 +168,26 @@ func TestBugs(t *testing.T) {
}
}
// Renamed to Precision in v2.7.0. Check that we support both.
func TestDecodeConfigDecimalIsNowPrecision(t *testing.T) {
c := qt.New(t)
v := viper.New()
v.Set("minify", map[string]interface{}{
"disablexml": true,
"tdewolff": map[string]interface{}{
"css": map[string]interface{}{
"decimal": 3,
},
"svg": map[string]interface{}{
"decimal": 3,
},
},
})
conf, err := decodeConfig(v)
c.Assert(err, qt.IsNil)
c.Assert(conf.Tdewolff.CSS.Precision, qt.Equals, 3)
}
+9 -2
View File
@@ -67,7 +67,9 @@ type cssClassCollectorWriter struct {
isCollecting bool
dropValue bool
inQuote bool
inQuote bool
quoteValue byte
}
func (w *cssClassCollectorWriter) Write(p []byte) (n int, err error) {
@@ -165,7 +167,12 @@ func (c *cssClassCollectorWriter) startCollecting() {
func (c *cssClassCollectorWriter) toggleIfQuote(b byte) {
if isQuote(b) {
c.inQuote = !c.inQuote
if c.inQuote && b == c.quoteValue {
c.inQuote = false
} else if !c.inQuote {
c.inQuote = true
c.quoteValue = b
}
}
}
+2
View File
@@ -87,6 +87,8 @@ func TestClassCollector(t *testing.T) {
{"Alpine transition 1", `<div x-transition:enter-start="opacity-0 transform mobile:-translate-x-8 sm:-translate-y-8">`, f("div", "mobile:-translate-x-8 opacity-0 sm:-translate-y-8 transform", "")},
{"Vue bind", `<div v-bind:class="{ active: isActive }"></div>`, f("div", "active", "")},
// https://github.com/gohugoio/hugo/issues/7746
{"Apostrophe inside attribute value", `<a class="missingclass" title="Plus d'information">my text</a><div></div>`, f("a div", "missingclass", "")},
} {
c.Run(test.name, func(c *qt.C) {
w := newHTMLElementsCollectorWriter(newHTMLElementsCollector())
@@ -21,6 +21,7 @@ import (
"github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/hugofs/files"
"github.com/gohugoio/hugo/identity"
"github.com/gohugoio/hugo/langs"
"github.com/gohugoio/hugo/media"
"github.com/gohugoio/hugo/navigation"
@@ -87,6 +88,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) {
isTranslated := p.IsTranslated()
allTranslations := p.AllTranslations()
translations := p.Translations()
getIdentity := p.GetIdentity()
s := struct {
Content interface{}
@@ -143,6 +145,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) {
IsTranslated bool
AllTranslations Pages
Translations Pages
GetIdentity identity.Identity
}{
Content: content,
Plain: plain,
@@ -198,6 +201,7 @@ func MarshalPageToJSON(p Page) ([]byte, error) {
IsTranslated: isTranslated,
AllTranslations: allTranslations,
Translations: translations,
GetIdentity: getIdentity,
}
return json.Marshal(&s)
+91
View File
@@ -0,0 +1,91 @@
// Copyright 2020 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 page
import (
"path/filepath"
"strings"
"github.com/pkg/errors"
"github.com/gohugoio/hugo/hugofs/glob"
"github.com/mitchellh/mapstructure"
)
// A PageMatcher can be used to match a Page with Glob patterns.
// Note that the pattern matching is case insensitive.
type PageMatcher struct {
// A Glob pattern matching the content path below /content.
// Expects Unix-styled slashes.
// Note that this is the virtual path, so it starts at the mount root
// with a leading "/".
Path string
// A Glob pattern matching the Page's Kind(s), e.g. "{home,section}"
Kind string
// A Glob pattern matching the Page's language, e.g. "{en,sv}".
Lang string
}
// Matches returns whether p matches this matcher.
func (m PageMatcher) Matches(p Page) bool {
if m.Kind != "" {
g, err := glob.GetGlob(m.Kind)
if err == nil && !g.Match(p.Kind()) {
return false
}
}
if m.Lang != "" {
g, err := glob.GetGlob(m.Lang)
if err == nil && !g.Match(p.Lang()) {
return false
}
}
if m.Path != "" {
g, err := glob.GetGlob(m.Path)
// TODO(bep) Path() vs filepath vs leading slash.
p := strings.ToLower(filepath.ToSlash(p.Path()))
if !(strings.HasPrefix(p, "/")) {
p = "/" + p
}
if err == nil && !g.Match(p) {
return false
}
}
return true
}
// DecodePageMatcher decodes m into v.
func DecodePageMatcher(m interface{}, v *PageMatcher) error {
if err := mapstructure.WeakDecode(m, v); err != nil {
return err
}
v.Kind = strings.ToLower(v.Kind)
if v.Kind != "" {
if _, found := kindMap[v.Kind]; !found {
return errors.Errorf("%q is not a valid Page Kind", v.Kind)
}
}
v.Path = filepath.ToSlash(strings.ToLower(v.Path))
return nil
}
+63
View File
@@ -0,0 +1,63 @@
// Copyright 2020 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 page
import (
"path/filepath"
"testing"
qt "github.com/frankban/quicktest"
)
func TestPageMatcher(t *testing.T) {
c := qt.New(t)
p1, p2, p3 := &testPage{path: "/p1", kind: "section", lang: "en"}, &testPage{path: "p2", kind: "page", lang: "no"}, &testPage{path: "p3", kind: "page", lang: "en"}
c.Run("Matches", func(c *qt.C) {
m := PageMatcher{Kind: "section"}
c.Assert(m.Matches(p1), qt.Equals, true)
c.Assert(m.Matches(p2), qt.Equals, false)
m = PageMatcher{Kind: "page"}
c.Assert(m.Matches(p1), qt.Equals, false)
c.Assert(m.Matches(p2), qt.Equals, true)
c.Assert(m.Matches(p3), qt.Equals, true)
m = PageMatcher{Kind: "page", Path: "/p2"}
c.Assert(m.Matches(p1), qt.Equals, false)
c.Assert(m.Matches(p2), qt.Equals, true)
c.Assert(m.Matches(p3), qt.Equals, false)
m = PageMatcher{Path: "/p*"}
c.Assert(m.Matches(p1), qt.Equals, true)
c.Assert(m.Matches(p2), qt.Equals, true)
c.Assert(m.Matches(p3), qt.Equals, true)
m = PageMatcher{Lang: "en"}
c.Assert(m.Matches(p1), qt.Equals, true)
c.Assert(m.Matches(p2), qt.Equals, false)
c.Assert(m.Matches(p3), qt.Equals, true)
})
c.Run("Decode", func(c *qt.C) {
var v PageMatcher
c.Assert(DecodePageMatcher(map[string]interface{}{"kind": "foo"}, &v), qt.Not((qt.IsNil)))
c.Assert(DecodePageMatcher(map[string]interface{}{"kind": "home", "path": filepath.FromSlash("/a/b/**")}, &v), qt.IsNil)
c.Assert(v, qt.Equals, PageMatcher{Kind: "home", Path: "/a/b/**"})
})
}
+18 -3
View File
@@ -28,11 +28,12 @@ const (
Never = "never"
Always = "always"
ListLocally = "local"
Link = "link"
)
var defaultBuildConfig = BuildConfig{
List: Always,
Render: true,
Render: Always,
PublishResources: true,
set: true,
}
@@ -49,7 +50,10 @@ type BuildConfig struct {
List string
// Whether to render it.
Render bool
// Valid values: never, always, link.
// The value link means it will not be rendered, but it will get a RelPermalink/Permalink.
// Note that before 0.76.0 this was a bool, so we accept those too.
Render string
// Whether to publish its resources. These will still be published on demand,
// but enabling this can be useful if the originals (e.g. images) are
@@ -62,7 +66,7 @@ type BuildConfig struct {
// Disable sets all options to their off value.
func (b *BuildConfig) Disable() {
b.List = Never
b.Render = false
b.Render = Never
b.PublishResources = false
b.set = true
}
@@ -91,5 +95,16 @@ func DecodeBuildConfig(m interface{}) (BuildConfig, error) {
b.List = Always
}
// In 0.76.0 we changed the Render from bool to a string.
switch b.Render {
case "0":
b.Render = Never
case "1":
b.Render = Always
case Always, Never, Link:
default:
b.Render = Always
}
return b, err
}
+43 -15
View File
@@ -31,33 +31,61 @@ func TestDecodeBuildConfig(t *testing.T) {
configTempl := `
[_build]
render = true
render = %s
list = %s
publishResources = true`
for _, test := range []struct {
list interface{}
expect string
args []interface{}
expect BuildConfig
}{
{"true", Always},
{"false", Never},
{`"always"`, Always},
{`"local"`, ListLocally},
{`"asdfadf"`, Always},
{
[]interface{}{"true", "true"},
BuildConfig{
Render: Always,
List: Always,
PublishResources: true,
set: true,
}},
{[]interface{}{"true", "false"}, BuildConfig{
Render: Always,
List: Never,
PublishResources: true,
set: true,
}},
{[]interface{}{`"always"`, `"always"`}, BuildConfig{
Render: Always,
List: Always,
PublishResources: true,
set: true,
}},
{[]interface{}{`"never"`, `"never"`}, BuildConfig{
Render: Never,
List: Never,
PublishResources: true,
set: true,
}},
{[]interface{}{`"link"`, `"local"`}, BuildConfig{
Render: Link,
List: ListLocally,
PublishResources: true,
set: true,
}},
{[]interface{}{`"always"`, `"asdfadf"`}, BuildConfig{
Render: Always,
List: Always,
PublishResources: true,
set: true,
}},
} {
cfg, err := config.FromConfigString(fmt.Sprintf(configTempl, test.list), "toml")
cfg, err := config.FromConfigString(fmt.Sprintf(configTempl, test.args...), "toml")
c.Assert(err, qt.IsNil)
bcfg, err := DecodeBuildConfig(cfg.Get("_build"))
c.Assert(err, qt.IsNil)
eq := qt.CmpEquals(hqt.DeepAllowUnexported(BuildConfig{}))
c.Assert(bcfg, eq, BuildConfig{
Render: true,
List: test.expect,
PublishResources: true,
set: true,
})
c.Assert(bcfg, eq, test.expect)
}
+5 -4
View File
@@ -85,11 +85,12 @@ func newTestPathSpecFor(cfg config.Provider) *helpers.PathSpec {
}
type testPage struct {
kind string
description string
title string
linkTitle string
section string
lang string
section string
content string
@@ -297,11 +298,11 @@ func (p *testPage) Keywords() []string {
}
func (p *testPage) Kind() string {
panic("not implemented")
return p.kind
}
func (p *testPage) Lang() string {
panic("not implemented")
return p.lang
}
func (p *testPage) Language() *langs.Language {
+19
View File
@@ -295,3 +295,22 @@ func (c *ResourceCache) DeletePartitions(partitions ...string) {
}
}
func (c *ResourceCache) DeleteContains(parts ...string) {
c.Lock()
defer c.Unlock()
for k := range c.cache {
clear := false
for _, part := range parts {
if strings.Contains(k, part) {
clear = true
break
}
}
if clear {
delete(c.cache, k)
}
}
}
+1 -1
View File
@@ -63,7 +63,7 @@ from snapcraft.internal import errors
logger = logging.getLogger(__name__)
_NODEJS_BASE = "node-v{version}-linux-{arch}"
_NODEJS_VERSION = "12.18.3"
_NODEJS_VERSION = "12.18.4"
_NODEJS_TMPL = "https://nodejs.org/dist/v{version}/{base}.tar.gz"
_NODEJS_ARCHES = {"i386": "x86", "amd64": "x64", "armhf": "armv7l", "arm64": "arm64", "ppc64el": "ppc64le", "s390x": "s390x"}
_YARN_URL = "https://yarnpkg.com/latest.tar.gz"
+1 -1
View File
@@ -1,5 +1,5 @@
name: hugo
version: "0.75.1"
version: "0.76.1"
summary: Fast and Flexible Static Site Generator
description: |
Hugo is a static HTML and CSS website generator written in Go. It is
-10
View File
@@ -1,10 +0,0 @@
This is a bug-fix release with a couple of important fixes.
* resources/image: Fix nilpointer for images with no Exif [cd00f7f9](https://github.com/gohugoio/hugo/commit/cd00f7f9661d67951ef16c5198541f09f1c058b4) [@bep](https://github.com/bep) [#7688](https://github.com/gohugoio/hugo/issues/7688)
* modules/npm: Preserve the original package.json if it exists [214afe4c](https://github.com/gohugoio/hugo/commit/214afe4c1bb9c37bc6159e659d66ba9a268a2849) [@bep](https://github.com/bep) [#7690](https://github.com/gohugoio/hugo/issues/7690)
* tpl: Fix grammar in the new 'requires non-zero' error message [cd830bb0](https://github.com/gohugoio/hugo/commit/cd830bb0275fc39240861627ef26e146985b5c86) [@nekr0z](https://github.com/nekr0z)
+9
View File
@@ -0,0 +1,9 @@
This is a bug-fix release with a couple of important fixes.
* langs/i18n: Fix i18n .Count regression [f9e798e8](https://github.com/gohugoio/hugo/commit/f9e798e8c4234bd60277e3cb10663ba254d4ecb7) [@bep](https://github.com/bep) [#7787](https://github.com/gohugoio/hugo/issues/7787)
* Fix typo in 0.76.0 release note [ee56efff](https://github.com/gohugoio/hugo/commit/ee56efffcb3f81120b0d3e0297b4fb5966124354) [@digitalcraftsman](https://github.com/digitalcraftsman)
+12 -2
View File
@@ -15,12 +15,13 @@
package lang
import (
"errors"
"fmt"
"math"
"strconv"
"strings"
"github.com/pkg/errors"
"github.com/gohugoio/hugo/deps"
"github.com/spf13/cast"
)
@@ -39,12 +40,21 @@ type Namespace struct {
// Translate returns a translated string for id.
func (ns *Namespace) Translate(id interface{}, args ...interface{}) (string, error) {
var templateData interface{}
if len(args) > 0 {
if len(args) > 1 {
return "", errors.Errorf("wrong number of arguments, expecting at most 2, got %d", len(args)+1)
}
templateData = args[0]
}
sid, err := cast.ToStringE(id)
if err != nil {
return "", nil
}
return ns.deps.Translate(sid, args...), nil
return ns.deps.Translate(sid, templateData), nil
}
// NumFmt formats a number with the given precision using the
+10 -7
View File
@@ -496,16 +496,19 @@ if (!doNotTrack) {
{{ template "_internal/shortcodes/vimeo_simple.html" . }}
{{- else -}}
{{ if .IsNamedParams }}<div {{ if .Get "class" }}class="{{ .Get "class" }}"{{ else }}style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"{{ end }}>
<iframe src="https://player.vimeo.com/video/{{ .Get "id" }}" {{ if not (.Get "class") }}style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" {{ end }}{{ if .Get "title"}}title="{{ .Get "title" }}"{{ else }}title="vimeo video"{{ end }} webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>{{ else }}
<iframe src="https://player.vimeo.com/video/{{ .Get "id" }}{{- if $pc.EnableDNT -}}?dnt=1{{- end -}}" {{ if not (.Get "class") }}style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" {{ end }}{{ if .Get "title"}}title="{{ .Get "title" }}"{{ else }}title="vimeo video"{{ end }} webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>{{ else }}
<div {{ if gt (len .Params) 1 }}class="{{ .Get 1 }}"{{ else }}style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"{{ end }}>
<iframe src="https://player.vimeo.com/video/{{ .Get 0 }}" {{ if len .Params | eq 1 }}style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" {{ end }}{{ if len .Params | eq 3 }}title="{{ .Get 2 }}"{{ else }}title="vimeo video"{{ end }} webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
<iframe src="https://player.vimeo.com/video/{{ .Get 0 }}{{- if $pc.EnableDNT -}}?dnt=1{{- end -}}" {{ if len .Params | eq 1 }}style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" {{ end }}{{ if len .Params | eq 3 }}title="{{ .Get 2 }}"{{ else }}title="vimeo video"{{ end }} webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
{{ end }}
{{- end -}}
{{- end -}}`},
{`shortcodes/vimeo_simple.html`, `{{ $id := .Get "id" | default (.Get 0) }}
{{- $item := getJSON "https://vimeo.com/api/oembed.json?url=https://vimeo.com/" $id -}}
{`shortcodes/vimeo_simple.html`, `{{- $pc := .Page.Site.Config.Privacy.Vimeo -}}
{{- if not $pc.Disable -}}
{{ $id := .Get "id" | default (.Get 0) }}
{{ $dnt := cond (eq $pc.EnableDNT true) "?dnt=1" "" }}
{{- $item := getJSON (print "https://vimeo.com/api/oembed.json?url=https://vimeo.com/" $id $dnt) -}}
{{ $class := .Get "class" | default (.Get 1) }}
{{ $hasClass := $class }}
{{ $class := $class | default "__h_video" }}
@@ -522,7 +525,7 @@ if (!doNotTrack) {
<img src="{{ $thumb }}" srcset="{{ $thumb }} 1x, {{ $original }} 2x" alt="{{ .title }}">
<div class="play">{{ template "__h_simple_icon_play" $ }}</div></a></div>
{{- end -}}
`},
{{- end -}}`},
{`shortcodes/youtube.html`, `{{- $pc := .Page.Site.Config.Privacy.YouTube -}}
{{- if not $pc.Disable -}}
{{- $ytHost := cond $pc.PrivacyEnhanced "www.youtube-nocookie.com" "www.youtube.com" -}}
@@ -4,11 +4,11 @@
{{ template "_internal/shortcodes/vimeo_simple.html" . }}
{{- else -}}
{{ if .IsNamedParams }}<div {{ if .Get "class" }}class="{{ .Get "class" }}"{{ else }}style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"{{ end }}>
<iframe src="https://player.vimeo.com/video/{{ .Get "id" }}" {{ if not (.Get "class") }}style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" {{ end }}{{ if .Get "title"}}title="{{ .Get "title" }}"{{ else }}title="vimeo video"{{ end }} webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>{{ else }}
<iframe src="https://player.vimeo.com/video/{{ .Get "id" }}{{- if $pc.EnableDNT -}}?dnt=1{{- end -}}" {{ if not (.Get "class") }}style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" {{ end }}{{ if .Get "title"}}title="{{ .Get "title" }}"{{ else }}title="vimeo video"{{ end }} webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>{{ else }}
<div {{ if gt (len .Params) 1 }}class="{{ .Get 1 }}"{{ else }}style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;"{{ end }}>
<iframe src="https://player.vimeo.com/video/{{ .Get 0 }}" {{ if len .Params | eq 1 }}style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" {{ end }}{{ if len .Params | eq 3 }}title="{{ .Get 2 }}"{{ else }}title="vimeo video"{{ end }} webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
<iframe src="https://player.vimeo.com/video/{{ .Get 0 }}{{- if $pc.EnableDNT -}}?dnt=1{{- end -}}" {{ if len .Params | eq 1 }}style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" {{ end }}{{ if len .Params | eq 3 }}title="{{ .Get 2 }}"{{ else }}title="vimeo video"{{ end }} webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
</div>
{{ end }}
{{- end -}}
{{- end -}}
@@ -1,5 +1,8 @@
{{- $pc := .Page.Site.Config.Privacy.Vimeo -}}
{{- if not $pc.Disable -}}
{{ $id := .Get "id" | default (.Get 0) }}
{{- $item := getJSON "https://vimeo.com/api/oembed.json?url=https://vimeo.com/" $id -}}
{{ $dnt := cond (eq $pc.EnableDNT true) "?dnt=1" "" }}
{{- $item := getJSON (print "https://vimeo.com/api/oembed.json?url=https://vimeo.com/" $id $dnt) -}}
{{ $class := .Get "class" | default (.Get 1) }}
{{ $hasClass := $class }}
{{ $class := $class | default "__h_video" }}
@@ -16,3 +19,4 @@
<img src="{{ $thumb }}" srcset="{{ $thumb }} 1x, {{ $original }} 2x" alt="{{ .title }}">
<div class="play">{{ template "__h_simple_icon_play" $ }}</div></a></div>
{{- end -}}
{{- end -}}