Compare commits

..

1 Commits

Author SHA1 Message Date
Bjørn Erik Pedersen 6389adcc90 Misc remote HTTP/content adapter enhancements
* Recover from server errors
* Improve go adapter rebuilds when adding new content

See #12502
Fixes #12570
2024-06-05 11:14:22 +02:00
733 changed files with 6196 additions and 12053 deletions
+84 -93
View File
@@ -5,7 +5,6 @@
[documentation repository]: https://github.com/gohugoio/hugoDocs
[documentation]: https://gohugo.io/documentation
[dragonfly bsd, freebsd, netbsd, and openbsd]: https://gohugo.io/installation/bsd
[features]: https://gohugo.io/about/features/
[forum]: https://discourse.gohugo.io
[friends]: https://github.com/gohugoio/hugo/graphs/contributors
[go]: https://go.dev/
@@ -20,6 +19,7 @@
[static site generator]: https://en.wikipedia.org/wiki/Static_site_generator
[support]: https://discourse.gohugo.io
[themes]: https://themes.gohugo.io/
[twitter]: https://twitter.com/gohugoio
[website]: https://gohugo.io
[windows]: https://gohugo.io/installation/windows
@@ -33,7 +33,7 @@ A fast and flexible static site generator built with love by [bep], [spf13], and
[![Tests on Linux, MacOS and Windows](https://github.com/gohugoio/hugo/workflows/Test/badge.svg)](https://github.com/gohugoio/hugo/actions?query=workflow%3ATest)
[![Go Report Card](https://goreportcard.com/badge/github.com/gohugoio/hugo)](https://goreportcard.com/report/github.com/gohugoio/hugo)
[Website] | [Installation] | [Documentation] | [Support] | [Contributing] | <a rel="me" href="https://fosstodon.org/@gohugoio">Mastodon</a> | <a rel="me" href="https://x.com/gohugoiov2">X</a>
[Website] | [Installation] | [Documentation] | [Support] | [Contributing] | <a rel="me" href="https://fosstodon.org/@gohugoio">Mastodon</a>
## Overview
@@ -52,23 +52,18 @@ Use Hugo's embedded web server during development to instantly see changes to co
Hugo's fast asset pipelines include:
- Image processing &ndash; Convert, resize, crop, rotate, adjust colors, apply filters, overlay text and images, and extract EXIF data
- JavaScript bundling &ndash; Transpile TypeScript and JSX to JavaScript, bundle, tree shake, minify, create source maps, and perform SRI hashing.
- Sass processing &ndash; Transpile Sass to CSS, bundle, tree shake, minify, create source maps, perform SRI hashing, and integrate with PostCSS
- Tailwind CSS processing &ndash; Compile Tailwind CSS utility classes into standard CSS, bundle, tree shake, optimize, minify, perform SRI hashing, and integrate with PostCSS
- CSS bundling &ndash; transpilation (Sass), tree shaking, minification, source maps, SRI hashing, and PostCSS integration
- JavaScript bundling &ndash; transpilation (TypeScript, JSX), tree shaking, minification, source maps, and SRI hashing
- Image processing &ndash; convert, resize, crop, rotate, adjust colors, apply filters, overlay text and images, and extract EXIF data
And with [Hugo Modules], you can share content, assets, data, translations, themes, templates, and configuration with other projects via public or private Git repositories.
See the [features] section of the documentation for a comprehensive summary of Hugo's capabilities.
## Sponsors
<p>&nbsp;</p>
<p float="left">
<a href="https://www.linode.com/?utm_campaign=hugosponsor&utm_medium=banner&utm_source=hugogithub" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/assets/images/sponsors/linode-logo_standard_light_medium.png" width="200" alt="Linode"></a>
&nbsp;&nbsp;&nbsp;
<a href="https://route4me.com/" target="_blank"><img src="https://raw.githubusercontent.com/gohugoio/gohugoioTheme/master/assets/images/sponsors/Route4MeLogoBlueOnWhite.svg" width="200" alt="Route Planning & Route Optimization Software"></a>
</p>
<p>&nbsp;</p>
## Installation
@@ -102,9 +97,6 @@ Build the extended edition:
```text
CGO_ENABLED=1 go install -tags extended github.com/gohugoio/hugo@latest
```
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=gohugoio/hugo&type=Timeline)](https://star-history.com/#gohugoio/hugo&Timeline)
## Documentation
@@ -149,39 +141,40 @@ Hugo stands on the shoulders of great open source libraries. Run `hugo env --log
```text
cloud.google.com/go/compute/metadata="v0.2.3"
cloud.google.com/go/iam="v1.1.5"
cloud.google.com/go/storage="v1.35.1"
cloud.google.com/go="v0.110.10"
github.com/Azure/azure-sdk-for-go/sdk/azcore="v1.9.0"
github.com/Azure/azure-sdk-for-go/sdk/azidentity="v1.4.0"
github.com/Azure/azure-sdk-for-go/sdk/internal="v1.5.0"
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob="v1.2.0"
cloud.google.com/go/iam="v1.1.3"
cloud.google.com/go/storage="v1.31.0"
cloud.google.com/go="v0.110.8"
github.com/Azure/azure-sdk-for-go/sdk/azcore="v1.7.0"
github.com/Azure/azure-sdk-for-go/sdk/azidentity="v1.3.0"
github.com/Azure/azure-sdk-for-go/sdk/internal="v1.3.0"
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob="v1.1.0"
github.com/Azure/go-autorest/autorest/to="v0.4.0"
github.com/AzureAD/microsoft-authentication-library-for-go="v1.2.0"
github.com/AzureAD/microsoft-authentication-library-for-go="v1.0.0"
github.com/BurntSushi/locker="v0.0.0-20171006230638-a6e239ea1c69"
github.com/alecthomas/chroma/v2="v2.14.0"
github.com/armon/go-radix="v1.0.1-0.20221118154546-54df44f2176c"
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream="v1.5.4"
github.com/aws/aws-sdk-go-v2/config="v1.26.1"
github.com/aws/aws-sdk-go-v2/credentials="v1.16.12"
github.com/aws/aws-sdk-go-v2/feature/ec2/imds="v1.14.10"
github.com/aws/aws-sdk-go-v2/feature/s3/manager="v1.15.7"
github.com/aws/aws-sdk-go-v2/internal/configsources="v1.3.5"
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2="v2.6.5"
github.com/aws/aws-sdk-go-v2/internal/ini="v1.7.2"
github.com/aws/aws-sdk-go-v2/internal/v4a="v1.2.9"
github.com/aws/aws-sdk-go-v2/service/cloudfront="v1.35.4"
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding="v1.10.4"
github.com/aws/aws-sdk-go-v2/service/internal/checksum="v1.2.9"
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url="v1.10.9"
github.com/aws/aws-sdk-go-v2/service/internal/s3shared="v1.16.9"
github.com/aws/aws-sdk-go-v2/service/s3="v1.47.5"
github.com/aws/aws-sdk-go-v2/service/sso="v1.18.5"
github.com/aws/aws-sdk-go-v2/service/ssooidc="v1.21.5"
github.com/aws/aws-sdk-go-v2/service/sts="v1.26.5"
github.com/aws/aws-sdk-go-v2="v1.26.1"
github.com/aws/aws-sdk-go="v1.50.7"
github.com/aws/smithy-go="v1.20.2"
github.com/PuerkitoBio/purell="v1.1.1"
github.com/PuerkitoBio/urlesc="v0.0.0-20170810143723-de5bf2ad4578"
github.com/alecthomas/chroma/v2="v2.11.1"
github.com/armon/go-radix="v1.0.0"
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream="v1.4.11"
github.com/aws/aws-sdk-go-v2/config="v1.18.32"
github.com/aws/aws-sdk-go-v2/credentials="v1.13.31"
github.com/aws/aws-sdk-go-v2/feature/ec2/imds="v1.13.7"
github.com/aws/aws-sdk-go-v2/feature/s3/manager="v1.11.76"
github.com/aws/aws-sdk-go-v2/internal/configsources="v1.1.37"
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2="v2.4.31"
github.com/aws/aws-sdk-go-v2/internal/ini="v1.3.38"
github.com/aws/aws-sdk-go-v2/internal/v4a="v1.1.0"
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding="v1.9.12"
github.com/aws/aws-sdk-go-v2/service/internal/checksum="v1.1.32"
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url="v1.9.31"
github.com/aws/aws-sdk-go-v2/service/internal/s3shared="v1.15.0"
github.com/aws/aws-sdk-go-v2/service/s3="v1.38.1"
github.com/aws/aws-sdk-go-v2/service/sso="v1.13.1"
github.com/aws/aws-sdk-go-v2/service/ssooidc="v1.15.1"
github.com/aws/aws-sdk-go-v2/service/sts="v1.21.1"
github.com/aws/aws-sdk-go-v2="v1.20.0"
github.com/aws/aws-sdk-go="v1.48.2"
github.com/aws/smithy-go="v1.14.0"
github.com/bep/clocks="v0.5.0"
github.com/bep/debounce="v1.2.0"
github.com/bep/gitmap="v1.1.2"
@@ -190,35 +183,32 @@ github.com/bep/godartsass/v2="v2.0.0"
github.com/bep/godartsass="v1.2.0"
github.com/bep/golibsass="v1.1.1"
github.com/bep/gowebp="v0.3.0"
github.com/bep/lazycache="v0.4.0"
github.com/bep/logg="v0.4.0"
github.com/bep/lazycache="v0.2.0"
github.com/bep/logg="v0.3.0"
github.com/bep/mclib="v1.20400.20402"
github.com/bep/overlayfs="v0.9.2"
github.com/bep/simplecobra="v0.4.0"
github.com/bep/overlayfs="v0.6.0"
github.com/bep/simplecobra="v0.3.2"
github.com/bep/tmc="v0.5.1"
github.com/clbanning/mxj/v2="v2.7.0"
github.com/cli/safeexec="v1.0.1"
github.com/cpuguy83/go-md2man/v2="v2.0.3"
github.com/cpuguy83/go-md2man/v2="v2.0.2"
github.com/disintegration/gift="v1.2.1"
github.com/dlclark/regexp2="v1.11.0"
github.com/dlclark/regexp2="v1.10.0"
github.com/dustin/go-humanize="v1.0.1"
github.com/evanw/esbuild="v0.21.4"
github.com/evanw/esbuild="v0.19.7"
github.com/fatih/color="v1.16.0"
github.com/frankban/quicktest="v1.14.6"
github.com/fsnotify/fsnotify="v1.7.0"
github.com/getkin/kin-openapi="v0.123.0"
github.com/getkin/kin-openapi="v0.120.0"
github.com/ghodss/yaml="v1.0.0"
github.com/go-openapi/jsonpointer="v0.20.2"
github.com/go-openapi/swag="v0.22.8"
github.com/go-openapi/jsonpointer="v0.19.6"
github.com/go-openapi/swag="v0.22.4"
github.com/gobuffalo/flect="v1.0.2"
github.com/gobwas/glob="v0.2.3"
github.com/gohugoio/go-i18n/v2="v2.1.3-0.20230805085216-e63c13218d0e"
github.com/gohugoio/httpcache="v0.7.0"
github.com/gohugoio/hugo-goldmark-extensions/extras="v0.2.0"
github.com/gohugoio/hugo-goldmark-extensions/passthrough="v0.2.0"
github.com/gohugoio/locales="v0.14.0"
github.com/gohugoio/localescompressed="v1.0.1"
github.com/golang-jwt/jwt/v5="v5.1.0"
github.com/golang-jwt/jwt/v4="v4.5.0"
github.com/golang/groupcache="v0.0.0-20210331224755-41bb18bfe9da"
github.com/golang/protobuf="v1.5.3"
github.com/google/go-cmp="v0.6.0"
@@ -229,7 +219,7 @@ github.com/googleapis/enterprise-certificate-proxy="v0.3.2"
github.com/googleapis/gax-go/v2="v2.12.0"
github.com/gorilla/websocket="v1.5.1"
github.com/hairyhenderson/go-codeowners="v0.4.0"
github.com/hashicorp/golang-lru/v2="v2.0.7"
github.com/hashicorp/golang-lru/v2="v2.0.1"
github.com/invopop/yaml="v0.2.0"
github.com/jdkato/prose="v1.2.1"
github.com/jmespath/go-jmespath="v0.4.0"
@@ -239,62 +229,63 @@ github.com/kr/text="v0.2.0"
github.com/kylelemons/godebug="v1.1.0"
github.com/kyokomi/emoji/v2="v2.2.12"
github.com/mailru/easyjson="v0.7.7"
github.com/makeworld-the-better-one/dither/v2="v2.4.0"
github.com/marekm4/color-extractor="v1.2.1"
github.com/mattn/go-colorable="v0.1.13"
github.com/mattn/go-isatty="v0.0.20"
github.com/mattn/go-runewidth="v0.0.9"
github.com/mitchellh/hashstructure="v1.1.0"
github.com/mitchellh/mapstructure="v1.5.1-0.20231216201459-8508981c8b6c"
github.com/mitchellh/mapstructure="v1.5.0"
github.com/mohae/deepcopy="v0.0.0-20170929034955-c48cc78d4826"
github.com/muesli/smartcrop="v0.3.0"
github.com/niklasfasching/go-org="v1.7.0"
github.com/olekukonko/tablewriter="v0.0.5"
github.com/pbnjay/memory="v0.0.0-20210728143218-7b4eea64cf58"
github.com/pelletier/go-toml/v2="v2.2.2"
github.com/pelletier/go-toml/v2="v2.1.0"
github.com/perimeterx/marshmallow="v1.1.5"
github.com/pkg/browser="v0.0.0-20210911075715-681adbf594b8"
github.com/pkg/errors="v0.9.1"
github.com/rogpeppe/go-internal="v1.12.0"
github.com/rogpeppe/go-internal="v1.11.0"
github.com/russross/blackfriday/v2="v2.1.0"
github.com/rwcarlsen/goexif="v0.0.0-20190401172101-9e8deecbddbd"
github.com/sass/dart-sass/compiler="1.77.5"
github.com/sass/dart-sass/implementation="1.77.5"
github.com/sass/dart-sass/protocol="2.7.1"
github.com/sanity-io/litter="v1.5.5"
github.com/sass/dart-sass/compiler="1.63.2"
github.com/sass/dart-sass/implementation="1.63.2"
github.com/sass/dart-sass/protocol="2.0.0"
github.com/sass/libsass="3.6.5"
github.com/spf13/afero="v1.11.0"
github.com/spf13/cast="v1.6.0"
github.com/spf13/cobra="v1.8.0"
github.com/spf13/fsync="v0.10.1"
github.com/spf13/afero="v1.10.0"
github.com/spf13/cast="v1.5.1"
github.com/spf13/cobra="v1.7.0"
github.com/spf13/fsync="v0.9.0"
github.com/spf13/pflag="v1.0.5"
github.com/tdewolff/minify/v2="v2.20.20"
github.com/tdewolff/parse/v2="v2.7.13"
github.com/tdewolff/minify/v2="v2.20.7"
github.com/tdewolff/parse/v2="v2.7.5"
github.com/webmproject/libwebp="v1.3.2"
github.com/yuin/goldmark-emoji="v1.0.3"
github.com/yuin/goldmark="v1.7.4"
github.com/yuin/goldmark-emoji="v1.0.2"
github.com/yuin/goldmark="v1.6.0"
go.opencensus.io="v0.24.0"
go.uber.org/atomic="v1.11.0"
go.uber.org/automaxprocs="v1.5.3"
gocloud.dev="v0.36.0"
golang.org/x/crypto="v0.23.0"
gocloud.dev="v0.34.0"
golang.org/x/crypto="v0.15.0"
golang.org/x/exp="v0.0.0-20221031165847-c99f073a8326"
golang.org/x/image="v0.16.0"
golang.org/x/mod="v0.17.0"
golang.org/x/net="v0.25.0"
golang.org/x/oauth2="v0.15.0"
golang.org/x/sync="v0.7.0"
golang.org/x/sys="v0.20.0"
golang.org/x/text="v0.15.0"
golang.org/x/time="v0.5.0"
golang.org/x/tools="v0.20.0"
golang.org/x/xerrors="v0.0.0-20231012003039-104605ab7028"
google.golang.org/api="v0.152.0"
google.golang.org/genproto/googleapis/api="v0.0.0-20231120223509-83a465c0220f"
google.golang.org/genproto/googleapis/rpc="v0.0.0-20231120223509-83a465c0220f"
google.golang.org/genproto="v0.0.0-20231120223509-83a465c0220f"
golang.org/x/image="v0.13.0"
golang.org/x/mod="v0.14.0"
golang.org/x/net="v0.18.0"
golang.org/x/oauth2="v0.13.0"
golang.org/x/sync="v0.5.0"
golang.org/x/sys="v0.14.0"
golang.org/x/text="v0.14.0"
golang.org/x/time="v0.3.0"
golang.org/x/tools="v0.15.0"
golang.org/x/xerrors="v0.0.0-20220907171357-04be3eba64a2"
google.golang.org/api="v0.151.0"
google.golang.org/genproto/googleapis/api="v0.0.0-20231016165738-49dd2c1f3d0b"
google.golang.org/genproto/googleapis/rpc="v0.0.0-20231030173426-d783a09b4405"
google.golang.org/genproto="v0.0.0-20231016165738-49dd2c1f3d0b"
google.golang.org/grpc="v1.59.0"
google.golang.org/protobuf="v1.33.0"
google.golang.org/protobuf="v1.31.0"
gopkg.in/yaml.v2="v2.4.0"
gopkg.in/yaml.v3="v3.0.1"
howett.net/plist="v1.0.0"
software.sslmate.com/src/go-pkcs12="v0.2.0"
```
</details>
+4 -14
View File
@@ -38,11 +38,6 @@ import (
const minMaxSize = 10
type KeyIdentity struct {
Key any
Identity identity.Identity
}
// New creates a new cache.
func New(opts Options) *Cache {
if opts.CheckInterval == 0 {
@@ -69,14 +64,14 @@ func New(opts Options) *Cache {
infol := opts.Log.InfoCommand("dynacache")
evictedIdentities := collections.NewStack[KeyIdentity]()
evictedIdentities := collections.NewStack[identity.Identity]()
onEvict := func(k, v any) {
if !opts.Watching {
return
}
identity.WalkIdentitiesShallow(v, func(level int, id identity.Identity) bool {
evictedIdentities.Push(KeyIdentity{Key: k, Identity: id})
evictedIdentities.Push(id)
return false
})
resource.MarkStale(v)
@@ -129,7 +124,7 @@ type Cache struct {
partitions map[string]PartitionManager
onEvict func(k, v any)
evictedIdentities *collections.Stack[KeyIdentity]
evictedIdentities *collections.Stack[identity.Identity]
opts Options
infol logg.LevelLogger
@@ -140,15 +135,10 @@ type Cache struct {
}
// DrainEvictedIdentities drains the evicted identities from the cache.
func (c *Cache) DrainEvictedIdentities() []KeyIdentity {
func (c *Cache) DrainEvictedIdentities() []identity.Identity {
return c.evictedIdentities.Drain()
}
// DrainEvictedIdentitiesMatching drains the evicted identities from the cache that match the given predicate.
func (c *Cache) DrainEvictedIdentitiesMatching(predicate func(KeyIdentity) bool) []KeyIdentity {
return c.evictedIdentities.DrainMatching(predicate)
}
// ClearMatching clears all partition for which the predicate returns true.
func (c *Cache) ClearMatching(predicatePartition func(k string, p PartitionManager) bool, predicateValue func(k, v any) bool) {
if predicatePartition == nil {
+1
View File
@@ -83,6 +83,7 @@ func (c *Config) Compile() (ConfigCompiled, error) {
}
// PollConfig holds the configuration for polling remote resources to detect changes in watch mode.
// TODO1 make sure this enabled only in watch mode.
type PollConfig struct {
// What remote resources to apply this configuration to.
For GlobMatcher
+16 -71
View File
@@ -744,20 +744,6 @@ func (c *hugoBuilder) handleEvents(watcher *watcher.Batcher,
staticEvents := []fsnotify.Event{}
dynamicEvents := []fsnotify.Event{}
filterDuplicateEvents := func(evs []fsnotify.Event) []fsnotify.Event {
seen := make(map[string]bool)
var n int
for _, ev := range evs {
if seen[ev.Name] {
continue
}
seen[ev.Name] = true
evs[n] = ev
n++
}
return evs[:n]
}
h, err := c.hugo()
if err != nil {
c.r.logger.Errorln("Error getting the Hugo object:", err)
@@ -847,11 +833,6 @@ func (c *hugoBuilder) handleEvents(watcher *watcher.Batcher,
}
}
lrl := c.r.logger.InfoCommand("livereload")
staticEvents = filterDuplicateEvents(staticEvents)
dynamicEvents = filterDuplicateEvents(dynamicEvents)
if len(staticEvents) > 0 {
c.printChangeDetected("Static files")
@@ -872,20 +853,19 @@ func (c *hugoBuilder) handleEvents(watcher *watcher.Batcher,
if c.s != nil && c.s.doLiveReload {
// Will block forever trying to write to a channel that nobody is reading if livereload isn't initialized
// force refresh when more than one file
if !c.errState.wasErr() && len(staticEvents) == 1 {
ev := staticEvents[0]
h, err := c.hugo()
if err != nil {
c.r.logger.Errorln("Error getting the Hugo object:", err)
return
}
path := h.BaseFs.SourceFilesystems.MakeStaticPathRelative(staticEvents[0].Name)
path := h.BaseFs.SourceFilesystems.MakeStaticPathRelative(ev.Name)
path = h.RelURL(paths.ToSlashTrimLeading(path), false)
lrl.Logf("refreshing static file %q", path)
livereload.RefreshPath(path)
} else {
lrl.Logf("got %d static file change events, force refresh", len(staticEvents))
livereload.ForceRefresh()
}
}
@@ -909,30 +889,20 @@ func (c *hugoBuilder) handleEvents(watcher *watcher.Batcher,
}()
if c.s != nil && c.s.doLiveReload {
if c.errState.wasErr() {
livereload.ForceRefresh()
return
}
changed := c.changeDetector.changed()
if c.changeDetector != nil {
lrl.Logf("build changed %d files", len(changed))
if len(changed) == 0 {
// Nothing has changed.
if len(partitionedEvents.ContentEvents) == 0 && len(partitionedEvents.AssetEvents) > 0 {
if c.errState.wasErr() {
livereload.ForceRefresh()
return
}
}
// If this change set also contains one or more CSS files, we need to
// refresh these as well.
var cssChanges []string
var otherChanges []string
for _, ev := range changed {
if strings.HasSuffix(ev, ".css") {
cssChanges = append(cssChanges, ev)
changed := c.changeDetector.changed()
if c.changeDetector != nil && len(changed) == 0 {
// Nothing has changed.
return
} else if len(changed) == 1 {
pathToRefresh := h.PathSpec.RelURL(paths.ToSlashTrimLeading(changed[0]), false)
livereload.RefreshPath(pathToRefresh)
} else {
otherChanges = append(otherChanges, ev)
livereload.ForceRefresh()
}
}
@@ -948,36 +918,11 @@ func (c *hugoBuilder) handleEvents(watcher *watcher.Batcher,
}
}
if p != nil && p.RelPermalink() != "" {
link, port := p.RelPermalink(), p.Site().ServerPort()
lrl.Logf("navigating to %q using port %d", link, port)
livereload.NavigateToPathForPort(link, port)
if p != nil {
livereload.NavigateToPathForPort(p.RelPermalink(), p.Site().ServerPort())
} else {
lrl.Logf("no page to navigate to, force refresh")
livereload.ForceRefresh()
}
} else if len(otherChanges) > 0 {
if len(otherChanges) == 1 {
// Allow single changes to be refreshed without a full page reload.
pathToRefresh := h.PathSpec.RelURL(paths.ToSlashTrimLeading(otherChanges[0]), false)
lrl.Logf("refreshing %q", pathToRefresh)
livereload.RefreshPath(pathToRefresh)
} else if len(cssChanges) == 0 {
lrl.Logf("force refresh")
livereload.ForceRefresh()
}
}
if len(cssChanges) > 0 {
// Allow some time for the live reload script to get reconnected.
if len(otherChanges) > 0 {
time.Sleep(200 * time.Millisecond)
}
for _, ev := range cssChanges {
pathToRefresh := h.PathSpec.RelURL(paths.ToSlashTrimLeading(ev), false)
lrl.Logf("refreshing CSS %q", pathToRefresh)
livereload.RefreshPath(pathToRefresh)
}
}
}
}
+2 -3
View File
@@ -268,14 +268,13 @@ Run "go help get" for more information. All flags available for "go get" is also
if info.Name() == "go.mod" {
// Found a module.
dir := filepath.Dir(path)
r.Println("Update module in", dir)
cfg := config.New()
cfg.Set("workingDir", dir)
conf, err := r.ConfigFromProvider(r.configVersionID.Add(1), flagsToCfg(cd, cfg))
conf, err := r.ConfigFromProvider(r.configVersionID.Load(), flagsToCfg(cd, cfg))
if err != nil {
return err
}
r.Println("Update module in", conf.configs.Base.WorkingDir)
client := conf.configs.ModulesClient
return client.Get(args...)
+8 -8
View File
@@ -162,16 +162,16 @@ type dynamicEvents struct {
type fileChangeDetector struct {
sync.Mutex
current map[string]uint64
prev map[string]uint64
current map[string]string
prev map[string]string
irrelevantRe *regexp.Regexp
}
func (f *fileChangeDetector) OnFileClose(name string, checksum uint64) {
func (f *fileChangeDetector) OnFileClose(name, md5sum string) {
f.Lock()
defer f.Unlock()
f.current[name] = checksum
f.current[name] = md5sum
}
func (f *fileChangeDetector) PrepareNew() {
@@ -183,16 +183,16 @@ func (f *fileChangeDetector) PrepareNew() {
defer f.Unlock()
if f.current == nil {
f.current = make(map[string]uint64)
f.prev = make(map[string]uint64)
f.current = make(map[string]string)
f.prev = make(map[string]string)
return
}
f.prev = make(map[string]uint64)
f.prev = make(map[string]string)
for k, v := range f.current {
f.prev[k] = v
}
f.current = make(map[string]uint64)
f.current = make(map[string]string)
}
func (f *fileChangeDetector) changed() []string {
-13
View File
@@ -65,16 +65,3 @@ func (s *Stack[T]) Drain() []T {
s.items = nil
return items
}
func (s *Stack[T]) DrainMatching(predicate func(T) bool) []T {
s.mu.Lock()
defer s.mu.Unlock()
var items []T
for i := len(s.items) - 1; i >= 0; i-- {
if predicate(s.items[i]) {
items = append(items, s.items[i])
s.items = append(s.items[:i], s.items[i+1:]...)
}
}
return items
}
-166
View File
@@ -1,166 +0,0 @@
// Copyright 2024 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 hashing provides common hashing utilities.
package hashing
import (
"crypto/md5"
"encoding/hex"
"io"
"strconv"
"sync"
"github.com/cespare/xxhash/v2"
"github.com/gohugoio/hashstructure"
"github.com/gohugoio/hugo/identity"
)
// XXHashFromReader calculates the xxHash for the given reader.
func XXHashFromReader(r io.Reader) (uint64, int64, error) {
h := getXxHashReadFrom()
defer putXxHashReadFrom(h)
size, err := io.Copy(h, r)
if err != nil {
return 0, 0, err
}
return h.Sum64(), size, nil
}
// XXHashFromString calculates the xxHash for the given string.
func XXHashFromString(s string) (uint64, error) {
h := xxhash.New()
h.WriteString(s)
return h.Sum64(), nil
}
// XxHashFromStringHexEncoded calculates the xxHash for the given string
// and returns the hash as a hex encoded string.
func XxHashFromStringHexEncoded(f string) string {
h := xxhash.New()
h.WriteString(f)
hash := h.Sum(nil)
return hex.EncodeToString(hash)
}
// MD5FromStringHexEncoded returns the MD5 hash of the given string.
func MD5FromStringHexEncoded(f string) string {
h := md5.New()
h.Write([]byte(f))
return hex.EncodeToString(h.Sum(nil))
}
// HashString returns a hash from the given elements.
// It will panic if the hash cannot be calculated.
// Note that this hash should be used primarily for identity, not for change detection as
// it in the more complex values (e.g. Page) will not hash the full content.
func HashString(vs ...any) string {
hash := HashUint64(vs...)
return strconv.FormatUint(hash, 10)
}
var hashOptsPool = sync.Pool{
New: func() any {
return &hashstructure.HashOptions{
Hasher: xxhash.New(),
}
},
}
func getHashOpts() *hashstructure.HashOptions {
return hashOptsPool.Get().(*hashstructure.HashOptions)
}
func putHashOpts(opts *hashstructure.HashOptions) {
opts.Hasher.Reset()
hashOptsPool.Put(opts)
}
// HashUint64 returns a hash from the given elements.
// It will panic if the hash cannot be calculated.
// Note that this hash should be used primarily for identity, not for change detection as
// it in the more complex values (e.g. Page) will not hash the full content.
func HashUint64(vs ...any) uint64 {
var o any
if len(vs) == 1 {
o = toHashable(vs[0])
} else {
elements := make([]any, len(vs))
for i, e := range vs {
elements[i] = toHashable(e)
}
o = elements
}
hashOpts := getHashOpts()
defer putHashOpts(hashOpts)
hash, err := hashstructure.Hash(o, hashOpts)
if err != nil {
panic(err)
}
return hash
}
type keyer interface {
Key() string
}
// For structs, hashstructure.Hash only works on the exported fields,
// so rewrite the input slice for known identity types.
func toHashable(v any) any {
switch t := v.(type) {
case keyer:
return t.Key()
case identity.IdentityProvider:
return t.GetIdentity()
default:
return v
}
}
type xxhashReadFrom struct {
buff []byte
*xxhash.Digest
}
func (x *xxhashReadFrom) ReadFrom(r io.Reader) (int64, error) {
for {
n, err := r.Read(x.buff)
if n > 0 {
x.Digest.Write(x.buff[:n])
}
if err != nil {
if err == io.EOF {
err = nil
}
return int64(n), err
}
}
}
var xXhashReadFromPool = sync.Pool{
New: func() any {
return &xxhashReadFrom{Digest: xxhash.New(), buff: make([]byte, 48*1024)}
},
}
func getXxHashReadFrom() *xxhashReadFrom {
return xXhashReadFromPool.Get().(*xxhashReadFrom)
}
func putXxHashReadFrom(h *xxhashReadFrom) {
h.Reset()
xXhashReadFromPool.Put(h)
}
-144
View File
@@ -1,144 +0,0 @@
// Copyright 2024 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 hashing
import (
"fmt"
"math"
"strings"
"sync"
"testing"
qt "github.com/frankban/quicktest"
)
func TestXxHashFromReader(t *testing.T) {
c := qt.New(t)
s := "Hello World"
r := strings.NewReader(s)
got, size, err := XXHashFromReader(r)
c.Assert(err, qt.IsNil)
c.Assert(size, qt.Equals, int64(len(s)))
c.Assert(got, qt.Equals, uint64(7148569436472236994))
}
func TestXxHashFromReaderPara(t *testing.T) {
c := qt.New(t)
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
i := i
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 100; j++ {
s := strings.Repeat("Hello ", i+j+1*42)
r := strings.NewReader(s)
got, size, err := XXHashFromReader(r)
c.Assert(size, qt.Equals, int64(len(s)))
c.Assert(err, qt.IsNil)
expect, _ := XXHashFromString(s)
c.Assert(got, qt.Equals, expect)
}
}()
}
wg.Wait()
}
func TestXxHashFromString(t *testing.T) {
c := qt.New(t)
s := "Hello World"
got, err := XXHashFromString(s)
c.Assert(err, qt.IsNil)
c.Assert(got, qt.Equals, uint64(7148569436472236994))
}
func TestXxHashFromStringHexEncoded(t *testing.T) {
c := qt.New(t)
s := "The quick brown fox jumps over the lazy dog"
got := XxHashFromStringHexEncoded(s)
// Facit: https://asecuritysite.com/encryption/xxhash?val=The%20quick%20brown%20fox%20jumps%20over%20the%20lazy%20dog
c.Assert(got, qt.Equals, "0b242d361fda71bc")
}
func BenchmarkXXHashFromReader(b *testing.B) {
r := strings.NewReader("Hello World")
b.ResetTimer()
for i := 0; i < b.N; i++ {
XXHashFromReader(r)
r.Seek(0, 0)
}
}
func BenchmarkXXHashFromString(b *testing.B) {
s := "Hello World"
b.ResetTimer()
for i := 0; i < b.N; i++ {
XXHashFromString(s)
}
}
func BenchmarkXXHashFromStringHexEncoded(b *testing.B) {
s := "The quick brown fox jumps over the lazy dog"
b.ResetTimer()
for i := 0; i < b.N; i++ {
XxHashFromStringHexEncoded(s)
}
}
func TestHashString(t *testing.T) {
c := qt.New(t)
c.Assert(HashString("a", "b"), qt.Equals, "3176555414984061461")
c.Assert(HashString("ab"), qt.Equals, "7347350983217793633")
var vals []any = []any{"a", "b", tstKeyer{"c"}}
c.Assert(HashString(vals...), qt.Equals, "4438730547989914315")
c.Assert(vals[2], qt.Equals, tstKeyer{"c"})
}
type tstKeyer struct {
key string
}
func (t tstKeyer) Key() string {
return t.key
}
func (t tstKeyer) String() string {
return "key: " + t.key
}
func BenchmarkHashString(b *testing.B) {
word := " hello "
var tests []string
for i := 1; i <= 5; i++ {
sentence := strings.Repeat(word, int(math.Pow(4, float64(i))))
tests = append(tests, sentence)
}
b.ResetTimer()
for _, test := range tests {
b.Run(fmt.Sprintf("n%d", len(test)), func(b *testing.B) {
for i := 0; i < b.N; i++ {
HashString(test)
}
})
}
}
+4 -37
View File
@@ -68,20 +68,6 @@ func (e *TimeoutError) Is(target error) bool {
return ok
}
// errMessage wraps an error with a message.
type errMessage struct {
msg string
err error
}
func (e *errMessage) Error() string {
return e.msg
}
func (e *errMessage) Unwrap() error {
return e.err
}
// IsFeatureNotAvailableError returns true if the given error is or contains a FeatureNotAvailableError.
func IsFeatureNotAvailableError(err error) bool {
return errors.Is(err, &FeatureNotAvailableError{})
@@ -135,38 +121,19 @@ func IsNotExist(err error) bool {
var nilPointerErrRe = regexp.MustCompile(`at <(.*)>: error calling (.*?): runtime error: invalid memory address or nil pointer dereference`)
const deferredPrefix = "__hdeferred/"
var deferredStringToRemove = regexp.MustCompile(`executing "__hdeferred/.*" `)
// ImproveRenderErr improves the error message for rendering errors.
func ImproveRenderErr(inErr error) (outErr error) {
func ImproveIfNilPointer(inErr error) (outErr error) {
outErr = inErr
msg := improveIfNilPointerMsg(inErr)
if msg != "" {
outErr = &errMessage{msg: msg, err: outErr}
}
if strings.Contains(inErr.Error(), deferredPrefix) {
msg := deferredStringToRemove.ReplaceAllString(inErr.Error(), "executing ")
outErr = &errMessage{msg: msg, err: outErr}
}
return
}
func improveIfNilPointerMsg(inErr error) string {
m := nilPointerErrRe.FindStringSubmatch(inErr.Error())
if len(m) == 0 {
return ""
return
}
call := m[1]
field := m[2]
parts := strings.Split(call, ".")
if len(parts) < 2 {
return ""
}
receiverName := parts[len(parts)-2]
receiver := strings.Join(parts[:len(parts)-1], ".")
s := fmt.Sprintf(" %s is nil; wrap it in if or with: {{ with %s }}{{ .%s }}{{ end }}", receiverName, receiver, field)
return nilPointerErrRe.ReplaceAllString(inErr.Error(), s)
outErr = errors.New(nilPointerErrRe.ReplaceAllString(inErr.Error(), s))
return
}
+17 -77
View File
@@ -21,10 +21,8 @@ import (
"io"
"os"
"os/exec"
"path/filepath"
"regexp"
"strings"
"sync"
"github.com/cli/safeexec"
"github.com/gohugoio/hugo/config"
@@ -86,7 +84,7 @@ var WithEnviron = func(env []string) func(c *commandeer) {
}
// New creates a new Exec using the provided security config.
func New(cfg security.Config, workingDir string) *Exec {
func New(cfg security.Config) *Exec {
var baseEnviron []string
for _, v := range os.Environ() {
k, _ := config.SplitEnvVar(v)
@@ -97,7 +95,6 @@ func New(cfg security.Config, workingDir string) *Exec {
return &Exec{
sc: cfg,
workingDir: workingDir,
baseEnviron: baseEnviron,
}
}
@@ -122,23 +119,15 @@ func SafeCommand(name string, arg ...string) (*exec.Cmd, error) {
// Exec enforces a security policy for commands run via os/exec.
type Exec struct {
sc security.Config
workingDir string
sc security.Config
// os.Environ filtered by the Exec.OsEnviron whitelist filter.
baseEnviron []string
npxInit sync.Once
npxAvailable bool
}
func (e *Exec) New(name string, arg ...any) (Runner, error) {
return e.new(name, "", arg...)
}
// New will fail if name is not allowed according to the configured security policy.
// Else a configured Runner will be returned ready to be Run.
func (e *Exec) new(name string, fullyQualifiedName string, arg ...any) (Runner, error) {
func (e *Exec) New(name string, arg ...any) (Runner, error) {
if err := e.sc.CheckAllowedExec(name); err != nil {
return nil, err
}
@@ -147,51 +136,17 @@ func (e *Exec) new(name string, fullyQualifiedName string, arg ...any) (Runner,
copy(env, e.baseEnviron)
cm := &commandeer{
name: name,
fullyQualifiedName: fullyQualifiedName,
env: env,
name: name,
env: env,
}
return cm.command(arg...)
}
// Npx will in order:
// 1. Try fo find the binary in the WORKINGDIR/node_modules/.bin directory.
// 2. If not found, and npx is available, run npx --no-install <name> <args>.
// 3. Fall back to the PATH.
// Npx is a convenience method to create a Runner running npx --no-install <name> <args.
func (e *Exec) Npx(name string, arg ...any) (Runner, error) {
// npx is slow, so first try the common case.
nodeBinFilename := filepath.Join(e.workingDir, nodeModulesBinPath, name)
_, err := safeexec.LookPath(nodeBinFilename)
if err == nil {
return e.new(name, nodeBinFilename, arg...)
}
e.checkNpx()
if e.npxAvailable {
r, err := e.npx(name, arg...)
if err == nil {
return r, nil
}
}
return e.New(name, arg...)
}
const (
npxNoInstall = "--no-install"
npxBinary = "npx"
nodeModulesBinPath = "node_modules/.bin"
)
func (e *Exec) checkNpx() {
e.npxInit.Do(func() {
e.npxAvailable = InPath(npxBinary)
})
}
// npx is a convenience method to create a Runner running npx --no-install <name> <args.
func (e *Exec) npx(name string, arg ...any) (Runner, error) {
arg = append(arg[:0], append([]any{npxNoInstall, name}, arg[0:]...)...)
return e.New(npxBinary, arg...)
arg = append(arg[:0], append([]any{"--no-install", name}, arg[0:]...)...)
return e.New("npx", arg...)
}
// Sec returns the security policies this Exec is configured with.
@@ -200,12 +155,11 @@ func (e *Exec) Sec() security.Config {
}
type NotFoundError struct {
name string
method string
name string
}
func (e *NotFoundError) Error() string {
return fmt.Sprintf("binary with name %q not found %s", e.name, e.method)
return fmt.Sprintf("binary with name %q not found", e.name)
}
// Runner wraps a *os.Cmd.
@@ -228,14 +182,8 @@ func (c *cmdWrapper) Run() error {
if err == nil {
return nil
}
name := c.name
method := "in PATH"
if name == npxBinary {
name = c.c.Args[2]
method = "using npx"
}
if notFoundRe.MatchString(c.outerr.String()) {
return &NotFoundError{name: name, method: method}
return &NotFoundError{name: c.name}
}
return fmt.Errorf("failed to execute binary %q with args %v: %s", c.name, c.c.Args[1:], c.outerr.String())
}
@@ -251,9 +199,8 @@ type commandeer struct {
dir string
ctx context.Context
name string
fullyQualifiedName string
env []string
name string
env []string
}
func (c *commandeer) command(arg ...any) (*cmdWrapper, error) {
@@ -273,17 +220,10 @@ func (c *commandeer) command(arg ...any) (*cmdWrapper, error) {
}
}
var bin string
if c.fullyQualifiedName != "" {
bin = c.fullyQualifiedName
} else {
var err error
bin, err = safeexec.LookPath(c.name)
if err != nil {
return nil, &NotFoundError{
name: c.name,
method: "in PATH",
}
bin, err := safeexec.LookPath(c.name)
if err != nil {
return nil, &NotFoundError{
name: c.name,
}
}
+9 -32
View File
@@ -17,35 +17,24 @@ import (
"bytes"
)
// HasBytesWriter is a writer will match against a slice of patterns.
// HasBytesWriter is a writer that will set Match to true if the given pattern
// is found in the stream.
type HasBytesWriter struct {
Patterns []*HasBytesPattern
Match bool
Pattern []byte
i int
done bool
buff []byte
}
type HasBytesPattern struct {
Match bool
Pattern []byte
}
func (h *HasBytesWriter) patternLen() int {
l := 0
for _, p := range h.Patterns {
l += len(p.Pattern)
}
return l
}
func (h *HasBytesWriter) Write(p []byte) (n int, err error) {
if h.done {
return len(p), nil
}
if len(h.buff) == 0 {
h.buff = make([]byte, h.patternLen()*2)
h.buff = make([]byte, len(h.Pattern)*2)
}
for i := range p {
@@ -57,23 +46,11 @@ func (h *HasBytesWriter) Write(p []byte) (n int, err error) {
h.i = len(h.buff) / 2
}
for _, pp := range h.Patterns {
if bytes.Contains(h.buff, pp.Pattern) {
pp.Match = true
done := true
for _, ppp := range h.Patterns {
if !ppp.Match {
done = false
break
}
}
if done {
h.done = true
}
return len(p), nil
}
if bytes.Contains(h.buff, h.Pattern) {
h.Match = true
h.done = true
return len(p), nil
}
}
return len(p), nil
+5 -8
View File
@@ -34,11 +34,8 @@ func TestHasBytesWriter(t *testing.T) {
var b bytes.Buffer
h := &HasBytesWriter{
Patterns: []*HasBytesPattern{
{Pattern: []byte("__foo")},
},
Pattern: []byte("__foo"),
}
return h, io.MultiWriter(&b, h)
}
@@ -49,19 +46,19 @@ func TestHasBytesWriter(t *testing.T) {
for i := 0; i < 22; i++ {
h, w := neww()
fmt.Fprintf(w, rndStr()+"abc __foobar"+rndStr())
c.Assert(h.Patterns[0].Match, qt.Equals, true)
c.Assert(h.Match, qt.Equals, true)
h, w = neww()
fmt.Fprintf(w, rndStr()+"abc __f")
fmt.Fprintf(w, "oo bar"+rndStr())
c.Assert(h.Patterns[0].Match, qt.Equals, true)
c.Assert(h.Match, qt.Equals, true)
h, w = neww()
fmt.Fprintf(w, rndStr()+"abc __moo bar")
c.Assert(h.Patterns[0].Match, qt.Equals, false)
c.Assert(h.Match, qt.Equals, false)
}
h, w := neww()
fmt.Fprintf(w, "__foo")
c.Assert(h.Patterns[0].Match, qt.Equals, true)
c.Assert(h.Match, qt.Equals, true)
}
+1 -1
View File
@@ -17,7 +17,7 @@ package hugo
// This should be the only one.
var CurrentVersion = Version{
Major: 0,
Minor: 131,
Minor: 127,
PatchLevel: 0,
Suffix: "-DEV",
}
+2 -2
View File
@@ -21,7 +21,7 @@ import (
"sync"
"github.com/bep/logg"
"github.com/gohugoio/hugo/common/hashing"
"github.com/gohugoio/hugo/identity"
)
// PanicOnWarningHook panics on warnings.
@@ -85,7 +85,7 @@ func (h *logOnceHandler) HandleLog(e *logg.Entry) error {
}
h.mu.Lock()
defer h.mu.Unlock()
hash := hashing.HashUint64(e.Level, e.Message, e.Fields)
hash := identity.HashUint64(e.Level, e.Message, e.Fields)
if h.seen[hash] {
return errStop
}
-2
View File
@@ -323,13 +323,11 @@ func (l *logAdapter) Errors() string {
}
func (l *logAdapter) Erroridf(id, format string, v ...any) {
id = strings.ToLower(id)
format += l.idfInfoStatement("error", id, format)
l.errorl.WithField(FieldNameStatementID, id).Logf(format, v...)
}
func (l *logAdapter) Warnidf(id, format string, v ...any) {
id = strings.ToLower(id)
format += l.idfInfoStatement("warning", id, format)
l.warnl.WithField(FieldNameStatementID, id).Logf(format, v...)
}
-20
View File
@@ -74,26 +74,6 @@ func (c *Cache[K, T]) ForEeach(f func(K, T)) {
}
}
func (c *Cache[K, T]) Drain() map[K]T {
c.Lock()
m := c.m
c.m = make(map[K]T)
c.Unlock()
return m
}
func (c *Cache[K, T]) Len() int {
c.RLock()
defer c.RUnlock()
return len(c.m)
}
func (c *Cache[K, T]) Reset() {
c.Lock()
c.m = make(map[K]T)
c.Unlock()
}
// SliceCache is a simple thread safe cache backed by a map.
type SliceCache[T any] struct {
m map[string][]T
+5 -36
View File
@@ -237,17 +237,12 @@ func prettifyPath(in string, b filepathPathBridge) string {
return b.Join(b.Dir(in), name, "index"+ext)
}
// CommonDirPath returns the common directory of the given paths.
func CommonDirPath(path1, path2 string) string {
// CommonDir returns the common directory of the given paths.
func CommonDir(path1, path2 string) string {
if path1 == "" || path2 == "" {
return ""
}
hadLeadingSlash := strings.HasPrefix(path1, "/") || strings.HasPrefix(path2, "/")
path1 = TrimLeading(path1)
path2 = TrimLeading(path2)
p1 := strings.Split(path1, "/")
p2 := strings.Split(path2, "/")
@@ -261,13 +256,7 @@ func CommonDirPath(path1, path2 string) string {
}
}
s := strings.Join(common, "/")
if hadLeadingSlash && s != "" {
s = "/" + s
}
return s
return strings.Join(common, "/")
}
// Sanitize sanitizes string to be used in Hugo's file paths and URLs, allowing only
@@ -395,27 +384,12 @@ func PathEscape(pth string) string {
// ToSlashTrimLeading is just a filepath.ToSlash with an added / prefix trimmer.
func ToSlashTrimLeading(s string) string {
return TrimLeading(filepath.ToSlash(s))
}
// TrimLeading trims the leading slash from the given string.
func TrimLeading(s string) string {
return strings.TrimPrefix(s, "/")
return strings.TrimPrefix(filepath.ToSlash(s), "/")
}
// ToSlashTrimTrailing is just a filepath.ToSlash with an added / suffix trimmer.
func ToSlashTrimTrailing(s string) string {
return TrimTrailing(filepath.ToSlash(s))
}
// TrimTrailing trims the trailing slash from the given string.
func TrimTrailing(s string) string {
return strings.TrimSuffix(s, "/")
}
// ToSlashTrim trims any leading and trailing slashes from the given string and converts it to a forward slash separated path.
func ToSlashTrim(s string) string {
return strings.Trim(filepath.ToSlash(s), "/")
return strings.TrimSuffix(filepath.ToSlash(s), "/")
}
// ToSlashPreserveLeading converts the path given to a forward slash separated path
@@ -423,8 +397,3 @@ func ToSlashTrim(s string) string {
func ToSlashPreserveLeading(s string) string {
return "/" + strings.Trim(filepath.ToSlash(s), "/")
}
// IsSameFilePath checks if s1 and s2 are the same file path.
func IsSameFilePath(s1, s2 string) bool {
return path.Clean(ToSlashTrim(s1)) == path.Clean(ToSlashTrim(s2))
}
-49
View File
@@ -262,52 +262,3 @@ func TestFieldsSlash(t *testing.T) {
c.Assert(FieldsSlash("/"), qt.DeepEquals, []string{})
c.Assert(FieldsSlash(""), qt.DeepEquals, []string{})
}
func TestCommonDirPath(t *testing.T) {
c := qt.New(t)
for _, this := range []struct {
a, b, expected string
}{
{"/a/b/c", "/a/b/d", "/a/b"},
{"/a/b/c", "a/b/d", "/a/b"},
{"a/b/c", "/a/b/d", "/a/b"},
{"a/b/c", "a/b/d", "a/b"},
{"/a/b/c", "/a/b/c", "/a/b/c"},
{"/a/b/c", "/a/b/c/d", "/a/b/c"},
{"/a/b/c", "/a/b", "/a/b"},
{"/a/b/c", "/a", "/a"},
{"/a/b/c", "/d/e/f", ""},
} {
c.Assert(CommonDirPath(this.a, this.b), qt.Equals, this.expected, qt.Commentf("a: %s b: %s", this.a, this.b))
}
}
func TestIsSameFilePath(t *testing.T) {
c := qt.New(t)
for _, this := range []struct {
a, b string
expected bool
}{
{"/a/b/c", "/a/b/c", true},
{"/a/b/c", "/a/b/c/", true},
{"/a/b/c", "/a/b/d", false},
{"/a/b/c", "/a/b", false},
{"/a/b/c", "/a/b/c/d", false},
{"/a/b/c", "/a/b/cd", false},
{"/a/b/c", "/a/b/cc", false},
{"/a/b/c", "/a/b/c/", true},
{"/a/b/c", "/a/b/c//", true},
{"/a/b/c", "/a/b/c/.", true},
{"/a/b/c", "/a/b/c/./", true},
{"/a/b/c", "/a/b/c/./.", true},
{"/a/b/c", "/a/b/c/././", true},
{"/a/b/c", "/a/b/c/././.", true},
{"/a/b/c", "/a/b/c/./././", true},
{"/a/b/c", "/a/b/c/./././.", true},
{"/a/b/c", "/a/b/c/././././", true},
} {
c.Assert(IsSameFilePath(filepath.FromSlash(this.a), filepath.FromSlash(this.b)), qt.Equals, this.expected, qt.Commentf("a: %s b: %s", this.a, this.b))
}
}
+1 -21
View File
@@ -179,9 +179,6 @@ type Config struct {
// Server configuration.
Server config.Server `mapstructure:"-"`
// Pagination configuration.
Pagination config.Pagination `mapstructure:"-"`
// Privacy configuration.
Privacy privacy.Config `mapstructure:"-"`
@@ -315,13 +312,9 @@ func (c *Config) CompileConfig(logger loggers.Logger) error {
}
}
for i, s := range c.IgnoreLogs {
c.IgnoreLogs[i] = strings.ToLower(s)
}
ignoredLogIDs := make(map[string]bool)
for _, err := range c.IgnoreLogs {
ignoredLogIDs[err] = true
ignoredLogIDs[strings.ToLower(err)] = true
}
baseURL, err := urls.NewBaseURLFromString(c.BaseURL)
@@ -376,17 +369,6 @@ func (c *Config) CompileConfig(logger loggers.Logger) error {
return err
}
// Legacy paginate values.
if c.Paginate != 0 {
hugo.Deprecate("site config key paginate", "Use paginator.pagerSize instead.", "v0.128.0")
c.Pagination.PagerSize = c.Paginate
}
if c.PaginatePath != "" {
hugo.Deprecate("site config key paginatePath", "Use paginator.path instead.", "v0.128.0")
c.Pagination.Path = c.PaginatePath
}
c.C = &ConfigCompiled{
Timeout: timeout,
BaseURL: baseURL,
@@ -575,11 +557,9 @@ type RootConfig struct {
HasCJKLanguage bool
// The default number of pages per page when paginating.
// Deprecated: Use the Pagination struct.
Paginate int
// The path to use when creating pagination URLs, e.g. "page" in /page/2/.
// Deprecated: Use the Pagination struct.
PaginatePath string
// Whether to pluralize default list titles.
@@ -102,85 +102,3 @@ suffixes = ["html", "xhtml"]
b.Assert(contentTypes.HTML.Suffixes(), qt.DeepEquals, []string{"html", "xhtml"})
b.Assert(contentTypes.Markdown.Suffixes(), qt.DeepEquals, []string{"md", "mdown", "markdown"})
}
func TestPaginationConfigOld(t *testing.T) {
files := `
-- hugo.toml --
[languages.en]
weight = 1
paginatePath = "page-en"
[languages.de]
weight = 2
paginatePath = "page-de"
paginate = 20
`
b := hugolib.Test(t, files)
confEn := b.H.Sites[0].Conf.Pagination()
confDe := b.H.Sites[1].Conf.Pagination()
b.Assert(confEn.Path, qt.Equals, "page-en")
b.Assert(confEn.PagerSize, qt.Equals, 10)
b.Assert(confDe.Path, qt.Equals, "page-de")
b.Assert(confDe.PagerSize, qt.Equals, 20)
}
func TestPaginationConfigNew(t *testing.T) {
files := `
-- hugo.toml --
[languages.en]
weight = 1
[languages.en.pagination]
pagerSize = 20
[languages.de]
weight = 2
[languages.de.pagination]
path = "page-de"
`
b := hugolib.Test(t, files)
confEn := b.H.Sites[0].Conf.Pagination()
confDe := b.H.Sites[1].Conf.Pagination()
b.Assert(confEn.Path, qt.Equals, "page")
b.Assert(confEn.PagerSize, qt.Equals, 20)
b.Assert(confDe.Path, qt.Equals, "page-de")
b.Assert(confDe.PagerSize, qt.Equals, 10)
}
func TestPaginationConfigDisableAliases(t *testing.T) {
files := `
-- hugo.toml --
disableKinds = ["taxonomy", "term"]
[pagination]
disableAliases = true
pagerSize = 2
-- layouts/_default/list.html --
{{ $paginator := .Paginate site.RegularPages }}
{{ template "_internal/pagination.html" . }}
{{ range $paginator.Pages }}
{{ .Title }}
{{ end }}
-- content/p1.md --
---
title: "p1"
---
-- content/p2.md --
---
title: "p2"
---
-- content/p3.md --
---
title: "p3"
---
`
b := hugolib.Test(t, files)
b.AssertFileExists("public/page/1/index.html", false)
b.AssertFileContent("public/page/2/index.html", "pagination-default")
}
-16
View File
@@ -327,22 +327,6 @@ var allDecoderSetups = map[string]decodeWeight{
return err
},
},
"pagination": {
key: "pagination",
decode: func(d decodeWeight, p decodeConfig) error {
p.c.Pagination = config.Pagination{
PagerSize: 10,
Path: "page",
}
if p.p.IsSet(d.key) {
if err := mapstructure.WeakDecode(p.p.Get(d.key), &p.c.Pagination); err != nil {
return err
}
}
return nil
},
},
"privacy": {
key: "privacy",
decode: func(d decodeWeight, p decodeConfig) error {
+6 -2
View File
@@ -248,8 +248,12 @@ func (c ConfigLanguage) CreateTitle(s string) string {
return c.config.C.CreateTitle(s)
}
func (c ConfigLanguage) Pagination() config.Pagination {
return c.config.Pagination
func (c ConfigLanguage) Paginate() int {
return c.config.Paginate
}
func (c ConfigLanguage) PaginatePath() string {
return c.config.PaginatePath
}
func (c ConfigLanguage) StaticDirs() []string {
+3 -5
View File
@@ -194,8 +194,8 @@ func (l configLoader) applyDefaultConfig() error {
"footnoteAnchorPrefix": "",
"footnoteReturnLinkContents": "",
"newContentEditor": "",
"paginate": 0, // Moved into the paginator struct in Hugo v0.128.0.
"paginatePath": "", // Moved into the paginator struct in Hugo v0.128.0.
"paginate": 10,
"paginatePath": "page",
"summaryLength": 70,
"rssLimit": -1,
"sectionPagesMenu": "",
@@ -458,7 +458,6 @@ func (l *configLoader) loadModules(configs *Configs) (modules.ModulesConfig, *mo
conf := configs.Base
workingDir := bcfg.WorkingDir
themesDir := bcfg.ThemesDir
publishDir := bcfg.PublishDir
cfg := configs.LoadingInfo.Cfg
@@ -467,7 +466,7 @@ func (l *configLoader) loadModules(configs *Configs) (modules.ModulesConfig, *mo
ignoreVendor, _ = hglob.GetGlob(hglob.NormalizePath(s))
}
ex := hexec.New(conf.Security, workingDir)
ex := hexec.New(conf.Security)
hook := func(m *modules.ModulesConfig) error {
for _, tc := range m.AllModules {
@@ -493,7 +492,6 @@ func (l *configLoader) loadModules(configs *Configs) (modules.ModulesConfig, *mo
HookBeforeFinalize: hook,
WorkingDir: workingDir,
ThemesDir: themesDir,
PublishDir: publishDir,
Environment: l.Environment,
CacheDir: conf.Caches.CacheDirModules(),
ModuleConfig: conf.Module,
-12
View File
@@ -410,15 +410,3 @@ func DecodeServer(cfg Provider) (Server, error) {
return *s, nil
}
// Pagination configures the pagination behavior.
type Pagination struct {
// Default number of elements per pager in pagination.
PagerSize int
// The path element used during pagination.
Path string
// Whether to disable generation of alias for the first pagination page.
DisableAliases bool
}
+2 -1
View File
@@ -52,7 +52,8 @@ type AllProvider interface {
DefaultContentLanguageInSubdir() bool
IsLangDisabled(string) bool
SummaryLength() int
Pagination() Pagination
Paginate() int
PaginatePath() string
BuildExpired() bool
BuildFuture() bool
BuildDrafts() bool
+2 -2
View File
@@ -16,13 +16,13 @@ package config
import (
"encoding/json"
"github.com/gohugoio/hugo/common/hashing"
"github.com/gohugoio/hugo/identity"
)
func DecodeNamespace[S, C any](configSource any, buildConfig func(any) (C, any, error)) (*ConfigNamespace[S, C], error) {
// Calculate the hash of the input (not including any defaults applied later).
// This allows us to introduce new config options without breaking the hash.
h := hashing.HashString(configSource)
h := identity.HashString(configSource)
// Build the config
c, ext, err := buildConfig(configSource)
+1 -1
View File
@@ -43,7 +43,7 @@ func TestNamespace(t *testing.T) {
c.Assert(err, qt.IsNil)
c.Assert(ns, qt.Not(qt.IsNil))
c.Assert(ns.SourceStructure, qt.DeepEquals, map[string]interface{}{"foo": "bar"})
c.Assert(ns.SourceHash, qt.Equals, "1450430416588600409")
c.Assert(ns.SourceHash, qt.Equals, "14368731254619220105")
c.Assert(ns.Config, qt.DeepEquals, &tstNsExt{Foo: "bar"})
c.Assert(ns.Signature(), qt.DeepEquals, []*tstNsExt(nil))
}
-2
View File
@@ -37,10 +37,8 @@ var DefaultConfig = Config{
Allow: MustNewWhitelist(
"^(dart-)?sass(-embedded)?$", // sass, dart-sass, dart-sass-embedded.
"^go$", // for Go Modules
"^git$", // For Git info
"^npx$", // used by all Node tools (Babel, PostCSS).
"^postcss$",
"^tailwindcss$",
),
// These have been tested to work with Hugo's external programs
// on Windows, Linux and MacOS.
+1 -1
View File
@@ -135,7 +135,7 @@ func TestToTOML(t *testing.T) {
got := DefaultConfig.ToTOML()
c.Assert(got, qt.Equals,
"[security]\n enableInlineShortcodes = false\n\n [security.exec]\n allow = ['^(dart-)?sass(-embedded)?$', '^go$', '^git$', '^npx$', '^postcss$', '^tailwindcss$']\n osEnv = ['(?i)^((HTTPS?|NO)_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\\w+|(XDG_CONFIG_)?HOME|USERPROFILE|SSH_AUTH_SOCK|DISPLAY|LANG|SYSTEMDRIVE)$']\n\n [security.funcs]\n getenv = ['^HUGO_', '^CI$']\n\n [security.http]\n methods = ['(?i)GET|POST']\n urls = ['.*']",
"[security]\n enableInlineShortcodes = false\n\n [security.exec]\n allow = ['^(dart-)?sass(-embedded)?$', '^go$', '^npx$', '^postcss$']\n osEnv = ['(?i)^((HTTPS?|NO)_PROXY|PATH(EXT)?|APPDATA|TE?MP|TERM|GO\\w+|(XDG_CONFIG_)?HOME|USERPROFILE|SSH_AUTH_SOCK|DISPLAY|LANG|SYSTEMDRIVE)$']\n\n [security.funcs]\n getenv = ['^HUGO_', '^CI$']\n\n [security.http]\n methods = ['(?i)GET|POST']\n urls = ['.*']",
)
}
+1 -1
View File
@@ -1,5 +1,5 @@
baseURL = 'https://example.org/'
languageCode = 'en-US'
languageCode = 'en-us'
title = 'My New Hugo Site'
[[menus.main]]
+2 -20
View File
@@ -133,14 +133,10 @@ func (d *Deployer) Deploy(ctx context.Context) error {
// Load local files from the source directory.
var include, exclude glob.Glob
var mappath func(string) string
if d.target != nil {
include, exclude = d.target.IncludeGlob, d.target.ExcludeGlob
if d.target.StripIndexHTML {
mappath = stripIndexHTML
}
}
local, err := d.walkLocal(d.localFs, d.cfg.Matchers, include, exclude, d.mediaTypes, mappath)
local, err := d.walkLocal(d.localFs, d.cfg.Matchers, include, exclude, d.mediaTypes)
if err != nil {
return err
}
@@ -487,7 +483,7 @@ func knownHiddenDirectory(name string) bool {
// walkLocal walks the source directory and returns a flat list of files,
// using localFile.SlashPath as the map keys.
func (d *Deployer) walkLocal(fs afero.Fs, matchers []*deployconfig.Matcher, include, exclude glob.Glob, mediaTypes media.Types, mappath func(string) string) (map[string]*localFile, error) {
func (d *Deployer) walkLocal(fs afero.Fs, matchers []*deployconfig.Matcher, include, exclude glob.Glob, mediaTypes media.Types) (map[string]*localFile, error) {
retval := map[string]*localFile{}
err := afero.Walk(fs, "", func(path string, info os.FileInfo, err error) error {
if err != nil {
@@ -533,11 +529,6 @@ func (d *Deployer) walkLocal(fs afero.Fs, matchers []*deployconfig.Matcher, incl
break
}
}
// Apply any additional modifications to the local path, to map it to
// the remote path.
if mappath != nil {
slashpath = mappath(slashpath)
}
lf, err := newLocalFile(fs, path, slashpath, m, mediaTypes)
if err != nil {
return err
@@ -551,15 +542,6 @@ func (d *Deployer) walkLocal(fs afero.Fs, matchers []*deployconfig.Matcher, incl
return retval, nil
}
// stripIndexHTML remaps keys matching "<dir>/index.html" to "<dir>/".
func stripIndexHTML(slashpath string) string {
const suffix = "/index.html"
if strings.HasSuffix(slashpath, suffix) {
return slashpath[:len(slashpath)-len(suffix)+1]
}
return slashpath
}
// walkRemote walks the target bucket and returns a flat list.
func (d *Deployer) walkRemote(ctx context.Context, bucket *blob.Bucket, include, exclude glob.Glob) (map[string]*blob.ListObject, error) {
retval := map[string]*blob.ListObject{}
+3 -66
View File
@@ -216,9 +216,8 @@ func TestFindDiffs(t *testing.T) {
func TestWalkLocal(t *testing.T) {
tests := map[string]struct {
Given []string
Expect []string
MapPath func(string) string
Given []string
Expect []string
}{
"Empty": {
Given: []string{},
@@ -236,11 +235,6 @@ func TestWalkLocal(t *testing.T) {
Given: []string{"file.txt", ".hidden_dir/file.txt", ".well-known/file.txt"},
Expect: []string{"file.txt", ".well-known/file.txt"},
},
"StripIndexHTML": {
Given: []string{"index.html", "file.txt", "dir/index.html", "dir/file.txt"},
Expect: []string{"index.html", "file.txt", "dir/", "dir/file.txt"},
MapPath: stripIndexHTML,
},
}
for desc, tc := range tests {
@@ -260,7 +254,7 @@ func TestWalkLocal(t *testing.T) {
}
}
d := newDeployer()
if got, err := d.walkLocal(fs, nil, nil, nil, media.DefaultTypes, tc.MapPath); err != nil {
if got, err := d.walkLocal(fs, nil, nil, nil, media.DefaultTypes); err != nil {
t.Fatal(err)
} else {
expect := map[string]any{}
@@ -280,63 +274,6 @@ func TestWalkLocal(t *testing.T) {
}
}
func TestStripIndexHTML(t *testing.T) {
tests := map[string]struct {
Input string
Output string
}{
"Unmapped": {Input: "normal_file.txt", Output: "normal_file.txt"},
"Stripped": {Input: "directory/index.html", Output: "directory/"},
"NoSlash": {Input: "prefix_index.html", Output: "prefix_index.html"},
"Root": {Input: "index.html", Output: "index.html"},
}
for desc, tc := range tests {
t.Run(desc, func(t *testing.T) {
got := stripIndexHTML(tc.Input)
if got != tc.Output {
t.Errorf("got %q, expect %q", got, tc.Output)
}
})
}
}
func TestStripIndexHTMLMatcher(t *testing.T) {
// StripIndexHTML should not affect matchers.
fs := afero.NewMemMapFs()
if err := fs.Mkdir("dir", 0o755); err != nil {
t.Fatal(err)
}
for _, name := range []string{"index.html", "dir/index.html", "file.txt"} {
if fd, err := fs.Create(name); err != nil {
t.Fatal(err)
} else {
fd.Close()
}
}
d := newDeployer()
const pattern = `\.html$`
matcher := &deployconfig.Matcher{Pattern: pattern, Gzip: true, Re: regexp.MustCompile(pattern)}
if got, err := d.walkLocal(fs, []*deployconfig.Matcher{matcher}, nil, nil, media.DefaultTypes, stripIndexHTML); err != nil {
t.Fatal(err)
} else {
for _, name := range []string{"index.html", "dir/"} {
lf := got[name]
if lf == nil {
t.Errorf("missing file %q", name)
} else if lf.matcher == nil {
t.Errorf("file %q has nil matcher, expect %q", name, pattern)
}
}
const name = "file.txt"
lf := got[name]
if lf == nil {
t.Errorf("missing file %q", name)
} else if lf.matcher != nil {
t.Errorf("file %q has matcher %q, expect nil", name, lf.matcher.Pattern)
}
}
}
func TestLocalFile(t *testing.T) {
const (
content = "hello world!"
-5
View File
@@ -69,11 +69,6 @@ type Target struct {
// Parsed versions of Include/Exclude.
IncludeGlob glob.Glob `json:"-"`
ExcludeGlob glob.Glob `json:"-"`
// If true, any local path matching <dir>/index.html will be mapped to the
// remote path <dir>/. This does not affect the top-level index.html file,
// since that would result in an empty path.
StripIndexHTML bool
}
func (tgt *Target) ParseIncludeExclude() error {
+7 -53
View File
@@ -15,7 +15,6 @@ import (
"github.com/gohugoio/hugo/cache/filecache"
"github.com/gohugoio/hugo/common/hexec"
"github.com/gohugoio/hugo/common/loggers"
"github.com/gohugoio/hugo/common/maps"
"github.com/gohugoio/hugo/common/types"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/config/allconfig"
@@ -136,15 +135,6 @@ func (d *Deps) Init() error {
if d.BuildState == nil {
d.BuildState = &BuildState{}
}
if d.BuildState.DeferredExecutions == nil {
if d.BuildState.DeferredExecutionsGroupedByRenderingContext == nil {
d.BuildState.DeferredExecutionsGroupedByRenderingContext = make(map[tpl.RenderingContext]*DeferredExecutions)
}
d.BuildState.DeferredExecutions = &DeferredExecutions{
Executions: maps.NewCache[string, *tpl.DeferredExecution](),
FilenamesWithPostPrefix: maps.NewCache[string, bool](),
}
}
if d.BuildStartListeners == nil {
d.BuildStartListeners = &Listeners{}
@@ -163,7 +153,7 @@ func (d *Deps) Init() error {
}
if d.ExecHelper == nil {
d.ExecHelper = hexec.New(d.Conf.GetConfigSection("security").(security.Config), d.Conf.WorkingDir())
d.ExecHelper = hexec.New(d.Conf.GetConfigSection("security").(security.Config))
}
if d.MemCache == nil {
@@ -171,29 +161,20 @@ func (d *Deps) Init() error {
}
if d.PathSpec == nil {
hashBytesReceiverFunc := func(name string, match []byte) {
s := string(match)
switch s {
case postpub.PostProcessPrefix:
d.BuildState.AddFilenameWithPostPrefix(name)
case tpl.HugoDeferredTemplatePrefix:
d.BuildState.DeferredExecutions.FilenamesWithPostPrefix.Set(name, true)
hashBytesReceiverFunc := func(name string, match bool) {
if !match {
return
}
d.BuildState.AddFilenameWithPostPrefix(name)
}
// Skip binary files.
mediaTypes := d.Conf.GetConfigSection("mediaTypes").(media.Types)
hashBytesShouldCheck := func(name string) bool {
hashBytesSHouldCheck := func(name string) bool {
ext := strings.TrimPrefix(filepath.Ext(name), ".")
return mediaTypes.IsTextSuffix(ext)
}
d.Fs.PublishDir = hugofs.NewHasBytesReceiver(
d.Fs.PublishDir,
hashBytesShouldCheck,
hashBytesReceiverFunc,
[]byte(tpl.HugoDeferredTemplatePrefix),
[]byte(postpub.PostProcessPrefix))
d.Fs.PublishDir = hugofs.NewHasBytesReceiver(d.Fs.PublishDir, hashBytesSHouldCheck, hashBytesReceiverFunc, []byte(postpub.PostProcessPrefix))
pathSpec, err := helpers.NewPathSpec(d.Fs, d.Conf, d.Log)
if err != nil {
return err
@@ -390,37 +371,10 @@ type BuildState struct {
// A set of filenames in /public that
// contains a post-processing prefix.
filenamesWithPostPrefix map[string]bool
DeferredExecutions *DeferredExecutions
// Deferred executions grouped by rendering context.
DeferredExecutionsGroupedByRenderingContext map[tpl.RenderingContext]*DeferredExecutions
}
type DeferredExecutions struct {
// A set of filenames in /public that
// contains a post-processing prefix.
FilenamesWithPostPrefix *maps.Cache[string, bool]
// Maps a placeholder to a deferred execution.
Executions *maps.Cache[string, *tpl.DeferredExecution]
}
var _ identity.SignalRebuilder = (*BuildState)(nil)
// StartStageRender will be called before a stage is rendered.
func (b *BuildState) StartStageRender(stage tpl.RenderingContext) {
}
// StopStageRender will be called after a stage is rendered.
func (b *BuildState) StopStageRender(stage tpl.RenderingContext) {
b.DeferredExecutionsGroupedByRenderingContext[stage] = b.DeferredExecutions
b.DeferredExecutions = &DeferredExecutions{
Executions: maps.NewCache[string, *tpl.DeferredExecution](),
FilenamesWithPostPrefix: maps.NewCache[string, bool](),
}
}
func (b *BuildState) SignalRebuild(ids ...identity.Identity) {
b.OnSignalRebuild(ids...)
}
+25 -57
View File
@@ -20,11 +20,13 @@
],
"ignoreRegExpList": [
"# cspell: ignore fenced code blocks",
"^(\\s*`{3,}).*[\\s\\S]*?^\\1$",
"^(\\s*`{3,}).*[\\s\\S]*?^\\1",
"# cspell: ignore words joined with dot",
"\\w+\\.\\w+",
"# cspell: ignore strings within backticks",
"`.+`",
"# cspell: ignore strings within single quotes",
"'.+'",
"# cspell: ignore strings within double quotes",
"\".+\"",
"# cspell: ignore strings within brackets",
@@ -40,11 +42,14 @@
],
"language": "en",
"words": [
"antialiasing",
"codeowners",
"composability",
"configurators",
"defang",
"deindent",
"downscale",
"downscaled",
"downscaling",
"exif",
"geolocalized",
@@ -52,99 +57,60 @@
"marshal",
"marshaling",
"multihost",
"multiplatfom",
"performantly",
"preconfigured",
"prerendering",
"redirection",
"redirections",
"shortcode",
"shortcodes",
"subexpression",
"suppressible",
"subexpressions",
"suppressable",
"templating",
"transpile",
"transpiles",
"unmarshal",
"unmarshaling",
"unmarshals",
"# ----------------------------------------------------------------------",
"# cspell: ignore hugo terminology",
"# ----------------------------------------------------------------------",
"attrlink",
"canonify",
"codeowners",
"eturl",
"getenv",
"gohugo",
"gohugoio",
"keyvals",
"leftdelim",
"linkify",
"numworkermultiplier",
"rightdelim",
"shortcode",
"stringifier",
"struct",
"toclevels",
"zgotmplz",
"unmarshaling",
"# ----------------------------------------------------------------------",
"# cspell: ignore foreign language words",
"# ----------------------------------------------------------------------",
"bezpieczeństwo",
"buch",
"descripción",
"dokumentation",
"erklärungen",
"libros",
"mercredi",
"miesiąc",
"miesiąc",
"miesiąca",
"miesiące",
"miesięcy",
"miesięcy",
"misérables",
"mittwoch",
"muchos",
"novembre",
"otro",
"pocos",
"produkte",
"projekt",
"prywatność",
"referenz",
"régime",
"# ----------------------------------------------------------------------",
"# cspell: ignore names",
"# cspell: ignore proper nouns",
"# ----------------------------------------------------------------------",
"Atishay",
"Cosette",
"Eliott",
"Furet",
"Gregor",
"Jaco",
"Lanczos",
"Ninke",
"Noll",
"Pastorius",
"Samsa",
"Stucki",
"Thénardier",
"# ----------------------------------------------------------------------",
"# cspell: ignore operating systems and software packages",
"# ----------------------------------------------------------------------",
"asciidoctor",
"brotli",
"cifs",
"corejs",
"disqus",
"docutils",
"dpkg",
"doas",
"eopkg",
"gitee",
"gohugoio",
"goldmark",
"katex",
"KaTeX",
"kubuntu",
"lubuntu",
"mathjax",
"MathJax",
"nosql",
"pandoc",
"pkgin",
@@ -153,19 +119,21 @@
"# ----------------------------------------------------------------------",
"# cspell: ignore miscellaneous",
"# ----------------------------------------------------------------------",
"achristie",
"ddmaurier",
"dring",
"getenv",
"gohugo",
"inor",
"jausten",
"jdoe",
"jsmith",
"milli",
"rgba",
"rsmith",
"stringifier",
"struct",
"tdewolff",
"tjones",
"wcag",
"xfeff"
"toclevels",
"vals",
"xfeff",
"zgotmplz"
]
}
@@ -6,12 +6,13 @@
bgcolor = "#ffffff"
[[banners]]
name = "Route4Me"
link = "https://route4me.com"
title = "Route Planning & Route Optimization Software"
utm_campaign = "hugosponsor"
bgcolor = "#334799"
link_attr = "style='color: #ffffff; font-weight: bold; text-decoration: none; text-align: center'"
name = "CloudCannon"
link = "https://cloudcannon.com/hugo-cms/"
logo = "/images/sponsors/cloudcannon-white.svg"
utm_campaign = "HugoSponsorship"
utm_source = "sponsor"
utm_content = "gohugo"
bgcolor = "#034AD8"
[[banners]]
name = "Your Company?"
@@ -19,4 +20,3 @@
utm_campaign = "hugosponsor"
show_on_hover = true
bgcolor = "#4e4f4f"
link_attr = "style='color: #ffffff; font-weight: bold; text-decoration: none; text-align: center'"
@@ -1,4 +1,4 @@
{{- /* Last modified: 2024-04-26T13:54:00-07:00 */}}
{{- /* Last modified: 2023-09-04T09:23:04-07:00 */}}
{{- /*
Copyright 2023 Veriphor LLC
@@ -118,7 +118,7 @@ either of these shortcodes in conjunction with this render hook.
{{- $attrs = merge $attrs (dict "rel" "external") }}
{{- else }}
{{- with $u.Path }}
{{- with $p := or ($.PageInner.GetPage .) ($.PageInner.GetPage (strings.TrimRight "/" .)) }}
{{- with $p := or ($.Page.GetPage .) ($.Page.GetPage (strings.TrimRight "/" .)) }}
{{- /* Destination is a page. */}}
{{- $href := .RelPermalink }}
{{- with $u.RawQuery }}
@@ -137,7 +137,7 @@ either of these shortcodes in conjunction with this render hook.
{{- end }}
{{- $attrs = dict "href" $href }}
{{- else }}
{{- with $.PageInner.Resources.Get $u.Path }}
{{- with $.Page.Resources.Get $u.Path }}
{{- /* Destination is a page resource; drop query and fragment. */}}
{{- $attrs = dict "href" .RelPermalink }}
{{- else }}
@@ -185,14 +185,14 @@ either of these shortcodes in conjunction with this render hook.
{{- end }}
{{- end }}
{{- end }}
{{- $attrs = merge $attrs (dict "title" (.Title | transform.HTMLEscape)) }}
{{- with .Title }}
{{- $attrs = merge $attrs (dict "title" .) }}
{{- end -}}
{{- /* Render anchor element. */ -}}
<a
{{- range $k, $v := $attrs }}
{{- if $v }}
{{- printf " %s=%q" $k $v | safeHTMLAttr }}
{{- end }}
{{- printf " %s=%q" $k $v | safeHTMLAttr }}
{{- end -}}
>{{ .Text | safeHTML }}</a>
@@ -1,68 +1,38 @@
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Hugo News</title>
<description>Recent news about Hugo, a static site generator written in Go, optimized for speed and designed for flexibility.</description>
<title>{{ .Site.Title }} {{ .Title }}</title>
<link>{{ .Permalink }}</link>
<generator>Hugo {{ hugo.Version }}</generator>
<language>{{ or site.Language.LanguageCode site.Language.Lang }}</language>
{{- with site.Copyright }}
<copyright>{{ . }}</copyright>
{{- end }}
{{- with .OutputFormats.Get "RSS" }}
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
{{- end }}
{{- $news_items := slice }}
{{- /* Get releases from GitHub. */}}
{{- $u := "https://api.github.com/repos/gohugoio/hugo/releases" }}
{{- $releases := partial "utilities/get-remote-data.html" $u }}
{{- $releases = where $releases "draft" false }}
{{- $releases = where $releases "prerelease" false }}
{{- range $releases | first 20 }}
{{- $summary := printf
"Hugo %s was released on %s. See [release notes](%s) for details."
.tag_name
(.published_at | time.AsTime | time.Format "2 Jan 2006")
.html_url
}}
{{- $ctx := dict
"PublishDate" (.published_at | time.AsTime)
"Title" (printf "Release %s" .name)
"Permalink" .html_url
"Section" "news"
"Summary" ($summary | $.Page.RenderString)
}}
{{- $news_items = $news_items | append $ctx }}
{{- end }}
{{- /* Get content pages from news section. */}}
{{- range where site.RegularPages "Section" "news" }}
{{- $ctx := dict
"PublishDate" .PublishDate
"Title" .Title
"RelPermalink" .RelPermalink
"Section" "news"
"Summary" .Summary
"Params" (dict "description" .Description)
}}
{{- $news_items = $news_items | append $ctx }}
{{- end }}
{{- /* Sort, limit, and render lastBuildDate. */}}
{{- $limit := cond (gt site.Config.Services.RSS.Limit 1) site.Config.Services.RSS.Limit 999 }}
{{- $news_items = sort $news_items "PublishDate" "desc" | first $limit }}
<lastBuildDate>{{ (index $news_items 0).PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>
{{- /* Render items. */}}
{{- range $news_items }}
<item>
<title>{{ .Title }}</title>
<link>{{ .Permalink }}</link>
<pubDate>{{ .PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
<guid>{{ .Permalink }}</guid>
<description>{{ .Summary | transform.XMLEscape | safeHTML }}</description>
</item>
{{- end }}
<description>Recent Hugo news from gohugo.io</description>
<generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
<language>{{.}}</language>{{end}}{{ with .Site.Author.email }}
<managingEditor>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</managingEditor>{{end}}{{ with .Site.Author.email }}
<webMaster>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</webMaster>{{end}}{{ with .Site.Copyright }}
<copyright>{{.}}</copyright>{{end}}{{ if not .Date.IsZero }}
<lastBuildDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ end }}
<image>
<url>{{ "img/hugo.png" | absURL }}</url>
<title>GoHugo.io</title>
<link>{{ .Permalink }}</link>
</image>
{{ with .OutputFormats.Get "RSS" }}
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
{{ end }}
{{ range first 50 (where .Site.RegularPages "Type" "in" (slice "news" "showcase")) }}
<item>
<title>{{ .Section | title }}: {{ .Title }}</title>
<link>{{ .Permalink }}</link>
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
{{ with .Site.Author.email }}<author>{{.}}{{ with $.Site.Author.name }} ({{.}}){{end}}</author>{{end}}
<guid>{{ .Permalink }}</guid>
<description>
{{ $img := (.Resources.ByType "image").GetMatch "*featured*" }}
{{ with $img }}
{{ $img := .Resize "640x" }}
{{ printf "<![CDATA[<img src=\"%s\" width=\"%d\" height=\"%d\"/>]]>" $img.Permalink $img.Width $img.Height | safeHTML }}
{{ end }}
{{ .Content | html }}
</description>
</item>
{{ end }}
</channel>
</rss>
</rss>
@@ -18,7 +18,7 @@
{{/* Get releases from GitHub. */}}
{{ $u := "https://api.github.com/repos/gohugoio/hugo/releases" }}
{{ $releases := partial "utilities/get-remote-data.html" $u }}
{{ $releases := partial "inline/get-remote-data.html" $u }}
{{ $releases = where $releases "draft" false }}
{{ $releases = where $releases "prerelease" false }}
{{ range $releases | first 20 }}
@@ -55,3 +55,16 @@
</div>
{{ end }}
{{ define "partials/inline/get-remote-data.html" }}
{{ $u := . }}
{{ $r := "" }}
{{ with $r = resources.GetRemote $u }}
{{ with .Err }}
{{ errorf "%s" . }}
{{ end }}
{{ else }}
{{ errorf "Unable to get remote resource %q" $u }}
{{ end }}
{{ return ($r | transform.Unmarshal) }}
{{ end }}
@@ -1,68 +0,0 @@
{{- printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Hugo News</title>
<description>Recent news about Hugo, a static site generator written in Go, optimized for speed and designed for flexibility.</description>
<link>{{ .Permalink }}</link>
<generator>Hugo {{ hugo.Version }}</generator>
<language>{{ or site.Language.LanguageCode site.Language.Lang }}</language>
{{- with site.Copyright }}
<copyright>{{ . }}</copyright>
{{- end }}
{{- with .OutputFormats.Get "RSS" }}
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML }}
{{- end }}
{{- $news_items := slice }}
{{- /* Get releases from GitHub. */}}
{{- $u := "https://api.github.com/repos/gohugoio/hugo/releases" }}
{{- $releases := partial "utilities/get-remote-data.html" $u }}
{{- $releases = where $releases "draft" false }}
{{- $releases = where $releases "prerelease" false }}
{{- range $releases | first 20 }}
{{- $summary := printf
"Hugo %s was released on %s. See [release notes](%s) for details."
.tag_name
(.published_at | time.AsTime | time.Format "2 Jan 2006")
.html_url
}}
{{- $ctx := dict
"PublishDate" (.published_at | time.AsTime)
"Title" (printf "Release %s" .name)
"Permalink" .html_url
"Section" "news"
"Summary" ($summary | $.Page.RenderString)
}}
{{- $news_items = $news_items | append $ctx }}
{{- end }}
{{- /* Get content pages from news section. */}}
{{- range .Pages }}
{{- $ctx := dict
"PublishDate" .PublishDate
"Title" .Title
"RelPermalink" .RelPermalink
"Section" "news"
"Summary" .Summary
"Params" (dict "description" .Description)
}}
{{- $news_items = $news_items | append $ctx }}
{{- end }}
{{- /* Sort, limit, and render lastBuildDate. */}}
{{- $limit := cond (gt site.Config.Services.RSS.Limit 1) site.Config.Services.RSS.Limit 999 }}
{{- $news_items = sort $news_items "PublishDate" "desc" | first $limit }}
<lastBuildDate>{{ (index $news_items 0).PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>
{{- /* Render items. */}}
{{- range $news_items }}
<item>
<title>{{ .Title }}</title>
<link>{{ .Permalink }}</link>
<pubDate>{{ .PublishDate.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
<guid>{{ .Permalink }}</guid>
<description>{{ .Summary | transform.XMLEscape | safeHTML }}</description>
</item>
{{- end }}
</channel>
</rss>
@@ -1,6 +1,6 @@
<div class="w-100 center pt5">
<div class="w-100 w-40-l tc center">
<img src="/images/Github.svg" alt="Github Logo" class="tc center">
<img src="/images/GitHub-Mark-64px.png" alt="Github Logo" class="tc center">
</div>
</div>
@@ -25,30 +25,26 @@
{{ $query_params := .query_params | default "" }}
{{ $url := printf "%s?%s%s" .link $query_params (querify "utm_source" (.utm_source | default $utmSource ) "utm_medium" "banner" "utm_campaign" (.utm_campaign | default "hugosponsor") "utm_content" (.utm_content | default "gohugoio")) | safeURL }}
{{ $logo := resources.Get .logo }}
{{ $gtagID := printf "Sponsor %s %s" .name $gtag | title }}
{{ $classes := "" }}
{{ if .show_on_hover }}
{{ $classes = printf "%s show-on-hover" $classes }}
{{ end }}
{{ if $isFooter }}
{{ $classes = printf "%s f3" $classes }}
{{ else }}
{{ $classes = printf "%s f1" $classes }}
{{ end }}
<a
href="{{ $url }}"
title="{{ .title | default .name }}"
{{ if hugo.IsProduction }}
{{ if hugo.IsProduction }}
{{ $gtagID := printf "Sponsor %s %s" .name $gtag | title }}
<a
href="{{ $url }}"
onclick="trackOutboundLink({{ printf "'%s', '%s'" $gtagID $url | safeJS }});"
{{ end }}
class="w-100 grow pa3 {{ $classes }}"
{{ with .link_attr }}{{ . | safeHTMLAttr }}{{ end }}>
{{ with $logo }}
{{ .Content | safeHTML }}
{{ else }}
{{ .name }}
{{ end }}
</a>
class="w-100 grow pa3{{ if .show_on_hover }}
show-on-hover
{{ end }}"
style="">
{{ with $logo }}{{ .Content | safeHTML }}{{ end }}
</a>
{{ else }}
<a
href="{{ $url }}"
class="w-100 grow pa3{{ if .show_on_hover }}
show-on-hover
{{ end }}">
{{ with $logo }}{{ .Content | safeHTML }}{{ end }}
</a>
{{ end }}
</div>
{{ end }}
</div>
@@ -1,23 +0,0 @@
{{/*
Parses the serialized data from the given URL and returns a map or an array.
Supports CSV, JSON, TOML, YAML, and XML.
@param {string} . The URL from which to retrieve the serialized data.
@returns {any}
@example {{ partial "get-remote-data.html" "https://example.org/foo.json" }}
*/}}
{{ $url := . }}
{{ $data := dict }}
{{ with resources.GetRemote $url }}
{{ with .Err }}
{{ errorf "%s" . }}
{{ else }}
{{ $data = .Content | transform.Unmarshal }}
{{ end }}
{{ else }}
{{ errorf "Unable to get remote resource %q" $url }}
{{ end }}
{{ return $data }}
@@ -1,36 +0,0 @@
{{- /*
Renders an absolute URL to the source code for an embedded template.
Accepts either positional or named parameters, and depends on the
embedded_templates.toml file in the data directory.
@param {string} filename The embedded template's file name, excluding extension.
@returns template.HTML
@example {{% et robots.txt %}}
@example {{% et filename=robots.txt %}}
*/}}
{{- /* Get parameters. */}}
{{- $filename := "" -}}
{{- if .IsNamedParams -}}
{{- $filename = .Get "filename" -}}
{{- else -}}
{{- $filename = .Get 0 -}}
{{- end -}}
{{- /* Render. */}}
{{- with $filename -}}
{{- with site.Data.embedded_template_urls -}}
{{- with index . $filename -}}
{{- urls.JoinPath site.Data.embedded_template_urls.base_url . -}}
{{- else -}}
{{- errorf "The %q shortcode was unable to find a URL for the embedded template named %q. Check the name. See %s" $.Name $filename $.Position -}}
{{- end -}}
{{- else -}}
{{- errorf "The %q shortcode was unable to find the embedded_template_urls data file in the site's data directory. See %s" $.Name $.Position -}}
{{- end -}}
{{- else -}}
{{- errorf "The %q shortcodes requires a named or positional parameter, the file name of the embedded template, excluding its extension. See %s" .Name .Position -}}
{{- end -}}
@@ -119,8 +119,8 @@ Renders the given image using the given filter, if any.
{{- end }}
{{- $validFilters := slice
"autoorient" "brightness" "colorbalance" "colorize" "contrast" "dither"
"gamma" "gaussianblur" "grayscale" "hue" "invert" "none" "opacity" "overlay"
"autoorient" "brightness" "colorbalance" "colorize" "contrast" "gamma"
"gaussianblur" "grayscale" "hue" "invert" "none" "opacity" "overlay"
"padding" "pixelate" "process" "saturation" "sepia" "sigmoid" "text"
"unsharpmask"
}}
@@ -198,8 +198,6 @@ Renders the given image using the given filter, if any.
{{- $ctx = merge $ctx (dict "argName" "percentage" "argValue" (index $filterArgs 0) "min" -100 "max" 100) }}
{{- template "validate-arg-value" $ctx }}
{{- $f = images.Contrast (index $filterArgs 0) }}
{{- else if eq $filter "dither" }}
{{- $f = images.Dither }}
{{- else if eq $filter "gamma" }}
{{- $ctx = merge $ctx (dict "argsRequired" 1) }}
{{- template "validate-arg-count" $ctx }}
@@ -356,7 +354,7 @@ Renders the given image using the given filter, if any.
{{- if $u.IsAbs }}
{{- with resources.GetRemote $u.String }}
{{- with .Err }}
{{- errorf "%s" . }}
{{- errorf "%s" }}
{{- else }}
{{- /* This is a remote resource. */}}
{{- $r = . }}
@@ -27,7 +27,9 @@ button will be hidden if any of the following conditions is true:
{{- warnf "This call to the %q shortcode should be removed: %s. The button is now hidden because the specified version (%s) is older than the display threshold." $.Name $.Position $version }}
{{- end }}
{{- else }}
<a class="dib f5 fw6 ba bw1 b--gray ph2 mt1" href="{{ printf "https://github.com/gohugoio/hugo/releases/tag/v%s" $version }}">New in v{{ $version }}</a>
<button class="bg-white hover:bg-gray-100 text-gray-800 font-semibold py-2 mr2 px-4 border border-gray-400 rounded shadow">
<a href="{{ printf "https://github.com/gohugoio/hugo/releases/tag/v%s" $version }}">New in v{{ $version }}</a>
</button>
{{- end }}
{{- else }}
{{- errorf "The %q shortcode requires a positional parameter (version). See %s" .Name .Position }}
Binary file not shown.

After

Width:  |  Height:  |  Size: 924 B

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 24 24"><path d="M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.5 11.5 0 0 1 12 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12"/></svg>

Before

Width:  |  Height:  |  Size: 795 B

+1 -1
View File
@@ -1 +1 @@
# github.com/gohugoio/gohugoioTheme v0.0.0-20240619093131-b595d5fb8c52
# github.com/gohugoio/gohugoioTheme v0.0.0-20240201183016-8e648a3b5342
Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

+22 -22
View File
@@ -1,6 +1,6 @@
[[docs]]
identifier = 'about'
name = 'About'
name = 'About Hugo'
pageRef = '/about/'
weight = 10
@@ -15,60 +15,60 @@ name = 'Getting started'
weight = 30
identifier = 'getting-started'
pageRef = '/getting-started/'
[[docs]]
name = 'Quick reference'
weight = 40
identifier = 'quick-reference'
pageRef = '/quick-reference/'
post = 'break'
[[docs]]
name = 'Content management'
weight = 50
weight = 40
identifier = 'content-management'
post = 'expanded'
pageRef = '/content-management/'
[[docs]]
name = 'Templates'
weight = 60
weight = 50
identifier = 'templates'
pageRef = '/templates/'
[[docs]]
name = 'Functions'
weight = 70
weight = 60
identifier = 'functions'
pageRef = '/functions/'
[[docs]]
name = 'Methods'
weight = 80
weight = 70
identifier = 'methods'
pageRef = '/methods/'
[[docs]]
name = 'Render hooks'
weight = 90
identifier = 'render-hooks'
pageRef = '/render-hooks/'
name = 'Quick reference'
weight = 80
identifier = 'quick-reference'
pageRef = '/quick-reference/'
[[docs]]
name = 'Variables'
weight = 85
identifier = 'variables'
pageRef = '/variables/'
[[docs]]
name = 'Hugo Modules'
weight = 100
weight = 90
identifier = 'modules'
pageRef = '/hugo-modules/'
[[docs]]
name = 'Hugo Pipes'
weight = 110
weight = 100
identifier = 'hugo-pipes'
pageRef = '/hugo-pipes/'
[[docs]]
name = 'CLI'
weight = 120
weight = 110
post = 'break'
identifier = 'commands'
pageRef = '/commands/'
@@ -77,25 +77,25 @@ pageRef = '/commands/'
[[docs]]
name = 'Troubleshooting'
weight = 130
weight = 120
identifier = 'troubleshooting'
pageRef = '/troubleshooting/'
[[docs]]
name = 'Developer tools'
weight = 140
weight = 130
identifier = 'developer-tools'
pageRef = '/tools/'
[[docs]]
name = 'Hosting and deployment'
weight = 150
weight = 140
identifier = 'hosting-and-deployment'
pageRef = '/hosting-and-deployment/'
[[docs]]
name = 'Contribute'
weight = 160
weight = 150
post = 'break'
identifier = 'contribute'
pageRef = '/contribute/'
+1 -1
View File
@@ -15,7 +15,7 @@ features:
- heading: Shortcodes
image_path: /images/icon-shortcodes.svg
tagline: Hugo's shortcodes are Markdown's hidden superpower.
copy: We love the beautiful simplicity of Markdowns syntax, but there are times when we want more flexibility. Hugo shortcodes allow for both beauty and flexibility.
copy: We love the beautiful simplicity of markdowns syntax, but there are times when we want more flexibility. Hugo shortcodes allow for both beauty and flexibility.
- heading: Built-in Templates
image_path: /images/icon-built-in-templates.svg
+4 -4
View File
@@ -1,16 +1,16 @@
---
title: About Hugo
linkTitle: In this section
description: Learn about Hugo and its features, security model, and privacy protections.
linkTitle: Overview
description: Hugo's features, roadmap, license, and motivation.
categories: []
keywords: []
menu:
docs:
identifier: about-hugo-in-this-section
identifier: about-hugo-overview
parent: about
weight: 10
weight: 10
aliases: [/about-hugo/,/docs/]
---
Learn about Hugo and its features, privacy protections, and security model.
Hugo is not your average static site generator.
+36
View File
@@ -0,0 +1,36 @@
---
title: Benefits of static site generators
linkTitle: Static site generators
description: Improved performance, security and ease of use are just a few of the reasons static site generators are so appealing.
categories: [about]
keywords: [ssg,static,performance,security]
menu:
docs:
parent: about
weight: 40
weight: 40
---
The purpose of website generators is to render content into HTML files. Most are "dynamic site generators." That means the HTTP server---i.e., the program that sends files to the browser to be viewed---runs the generator to create a new HTML file every time an end user requests a page.
Over time, dynamic site generators were programmed to cache their HTML files to prevent unnecessary delays in delivering pages to end users. A cached page is a static version of a web page.
Hugo takes caching a step further and all HTML files are rendered on your computer. You can review the files locally before copying them to the computer hosting the HTTP server. Since the HTML files aren't generated dynamically, we say that Hugo is a *static site generator*.
This has many benefits. The most noticeable is performance. HTTP servers are *very* good at sending files---so good, in fact, that you can effectively serve the same number of pages with a fraction of the memory and CPU needed for a dynamic site.
## More on static site generators
* ["An Introduction to Static Site Generators", David Walsh]
* ["Hugo vs. WordPress page load speed comparison: Hugo leaves WordPress in its dust", GettingThingsTech][hugovwordpress]
* ["Static Site Generators", O'Reilly]
* [StaticGen: Top Open-Source Static Site Generators (GitHub Stars)]
* ["Top 10 Static Website Generators", Netlify blog]
* ["The Resurgence of Static", dotCMS][dotcms]
["An Introduction to Static Site Generators", David Walsh]: https://davidwalsh.name/introduction-static-site-generators
["Static Site Generators", O'Reilly]: https://github.com/gohugoio/hugoDocs/files/1242701/static-site-generators.pdf
["Top 10 Static Website Generators", Netlify blog]: https://www.netlify.com/blog/2016/05/02/top-ten-static-website-generators/
[hugovwordpress]: https://gettingthingstech.com/hugo-vs.-wordpress-page-load-speed-comparison-hugo-leaves-wordpress-in-its-dust/
[StaticGen: Top Open-Source Static Site Generators (GitHub Stars)]: https://www.staticgen.com/
[dotcms]: https://dotcms.com/blog/post/the-resurgence-of-static
+59 -115
View File
@@ -1,6 +1,6 @@
---
title: Features
description: Hugo's rich and powerful feature set provides the framework and tools to create static sites that build in seconds, often less.
title: Hugo features
description: Hugo boasts blistering speed, robust content management, and a powerful templating language making it a great fit for all kinds of static websites.
categories: [about]
keywords: []
menu:
@@ -11,126 +11,70 @@ weight: 30
toc: true
---
## Framework
## General
[Multiplatform]
: Install Hugo's single executable on Linux, macOS, Windows, and more.
* [Extremely fast] build times (&lt; 1 ms per page)
* Completely cross platform, with [easy installation][install] on macOS, Linux, Windows, and more
* Renders changes on the fly with [LiveReload] as you develop
* [Powerful theming]
* [Host your site anywhere][hostanywhere]
[Multilingual]
: Localize your project for each language and region, including translations, images, dates, currencies, numbers, percentages, and collation sequence. Hugo's multilingual framework supports single-host and multihost configurations.
## Organization
[Output formats]
: Render each page of your site to one or more output formats, with granular control by page kind, section, and path. While HTML is the default output format, you can add JSON, RSS, CSV, and more. For example, create a REST API to access content.
* Straightforward [organization for your projects], including website sections
* Customizable [URLs]
* Support for configurable [taxonomies], including categories and tags
* [Sort content] as you desire through powerful template [functions]
* Automatic [table of contents] generation
* [Dynamic menu] creation
* [Pretty URLs] support
* [Permalink] pattern support
* Redirects via [aliases]
[Templates]
: Create templates usings variables, functions, and methods to transform your content, resources, and data into a published page. While HTML templates are the most common, you can create templates for any output format.
## Content
[Themes]
: Reduce development time and cost by using one of the hundreds of themes contributed by the Hugo community. Themes are available for corporate sites, documentation projects, image portfolios, landing pages, personal and professional blogs, resumes, CVs, and more.
* Native Markdown and Emacs Org-Mode support, as well as other languages via *external helpers* (see [supported formats])
* TOML, YAML, and JSON metadata support in [front matter]
* Customizable [homepage]
* Multiple [content types]
* Automatic and user defined [content summaries]
* [Shortcodes] to enable rich content inside of Markdown
* ["Minutes to Read"][pagevars] functionality
* ["WordCount"][pagevars] functionality
[Modules]
: Reduce development time and cost by creating or importing packaged combinations of archetypes, assets, content, data, templates, translation tables, static files, or configuration settings. A module may serve as the basis for a new site, or to augment an existing site.
## Additional features
[Privacy]
: Configure the behavior of Hugo's embedded templates and shortcodes to facilitate compliance with regional privacy regulations, including the [GDPR] and [CCPA].
* Integrated [Disqus] comment support
* Integrated [Google Analytics] support
* Automatic [RSS] creation
* Support for [Go] HTML templates
* [Syntax highlighting] powered by [Chroma]
[Security]
: Hugo's security model is based on the premise that template and configuration authors are trusted, but content authors are not. This model enables generation of HTML output safe against code injection. Other protections prevent "shelling out" to arbitrary applications, limit access to specific environment variables, prevent connections to arbitrary remote data sources, and more.
## Content authoring
[Content formats]
: Create your content using Markdown, HTML, AsciiDoc, Emacs Org Mode, Pandoc, or reStructuredText. Markdown is the default content format, conforming to the [CommonMark] and [GitHub Flavored Markdown] specifications.
[Markdown attributes]
: Apply HTML attributes such as `class` and `id` to Markdown images and block elements including blockquotes, fenced code blocks, headings, horizontal rules, lists, paragraphs, and tables.
[Markdown extensions]
: Leverage the embedded Markdown extensions to create tables, definition lists, footnotes, task lists, inserted text, mark text, subscripts, superscripts, and more.
[Markdown render hooks]
: Override the conversion of Markdown to HTML when rendering fenced code blocks, headings, images, and links. For example, render every standalone image as an HTML `figure` element.
[Diagrams]
: Use fenced code blocks and Markdown render hooks to include diagrams in your content.
[Mathematics]
: Include mathematical equations and expressions in Markdown using LaTeX or TeX typesetting syntax.
[Syntax highlighting]
: Syntactically highlight code examples using Hugo's embedded syntax highlighter, enabled by default for fenced code blocks in Markdown. The syntax highlighter supports hundreds of code languages and dozens of styles.
[Shortcodes]
: Use Hugo's embedded shortcodes, or create your own, to insert complex content. For example, use shortcodes to include `audio` and `video` elements, render tables from local or remote data sources, insert snippets from other pages, and more.
## Content management
[Content adapters]
: Create content adapters to dynamically add content when building your site. For example, use a content adapter to create pages from a remote data source such as JSON, TOML, YAML, or XML.
[Taxonomies]
: Classify content to establish simple or complex logical relationships between pages. For example, create an authors taxonomy, and assign one or more authors to each page. Among other uses, the taxonomy system provides an inverted, weighted index to render a list of related pages, ordered by relevance.
[Data]
: Augment your content using local or remote data sources including CSV, JSON, TOML, YAML, and XML. For example, create a shortcode to render an HTML table from a remote CSV file.
[Menus]
: Provide rapid access to content via Hugo's menu system, configured automatically, globally, or on a page-by-page basis. The menu system is a key component of Hugo's multilingual architecture.
[URL management]
: Serve any page from any path via global configuration or on a page-by-page basis.
## Asset pipelines
[CSS bundling]
: Transpile Sass to CSS, bundle, tree shake, minify, create source maps, perform SRI hashing, and integrate with PostCSS.
[JavaScript bundling]
: Transpile TypeScript and JSX to JavaScript, bundle, tree shake, minify, create source maps, and perform SRI hashing.
[Image processing]
: Convert, resize, crop, rotate, adjust colors, apply filters, overlay text and images, and extract EXIF data.
## Performance
[Caching]
: Reduce build time and cost by rendering a partial template once then cache the result, either globally or within a given context. For example, cache the result of an asset pipeline to prevent reprocessing on every rendered page.
[Segmentation]
: Reduce build time and cost by partitioning your sites into segments. For example, render the home page and the "news section" every hour, and render the entire site once a week.
[Minification]
: Minify HTML, CSS, and JavaScript to reduce file size, bandwidth consumption, and loading times.
[CCPA]: https://en.wikipedia.org/wiki/California_Consumer_Privacy_Act
[CSS bundling]: /functions/resources/tocss/
[Caching]: /functions/partials/includecached/
[CommonMark]: https://spec.commonmark.org/current/
[Content adapters]: /content-management/content-adapters/
[Content formats]: /content-management/formats/
[Data]: /content-management/data-sources/
[Diagrams]: /content-management/diagrams/
[GDPR]: https://en.wikipedia.org/wiki/General_Data_Protection_Regulation
[GitHub Flavored Markdown]: https://github.github.com/gfm/
[Image processing]: /content-management/image-processing/
[JavaScript bundling]: /functions/js/build/
[Markdown attributes]: /content-management/markdown-attributes/
[Markdown extensions]: /getting-started/configuration-markup/#goldmark-extensions
[Markdown render hooks]: /render-hooks/introduction/
[Mathematics]: /content-management/mathematics/
[Menus]: /content-management/menus/
[Minification]: /getting-started/configuration/#configure-minify
[Modules]: https://gohugo.io/hugo-modules/
[Multilingual]: /content-management/multilingual/
[Multiplatform]: /installation/
[Output formats]: /templates/output-formats/
[Privacy]: /about/privacy/
[Security]: /about/security/
[Segmentation]: /getting-started/configuration/#configure-segments
[aliases]: /content-management/urls/#aliases
[Chroma]: https://github.com/alecthomas/chroma
[content summaries]: /content-management/summaries/
[content types]: /content-management/types/
[Disqus]: https://disqus.com/
[Dynamic menu]: /templates/menu-templates/
[Extremely fast]: https://github.com/bep/hugo-benchmark
[front matter]: /content-management/front-matter/
[functions]: /functions/
[Go]: https://pkg.go.dev/html/template
[Google Analytics]: https://google-analytics.com/
[homepage]: /templates/homepage/
[hostanywhere]: /hosting-and-deployment/
[install]: /installation/
[LiveReload]: /getting-started/usage/
[organization for your projects]: /getting-started/directory-structure/
[pagevars]: /variables/page/
[Permalink]: /content-management/urls/#permalinks
[Powerful theming]: /hugo-modules/theme-components/
[Pretty URLs]: /content-management/urls/
[RSS]: /templates/rss/
[Shortcodes]: /content-management/shortcodes/
[sort content]: /templates/
[supported formats]: /content-management/formats/
[Syntax highlighting]: /content-management/syntax-highlighting/
[Taxonomies]: /content-management/taxonomies/
[Templates]: templates/introduction/
[Themes]: https://themes.gohugo.io/
[URL management]: /content-management/urls/
[table of contents]: /content-management/toc/
[taxonomies]: /content-management/taxonomies/
[URLs]: /content-management/urls/
@@ -1,16 +1,16 @@
---
title: Privacy
linkTitle: Privacy
description: Configure your site to facilitate compliance with regional privacy regulations.
title: Hugo and the General Data Protection Regulation
linkTitle: Hugo and the GDPR
description: About how to configure your Hugo site to meet the new regulations.
categories: [about]
keywords: ["GDPR", "Privacy", "Data Protection"]
menu:
docs:
parent: about
weight: 40
weight: 40
weight: 60
weight: 60
toc: true
aliases: [/gdpr/,/about/hugo-and-gdpr/]
aliases: [/privacy/,/gdpr/]
---
General Data Protection Regulation ([GDPR](https://en.wikipedia.org/wiki/General_Data_Protection_Regulation)) is a regulation in EU law on data protection and privacy for all individuals within the European Union and the European Economic Area. It became enforceable on 25 May 2018.
@@ -22,7 +22,7 @@ aliases: [/gdpr/,/about/hugo-and-gdpr/]
Note that:
* These settings have their defaults setting set to _off_, i.e. how it worked before Hugo `0.41`. You must do your own evaluation of your site and apply the appropriate settings.
* These settings work with the [embedded templates](/templates/embedded/). Some theme may contain custom templates for embedding services like Google Analytics. In that case these options have no effect.
* These settings work with the [internal templates](/templates/internal/). Some theme may contain custom templates for embedding services like Google Analytics. In that case these options have no effect.
* We will continue this work and improve this further in future Hugo versions.
## All privacy settings
@@ -36,6 +36,8 @@ disable = false
[privacy.googleAnalytics]
disable = false
respectDoNotTrack = false
anonymizeIP = false
useSessionStorage = false
[privacy.instagram]
disable = false
simple = false
@@ -76,9 +78,19 @@ disable = true
### GoogleAnalytics
anonymizeIP
: Enabling this will make it so the users' IP addresses are anonymized within Google Analytics.
respectDoNotTrack
: Enabling this will make the GA templates respect the "Do Not Track" HTTP header.
useSessionStorage
: Enabling this will disable the use of Cookies and use Session Storage to Store the GA Client ID.
{{% note %}}
`useSessionStorage` is not supported when using Google Analytics v4 (gtag.js).
{{% /note %}}
### Instagram
simple
-39
View File
@@ -1,39 +0,0 @@
---
title: Introduction
description: Hugo is a static site generator written in Go, optimized for speed and designed for flexibility.
categories: [about]
keywords: []
menu:
docs:
identifier: about-introduction
parent: about
weight: 20
weight: 20
aliases: [/about/what-is-hugo/,/about/benefits/]
---
Hugo is a [static site generator] written in [Go], optimized for speed and designed for flexibility. With its advanced templating system and fast asset pipelines, Hugo renders a complete site in seconds, often less.
Due to its flexible framework, multilingual support, and powerful taxonomy system, Hugo is widely used to create:
- Corporate, government, nonprofit, education, news, event, and project sites
- Documentation sites
- Image portfolios
- Landing pages
- Business, professional, and personal blogs
- Resumes and CVs
Use Hugo's embedded web server during development to instantly see changes to content, structure, behavior, and presentation. Then deploy the site to your host, or push changes to your Git provider for automated builds and deployment.
And with [Hugo Modules], you can share content, assets, data, translations, themes, templates, and configuration with other projects via public or private Git repositories.
Learn more about Hugo's [features], [privacy protections], and [security model].
[Go]: https://go.dev
[Hugo Modules]: /hugo-modules/
[static site generator]: https://en.wikipedia.org/wiki/Static_site_generator
[features]: /about/features
[security model]: /about/security
[privacy protections]: /about/privacy
{{< youtube 0RKpf3rK57I >}}
+3 -3
View File
@@ -2,12 +2,12 @@
title: License
description: Hugo is released under the Apache 2.0 license.
categories: [about]
keywords: [apache]
keywords: [license,apache]
menu:
docs:
parent: about
weight: 60
weight: 60
weight: 70
weight: 70
---
## Apache License
@@ -1,6 +1,5 @@
---
title: Security model
linkTitle: Security
title: Hugo's security model
description: A summary of Hugo's security model.
categories: [about]
keywords: [security,privacy]
@@ -10,7 +9,7 @@ menu:
weight: 50
weight: 50
toc: true
aliases: [/about/security-model/]
aliases: [/security/]
---
## Runtime security
@@ -22,8 +21,9 @@ But when developing and building your site, the runtime is the `hugo` executable
**Hugo's main approach is that of sandboxing and a security policy with strict defaults:**
* Hugo has a virtual file system and only the main project (not third-party components) is allowed to mount directories or files outside the project root.
* Only the main project can walk symbolic links.
* User-defined components have read-only access to the filesystem.
* We shell out to some external binaries to support [Asciidoctor](/content-management/formats/#formats) and similar, but those binaries and their flags are predefined and disabled by default (see [Security Policy](#security-policy)). General functions to run arbitrary external OS commands have been [discussed](https://github.com/gohugoio/hugo/issues/796), but not implemented because of security concerns.
* We shell out to some external binaries to support [Asciidoctor](/content-management/formats/#list-of-content-formats) and similar, but those binaries and their flags are predefined and disabled by default (see [Security Policy](#security-policy)). General functions to run arbitrary external OS commands have been [discussed](https://github.com/gohugoio/hugo/issues/796), but not implemented because of security concerns.
## Security policy
@@ -33,16 +33,7 @@ The default configuration is listed below. Any build using features not in the a
{{< code-toggle config=security />}}
By default, Hugo permits the [`resources.GetRemote`] function to download files with media types corresponding to an internal allow list. To add media types to the allow list:
[`resources.GetRemote`]: /functions/resources/getremote
{{< code-toggle file=hugo >}}
[security.http]
mediaTypes = ['^image/avif$']
{{< /code-toggle >}}
Note that these and other configuration settings in Hugo can be overridden by the OS environment. For example, if you want to block all remote HTTP fetching of data:
Note that these and other configuration settings in Hugo can be overridden by the OS environment. If you want to block all remote HTTP fetching of data:
```txt
HUGO_SECURITY_HTTP_URLS=none hugo
+57
View File
@@ -0,0 +1,57 @@
---
title: What is Hugo
description: Hugo is a fast and modern static site generator written in Go, and designed to make website creation fun again.
categories: [about]
keywords: []
menu:
docs:
parent: about
weight: 20
weight: 20
toc: true
aliases: [/overview/introduction/,/about/why-i-built-hugo/]
---
Hugo is a general-purpose website framework. Technically speaking, Hugo is a [static site generator]. Unlike systems that dynamically build a page with each visitor request, Hugo builds pages when you create or update your content. Since websites are viewed far more often than they are edited, Hugo is designed to provide an optimal viewing experience for your website's end users and an ideal writing experience for website authors.
Websites built with Hugo are extremely fast and secure. Hugo sites can be hosted anywhere, including [Netlify], [Heroku], [GoDaddy], [DreamHost], [GitHub Pages], [GitLab Pages], [Surge], [Firebase], [Google Cloud Storage], [Amazon S3], [Rackspace], [Azure], and [CloudFront] and work well with CDNs. Hugo sites run without the need for a database or dependencies on expensive runtimes like Ruby, Python, or PHP.
We think of Hugo as the ideal website creation tool with nearly instant build times, able to rebuild whenever a change is made.
## How fast is Hugo?
{{< youtube "CdiDYZ51a2o" >}}
## What does Hugo do?
In technical terms, Hugo takes a source directory of files and templates and uses these as input to create a complete website.
## Who should use Hugo?
Hugo is for people that prefer writing in a text editor over a browser.
Hugo is for people who want to hand code their own website without worrying about setting up complicated runtimes, dependencies and databases.
Hugo is for people building a blog, a company site, a portfolio site, documentation, a single landing page, or a website with thousands of pages.
[@spf13]: https://twitter.com/spf13
[Amazon S3]: https://aws.amazon.com/s3/
[Azure]: https://docs.microsoft.com/en-us/azure/storage/blobs/storage-blob-static-website
[CloudFront]: https://aws.amazon.com/cloudfront/
[DreamHost]: https://www.dreamhost.com/
[Firebase]: https://firebase.google.com/docs/hosting/
[GitHub Pages]: https://pages.github.com/
[GitLab Pages]: https://about.gitlab.com/features/pages/
[Go language]: https://go.dev/
[GoDaddy]: https://www.godaddy.com/
[Google Cloud Storage]: https://cloud.google.com/storage/
[Heroku]: https://www.heroku.com/
[Jekyll]: https://jekyllrb.com/
[Middleman]: https://middlemanapp.com/
[Nanoc]: https://nanoc.ws/
[Netlify]: https://netlify.com
[Rackspace]: https://www.rackspace.com/cloud/files
[Surge]: https://surge.sh
[contributing to it]: https://github.com/gohugoio/hugo
[rackspace]: https://www.rackspace.com/openstack/public/files
[static site generator]: /about/benefits/
+1 -1
View File
@@ -57,7 +57,7 @@ hugo [flags]
--printUnusedTemplates print warnings on unused templates.
--quiet build in quiet mode
--renderSegments strings named segments to render (configured in the segments config)
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--templateMetrics display metrics about template executions
--templateMetricsHints calculate some improvement hints when combined with --templateMetrics
+1 -1
View File
@@ -31,7 +31,7 @@ See each sub-command's help for details on how to use the generated script.
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
@@ -54,7 +54,7 @@ hugo completion bash
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
@@ -45,7 +45,7 @@ hugo completion fish [flags]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
@@ -42,7 +42,7 @@ hugo completion powershell [flags]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
@@ -56,7 +56,7 @@ hugo completion zsh [flags]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -40,7 +40,7 @@ hugo config [command] [flags]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
@@ -34,7 +34,7 @@ hugo config mounts [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -33,7 +33,7 @@ See convert's subcommands toJSON, toTOML and toYAML for more information.
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
@@ -35,7 +35,7 @@ hugo convert toJSON [flags] [args]
--logLevel string log level (debug|info|warn|error)
-o, --output string filesystem path to write files to
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
--unsafe enable less safe operations, please backup first
@@ -35,7 +35,7 @@ hugo convert toTOML [flags] [args]
--logLevel string log level (debug|info|warn|error)
-o, --output string filesystem path to write files to
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
--unsafe enable less safe operations, please backup first
@@ -35,7 +35,7 @@ hugo convert toYAML [flags] [args]
--logLevel string log level (debug|info|warn|error)
-o, --output string filesystem path to write files to
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
--unsafe enable less safe operations, please backup first
+1 -1
View File
@@ -44,7 +44,7 @@ hugo deploy [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -33,7 +33,7 @@ hugo env [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -25,7 +25,7 @@ A collection of several useful generators.
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
@@ -39,7 +39,7 @@ hugo gen chromastyles [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -39,7 +39,7 @@ hugo gen doc [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -36,7 +36,7 @@ hugo gen man [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -31,7 +31,7 @@ Import requires a subcommand, e.g. `hugo import jekyll jekyll_root_path target_p
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
@@ -36,7 +36,7 @@ hugo import jekyll [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+5 -6
View File
@@ -31,7 +31,7 @@ List requires a subcommand, e.g. hugo list drafts
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
@@ -40,9 +40,8 @@ List requires a subcommand, e.g. hugo list drafts
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo list all](/commands/hugo_list_all/) - List all content
* [hugo list drafts](/commands/hugo_list_drafts/) - List draft content
* [hugo list expired](/commands/hugo_list_expired/) - List expired content
* [hugo list future](/commands/hugo_list_future/) - List future content
* [hugo list published](/commands/hugo_list_published/) - List published content
* [hugo list all](/commands/hugo_list_all/) - List all posts
* [hugo list drafts](/commands/hugo_list_drafts/) - List all drafts
* [hugo list expired](/commands/hugo_list_expired/) - List all posts already expired
* [hugo list future](/commands/hugo_list_future/) - List all posts dated in the future
+3 -3
View File
@@ -5,11 +5,11 @@ url: /commands/hugo_list_all/
---
## hugo list all
List all content
List all posts
### Synopsis
List all content including draft, future, and expired.
List all of the posts in your content directory, include drafts, future and expired pages.
```
hugo list all [flags] [args]
@@ -33,7 +33,7 @@ hugo list all [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+3 -3
View File
@@ -5,11 +5,11 @@ url: /commands/hugo_list_drafts/
---
## hugo list drafts
List draft content
List all drafts
### Synopsis
List draft content.
List all of the drafts in your content directory.
```
hugo list drafts [flags] [args]
@@ -33,7 +33,7 @@ hugo list drafts [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
@@ -5,11 +5,11 @@ url: /commands/hugo_list_expired/
---
## hugo list expired
List expired content
List all posts already expired
### Synopsis
List content with a past expiration date.
List all of the posts in your content directory which has already expired.
```
hugo list expired [flags] [args]
@@ -33,7 +33,7 @@ hugo list expired [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+3 -3
View File
@@ -5,11 +5,11 @@ url: /commands/hugo_list_future/
---
## hugo list future
List future content
List all posts dated in the future
### Synopsis
List content with a future publication date.
List all of the posts in your content directory which will be posted in the future.
```
hugo list future [flags] [args]
@@ -33,7 +33,7 @@ hugo list future [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
@@ -1,45 +0,0 @@
---
title: "hugo list published"
slug: hugo_list_published
url: /commands/hugo_list_published/
---
## hugo list published
List published content
### Synopsis
List content that is not draft, future, or expired.
```
hugo list published [flags] [args]
```
### Options
```
-h, --help help for published
```
### Options inherited from parent commands
```
--clock string set the clock used by Hugo, e.g. --clock 2021-11-06T22:30:00.00+09:00
--config string config file (default is hugo.yaml|json|toml)
--configDir string config dir (default "config")
--debug debug output
-d, --destination string filesystem path to write files to
-e, --environment string build environment
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
```
### SEE ALSO
* [hugo list](/commands/hugo_list/) - Listing out various types of content
+1 -1
View File
@@ -40,7 +40,7 @@ See https://gohugo.io/hugo-modules/ for more information.
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -40,7 +40,7 @@ hugo mod clean [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -64,7 +64,7 @@ hugo mod get [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -41,7 +41,7 @@ hugo mod graph [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -45,7 +45,7 @@ hugo mod init [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -33,7 +33,7 @@ hugo mod npm [command] [flags]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
@@ -48,7 +48,7 @@ hugo mod npm pack [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -34,7 +34,7 @@ hugo mod tidy [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -40,7 +40,7 @@ hugo mod vendor [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -39,7 +39,7 @@ hugo mod verify [flags] [args]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -36,7 +36,7 @@ Ensure you run this within the root directory of your site.
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -48,7 +48,7 @@ hugo new content [path] [flags]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output
+1 -1
View File
@@ -37,7 +37,7 @@ hugo new site [path] [flags]
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
--logLevel string log level (debug|info|warn|error)
--quiet build in quiet mode
-M, --renderToMemory render to memory (mostly useful when running the server)
--renderToMemory render to memory (mostly useful when running the server)
-s, --source string filesystem path to read files relative from
--themesDir string filesystem path to themes directory
-v, --verbose verbose output

Some files were not shown because too many files have changed in this diff Show More