mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-25 15:58:53 +00:00
Compare commits
85 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b13e1ce066 | |||
| 099b05a63c | |||
| 5bbe95f9c5 | |||
| 31d19b505d | |||
| bfa2fd683e | |||
| 88d598a049 | |||
| 352be5ba87 | |||
| d37606d2c2 | |||
| f5e54d9c7d | |||
| 42f37b4e98 | |||
| e971b7d866 | |||
| ad985550a4 | |||
| b5852d0e68 | |||
| b5801d8b6a | |||
| 64d1865c1e | |||
| e4ad0c5271 | |||
| a2f666b586 | |||
| b1b3bbcdbd | |||
| 1cfe9741b9 | |||
| 2939270a3b | |||
| 5db27b19c1 | |||
| b7d62d76c5 | |||
| 6e1c5b61b3 | |||
| e7d0757f95 | |||
| 6b5e117a12 | |||
| 4985be1a4a | |||
| db653a8485 | |||
| 05bbd2c515 | |||
| 21366e0411 | |||
| ea633dd809 | |||
| 57151a5e91 | |||
| 5bb22b6b4e | |||
| 41f69a7255 | |||
| 4a79956276 | |||
| 039845804f | |||
| 9b635522e2 | |||
| 3223a65c9b | |||
| bc6fc47727 | |||
| ffb41d1111 | |||
| 5b0b663ec3 | |||
| 3f68309148 | |||
| ab03588db9 | |||
| 0450d69fc6 | |||
| 1158e63072 | |||
| d1ba52f3c3 | |||
| d0dca65625 | |||
| f30603c47f | |||
| 12c9ce34bb | |||
| 47b055589c | |||
| e56ea40666 | |||
| 4c02a52f7c | |||
| 578442f892 | |||
| 0d390d7eb8 | |||
| da72ac2db9 | |||
| 0ea796dad1 | |||
| 1e690c0f23 | |||
| a619deec18 | |||
| 5fb333b9f5 | |||
| e07028cb90 | |||
| 22a9f3fc98 | |||
| e363964f2f | |||
| c260cb28a9 | |||
| e079145373 | |||
| 5b442b3cce | |||
| 2bc27657d8 | |||
| 28f621d4a7 | |||
| fe7e137e28 | |||
| 1c74abd260 | |||
| 3d6baedaec | |||
| 84ee00bbc2 | |||
| 2f89169baa | |||
| 66a3a11001 | |||
| 8f2eac0195 | |||
| b570a5f118 | |||
| 39fd3b5570 | |||
| aacff7aff4 | |||
| 77df7bbbff | |||
| ae3815898f | |||
| 504a23184f | |||
| e651d29801 | |||
| dec8cd4ada | |||
| 0c453420e6 | |||
| 469124823c | |||
| 96afea4acc | |||
| 6d97ee711e |
@@ -4,7 +4,7 @@ parameters:
|
||||
defaults: &defaults
|
||||
resource_class: large
|
||||
docker:
|
||||
- image: bepsays/ci-hugoreleaser:1.22300.20000
|
||||
- image: bepsays/ci-hugoreleaser:1.22300.20200
|
||||
environment: &buildenv
|
||||
GOMODCACHE: /root/project/gomodcache
|
||||
version: 2
|
||||
@@ -14,9 +14,7 @@ jobs:
|
||||
environment: &buildenv
|
||||
GOMODCACHE: /root/project/gomodcache
|
||||
steps:
|
||||
- &remote-docker
|
||||
setup_remote_docker:
|
||||
version: 20.10.14
|
||||
- setup_remote_docker
|
||||
- checkout:
|
||||
path: hugo
|
||||
- &git-config
|
||||
@@ -60,7 +58,7 @@ jobs:
|
||||
environment:
|
||||
<<: [*buildenv]
|
||||
docker:
|
||||
- image: bepsays/ci-hugoreleaser-linux-arm64:1.22300.20000
|
||||
- image: bepsays/ci-hugoreleaser-linux-arm64:1.22300.20200
|
||||
steps:
|
||||
- *restore-cache
|
||||
- &attach-workspace
|
||||
|
||||
+10
-79
@@ -1,10 +1,9 @@
|
||||
name: Build Docker image
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "*"
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [published]
|
||||
pull_request:
|
||||
permissions:
|
||||
packages: write
|
||||
|
||||
@@ -14,18 +13,8 @@ env:
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform:
|
||||
- linux/amd64
|
||||
- linux/arm64
|
||||
steps:
|
||||
- name: Prepare
|
||||
run: |
|
||||
platform=${{ matrix.platform }}
|
||||
echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
|
||||
|
||||
@@ -35,9 +24,6 @@ jobs:
|
||||
with:
|
||||
images: ${{ env.REGISTRY_IMAGE }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
|
||||
|
||||
@@ -49,69 +35,14 @@ jobs:
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push by digest
|
||||
- name: Build and push
|
||||
id: build
|
||||
uses: docker/build-push-action@16ebe778df0e7752d2cfcbd924afdbbd89c1a755 # v6.6.1
|
||||
with:
|
||||
context: .
|
||||
push: ${{ startsWith(github.ref, 'refs/tags') }}
|
||||
platforms: ${{ matrix.platform }}
|
||||
provenance: mode=max
|
||||
sbom: true
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
|
||||
|
||||
- name: Export digest
|
||||
run: |
|
||||
mkdir -p /tmp/digests
|
||||
digest="${{ steps.build.outputs.digest }}"
|
||||
touch "/tmp/digests/${digest#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
|
||||
with:
|
||||
name: digests-${{ env.PLATFORM_PAIR }}
|
||||
path: /tmp/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
merge:
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build
|
||||
steps:
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
|
||||
with:
|
||||
path: /tmp/digests
|
||||
pattern: digests-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
|
||||
|
||||
- name: Docker meta
|
||||
id: meta
|
||||
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1
|
||||
with:
|
||||
images: ${{ env.REGISTRY_IMAGE }}
|
||||
|
||||
flavor: |
|
||||
latest=false
|
||||
|
||||
- name: Login to GHCR
|
||||
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Create manifest list and push
|
||||
if: ${{ startsWith(github.ref, 'refs/tags') }}
|
||||
working-directory: /tmp/digests
|
||||
run: |
|
||||
docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
|
||||
$(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
|
||||
|
||||
- name: Inspect image
|
||||
if: ${{ startsWith(github.ref, 'refs/tags') }}
|
||||
run: |
|
||||
docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
go-version: [1.22.x, 1.23.x]
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
os: [ubuntu-latest, windows-latest] # macos disabled for now because of disk space issues.
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- if: matrix.os == 'ubuntu-latest'
|
||||
|
||||
+78
-24
@@ -2,44 +2,98 @@
|
||||
# Twitter: https://twitter.com/gohugoio
|
||||
# Website: https://gohugo.io/
|
||||
|
||||
FROM golang:1.21-alpine AS build
|
||||
ARG GO_VERSION="1.23.2"
|
||||
ARG ALPINE_VERSION="3.20"
|
||||
ARG DART_SASS_VERSION="1.79.3"
|
||||
|
||||
# Optionally set HUGO_BUILD_TAGS to "extended" or "nodeploy" when building like so:
|
||||
# docker build --build-arg HUGO_BUILD_TAGS=extended .
|
||||
ARG HUGO_BUILD_TAGS
|
||||
FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.5.0 AS xx
|
||||
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS gobuild
|
||||
FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS gorun
|
||||
|
||||
ARG CGO=1
|
||||
ENV CGO_ENABLED=${CGO}
|
||||
ENV GOOS=linux
|
||||
ENV GO111MODULE=on
|
||||
|
||||
FROM gobuild AS build
|
||||
|
||||
RUN apk add clang lld
|
||||
|
||||
# Set up cross-compilation helpers
|
||||
COPY --from=xx / /
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
RUN xx-apk add musl-dev gcc g++
|
||||
|
||||
# Optionally set HUGO_BUILD_TAGS to "none" or "nodeploy" when building like so:
|
||||
# docker build --build-arg HUGO_BUILD_TAGS=nodeploy .
|
||||
#
|
||||
# We build the extended version by default.
|
||||
ARG HUGO_BUILD_TAGS="extended"
|
||||
ENV CGO_ENABLED=1
|
||||
ENV GOPROXY=https://proxy.golang.org
|
||||
ENV GOCACHE=/root/.cache/go-build
|
||||
ENV GOMODCACHE=/go/pkg/mod
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
WORKDIR /go/src/github.com/gohugoio/hugo
|
||||
|
||||
COPY . /go/src/github.com/gohugoio/hugo/
|
||||
# For --mount=type=cache the value of target is the default cache id, so
|
||||
# for the go mod cache it would be good if we could share it with other Go images using the same setup,
|
||||
# but the go build cache needs to be per platform.
|
||||
# See this comment: https://github.com/moby/buildkit/issues/1706#issuecomment-702238282
|
||||
RUN --mount=target=. \
|
||||
--mount=type=cache,target=/go/pkg/mod \
|
||||
--mount=type=cache,target=/root/.cache/go-build,id=go-build-$TARGETPLATFORM <<EOT
|
||||
set -ex
|
||||
xx-go build -tags "$HUGO_BUILD_TAGS" -ldflags "-s -w -X github.com/gohugoio/hugo/common/hugo.vendorInfo=docker" -o /usr/bin/hugo
|
||||
xx-verify /usr/bin/hugo
|
||||
EOT
|
||||
|
||||
# gcc/g++ are required to build SASS libraries for extended version
|
||||
RUN apk update && \
|
||||
apk add --no-cache gcc g++ musl-dev git && \
|
||||
go install github.com/magefile/mage
|
||||
# dart-sass downloads the dart-sass runtime dependency
|
||||
FROM alpine:${ALPINE_VERSION} AS dart-sass
|
||||
ARG TARGETARCH
|
||||
ARG DART_SASS_VERSION
|
||||
ARG DART_ARCH=${TARGETARCH/amd64/x64}
|
||||
WORKDIR /out
|
||||
ADD https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-${DART_ARCH}.tar.gz .
|
||||
RUN tar -xf dart-sass-${DART_SASS_VERSION}-linux-${DART_ARCH}.tar.gz
|
||||
|
||||
RUN mage hugo && mage install
|
||||
FROM gorun AS final
|
||||
|
||||
# ---
|
||||
COPY --from=build /usr/bin/hugo /usr/bin/hugo
|
||||
|
||||
FROM alpine:3.18
|
||||
# libc6-compat are required for extended libraries (libsass, libwebp).
|
||||
RUN apk add --no-cache \
|
||||
libc6-compat \
|
||||
git \
|
||||
runuser \
|
||||
nodejs \
|
||||
npm
|
||||
|
||||
COPY --from=build /go/bin/hugo /usr/bin/hugo
|
||||
RUN mkdir -p /var/hugo/bin /cache && \
|
||||
addgroup -Sg 1000 hugo && \
|
||||
adduser -Sg hugo -u 1000 -h /var/hugo hugo && \
|
||||
chown -R hugo: /var/hugo /cache && \
|
||||
# For the Hugo's Git integration to work.
|
||||
runuser -u hugo -- git config --global --add safe.directory /project && \
|
||||
# See https://github.com/gohugoio/hugo/issues/9810
|
||||
runuser -u hugo -- git config --global core.quotepath false
|
||||
|
||||
# libc6-compat & libstdc++ are required for extended SASS libraries
|
||||
# ca-certificates are required to fetch outside resources (like Twitter oEmbeds)
|
||||
RUN apk update && \
|
||||
apk add --no-cache ca-certificates libc6-compat libstdc++ git
|
||||
USER hugo:hugo
|
||||
VOLUME /project
|
||||
WORKDIR /project
|
||||
ENV HUGO_CACHEDIR=/cache
|
||||
ENV PATH="/var/hugo/bin:$PATH"
|
||||
|
||||
VOLUME /site
|
||||
WORKDIR /site
|
||||
COPY scripts/docker/entrypoint.sh /entrypoint.sh
|
||||
COPY --from=dart-sass /out/dart-sass /var/hugo/bin/dart-sass
|
||||
|
||||
# Update PATH to reflect the new dependencies.
|
||||
# For more complex setups, we should probably find a way to
|
||||
# delegate this to the script itself, but this will have to do for now.
|
||||
# Also, the dart-sass binary is a little special, other binaries can be put/linked
|
||||
# directly in /var/hugo/bin.
|
||||
ENV PATH="/var/hugo/bin/dart-sass:$PATH"
|
||||
|
||||
# Expose port for live server
|
||||
EXPOSE 1313
|
||||
|
||||
ENTRYPOINT ["hugo"]
|
||||
ENTRYPOINT ["/entrypoint.sh"]
|
||||
CMD ["--help"]
|
||||
|
||||
+68
-26
@@ -42,6 +42,7 @@ import (
|
||||
"github.com/gohugoio/hugo/common/hugo"
|
||||
"github.com/gohugoio/hugo/common/loggers"
|
||||
"github.com/gohugoio/hugo/common/paths"
|
||||
"github.com/gohugoio/hugo/common/types"
|
||||
"github.com/gohugoio/hugo/config"
|
||||
"github.com/gohugoio/hugo/config/allconfig"
|
||||
"github.com/gohugoio/hugo/deps"
|
||||
@@ -66,6 +67,12 @@ func Execute(args []string) error {
|
||||
}
|
||||
args = mapLegacyArgs(args)
|
||||
cd, err := x.Execute(context.Background(), args)
|
||||
if cd != nil {
|
||||
if closer, ok := cd.Root.Command.(types.Closer); ok {
|
||||
closer.Close()
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if err == errHelp {
|
||||
cd.CobraCommand.Help()
|
||||
@@ -88,6 +95,11 @@ type commonConfig struct {
|
||||
fs *hugofs.Fs
|
||||
}
|
||||
|
||||
type configKey struct {
|
||||
counter int32
|
||||
ignoreModulesDoesNotExists bool
|
||||
}
|
||||
|
||||
// This is the root command.
|
||||
type rootCommand struct {
|
||||
Printf func(format string, v ...interface{})
|
||||
@@ -101,8 +113,8 @@ type rootCommand struct {
|
||||
|
||||
// Some, but not all commands need access to these.
|
||||
// Some needs more than one, so keep them in a small cache.
|
||||
commonConfigs *lazycache.Cache[int32, *commonConfig]
|
||||
hugoSites *lazycache.Cache[int32, *hugolib.HugoSites]
|
||||
commonConfigs *lazycache.Cache[configKey, *commonConfig]
|
||||
hugoSites *lazycache.Cache[configKey, *hugolib.HugoSites]
|
||||
|
||||
// changesFromBuild received from Hugo in watch mode.
|
||||
changesFromBuild chan []identity.Identity
|
||||
@@ -144,6 +156,18 @@ func (r *rootCommand) isVerbose() bool {
|
||||
return r.logger.Level() <= logg.LevelInfo
|
||||
}
|
||||
|
||||
func (r *rootCommand) Close() error {
|
||||
if r.hugoSites != nil {
|
||||
r.hugoSites.DeleteFunc(func(key configKey, value *hugolib.HugoSites) bool {
|
||||
if value != nil {
|
||||
value.Close()
|
||||
}
|
||||
return false
|
||||
})
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *rootCommand) Build(cd *simplecobra.Commandeer, bcfg hugolib.BuildCfg, cfg config.Provider) (*hugolib.HugoSites, error) {
|
||||
h, err := r.Hugo(cfg)
|
||||
if err != nil {
|
||||
@@ -160,17 +184,18 @@ func (r *rootCommand) Commands() []simplecobra.Commander {
|
||||
return r.commands
|
||||
}
|
||||
|
||||
func (r *rootCommand) ConfigFromConfig(key int32, oldConf *commonConfig) (*commonConfig, error) {
|
||||
cc, _, err := r.commonConfigs.GetOrCreate(key, func(key int32) (*commonConfig, error) {
|
||||
func (r *rootCommand) ConfigFromConfig(key configKey, oldConf *commonConfig) (*commonConfig, error) {
|
||||
cc, _, err := r.commonConfigs.GetOrCreate(key, func(key configKey) (*commonConfig, error) {
|
||||
fs := oldConf.fs
|
||||
configs, err := allconfig.LoadConfig(
|
||||
allconfig.ConfigSourceDescriptor{
|
||||
Flags: oldConf.cfg,
|
||||
Fs: fs.Source,
|
||||
Filename: r.cfgFile,
|
||||
ConfigDir: r.cfgDir,
|
||||
Logger: r.logger,
|
||||
Environment: r.environment,
|
||||
Flags: oldConf.cfg,
|
||||
Fs: fs.Source,
|
||||
Filename: r.cfgFile,
|
||||
ConfigDir: r.cfgDir,
|
||||
Logger: r.logger,
|
||||
Environment: r.environment,
|
||||
IgnoreModuleDoesNotExist: key.ignoreModulesDoesNotExists,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
@@ -193,11 +218,11 @@ func (r *rootCommand) ConfigFromConfig(key int32, oldConf *commonConfig) (*commo
|
||||
return cc, err
|
||||
}
|
||||
|
||||
func (r *rootCommand) ConfigFromProvider(key int32, cfg config.Provider) (*commonConfig, error) {
|
||||
func (r *rootCommand) ConfigFromProvider(key configKey, cfg config.Provider) (*commonConfig, error) {
|
||||
if cfg == nil {
|
||||
panic("cfg must be set")
|
||||
}
|
||||
cc, _, err := r.commonConfigs.GetOrCreate(key, func(key int32) (*commonConfig, error) {
|
||||
cc, _, err := r.commonConfigs.GetOrCreate(key, func(key configKey) (*commonConfig, error) {
|
||||
var dir string
|
||||
if r.source != "" {
|
||||
dir, _ = filepath.Abs(r.source)
|
||||
@@ -220,12 +245,13 @@ func (r *rootCommand) ConfigFromProvider(key int32, cfg config.Provider) (*commo
|
||||
// Load the config first to allow publishDir to be configured in config file.
|
||||
configs, err := allconfig.LoadConfig(
|
||||
allconfig.ConfigSourceDescriptor{
|
||||
Flags: cfg,
|
||||
Fs: hugofs.Os,
|
||||
Filename: r.cfgFile,
|
||||
ConfigDir: r.cfgDir,
|
||||
Environment: r.environment,
|
||||
Logger: r.logger,
|
||||
Flags: cfg,
|
||||
Fs: hugofs.Os,
|
||||
Filename: r.cfgFile,
|
||||
ConfigDir: r.cfgDir,
|
||||
Environment: r.environment,
|
||||
Logger: r.logger,
|
||||
IgnoreModuleDoesNotExist: key.ignoreModulesDoesNotExists,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
@@ -307,7 +333,8 @@ func (r *rootCommand) ConfigFromProvider(key int32, cfg config.Provider) (*commo
|
||||
}
|
||||
|
||||
func (r *rootCommand) HugFromConfig(conf *commonConfig) (*hugolib.HugoSites, error) {
|
||||
h, _, err := r.hugoSites.GetOrCreate(r.configVersionID.Load(), func(key int32) (*hugolib.HugoSites, error) {
|
||||
k := configKey{counter: r.configVersionID.Load()}
|
||||
h, _, err := r.hugoSites.GetOrCreate(k, func(key configKey) (*hugolib.HugoSites, error) {
|
||||
depsCfg := r.newDepsConfig(conf)
|
||||
return hugolib.NewHugoSites(depsCfg)
|
||||
})
|
||||
@@ -315,7 +342,12 @@ func (r *rootCommand) HugFromConfig(conf *commonConfig) (*hugolib.HugoSites, err
|
||||
}
|
||||
|
||||
func (r *rootCommand) Hugo(cfg config.Provider) (*hugolib.HugoSites, error) {
|
||||
h, _, err := r.hugoSites.GetOrCreate(r.configVersionID.Load(), func(key int32) (*hugolib.HugoSites, error) {
|
||||
return r.getOrCreateHugo(cfg, false)
|
||||
}
|
||||
|
||||
func (r *rootCommand) getOrCreateHugo(cfg config.Provider, ignoreModuleDoesNotExist bool) (*hugolib.HugoSites, error) {
|
||||
k := configKey{counter: r.configVersionID.Load(), ignoreModulesDoesNotExists: ignoreModuleDoesNotExist}
|
||||
h, _, err := r.hugoSites.GetOrCreate(k, func(key configKey) (*hugolib.HugoSites, error) {
|
||||
conf, err := r.ConfigFromProvider(key, cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -418,11 +450,11 @@ func (r *rootCommand) PreRun(cd, runner *simplecobra.Commandeer) error {
|
||||
|
||||
r.changesFromBuild = make(chan []identity.Identity, 10)
|
||||
|
||||
r.commonConfigs = lazycache.New(lazycache.Options[int32, *commonConfig]{MaxEntries: 5})
|
||||
r.commonConfigs = lazycache.New(lazycache.Options[configKey, *commonConfig]{MaxEntries: 5})
|
||||
// We don't want to keep stale HugoSites in memory longer than needed.
|
||||
r.hugoSites = lazycache.New(lazycache.Options[int32, *hugolib.HugoSites]{
|
||||
r.hugoSites = lazycache.New(lazycache.Options[configKey, *hugolib.HugoSites]{
|
||||
MaxEntries: 1,
|
||||
OnEvict: func(key int32, value *hugolib.HugoSites) {
|
||||
OnEvict: func(key configKey, value *hugolib.HugoSites) {
|
||||
value.Close()
|
||||
runtime.GC()
|
||||
},
|
||||
@@ -486,16 +518,26 @@ func (r *rootCommand) IsTestRun() bool {
|
||||
}
|
||||
|
||||
func (r *rootCommand) Init(cd *simplecobra.Commandeer) error {
|
||||
return r.initRootCommand("", cd)
|
||||
}
|
||||
|
||||
func (r *rootCommand) initRootCommand(subCommandName string, cd *simplecobra.Commandeer) error {
|
||||
cmd := cd.CobraCommand
|
||||
cmd.Use = "hugo [flags]"
|
||||
cmd.Short = "hugo builds your site"
|
||||
cmd.Long = `hugo is the main command, used to build your Hugo site.
|
||||
commandName := "hugo"
|
||||
if subCommandName != "" {
|
||||
commandName = subCommandName
|
||||
}
|
||||
cmd.Use = fmt.Sprintf("%s [flags]", commandName)
|
||||
cmd.Short = "Build your site"
|
||||
cmd.Long = `COMMAND_NAME is the main command, used to build your Hugo site.
|
||||
|
||||
Hugo is a Fast and Flexible Static Site Generator
|
||||
built with love by spf13 and friends in Go.
|
||||
|
||||
Complete documentation is available at https://gohugo.io/.`
|
||||
|
||||
cmd.Long = strings.ReplaceAll(cmd.Long, "COMMAND_NAME", commandName)
|
||||
|
||||
// Configure persistent flags
|
||||
cmd.PersistentFlags().StringVarP(&r.source, "source", "s", "", "filesystem path to read files relative from")
|
||||
_ = cmd.MarkFlagDirname("source")
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/bep/simplecobra"
|
||||
)
|
||||
|
||||
@@ -21,6 +23,7 @@ import (
|
||||
func newExec() (*simplecobra.Exec, error) {
|
||||
rootCmd := &rootCommand{
|
||||
commands: []simplecobra.Commander{
|
||||
newHugoBuildCmd(),
|
||||
newVersionCmd(),
|
||||
newEnvCommand(),
|
||||
newServerCommand(),
|
||||
@@ -38,3 +41,33 @@ func newExec() (*simplecobra.Exec, error) {
|
||||
|
||||
return simplecobra.New(rootCmd)
|
||||
}
|
||||
|
||||
func newHugoBuildCmd() simplecobra.Commander {
|
||||
return &hugoBuildCommand{}
|
||||
}
|
||||
|
||||
// hugoBuildCommand just delegates to the rootCommand.
|
||||
type hugoBuildCommand struct {
|
||||
rootCmd *rootCommand
|
||||
}
|
||||
|
||||
func (c *hugoBuildCommand) Commands() []simplecobra.Commander {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *hugoBuildCommand) Name() string {
|
||||
return "build"
|
||||
}
|
||||
|
||||
func (c *hugoBuildCommand) Init(cd *simplecobra.Commandeer) error {
|
||||
c.rootCmd = cd.Root.Command.(*rootCommand)
|
||||
return c.rootCmd.initRootCommand("build", cd)
|
||||
}
|
||||
|
||||
func (c *hugoBuildCommand) PreRun(cd, runner *simplecobra.Commandeer) error {
|
||||
return c.rootCmd.PreRun(cd, runner)
|
||||
}
|
||||
|
||||
func (c *hugoBuildCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, args []string) error {
|
||||
return c.rootCmd.Run(ctx, cd, args)
|
||||
}
|
||||
|
||||
+4
-4
@@ -58,7 +58,7 @@ func (c *configCommand) Name() string {
|
||||
}
|
||||
|
||||
func (c *configCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, args []string) error {
|
||||
conf, err := c.r.ConfigFromProvider(c.r.configVersionID.Load(), flagsToCfg(cd, nil))
|
||||
conf, err := c.r.ConfigFromProvider(configKey{counter: c.r.configVersionID.Load()}, flagsToCfg(cd, nil))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -110,8 +110,8 @@ func (c *configCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, arg
|
||||
func (c *configCommand) Init(cd *simplecobra.Commandeer) error {
|
||||
c.r = cd.Root.Command.(*rootCommand)
|
||||
cmd := cd.CobraCommand
|
||||
cmd.Short = "Print the site configuration"
|
||||
cmd.Long = `Print the site configuration, both default and custom settings.`
|
||||
cmd.Short = "Display site configuration"
|
||||
cmd.Long = `Display site configuration, both default and custom settings.`
|
||||
cmd.Flags().StringVar(&c.format, "format", "toml", "preferred file format (toml, yaml or json)")
|
||||
_ = cmd.RegisterFlagCompletionFunc("format", cobra.FixedCompletions([]string{"toml", "yaml", "json"}, cobra.ShellCompDirectiveNoFileComp))
|
||||
cmd.Flags().StringVar(&c.lang, "lang", "", "the language to display config for. Defaults to the first language defined.")
|
||||
@@ -209,7 +209,7 @@ func (c *configMountsCommand) Name() string {
|
||||
|
||||
func (c *configMountsCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, args []string) error {
|
||||
r := c.configCmd.r
|
||||
conf, err := r.ConfigFromProvider(r.configVersionID.Load(), flagsToCfg(cd, nil))
|
||||
conf, err := r.ConfigFromProvider(configKey{counter: c.r.configVersionID.Load()}, flagsToCfg(cd, nil))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+2
-2
@@ -105,8 +105,8 @@ func (c *convertCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, ar
|
||||
|
||||
func (c *convertCommand) Init(cd *simplecobra.Commandeer) error {
|
||||
cmd := cd.CobraCommand
|
||||
cmd.Short = "Convert your content to different formats"
|
||||
cmd.Long = `Convert your content (e.g. front matter) to different formats.
|
||||
cmd.Short = "Convert front matter to another format"
|
||||
cmd.Long = `Convert front matter to another format.
|
||||
|
||||
See convert's subcommands toJSON, toTOML and toYAML for more information.`
|
||||
|
||||
|
||||
+2
-2
@@ -42,8 +42,8 @@ import (
|
||||
func newDeployCommand() simplecobra.Commander {
|
||||
return &simpleCommand{
|
||||
name: "deploy",
|
||||
short: "Deploy your site to a Cloud provider.",
|
||||
long: `Deploy your site to a Cloud provider.
|
||||
short: "Deploy your site to a cloud provider",
|
||||
long: `Deploy your site to a cloud provider
|
||||
|
||||
See https://gohugo.io/hosting-and-deployment/hugo-deploy/ for detailed
|
||||
documentation.
|
||||
|
||||
+4
-4
@@ -25,8 +25,8 @@ import (
|
||||
func newEnvCommand() simplecobra.Commander {
|
||||
return &simpleCommand{
|
||||
name: "env",
|
||||
short: "Print Hugo version and environment info",
|
||||
long: "Print Hugo version and environment info. This is useful in Hugo bug reports",
|
||||
short: "Display version and environment info",
|
||||
long: "Display version and environment info. This is useful in Hugo bug reports",
|
||||
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
||||
r.Printf("%s\n", hugo.BuildVersionString())
|
||||
r.Printf("GOOS=%q\n", runtime.GOOS)
|
||||
@@ -61,8 +61,8 @@ func newVersionCmd() simplecobra.Commander {
|
||||
r.Println(hugo.BuildVersionString())
|
||||
return nil
|
||||
},
|
||||
short: "Print Hugo version and environment info",
|
||||
long: "Print Hugo version and environment info. This is useful in Hugo bug reports.",
|
||||
short: "Display version",
|
||||
long: "Display version and environment info. This is useful in Hugo bug reports.",
|
||||
withc: func(cmd *cobra.Command, r *rootCommand) {
|
||||
cmd.ValidArgsFunction = cobra.NoFileCompletions
|
||||
},
|
||||
|
||||
+2
-1
@@ -273,7 +273,8 @@ func (c *genCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, args [
|
||||
|
||||
func (c *genCommand) Init(cd *simplecobra.Commandeer) error {
|
||||
cmd := cd.CobraCommand
|
||||
cmd.Short = "A collection of several useful generators."
|
||||
cmd.Short = "Generate documentation and syntax highlighting styles"
|
||||
cmd.Long = "Generate documentation for your project using Hugo's documentation engine, including syntax highlighting for various programming languages."
|
||||
|
||||
cmd.RunE = nil
|
||||
return nil
|
||||
|
||||
@@ -779,6 +779,7 @@ func (c *hugoBuilder) handleEvents(watcher *watcher.Batcher,
|
||||
istemp := strings.HasSuffix(ext, "~") ||
|
||||
(ext == ".swp") || // vim
|
||||
(ext == ".swx") || // vim
|
||||
(ext == ".bck") || // helix
|
||||
(ext == ".tmp") || // generic temp file
|
||||
(ext == ".DS_Store") || // OSX Thumbnail
|
||||
baseName == "4913" || // vim
|
||||
@@ -1046,7 +1047,7 @@ func (c *hugoBuilder) loadConfig(cd *simplecobra.Commandeer, running bool) error
|
||||
"fastRenderMode": c.fastRenderMode,
|
||||
})
|
||||
|
||||
conf, err := c.r.ConfigFromProvider(c.r.configVersionID.Load(), flagsToCfg(cd, cfg))
|
||||
conf, err := c.r.ConfigFromProvider(configKey{counter: c.r.configVersionID.Load()}, flagsToCfg(cd, cfg))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -1115,7 +1116,7 @@ func (c *hugoBuilder) reloadConfig() error {
|
||||
|
||||
if err := c.withConfE(func(conf *commonConfig) error {
|
||||
oldConf := conf
|
||||
newConf, err := c.r.ConfigFromConfig(c.r.configVersionID.Load(), conf)
|
||||
newConf, err := c.r.ConfigFromConfig(configKey{counter: c.r.configVersionID.Load()}, conf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
+2
-2
@@ -90,8 +90,8 @@ func (c *importCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, arg
|
||||
|
||||
func (c *importCommand) Init(cd *simplecobra.Commandeer) error {
|
||||
cmd := cd.CobraCommand
|
||||
cmd.Short = "Import your site from others."
|
||||
cmd.Long = `Import your site from other web site generators like Jekyll.
|
||||
cmd.Short = "Import a site from another system"
|
||||
cmd.Long = `Import a site from another system.
|
||||
|
||||
Import requires a subcommand, e.g. ` + "`hugo import jekyll jekyll_root_path target_path`."
|
||||
|
||||
|
||||
+2
-2
@@ -199,8 +199,8 @@ func (c *listCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, args
|
||||
|
||||
func (c *listCommand) Init(cd *simplecobra.Commandeer) error {
|
||||
cmd := cd.CobraCommand
|
||||
cmd.Short = "Listing out various types of content"
|
||||
cmd.Long = `Listing out various types of content.
|
||||
cmd.Short = "List content"
|
||||
cmd.Long = `List content.
|
||||
|
||||
List requires a subcommand, e.g. hugo list drafts`
|
||||
|
||||
|
||||
+12
-8
@@ -94,7 +94,7 @@ so this may/will change in future versions of Hugo.
|
||||
applyLocalFlagsBuildConfig(cmd, r)
|
||||
},
|
||||
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
||||
h, err := r.Hugo(flagsToCfg(cd, nil))
|
||||
h, err := r.getOrCreateHugo(flagsToCfg(cd, nil), true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -102,7 +102,11 @@ so this may/will change in future versions of Hugo.
|
||||
if len(args) >= 1 {
|
||||
initPath = args[0]
|
||||
}
|
||||
return h.Configs.ModulesClient.Init(initPath)
|
||||
c := h.Configs.ModulesClient
|
||||
if err := c.Init(initPath); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
&simpleCommand{
|
||||
@@ -115,7 +119,7 @@ so this may/will change in future versions of Hugo.
|
||||
cmd.Flags().BoolVarP(&clean, "clean", "", false, "delete module cache for dependencies that fail verification")
|
||||
},
|
||||
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
||||
conf, err := r.ConfigFromProvider(r.configVersionID.Load(), flagsToCfg(cd, nil))
|
||||
conf, err := r.ConfigFromProvider(configKey{counter: r.configVersionID.Load()}, flagsToCfg(cd, nil))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -135,7 +139,7 @@ Note that for vendored modules, that is the version listed and not the one from
|
||||
cmd.Flags().BoolVarP(&clean, "clean", "", false, "delete module cache for dependencies that fail verification")
|
||||
},
|
||||
run: func(ctx context.Context, cd *simplecobra.Commandeer, r *rootCommand, args []string) error {
|
||||
conf, err := r.ConfigFromProvider(r.configVersionID.Load(), flagsToCfg(cd, nil))
|
||||
conf, err := r.ConfigFromProvider(configKey{counter: r.configVersionID.Load()}, flagsToCfg(cd, nil))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -271,7 +275,7 @@ Run "go help get" for more information. All flags available for "go get" is also
|
||||
|
||||
cfg := config.New()
|
||||
cfg.Set("workingDir", dir)
|
||||
conf, err := r.ConfigFromProvider(r.configVersionID.Add(1), flagsToCfg(cd, cfg))
|
||||
conf, err := r.ConfigFromProvider(configKey{counter: r.configVersionID.Add(1)}, flagsToCfg(cd, cfg))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -284,7 +288,7 @@ Run "go help get" for more information. All flags available for "go get" is also
|
||||
})
|
||||
return nil
|
||||
} else {
|
||||
conf, err := r.ConfigFromProvider(r.configVersionID.Load(), flagsToCfg(cd, nil))
|
||||
conf, err := r.ConfigFromProvider(configKey{counter: r.configVersionID.Load()}, flagsToCfg(cd, nil))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -313,7 +317,7 @@ func (c *modCommands) Name() string {
|
||||
}
|
||||
|
||||
func (c *modCommands) Run(ctx context.Context, cd *simplecobra.Commandeer, args []string) error {
|
||||
_, err := c.r.ConfigFromProvider(c.r.configVersionID.Load(), nil)
|
||||
_, err := c.r.ConfigFromProvider(configKey{counter: c.r.configVersionID.Load()}, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -324,7 +328,7 @@ func (c *modCommands) Run(ctx context.Context, cd *simplecobra.Commandeer, args
|
||||
|
||||
func (c *modCommands) Init(cd *simplecobra.Commandeer) error {
|
||||
cmd := cd.CobraCommand
|
||||
cmd.Short = "Various Hugo Modules helpers."
|
||||
cmd.Short = "Manage modules"
|
||||
cmd.Long = `Various helpers to help manage the modules in your project's dependency graph.
|
||||
Most operations here requires a Go version installed on your system (>= Go 1.12) and the relevant VCS client (typically Git).
|
||||
This is not needed if you only operate on modules inside /themes or if you have vendored them via "hugo mod vendor".
|
||||
|
||||
+4
-4
@@ -40,7 +40,7 @@ func newNewCommand() *newCommand {
|
||||
&simpleCommand{
|
||||
name: "content",
|
||||
use: "content [path]",
|
||||
short: "Create new content for your site",
|
||||
short: "Create new content",
|
||||
long: `Create a new content file and automatically set the date and title.
|
||||
It will guess which kind of file to create based on the path provided.
|
||||
|
||||
@@ -93,7 +93,7 @@ Use ` + "`hugo new [contentPath]`" + ` to create new content.`,
|
||||
cfg.Set("workingDir", createpath)
|
||||
cfg.Set("publishDir", "public")
|
||||
|
||||
conf, err := r.ConfigFromProvider(r.configVersionID.Load(), flagsToCfg(cd, cfg))
|
||||
conf, err := r.ConfigFromProvider(configKey{counter: r.configVersionID.Load()}, flagsToCfg(cd, cfg))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -136,7 +136,7 @@ according to your needs.`,
|
||||
cfg := config.New()
|
||||
cfg.Set("publishDir", "public")
|
||||
|
||||
conf, err := r.ConfigFromProvider(r.configVersionID.Load(), flagsToCfg(cd, cfg))
|
||||
conf, err := r.ConfigFromProvider(configKey{counter: r.configVersionID.Load()}, flagsToCfg(cd, cfg))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -181,7 +181,7 @@ func (c *newCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, args [
|
||||
|
||||
func (c *newCommand) Init(cd *simplecobra.Commandeer) error {
|
||||
cmd := cd.CobraCommand
|
||||
cmd.Short = "Create new content for your site"
|
||||
cmd.Short = "Create new content"
|
||||
cmd.Long = `Create a new content file and automatically set the date and title.
|
||||
It will guess which kind of file to create based on the path provided.
|
||||
|
||||
|
||||
+1
-5
@@ -508,7 +508,7 @@ func (c *serverCommand) Run(ctx context.Context, cd *simplecobra.Commandeer, arg
|
||||
|
||||
func (c *serverCommand) Init(cd *simplecobra.Commandeer) error {
|
||||
cmd := cd.CobraCommand
|
||||
cmd.Short = "A high performance webserver"
|
||||
cmd.Short = "Start the embedded web server"
|
||||
cmd.Long = `Hugo provides its own webserver which builds and serves the site.
|
||||
While hugo server is high performance, it is a webserver with limited options.
|
||||
|
||||
@@ -1012,10 +1012,6 @@ func (c *serverCommand) serve() error {
|
||||
c.r.Println("Error:", err)
|
||||
}
|
||||
|
||||
if h := c.hugoTry(); h != nil {
|
||||
h.Close()
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
wg2, ctx := errgroup.WithContext(ctx)
|
||||
|
||||
@@ -137,7 +137,7 @@ var nilPointerErrRe = regexp.MustCompile(`at <(.*)>: error calling (.*?): runtim
|
||||
|
||||
const deferredPrefix = "__hdeferred/"
|
||||
|
||||
var deferredStringToRemove = regexp.MustCompile(`executing "__hdeferred/.*" `)
|
||||
var deferredStringToRemove = regexp.MustCompile(`executing "__hdeferred/.*?" `)
|
||||
|
||||
// ImproveRenderErr improves the error message for rendering errors.
|
||||
func ImproveRenderErr(inErr error) (outErr error) {
|
||||
|
||||
@@ -17,7 +17,7 @@ package hugo
|
||||
// This should be the only one.
|
||||
var CurrentVersion = Version{
|
||||
Major: 0,
|
||||
Minor: 134,
|
||||
Minor: 137,
|
||||
PatchLevel: 0,
|
||||
Suffix: "-DEV",
|
||||
}
|
||||
|
||||
@@ -13,8 +13,24 @@
|
||||
|
||||
package hstring
|
||||
|
||||
type RenderedString string
|
||||
import (
|
||||
"html/template"
|
||||
|
||||
func (s RenderedString) String() string {
|
||||
"github.com/gohugoio/hugo/common/types"
|
||||
)
|
||||
|
||||
var _ types.PrintableValueProvider = HTML("")
|
||||
|
||||
// HTML is a string that represents rendered HTML.
|
||||
// When printed in templates it will be rendered as template.HTML and considered safe so no need to pipe it into `safeHTML`.
|
||||
// This type was introduced as a wasy to prevent a common case of inifinite recursion in the template rendering
|
||||
// when the `linkify` option is enabled with a common (wrong) construct like `{{ .Text | .Page.RenderString }}` in a hook template.
|
||||
type HTML string
|
||||
|
||||
func (s HTML) String() string {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func (s HTML) PrintableValue() any {
|
||||
return template.HTML(s)
|
||||
}
|
||||
|
||||
@@ -25,6 +25,6 @@ func TestRenderedString(t *testing.T) {
|
||||
c := qt.New(t)
|
||||
|
||||
// Validate that it will behave like a string in Hugo settings.
|
||||
c.Assert(cast.ToString(RenderedString("Hugo")), qt.Equals, "Hugo")
|
||||
c.Assert(template.HTML(RenderedString("Hugo")), qt.Equals, template.HTML("Hugo"))
|
||||
c.Assert(cast.ToString(HTML("Hugo")), qt.Equals, "Hugo")
|
||||
c.Assert(template.HTML(HTML("Hugo")), qt.Equals, template.HTML("Hugo"))
|
||||
}
|
||||
|
||||
@@ -809,7 +809,7 @@ func (c *Configs) Init() error {
|
||||
}
|
||||
|
||||
if len(c.Modules) == 0 {
|
||||
return errors.New("no modules loaded (ned at least the main module)")
|
||||
return errors.New("no modules loaded (need at least the main module)")
|
||||
}
|
||||
|
||||
// Apply default project mounts.
|
||||
|
||||
@@ -103,31 +103,7 @@ suffixes = ["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) {
|
||||
func TestPaginationConfig(t *testing.T) {
|
||||
files := `
|
||||
-- hugo.toml --
|
||||
[languages.en]
|
||||
@@ -184,3 +160,18 @@ title: "p3"
|
||||
b.AssertFileExists("public/page/1/index.html", false)
|
||||
b.AssertFileContent("public/page/2/index.html", "pagination-default")
|
||||
}
|
||||
|
||||
func TestMapUglyURLs(t *testing.T) {
|
||||
files := `
|
||||
-- hugo.toml --
|
||||
[uglyurls]
|
||||
posts = true
|
||||
`
|
||||
|
||||
b := hugolib.Test(t, files)
|
||||
|
||||
c := b.H.Configs.Base
|
||||
|
||||
b.Assert(c.C.IsUglyURLSection("posts"), qt.IsTrue)
|
||||
b.Assert(c.C.IsUglyURLSection("blog"), qt.IsFalse)
|
||||
}
|
||||
|
||||
@@ -419,6 +419,8 @@ var allDecoderSetups = map[string]decodeWeight{
|
||||
p.c.UglyURLs = vv
|
||||
case string:
|
||||
p.c.UglyURLs = vv == "true"
|
||||
case maps.Params:
|
||||
p.c.UglyURLs = cast.ToStringMapBool(maps.CleanConfigStringMap(vv))
|
||||
default:
|
||||
p.c.UglyURLs = cast.ToStringMapBool(v)
|
||||
}
|
||||
|
||||
+17
-13
@@ -64,7 +64,7 @@ func LoadConfig(d ConfigSourceDescriptor) (*Configs, error) {
|
||||
return nil, fmt.Errorf("failed to create config from result: %w", err)
|
||||
}
|
||||
|
||||
moduleConfig, modulesClient, err := l.loadModules(configs)
|
||||
moduleConfig, modulesClient, err := l.loadModules(configs, d.IgnoreModuleDoesNotExist)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to load modules: %w", err)
|
||||
}
|
||||
@@ -116,6 +116,9 @@ type ConfigSourceDescriptor struct {
|
||||
|
||||
// Defaults to os.Environ if not set.
|
||||
Environ []string
|
||||
|
||||
// If set, this will be used to ignore the module does not exist error.
|
||||
IgnoreModuleDoesNotExist bool
|
||||
}
|
||||
|
||||
func (d ConfigSourceDescriptor) configFilenames() []string {
|
||||
@@ -453,7 +456,7 @@ func (l *configLoader) loadConfigMain(d ConfigSourceDescriptor) (config.LoadConf
|
||||
return res, l.ModulesConfig, err
|
||||
}
|
||||
|
||||
func (l *configLoader) loadModules(configs *Configs) (modules.ModulesConfig, *modules.Client, error) {
|
||||
func (l *configLoader) loadModules(configs *Configs, ignoreModuleDoesNotExist bool) (modules.ModulesConfig, *modules.Client, error) {
|
||||
bcfg := configs.LoadingInfo.BaseConfig
|
||||
conf := configs.Base
|
||||
workingDir := bcfg.WorkingDir
|
||||
@@ -487,17 +490,18 @@ func (l *configLoader) loadModules(configs *Configs) (modules.ModulesConfig, *mo
|
||||
}
|
||||
|
||||
modulesClient := modules.NewClient(modules.ClientConfig{
|
||||
Fs: l.Fs,
|
||||
Logger: l.Logger,
|
||||
Exec: ex,
|
||||
HookBeforeFinalize: hook,
|
||||
WorkingDir: workingDir,
|
||||
ThemesDir: themesDir,
|
||||
PublishDir: publishDir,
|
||||
Environment: l.Environment,
|
||||
CacheDir: conf.Caches.CacheDirModules(),
|
||||
ModuleConfig: conf.Module,
|
||||
IgnoreVendor: ignoreVendor,
|
||||
Fs: l.Fs,
|
||||
Logger: l.Logger,
|
||||
Exec: ex,
|
||||
HookBeforeFinalize: hook,
|
||||
WorkingDir: workingDir,
|
||||
ThemesDir: themesDir,
|
||||
PublishDir: publishDir,
|
||||
Environment: l.Environment,
|
||||
CacheDir: conf.Caches.CacheDirModules(),
|
||||
ModuleConfig: conf.Module,
|
||||
IgnoreVendor: ignoreVendor,
|
||||
IgnoreModuleDoesNotExist: ignoreModuleDoesNotExist,
|
||||
})
|
||||
|
||||
moduleConfig, err := modulesClient.Collect()
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
+++
|
||||
title = '{{ replace .File.ContentBaseName "-" " " | title }}'
|
||||
date = {{ .Date }}
|
||||
draft = true
|
||||
+++
|
||||
@@ -76,6 +76,11 @@ func CreateSite(createpath string, sourceFs afero.Fs, force bool, format string)
|
||||
return err
|
||||
}
|
||||
|
||||
err = newSiteCreateArchetype(sourceFs, createpath, format)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return copyFiles(createpath, sourceFs, siteFs)
|
||||
}
|
||||
|
||||
@@ -109,3 +114,19 @@ func newSiteCreateConfig(fs afero.Fs, createpath string, format string) (err err
|
||||
|
||||
return helpers.WriteToDisk(filepath.Join(createpath, "hugo."+format), &buf, fs)
|
||||
}
|
||||
|
||||
func newSiteCreateArchetype(fs afero.Fs, createpath string, format string) (err error) {
|
||||
in := map[string]any{
|
||||
"title": "{{ replace .File.ContentBaseName \"-\" \" \" | title }}",
|
||||
"date": "{{ .Date }}",
|
||||
"draft": true,
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
err = parser.InterfaceToFrontMatter(in, metadecoders.FormatFromString(format), &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return helpers.WriteToDisk(filepath.Join(createpath, "archetypes", "default.md"), &buf, fs)
|
||||
}
|
||||
|
||||
Vendored
+7
@@ -98,6 +98,8 @@ type Deps struct {
|
||||
// TODO(bep) rethink this re. a plugin setup, but this will have to do for now.
|
||||
WasmDispatchers *warpc.Dispatchers
|
||||
|
||||
isClosed bool
|
||||
|
||||
*globalErrHandler
|
||||
}
|
||||
|
||||
@@ -345,6 +347,11 @@ func (d *Deps) TextTmpl() tpl.TemplateParseFinder {
|
||||
}
|
||||
|
||||
func (d *Deps) Close() error {
|
||||
if d.isClosed {
|
||||
return nil
|
||||
}
|
||||
d.isClosed = true
|
||||
|
||||
if d.MemCache != nil {
|
||||
d.MemCache.Stop()
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
{{ define "main" }}
|
||||
{{ $section_to_display := (.Site.Taxonomies.categories.fundamentals).Pages | lang.Merge (.Sites.First.Taxonomies.categories.fundamentals).Pages }}
|
||||
{{ $section_to_display := (.Site.Taxonomies.categories.fundamentals).Pages | lang.Merge (.Sites.Default.Taxonomies.categories.fundamentals).Pages }}
|
||||
{{ partial "pagelayout.html" (dict "context" . "section_to_display" $section_to_display ) }}
|
||||
{{ end }}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{{ define "main" }}
|
||||
{{ $paginator := .Paginate (.Pages | lang.Merge (where .Sites.First.RegularPages "Section" .Section)) }}
|
||||
{{ $paginator := .Paginate (.Pages | lang.Merge (where .Sites.Default.RegularPages "Section" .Section)) }}
|
||||
{{ $section_to_display := .Sections | default $paginator.Pages }}
|
||||
{{ partial "pagelayout.html" (dict "context" . "section_to_display" $section_to_display ) }}
|
||||
{{ end }}
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
{{ $text := `
|
||||
Most of the commands for **Hugo Modules** require a newer version of Go installed (see https://golang.org/dl/) and the relevant VCS client (e.g. Git, see https://git-scm.com/downloads/ ). If you have an "older" site running on Netlify, you may have to set GO_VERSION to 1.12 in your Environment settings.
|
||||
Most of the commands for **Hugo Modules** require a newer version (>= 1.18) of Go installed (see https://golang.org/dl/) and the relevant VCS client (e.g. Git, see https://git-scm.com/downloads/ ).
|
||||
If you have an "older" site running on Netlify, you may have to set GO_VERSION to 1.19 or newer in your Environment settings.
|
||||
|
||||
For more information about Go Modules, see:
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
# github.com/gohugoio/gohugoioTheme v0.0.0-20240728210410-d42c342ce472
|
||||
# github.com/gohugoio/gohugoioTheme v0.0.0-20240815082608-66ccd383a90f
|
||||
|
||||
@@ -49,7 +49,7 @@ toc: true
|
||||
: 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.
|
||||
: Override the conversion of Markdown to HTML when rendering blockquotes, fenced code blocks, headings, images, links, and tables. 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.
|
||||
|
||||
@@ -5,7 +5,7 @@ url: /commands/hugo/
|
||||
---
|
||||
## hugo
|
||||
|
||||
hugo builds your site
|
||||
Build your site
|
||||
|
||||
### Synopsis
|
||||
|
||||
@@ -70,16 +70,17 @@ hugo [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo build](/commands/hugo_build/) - Build your site
|
||||
* [hugo completion](/commands/hugo_completion/) - Generate the autocompletion script for the specified shell
|
||||
* [hugo config](/commands/hugo_config/) - Print the site configuration
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
* [hugo deploy](/commands/hugo_deploy/) - Deploy your site to a Cloud provider.
|
||||
* [hugo env](/commands/hugo_env/) - Print Hugo version and environment info
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
* [hugo import](/commands/hugo_import/) - Import your site from others.
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
|
||||
* [hugo new](/commands/hugo_new/) - Create new content for your site
|
||||
* [hugo server](/commands/hugo_server/) - A high performance webserver
|
||||
* [hugo version](/commands/hugo_version/) - Print Hugo version and environment info
|
||||
* [hugo config](/commands/hugo_config/) - Display site configuration
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert front matter to another format
|
||||
* [hugo deploy](/commands/hugo_deploy/) - Deploy your site to a cloud provider
|
||||
* [hugo env](/commands/hugo_env/) - Display version and environment info
|
||||
* [hugo gen](/commands/hugo_gen/) - Generate documentation and syntax highlighting styles
|
||||
* [hugo import](/commands/hugo_import/) - Import a site from another system
|
||||
* [hugo list](/commands/hugo_list/) - List content
|
||||
* [hugo mod](/commands/hugo_mod/) - Manage modules
|
||||
* [hugo new](/commands/hugo_new/) - Create new content
|
||||
* [hugo server](/commands/hugo_server/) - Start the embedded web server
|
||||
* [hugo version](/commands/hugo_version/) - Display version
|
||||
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
title: "hugo build"
|
||||
slug: hugo_build
|
||||
url: /commands/hugo_build/
|
||||
---
|
||||
## hugo build
|
||||
|
||||
Build your site
|
||||
|
||||
### Synopsis
|
||||
|
||||
build is the main command, used to build your Hugo site.
|
||||
|
||||
Hugo is a Fast and Flexible Static Site Generator
|
||||
built with love by spf13 and friends in Go.
|
||||
|
||||
Complete documentation is available at https://gohugo.io/.
|
||||
|
||||
```
|
||||
hugo build [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. https://spf13.com/
|
||||
-D, --buildDrafts include content marked as draft
|
||||
-E, --buildExpired include expired content
|
||||
-F, --buildFuture include content with publishdate in the future
|
||||
--cacheDir string filesystem path to cache directory
|
||||
--cleanDestinationDir remove files from destination not found in static directories
|
||||
--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")
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
--debug debug output
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disableKinds strings disable different kind of pages (home, RSS etc.)
|
||||
--enableGitInfo add Git revision, date, author, and CODEOWNERS info to the pages
|
||||
-e, --environment string build environment
|
||||
--forceSyncStatic copy all files when static is changed.
|
||||
--gc enable to run some cleanup tasks (remove unused cache files) after the build
|
||||
-h, --help help for build
|
||||
--ignoreCache ignores the cache directory
|
||||
--ignoreVendorPaths string ignores any _vendor for module paths matching the given Glob pattern
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--logLevel string log level (debug|info|warn|error)
|
||||
--minify minify any supported output format (HTML, XML etc.)
|
||||
--noBuildLock don't create .hugo_build.lock file
|
||||
--noChmod don't sync permission mode of files
|
||||
--noTimes don't sync modification time of files
|
||||
--panicOnWarning panic on first WARNING log
|
||||
--poll string set this to a poll interval, e.g --poll 700ms, to use a poll based approach to watch for file system changes
|
||||
--printI18nWarnings print missing translations
|
||||
--printMemoryUsage print memory usage to screen at intervals
|
||||
--printPathWarnings print warnings on duplicate target paths etc.
|
||||
--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)
|
||||
-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
|
||||
-t, --theme strings themes to use (located in /themes/THEMENAME/)
|
||||
--themesDir string filesystem path to themes directory
|
||||
--trace file write trace to file (not useful in general)
|
||||
-v, --verbose verbose output
|
||||
-w, --watch watch filesystem for changes and recreate as needed
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - Build your site
|
||||
|
||||
@@ -39,7 +39,7 @@ See each sub-command's help for details on how to use the generated script.
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo](/commands/hugo/) - Build your site
|
||||
* [hugo completion bash](/commands/hugo_completion_bash/) - Generate the autocompletion script for bash
|
||||
* [hugo completion fish](/commands/hugo_completion_fish/) - Generate the autocompletion script for fish
|
||||
* [hugo completion powershell](/commands/hugo_completion_powershell/) - Generate the autocompletion script for powershell
|
||||
|
||||
@@ -5,11 +5,11 @@ url: /commands/hugo_config/
|
||||
---
|
||||
## hugo config
|
||||
|
||||
Print the site configuration
|
||||
Display site configuration
|
||||
|
||||
### Synopsis
|
||||
|
||||
Print the site configuration, both default and custom settings.
|
||||
Display site configuration, both default and custom settings.
|
||||
|
||||
```
|
||||
hugo config [command] [flags]
|
||||
@@ -48,6 +48,6 @@ hugo config [command] [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo](/commands/hugo/) - Build your site
|
||||
* [hugo config mounts](/commands/hugo_config_mounts/) - Print the configured file mounts
|
||||
|
||||
|
||||
@@ -42,5 +42,5 @@ hugo config mounts [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo config](/commands/hugo_config/) - Print the site configuration
|
||||
* [hugo config](/commands/hugo_config/) - Display site configuration
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ url: /commands/hugo_convert/
|
||||
---
|
||||
## hugo convert
|
||||
|
||||
Convert your content to different formats
|
||||
Convert front matter to another format
|
||||
|
||||
### Synopsis
|
||||
|
||||
Convert your content (e.g. front matter) to different formats.
|
||||
Convert front matter to another format.
|
||||
|
||||
See convert's subcommands toJSON, toTOML and toYAML for more information.
|
||||
|
||||
@@ -41,7 +41,7 @@ See convert's subcommands toJSON, toTOML and toYAML for more information.
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo](/commands/hugo/) - Build your site
|
||||
* [hugo convert toJSON](/commands/hugo_convert_tojson/) - Convert front matter to JSON
|
||||
* [hugo convert toTOML](/commands/hugo_convert_totoml/) - Convert front matter to TOML
|
||||
* [hugo convert toYAML](/commands/hugo_convert_toyaml/) - Convert front matter to YAML
|
||||
|
||||
@@ -44,5 +44,5 @@ hugo convert toJSON [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert front matter to another format
|
||||
|
||||
|
||||
@@ -44,5 +44,5 @@ hugo convert toTOML [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert front matter to another format
|
||||
|
||||
|
||||
@@ -44,5 +44,5 @@ hugo convert toYAML [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert front matter to another format
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ url: /commands/hugo_deploy/
|
||||
---
|
||||
## hugo deploy
|
||||
|
||||
Deploy your site to a Cloud provider.
|
||||
Deploy your site to a cloud provider
|
||||
|
||||
### Synopsis
|
||||
|
||||
Deploy your site to a Cloud provider.
|
||||
Deploy your site to a cloud provider
|
||||
|
||||
See https://gohugo.io/hosting-and-deployment/hugo-deploy/ for detailed
|
||||
documentation.
|
||||
@@ -52,5 +52,5 @@ hugo deploy [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo](/commands/hugo/) - Build your site
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ url: /commands/hugo_env/
|
||||
---
|
||||
## hugo env
|
||||
|
||||
Print Hugo version and environment info
|
||||
Display version and environment info
|
||||
|
||||
### Synopsis
|
||||
|
||||
Print Hugo version and environment info. This is useful in Hugo bug reports
|
||||
Display version and environment info. This is useful in Hugo bug reports
|
||||
|
||||
```
|
||||
hugo env [flags] [args]
|
||||
@@ -41,5 +41,5 @@ hugo env [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo](/commands/hugo/) - Build your site
|
||||
|
||||
|
||||
@@ -5,7 +5,11 @@ url: /commands/hugo_gen/
|
||||
---
|
||||
## hugo gen
|
||||
|
||||
A collection of several useful generators.
|
||||
Generate documentation and syntax highlighting styles
|
||||
|
||||
### Synopsis
|
||||
|
||||
Generate documentation for your project using Hugo's documentation engine, including syntax highlighting for various programming languages.
|
||||
|
||||
### Options
|
||||
|
||||
@@ -33,7 +37,7 @@ A collection of several useful generators.
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo](/commands/hugo/) - Build your site
|
||||
* [hugo gen chromastyles](/commands/hugo_gen_chromastyles/) - Generate CSS stylesheet for the Chroma code highlighter
|
||||
* [hugo gen doc](/commands/hugo_gen_doc/) - Generate Markdown documentation for the Hugo CLI.
|
||||
* [hugo gen man](/commands/hugo_gen_man/) - Generate man pages for the Hugo CLI
|
||||
|
||||
@@ -47,5 +47,5 @@ hugo gen chromastyles [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
* [hugo gen](/commands/hugo_gen/) - Generate documentation and syntax highlighting styles
|
||||
|
||||
|
||||
@@ -47,5 +47,5 @@ hugo gen doc [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
* [hugo gen](/commands/hugo_gen/) - Generate documentation and syntax highlighting styles
|
||||
|
||||
|
||||
@@ -44,5 +44,5 @@ hugo gen man [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
* [hugo gen](/commands/hugo_gen/) - Generate documentation and syntax highlighting styles
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ url: /commands/hugo_import/
|
||||
---
|
||||
## hugo import
|
||||
|
||||
Import your site from others.
|
||||
Import a site from another system
|
||||
|
||||
### Synopsis
|
||||
|
||||
Import your site from other web site generators like Jekyll.
|
||||
Import a site from another system.
|
||||
|
||||
Import requires a subcommand, e.g. `hugo import jekyll jekyll_root_path target_path`.
|
||||
|
||||
@@ -39,6 +39,6 @@ Import requires a subcommand, e.g. `hugo import jekyll jekyll_root_path target_p
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo](/commands/hugo/) - Build your site
|
||||
* [hugo import jekyll](/commands/hugo_import_jekyll/) - hugo import from Jekyll
|
||||
|
||||
|
||||
@@ -44,5 +44,5 @@ hugo import jekyll [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo import](/commands/hugo_import/) - Import your site from others.
|
||||
* [hugo import](/commands/hugo_import/) - Import a site from another system
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ url: /commands/hugo_list/
|
||||
---
|
||||
## hugo list
|
||||
|
||||
Listing out various types of content
|
||||
List content
|
||||
|
||||
### Synopsis
|
||||
|
||||
Listing out various types of content.
|
||||
List content.
|
||||
|
||||
List requires a subcommand, e.g. hugo list drafts
|
||||
|
||||
@@ -39,7 +39,7 @@ List requires a subcommand, e.g. hugo list drafts
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo](/commands/hugo/) - Build 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
|
||||
|
||||
@@ -41,5 +41,5 @@ hugo list all [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
* [hugo list](/commands/hugo_list/) - List content
|
||||
|
||||
|
||||
@@ -41,5 +41,5 @@ hugo list drafts [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
* [hugo list](/commands/hugo_list/) - List content
|
||||
|
||||
|
||||
@@ -41,5 +41,5 @@ hugo list expired [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
* [hugo list](/commands/hugo_list/) - List content
|
||||
|
||||
|
||||
@@ -41,5 +41,5 @@ hugo list future [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
* [hugo list](/commands/hugo_list/) - List content
|
||||
|
||||
|
||||
@@ -41,5 +41,5 @@ hugo list published [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
* [hugo list](/commands/hugo_list/) - List content
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ url: /commands/hugo_mod/
|
||||
---
|
||||
## hugo mod
|
||||
|
||||
Various Hugo Modules helpers.
|
||||
Manage modules
|
||||
|
||||
### Synopsis
|
||||
|
||||
@@ -48,7 +48,7 @@ See https://gohugo.io/hugo-modules/ for more information.
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo](/commands/hugo/) - Build your site
|
||||
* [hugo mod clean](/commands/hugo_mod_clean/) - Delete the Hugo Module cache for the current project.
|
||||
* [hugo mod get](/commands/hugo_mod_get/) - Resolves dependencies in your current Hugo Project.
|
||||
* [hugo mod graph](/commands/hugo_mod_graph/) - Print a module dependency graph.
|
||||
|
||||
@@ -48,5 +48,5 @@ hugo mod clean [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
|
||||
* [hugo mod](/commands/hugo_mod/) - Manage modules
|
||||
|
||||
|
||||
@@ -72,5 +72,5 @@ hugo mod get [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
|
||||
* [hugo mod](/commands/hugo_mod/) - Manage modules
|
||||
|
||||
|
||||
@@ -49,5 +49,5 @@ hugo mod graph [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
|
||||
* [hugo mod](/commands/hugo_mod/) - Manage modules
|
||||
|
||||
|
||||
@@ -53,5 +53,5 @@ hugo mod init [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
|
||||
* [hugo mod](/commands/hugo_mod/) - Manage modules
|
||||
|
||||
|
||||
@@ -41,6 +41,6 @@ hugo mod npm [command] [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
|
||||
* [hugo mod](/commands/hugo_mod/) - Manage modules
|
||||
* [hugo mod npm pack](/commands/hugo_mod_npm_pack/) - Experimental: Prepares and writes a composite package.json file for your project.
|
||||
|
||||
|
||||
@@ -42,5 +42,5 @@ hugo mod tidy [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
|
||||
* [hugo mod](/commands/hugo_mod/) - Manage modules
|
||||
|
||||
|
||||
@@ -48,5 +48,5 @@ hugo mod vendor [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
|
||||
* [hugo mod](/commands/hugo_mod/) - Manage modules
|
||||
|
||||
|
||||
@@ -47,5 +47,5 @@ hugo mod verify [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo mod](/commands/hugo_mod/) - Various Hugo Modules helpers.
|
||||
* [hugo mod](/commands/hugo_mod/) - Manage modules
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ url: /commands/hugo_new/
|
||||
---
|
||||
## hugo new
|
||||
|
||||
Create new content for your site
|
||||
Create new content
|
||||
|
||||
### Synopsis
|
||||
|
||||
@@ -44,8 +44,8 @@ Ensure you run this within the root directory of your site.
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo new content](/commands/hugo_new_content/) - Create new content for your site
|
||||
* [hugo](/commands/hugo/) - Build your site
|
||||
* [hugo new content](/commands/hugo_new_content/) - Create new content
|
||||
* [hugo new site](/commands/hugo_new_site/) - Create a new site (skeleton)
|
||||
* [hugo new theme](/commands/hugo_new_theme/) - Create a new theme (skeleton)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ url: /commands/hugo_new_content/
|
||||
---
|
||||
## hugo new content
|
||||
|
||||
Create new content for your site
|
||||
Create new content
|
||||
|
||||
### Synopsis
|
||||
|
||||
@@ -56,5 +56,5 @@ hugo new content [path] [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo new](/commands/hugo_new/) - Create new content for your site
|
||||
* [hugo new](/commands/hugo_new/) - Create new content
|
||||
|
||||
|
||||
@@ -45,5 +45,5 @@ hugo new site [path] [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo new](/commands/hugo_new/) - Create new content for your site
|
||||
* [hugo new](/commands/hugo_new/) - Create new content
|
||||
|
||||
|
||||
@@ -44,5 +44,5 @@ hugo new theme [name] [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo new](/commands/hugo_new/) - Create new content for your site
|
||||
* [hugo new](/commands/hugo_new/) - Create new content
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ url: /commands/hugo_server/
|
||||
---
|
||||
## hugo server
|
||||
|
||||
A high performance webserver
|
||||
Start the embedded web server
|
||||
|
||||
### Synopsis
|
||||
|
||||
@@ -94,6 +94,6 @@ hugo server [command] [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo](/commands/hugo/) - Build your site
|
||||
* [hugo server trust](/commands/hugo_server_trust/) - Install the local CA in the system trust store.
|
||||
|
||||
|
||||
@@ -38,5 +38,5 @@ hugo server trust [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo server](/commands/hugo_server/) - A high performance webserver
|
||||
* [hugo server](/commands/hugo_server/) - Start the embedded web server
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ url: /commands/hugo_version/
|
||||
---
|
||||
## hugo version
|
||||
|
||||
Print Hugo version and environment info
|
||||
Display version
|
||||
|
||||
### Synopsis
|
||||
|
||||
Print Hugo version and environment info. This is useful in Hugo bug reports.
|
||||
Display version and environment info. This is useful in Hugo bug reports.
|
||||
|
||||
```
|
||||
hugo version [flags] [args]
|
||||
@@ -41,5 +41,5 @@ hugo version [flags] [args]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo](/commands/hugo/) - Build your site
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ Set any [front matter field] in the map passed to the [`AddPage`](#addpage) meth
|
||||
|
||||
This table describes the fields most commonly passed to the `AddPage` method.
|
||||
|
||||
Key|Descripion|Required
|
||||
Key|Description|Required
|
||||
:--|:--|:-:
|
||||
`content.mediaType`|The content [media type]. Default is `text/markdown`. See [content formats] for examples.|
|
||||
`content.value`|The content value as a string.|
|
||||
@@ -148,7 +148,7 @@ When setting the `path`, Hugo transforms the given string to a logical path. For
|
||||
|
||||
Construct the map passed to the [`AddResource`](#addresource) method using the fields below.
|
||||
|
||||
Key|Descripion|Required
|
||||
Key|Description|Required
|
||||
:--|:--|:-:
|
||||
`content.mediaType`|The content [media type].|:heavy_check_mark:
|
||||
`content.value`|The content value as a string or resource.|:heavy_check_mark:
|
||||
|
||||
@@ -21,15 +21,22 @@ This is the default language configuration:
|
||||
|
||||
In the above, `en` is the language key.
|
||||
|
||||
{{% note %}}
|
||||
Each language key must conform to the syntax described in [RFC 5646]. You must use hyphens to separate subtags. For example:
|
||||
|
||||
Language keys must conform to the syntax described in [RFC 5646]. For example:
|
||||
|
||||
- `en`
|
||||
- `en-GB`
|
||||
- `pt-BR`
|
||||
- `en-US`
|
||||
|
||||
Artificial languages with private use subtags as defined in [RFC 5646 § 2.2.7] are also supported. Omit the `art-x-` prefix from the language key. For example:
|
||||
|
||||
- `hugolang`
|
||||
|
||||
{{% note %}}
|
||||
Private use subtags must not exceed 8 alphanumeric characters.
|
||||
{{% /note %}}
|
||||
|
||||
[RFC 5646]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.1
|
||||
{{% /note %}}
|
||||
[RFC 5646 § 2.2.7]: https://datatracker.ietf.org/doc/html/rfc5646#section-2.2.7
|
||||
|
||||
This is an example of a site configuration for a multilingual project. Any key not defined in a `languages` object will fall back to the global value in the root of your site configuration.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Page resources
|
||||
description: Page resources -- images, other pages, documents, etc. -- have page-relative URLs and their own metadata.
|
||||
description: Use page resources to logically associate assets with a page.
|
||||
categories: [content management]
|
||||
keywords: [bundle,content,resources]
|
||||
menu:
|
||||
@@ -37,82 +37,83 @@ content
|
||||
└── index.md (root of page bundle)
|
||||
```
|
||||
|
||||
## Properties
|
||||
## Examples
|
||||
|
||||
ResourceType
|
||||
: The main type of the resource's [Media Type](/templates/output-formats/#media-types). For example, a file of MIME type `image/jpeg` has the ResourceType `image`. A `Page` will have `ResourceType` with value `page`.
|
||||
Use any of these methods on a `Page` object to capture page resources:
|
||||
|
||||
Name
|
||||
: Default value is the file name (relative to the owning page). Can be set in front matter.
|
||||
- [`Resources.ByType`]
|
||||
- [`Resources.Get`]
|
||||
- [`Resources.GetMatch`]
|
||||
- [`Resources.Match`]
|
||||
|
||||
Title
|
||||
: Default value is the same as `.Name`. Can be set in front matter.
|
||||
Once you have captured a resource, use any of the applicable [`Resource`] methods to return a value or perform an action.
|
||||
|
||||
Permalink
|
||||
: The absolute URL to the resource. Resources of type `page` will have no value.
|
||||
[`Resource`]: /methods/resource
|
||||
[`Resources.ByType`]: /methods/page/resources#bytype
|
||||
[`Resources.GetMatch`]: /methods/page/resources#getmatch
|
||||
[`Resources.Get`]: /methods/page/resources#get
|
||||
[`Resources.Match`]: /methods/page/resources#match
|
||||
|
||||
RelPermalink
|
||||
: The relative URL to the resource. Resources of type `page` will have no value.
|
||||
The following examples assume this content structure:
|
||||
|
||||
Content
|
||||
: The content of the resource itself. For most resources, this returns a string
|
||||
with the contents of the file. Use this to create inline resources.
|
||||
```text
|
||||
content/
|
||||
└── example/
|
||||
├── data/
|
||||
│ └── books.json <-- page resource
|
||||
├── images/
|
||||
│ ├── a.jpg <-- page resource
|
||||
│ └── b.jpg <-- page resource
|
||||
├── snippets/
|
||||
│ └── text.md <-- page resource
|
||||
└── index.md
|
||||
```
|
||||
|
||||
Render a single image, and throw an error if the file does not exist:
|
||||
|
||||
```go-html-template
|
||||
{{ with .Resources.GetMatch "script.js" }}
|
||||
<script>{{ .Content | safeJS }}</script>
|
||||
{{ end }}
|
||||
|
||||
{{ with .Resources.GetMatch "style.css" }}
|
||||
<style>{{ .Content | safeCSS }}</style>
|
||||
{{ end }}
|
||||
|
||||
{{ with .Resources.GetMatch "img.png" }}
|
||||
<img src="data:{{ .MediaType.Type }};base64,{{ .Content | base64Encode }}">
|
||||
{{ $path := "images/a.jpg" }}
|
||||
{{ with .Resources.Get $path }}
|
||||
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
|
||||
{{ else }}
|
||||
{{ errorf "Unable to get page resource %q" $path }}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
MediaType.Type
|
||||
: The media type (formerly known as a MIME type) of the resource (e.g., `image/jpeg`).
|
||||
|
||||
MediaType.MainType
|
||||
: The main type of the resource's media type (e.g., `image`).
|
||||
|
||||
MediaType.SubType
|
||||
: The subtype of the resource's type (e.g., `jpeg`). This may or may not correspond to the file suffix.
|
||||
|
||||
MediaType.Suffixes
|
||||
: A slice of possible file suffixes for the resource's media type (e.g., `[jpg jpeg jpe jif jfif]`).
|
||||
|
||||
## Methods
|
||||
|
||||
ByType
|
||||
: Returns the page resources of the given type.
|
||||
Render all images, resized to 300 px wide:
|
||||
|
||||
```go-html-template
|
||||
{{ .Resources.ByType "image" }}
|
||||
{{ range .Resources.ByType "image" }}
|
||||
{{ with .Resize "300x" }}
|
||||
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}" alt="">
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
```
|
||||
Match
|
||||
: Returns all the page resources (as a slice) whose `Name` matches the given Glob pattern ([examples](https://github.com/gobwas/glob/blob/master/readme.md)). The matching is case-insensitive.
|
||||
|
||||
Render the markdown snippet:
|
||||
|
||||
```go-html-template
|
||||
{{ .Resources.Match "images/*" }}
|
||||
{{ with .Resources.Get "snippets/text.md" }}
|
||||
{{ .Content }}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
GetMatch
|
||||
: Same as `Match` but will return the first match.
|
||||
List the titles in the data file, and throw an error if the file does not exist.
|
||||
|
||||
### Pattern matching
|
||||
|
||||
```go
|
||||
// Using Match/GetMatch to find this images/sunset.jpg ?
|
||||
.Resources.Match "images/sun*" ✅
|
||||
.Resources.Match "**/sunset.jpg" ✅
|
||||
.Resources.Match "images/*.jpg" ✅
|
||||
.Resources.Match "**.jpg" ✅
|
||||
.Resources.Match "*" 🚫
|
||||
.Resources.Match "sunset.jpg" 🚫
|
||||
.Resources.Match "*sunset.jpg" 🚫
|
||||
```go-html-template
|
||||
{{ $path := "data/books.json" }}
|
||||
{{ with .Resources.Get $path }}
|
||||
{{ with . | transform.Unmarshal }}
|
||||
<p>Books:</p>
|
||||
<ul>
|
||||
{{ range . }}
|
||||
<li>{{ .title }}</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
{{ else }}
|
||||
{{ errorf "Unable to get page resource %q" $path }}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
## Metadata
|
||||
@@ -124,21 +125,21 @@ Resources of type `page` get `Title` etc. from their own front matter.
|
||||
{{% /note %}}
|
||||
|
||||
name
|
||||
: Sets the value returned in `Name`.
|
||||
: (`string`) Sets the value returned in `Name`.
|
||||
|
||||
{{% note %}}
|
||||
The methods `Match`, `Get` and `GetMatch` use `Name` to match the resources.
|
||||
{{% /note %}}
|
||||
|
||||
title
|
||||
: Sets the value returned in `Title`
|
||||
: (`string`) Sets the value returned in `Title`
|
||||
|
||||
params
|
||||
: A map of custom key-value pairs.
|
||||
: (`map`) A map of custom key-value pairs.
|
||||
|
||||
### Resources metadata example
|
||||
|
||||
{{< code-toggle >}}
|
||||
{{< code-toggle file=content/example.md fm=true >}}
|
||||
title: Application
|
||||
date : 2018-01-25
|
||||
resources :
|
||||
@@ -173,7 +174,7 @@ From the example above:
|
||||
- Every docx in the bundle will receive the `word` icon.
|
||||
|
||||
{{% note %}}
|
||||
The __order matters__ --- Only the **first set** values of the `title`, `name` and `params`-**keys** will be used. Consecutive parameters will be set only for the ones not already set. In the above example, `.Params.icon` is first set to `"photo"` in `src = "documents/photo_specs.pdf"`. So that would not get overridden to `"pdf"` by the later set `src = "**.pdf"` rule.
|
||||
The order matters; only the first set values of the `title`, `name` and `params` keys will be used. Consecutive parameters will be set only for the ones not already set. In the above example, `.Params.icon` is first set to `"photo"` in `src = "documents/photo_specs.pdf"`. So that would not get overridden to `"pdf"` by the later set `src = "**.pdf"` rule.
|
||||
{{% /note %}}
|
||||
|
||||
### The `:counter` placeholder in `name` and `title`
|
||||
|
||||
@@ -92,11 +92,11 @@ Note that the `summaryLength` is an approximate number of words.
|
||||
|
||||
Each summary type has different characteristics:
|
||||
|
||||
Type|Precedence|Renders markdown|Renders shortcodes|Strips HTML tags|Wraps single lines with `<p>`
|
||||
:--|:-:|:-:|:-:|:-:|:-:
|
||||
Manual|1|:heavy_check_mark:|:heavy_check_mark:|:x:|:heavy_check_mark:
|
||||
Front matter|2|:heavy_check_mark:|:x:|:x:|:x:
|
||||
Automatic|3|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:|:x:
|
||||
Type|Precedence|Renders markdown|Renders shortcodes|Wraps single lines with `<p>`
|
||||
:--|:-:|:-:|:-:|:-:
|
||||
Manual|1|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:
|
||||
Front matter|2|:heavy_check_mark:|:x:|:x:
|
||||
Automatic|3|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:
|
||||
|
||||
## Rendering
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ For a complete guide to contributing to Hugo, see the [Contribution Guide].
|
||||
To build the extended edition of Hugo from source you must:
|
||||
|
||||
1. Install [Git]
|
||||
1. Install [Go] version 1.20 or later
|
||||
1. Install [Go] version 1.23.0 or later
|
||||
1. Install a C compiler, either [GCC] or [Clang]
|
||||
1. Update your `PATH` environment variable as described in the [Go documentation]
|
||||
|
||||
|
||||
@@ -2,4 +2,6 @@
|
||||
# Do not remove front matter.
|
||||
---
|
||||
|
||||
In Go templates, the falsy values are `false`, `0`, any nil pointer or interface value, and any array, slice, map, or string of length zero. Everything else is truthy.
|
||||
The falsy values are `false`, `0`, any `nil` pointer or interface value, any array, slice, map, or string of length zero, and zero `time.Time` values.
|
||||
|
||||
Everything else is truthy.
|
||||
|
||||
@@ -34,7 +34,7 @@ Use with the [`else`] statement:
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
Use `else if` to check multiple conditions.
|
||||
Use `else if` to check multiple conditions:
|
||||
|
||||
```go-html-template
|
||||
{{ $var := 12 }}
|
||||
|
||||
@@ -36,6 +36,20 @@ Use with the [`else`] statement:
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
Use `else with` to check multiple conditions:
|
||||
|
||||
```go-html-template
|
||||
{{ $v1 := 0 }}
|
||||
{{ $v2 := 42 }}
|
||||
{{ with $v1 }}
|
||||
{{ . }}
|
||||
{{ else with $v2 }}
|
||||
{{ . }} → 42
|
||||
{{ else }}
|
||||
{{ print "v1 and v2 are falsy" }}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
Initialize a variable, scoped to the current block:
|
||||
|
||||
```go-html-template
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: transform.ToMath
|
||||
description: Renders a math expression using KaTeX.
|
||||
categories: []
|
||||
keywords: []
|
||||
action:
|
||||
aliases: []
|
||||
related:
|
||||
- content-management/mathematics
|
||||
returnType: types.Result[template.HTML]
|
||||
signatures: ['transform.ToMath EXPRESSION [OPTIONS]']
|
||||
aliases: [/functions/tomath]
|
||||
toc: true
|
||||
---
|
||||
|
||||
{{< new-in "0.132.0" >}}
|
||||
|
||||
{{% note %}}
|
||||
This feature was introduced in Hugo 0.132.0 and is marked as experimental.
|
||||
|
||||
This does not mean that it's going to be removed, but this is our first use of WASI/Wasm in Hugo, and we need to see how it [works in the wild](https://github.com/gohugoio/hugo/issues/12736) before we can set it in stone.
|
||||
{{% /note %}}
|
||||
|
||||
## Arguments
|
||||
|
||||
EXPRESSION
|
||||
: The math expression to render using KaTeX.
|
||||
|
||||
OPTIONS
|
||||
: A map of zero or more options.
|
||||
|
||||
## Options
|
||||
|
||||
These are a subset of the [KaTeX options].
|
||||
|
||||
output
|
||||
: (`string`). Determines the markup language of the output. One of `html`, `mathml`, or `htmlAndMathml`. Default is `mathml`.
|
||||
|
||||
<!-- Indent to prevent spliting the description list. -->
|
||||
|
||||
With `html` and `htmlAndMathml` you must include KaTeX CSS within the `head` element of your base template. For example:
|
||||
|
||||
```html
|
||||
<head>
|
||||
...
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css" integrity="sha384-nB0miv6/jRmo5UMMR1wu3Gz6NLsoTkbqJghGIsx//Rlm+ZU03BU6SQNC66uf4l5+" crossorigin="anonymous">
|
||||
...
|
||||
</head>
|
||||
```
|
||||
|
||||
displayMode
|
||||
: (`bool`) If `true` render in display mode, else render in inline mode. Default is `false`.
|
||||
|
||||
leqno
|
||||
: (`bool`) If `true` render with the equation numbers on the left. Default is `false`.
|
||||
|
||||
fleqn
|
||||
: (`bool`) If `true` render flush left with a 2em left margin. Default is `false`.
|
||||
|
||||
minRuleThickness
|
||||
: (`float`) The minimum thickness of the fraction lines in `em`. Default is `0.04`.
|
||||
|
||||
macros
|
||||
: (`map`) A map of macros to be used in the math expression. Default is `{}`.
|
||||
|
||||
throwOnError
|
||||
: (`bool`) If `true` throw a `ParseError` when KaTeX encounters an unsupported command or invalid LaTex. See [error handling]. Default is `true`.
|
||||
|
||||
errorColor
|
||||
: (`string`) The color of the error messages expressed as an RGB [hexadecimal color]. Default is `#cc0000`.
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
```go-html-template
|
||||
{{ transform.ToMath "c = \\pm\\sqrt{a^2 + b^2}" }}
|
||||
```
|
||||
|
||||
### Macros
|
||||
|
||||
```go-html-template
|
||||
{{ $macros := dict
|
||||
"\\addBar" "\\bar{#1}"
|
||||
"\\bold" "\\mathbf{#1}"
|
||||
}}
|
||||
{{ $opts := dict "macros" $macros }}
|
||||
{{ transform.ToMath "\\addBar{y} + \\bold{H}" $opts }}
|
||||
```
|
||||
|
||||
## Error handling
|
||||
|
||||
There are 3 ways to handle errors from KaTeX:
|
||||
|
||||
1. Let KaTeX throw an error and make the build fail. This is the default behavior.
|
||||
1. Handle the error in your template. See the render hook example below.
|
||||
1. Set the `throwOnError` option to `false` to make KaTeX render the expression as an error instead of throwing an error. See [options].
|
||||
|
||||
{{< code file=layouts/_default/_markup/render-passthrough-inline.html copy=true >}}
|
||||
{{ with transform.ToMath .Inner }}
|
||||
{{ with .Err }}
|
||||
{{ errorf "Failed to render KaTeX: %q. See %s" . $.Position }}
|
||||
{{ else }}
|
||||
{{ . }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{- /* chomp trailing newline */ -}}
|
||||
{{< /code >}}
|
||||
|
||||
[error handling]: #error-handling
|
||||
[KaTeX options]: https://katex.org/docs/options.html
|
||||
[hexadecimal color]: https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color
|
||||
@@ -238,7 +238,7 @@ This is the default configuration for the AsciiDoc renderer:
|
||||
|
||||
###### attributes
|
||||
|
||||
(`map`) A map of key-value pairs, each a document attributes,See Asciidoctor’s [attributes].
|
||||
(`map`) A map of key-value pairs, each a document attributes. See Asciidoctor’s [attributes].
|
||||
|
||||
[attributes]: https://asciidoctor.org/docs/asciidoc-syntax-quick-reference/#attributes-and-substitutions
|
||||
|
||||
@@ -302,6 +302,51 @@ To mitigate security risks, entries in the extension array may not contain forwa
|
||||
my-attribute-name = "my value"
|
||||
{{< /code-toggle >}}
|
||||
|
||||
### AsciiDoc syntax highlighting
|
||||
|
||||
Follow the steps below to enable syntax highlighting.
|
||||
|
||||
Step 1
|
||||
: Set the `source-highlighter` attribute in your site configuration. For example:
|
||||
|
||||
{{< code-toggle file=hugo >}}
|
||||
[markup.asciidocExt.attributes]
|
||||
source-highlighter = 'rouge'
|
||||
{{< /code-toggle >}}
|
||||
|
||||
Step 2
|
||||
: Generate the highlighter CSS. For example:
|
||||
|
||||
```text
|
||||
rougify style monokai.sublime > assets/css/syntax.css
|
||||
```
|
||||
|
||||
Step 3
|
||||
: In your base template add a link to the CSS file:
|
||||
|
||||
{{< code file=layouts/_default/baseof.html >}}
|
||||
<head>
|
||||
...
|
||||
{{ with resources.Get "css/syntax.css" }}
|
||||
<link rel="stylesheet" href="{{ .RelPermalink }}" integrity="{{ .Data.Integrity }}" crossorigin="anonymous">
|
||||
{{ end }}
|
||||
...
|
||||
</head>
|
||||
{{< /code >}}
|
||||
|
||||
Then add the code to be highlighted to your markup:
|
||||
|
||||
```text
|
||||
[#hello,ruby]
|
||||
----
|
||||
require 'sinatra'
|
||||
|
||||
get '/hi' do
|
||||
"Hello World!"
|
||||
end
|
||||
----
|
||||
```
|
||||
|
||||
### AsciiDoc troubleshooting
|
||||
|
||||
Run `hugo --logLevel debug` to examine Hugo's call to the Asciidoctor executable:
|
||||
|
||||
@@ -378,6 +378,10 @@ Module configuration see [module configuration](/hugo-modules/configuration/).
|
||||
|
||||
See [custom output formats].
|
||||
|
||||
###### page
|
||||
|
||||
See [configure page](#configure-page).
|
||||
|
||||
###### pagination
|
||||
|
||||
See [configure pagination](/templates/pagination/#configuration).
|
||||
@@ -496,6 +500,50 @@ enableemoji: true
|
||||
```
|
||||
{{% /note %}}
|
||||
|
||||
## Configure page
|
||||
|
||||
{{< new-in 0.133.0 >}}
|
||||
|
||||
These methods on a `Page` object navigate to the next or previous page within a page collection, relative to the current page:
|
||||
|
||||
- [Next](/methods/page/next/)
|
||||
- [NextInSection](/methods/page/nextinsection/)
|
||||
- [Prev](/methods/page/prev/)
|
||||
- [PrevInSection](/methods/page/previnsection/)
|
||||
|
||||
Hugo determines the _next_ and _previous_ page by sorting a page collection according to this sorting hierarchy:
|
||||
|
||||
Field|Precedence|Sort direction
|
||||
:--|:--|:--
|
||||
[`weight`]|1|descending
|
||||
[`date`]|2|descending
|
||||
[`linkTitle`]|3|descending
|
||||
[`path`]|4|descending
|
||||
|
||||
[`date`]: /methods/page/date/
|
||||
[`weight`]: /methods/page/weight/
|
||||
[`linkTitle`]: /methods/page/linktitle/
|
||||
[`path`]: /methods/page/path/
|
||||
|
||||
The sort direction in the table above corresponds to these default site configuration values:
|
||||
|
||||
{{< code-toggle config=page />}}
|
||||
|
||||
To sort all fields in ascending order:
|
||||
|
||||
{{< code-toggle file=hugo >}}
|
||||
[page]
|
||||
nextPrevInSectionSortOrder = 'asc'
|
||||
nextPrevSortOrder = 'asc'
|
||||
{{< /code-toggle >}}
|
||||
|
||||
{{% note %}}
|
||||
These settings do not apply to the [`Next`] or [`Prev`] methods on a `Pages` object.
|
||||
|
||||
[`Next`]: /methods/pages/next
|
||||
[`Prev`]: /methods/pages/next
|
||||
{{% /note %}}
|
||||
|
||||
## Configure build
|
||||
|
||||
The `build` configuration section contains global build-related configuration options.
|
||||
@@ -609,8 +657,6 @@ Setting `force=true` will make a redirect even if there is existing content in t
|
||||
|
||||
## 404 server error page {#_404-server-error-page}
|
||||
|
||||
{{< new-in 0.103.0 >}}
|
||||
|
||||
Hugo will, by default, render all 404 errors when running `hugo server` with the `404.html` template. Note that if you have already added one or more redirects to your [server configuration](#configure-server), you need to add the 404 redirect explicitly, e.g:
|
||||
|
||||
{{< code-toggle file=config/development/server >}}
|
||||
@@ -924,7 +970,6 @@ output
|
||||
|
||||
It is recommended to put coarse grained filters (e.g. for language and output format) in the excludes section, e.g.:
|
||||
|
||||
|
||||
{{< code-toggle file=hugo >}}
|
||||
[segments.segment1]
|
||||
[[segments.segment1.excludes]]
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
cascade:
|
||||
_build:
|
||||
list: never
|
||||
publishResources: false
|
||||
render: never
|
||||
---
|
||||
|
||||
<!--
|
||||
Files within this headless branch bundle are Markdown snippets. Each file must contain front matter delimiters, though front matter fields are not required.
|
||||
|
||||
Include the rendered content using the "include" shortcode.
|
||||
-->
|
||||
@@ -1,37 +0,0 @@
|
||||
---
|
||||
# Do not remove front matter.
|
||||
---
|
||||
|
||||
The `Next` and `Prev` methods on a `Pages` object are more flexible than the `Next` and `Prev` methods on a `Page` object.
|
||||
|
||||
||Page collection|Custom sort order
|
||||
:--|:--|:-:
|
||||
[`PAGES.Next`] and [`PAGES.Prev`]|locally defined|✔️
|
||||
[`PAGE.Next`] and [`PAGE.Prev`]|globally defined|❌
|
||||
|
||||
[`PAGES.Next`]: /methods/pages/next/
|
||||
[`PAGES.Prev`]: /methods/pages/prev/
|
||||
[`PAGE.Next`]: /methods/page/next/
|
||||
[`PAGE.Prev`]: /methods/page/prev/
|
||||
|
||||
locally defined
|
||||
: Build the page collection every time you call `PAGES.Next` and `PAGES.Prev`. Navigation between pages is relative to the current page's position within the local collection, independent of the global collection.
|
||||
|
||||
With a local collection, the navigation sort order is the same as the collection sort order.
|
||||
|
||||
globally defined
|
||||
: Build the page collection once, on a list page. Navigation between pages is relative to the current page's position within the global collection.
|
||||
|
||||
With a global collection, the navigation sort order is fixed, using Hugo's default sort order. In order of precedence:
|
||||
|
||||
1. Page [weight]
|
||||
2. Page [date] (descending)
|
||||
3. Page [linkTitle], falling back to page [title]
|
||||
4. Page file path if the page is backed by a file
|
||||
|
||||
For example, with a global collection sorted by title, the navigation sort order will use Hugo's default sort order. This is probably not what you want or expect. For this reason, the `Next` and `Prev` methods on a `Pages` object are generally a better choice.
|
||||
|
||||
[date]: /methods/page/date/
|
||||
[weight]: /methods/page/weight/
|
||||
[linkTitle]: /methods/page/linktitle/
|
||||
[title]: /methods/page/title/
|
||||
@@ -5,6 +5,8 @@ categories: []
|
||||
keywords: []
|
||||
action:
|
||||
related:
|
||||
- methods/page/Summary
|
||||
- methods/page/ContentWithoutSummary
|
||||
- methods/page/RawContent
|
||||
- methods/page/Plain
|
||||
- methods/page/PlainWords
|
||||
@@ -13,9 +15,7 @@ action:
|
||||
signatures: [PAGE.Content]
|
||||
---
|
||||
|
||||
The `Content` method on a `Page` object renders Markdown and shortcodes to HTML. The content does not include front matter.
|
||||
|
||||
[shortcodes]: /getting-started/glossary/#shortcode
|
||||
The `Content` method on a `Page` object renders Markdown and shortcodes to HTML.
|
||||
|
||||
```go-html-template
|
||||
{{ .Content }}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: ContentWithoutSummary
|
||||
description: Returns the rendered content of the given page, excluding the content summary.
|
||||
categories: []
|
||||
keywords: []
|
||||
action:
|
||||
related:
|
||||
- methods/page/Content
|
||||
- methods/page/Summary
|
||||
- methods/page/RawContent
|
||||
- methods/page/Plain
|
||||
- methods/page/PlainWords
|
||||
- methods/page/RenderShortcodes
|
||||
returnType: template.HTML
|
||||
signatures: [PAGE.ContentWithoutSummary]
|
||||
---
|
||||
|
||||
{{< new-in 0.134.0 >}}
|
||||
|
||||
Applicable when using manual or automatic [content summaries], the `ContentWithoutSummary` method on a `Page` object renders Markdown and shortcodes to HTML, excluding the content summary from the result.
|
||||
|
||||
[content summaries]: /content-management/summaries/#manual-summary
|
||||
|
||||
```go-html-template
|
||||
{{ .ContentWithoutSummary }}
|
||||
```
|
||||
|
||||
The `ContentWithoutSummary` method returns an empty string if you define the content summary in front matter.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Next
|
||||
description: Returns the next page in a global page collection, relative to the given page.
|
||||
description: Returns the next page in a site's collection of regular pages, relative to the current page.
|
||||
categories: []
|
||||
keywords: []
|
||||
action:
|
||||
@@ -12,42 +12,6 @@ action:
|
||||
- methods/pages/Prev
|
||||
returnType: page.Page
|
||||
signatures: [PAGE.Next]
|
||||
toc: true
|
||||
---
|
||||
|
||||
The behavior of the `Prev` and `Next` methods on a `Page` object is probably the reverse of what you expect.
|
||||
|
||||
With this content structure:
|
||||
|
||||
```text
|
||||
content/
|
||||
├── pages/
|
||||
│ ├── _index.md
|
||||
│ ├── page-1.md <-- front matter: weight = 10
|
||||
│ ├── page-2.md <-- front matter: weight = 20
|
||||
│ └── page-3.md <-- front matter: weight = 30
|
||||
└── _index.md
|
||||
```
|
||||
|
||||
When you visit page-2:
|
||||
|
||||
- The `Prev` method points to page-3
|
||||
- The `Next` method points to page-1
|
||||
|
||||
{{% note %}}
|
||||
Use the opposite label in your navigation links as shown in the example below.
|
||||
{{% /note %}}
|
||||
|
||||
```go-html-template
|
||||
{{ with .Next }}
|
||||
<a href="{{ .RelPermalink }}">Prev</a>
|
||||
{{ end }}
|
||||
|
||||
{{ with .Prev }}
|
||||
<a href="{{ .RelPermalink }}">Next</a>
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
## Compare to Pages methods
|
||||
|
||||
{{% include "methods/_common/next-prev-on-page-vs-next-prev-on-pages.md" %}}
|
||||
{{% include "methods/page/_common/next-and-prev.md" %}}
|
||||
|
||||
@@ -1,71 +1,15 @@
|
||||
---
|
||||
title: NextInSection
|
||||
description: Returns the next page within a section, relative to the given page.
|
||||
description: Returns the next regular page in a section, relative to the given page.
|
||||
categories: []
|
||||
keywords: []
|
||||
action:
|
||||
related:
|
||||
- methods/page/PrevInSection
|
||||
- methods/page/Next
|
||||
- methods/page/Prev
|
||||
- methods/pages/Next
|
||||
- methods/pages/Prev
|
||||
returnType: page.Page
|
||||
signatures: [PAGE.NextInSection]
|
||||
---
|
||||
|
||||
The behavior of the `PrevInSection` and `NextInSection` methods on a `Page` object is probably the reverse of what you expect.
|
||||
|
||||
With this content structure:
|
||||
|
||||
```text
|
||||
content/
|
||||
├── books/
|
||||
│ ├── _index.md
|
||||
│ ├── book-1.md
|
||||
│ ├── book-2.md
|
||||
│ └── book-3.md
|
||||
├── films/
|
||||
│ ├── _index.md
|
||||
│ ├── film-1.md
|
||||
│ ├── film-2.md
|
||||
│ └── film-3.md
|
||||
└── _index.md
|
||||
```
|
||||
|
||||
When you visit book-2:
|
||||
|
||||
- The `PrevInSection` method points to book-3
|
||||
- The `NextInSection` method points to book-1
|
||||
|
||||
{{% note %}}
|
||||
Use the opposite label in your navigation links as shown in the example below.
|
||||
{{% /note %}}
|
||||
|
||||
```go-html-template
|
||||
{{ with .NextInSection }}
|
||||
<a href="{{ .RelPermalink }}">Previous in section</a>
|
||||
{{ end }}
|
||||
|
||||
{{ with .PrevInSection }}
|
||||
<a href="{{ .RelPermalink }}">Next in section</a>
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
{{% note %}}
|
||||
The navigation sort order may be different than the page collection sort order.
|
||||
{{% /note %}}
|
||||
|
||||
With the `PrevInSection` and `NextInSection` methods, the navigation sort order is fixed, using Hugo’s default sort order. In order of precedence:
|
||||
|
||||
1. Page [weight]
|
||||
2. Page [date] (descending)
|
||||
3. Page [linkTitle], falling back to page [title]
|
||||
4. Page file path if the page is backed by a file
|
||||
|
||||
For example, with a page collection sorted by title, the navigation sort order will use Hugo’s default sort order. This is probably not what you want or expect. For this reason, the Next and Prev methods on a Pages object are generally a better choice.
|
||||
|
||||
[date]: /methods/page/date/
|
||||
[weight]: /methods/page/weight/
|
||||
[linkTitle]: /methods/page/linktitle/
|
||||
[title]: /methods/page/title/
|
||||
{{% include "methods/page/_common/nextinsection-and-previnsection.md" %}}
|
||||
|
||||
@@ -6,6 +6,8 @@ keywords: []
|
||||
action:
|
||||
related:
|
||||
- methods/page/Content
|
||||
- methods/page/Summary
|
||||
- methods/page/ContentWithoutSummary
|
||||
- methods/page/RawContent
|
||||
- methods/page/PlainWords
|
||||
- methods/page/RenderShortcodes
|
||||
@@ -13,7 +15,7 @@ action:
|
||||
signatures: [PAGE.Plain]
|
||||
---
|
||||
|
||||
The `Plain` method on a `Page` object renders Markdown and [shortcodes] to HTML, then strips the HTML [tags]. It does not strip HTML [entities]. The plain content does not include front matter.
|
||||
The `Plain` method on a `Page` object renders Markdown and [shortcodes] to HTML, then strips the HTML [tags]. It does not strip HTML [entities].
|
||||
|
||||
To prevent Go's [html/template] package from escaping HTML entities, pass the result through the [`htmlUnescape`] function.
|
||||
|
||||
|
||||
@@ -6,8 +6,11 @@ keywords: []
|
||||
action:
|
||||
related:
|
||||
- methods/page/Content
|
||||
- methods/page/Summary
|
||||
- methods/page/ContentWithoutSummary
|
||||
- methods/page/RawContent
|
||||
- methods/page/Plain
|
||||
- methods/page/RenderShortcodes
|
||||
returnType: '[]string'
|
||||
signatures: [PAGE.PlainWords]
|
||||
---
|
||||
|
||||
@@ -1,53 +1,17 @@
|
||||
---
|
||||
title: Prev
|
||||
description: Returns the previous page in a global page collection, relative to the given page.
|
||||
description: Returns the previous page in a site's collection of regular pages, relative to the current page.
|
||||
categories: []
|
||||
keywords: []
|
||||
action:
|
||||
related:
|
||||
- methods/page/Next
|
||||
- methods/page/PrevInSection
|
||||
- methods/page/NextInSection
|
||||
- methods/pages/Prev
|
||||
- methods/page/PrevInSection
|
||||
- methods/pages/Next
|
||||
- methods/pages/Prev
|
||||
returnType: page.Page
|
||||
signatures: [PAGE.Prev]
|
||||
toc: true
|
||||
---
|
||||
|
||||
The behavior of the `Prev` and `Next` methods on a `Page` object is probably the reverse of what you expect.
|
||||
|
||||
With this content structure:
|
||||
|
||||
```text
|
||||
content/
|
||||
├── pages/
|
||||
│ ├── _index.md
|
||||
│ ├── page-1.md <-- front matter: weight = 10
|
||||
│ ├── page-2.md <-- front matter: weight = 20
|
||||
│ └── page-3.md <-- front matter: weight = 30
|
||||
└── _index.md
|
||||
```
|
||||
|
||||
When you visit page-2:
|
||||
|
||||
- The `Prev` method points to page-3
|
||||
- The `Next` method points to page-1
|
||||
|
||||
{{% note %}}
|
||||
Use the opposite label in your navigation links as shown in the example below.
|
||||
{{% /note %}}
|
||||
|
||||
```go-html-template
|
||||
{{ with .Next }}
|
||||
<a href="{{ .RelPermalink }}">Prev</a>
|
||||
{{ end }}
|
||||
|
||||
{{ with .Prev }}
|
||||
<a href="{{ .RelPermalink }}">Next</a>
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
## Compare to Pages methods
|
||||
|
||||
{{% include "methods/_common/next-prev-on-page-vs-next-prev-on-pages.md" %}}
|
||||
{{% include "methods/page/_common/next-and-prev.md" %}}
|
||||
|
||||
@@ -1,72 +1,15 @@
|
||||
---
|
||||
title: PrevInSection
|
||||
description: Returns the previous page within a section, relative to the given page.
|
||||
description: Returns the previous regular page in a section, relative to the given page.
|
||||
categories: []
|
||||
keywords: []
|
||||
action:
|
||||
related:
|
||||
- methods/page/NextInSection
|
||||
- methods/page/Next
|
||||
- methods/pages/Next
|
||||
- methods/page/Prev
|
||||
- methods/pages/Prev
|
||||
returnType: page.Page
|
||||
signatures: [PAGE.PrevInSection]
|
||||
---
|
||||
|
||||
|
||||
The behavior of the `PrevInSection` and `NextInSection` methods on a `Page` object is probably the reverse of what you expect.
|
||||
|
||||
With this content structure:
|
||||
|
||||
```text
|
||||
content/
|
||||
├── books/
|
||||
│ ├── _index.md
|
||||
│ ├── book-1.md
|
||||
│ ├── book-2.md
|
||||
│ └── book-3.md
|
||||
├── films/
|
||||
│ ├── _index.md
|
||||
│ ├── film-1.md
|
||||
│ ├── film-2.md
|
||||
│ └── film-3.md
|
||||
└── _index.md
|
||||
```
|
||||
|
||||
When you visit book-2:
|
||||
|
||||
- The `PrevInSection` method points to book-3
|
||||
- The `NextInSection` method points to book-1
|
||||
|
||||
{{% note %}}
|
||||
Use the opposite label in your navigation links as shown in the example below.
|
||||
{{% /note %}}
|
||||
|
||||
```go-html-template
|
||||
{{ with .NextInSection }}
|
||||
<a href="{{ .RelPermalink }}">Previous in section</a>
|
||||
{{ end }}
|
||||
|
||||
{{ with .PrevInSection }}
|
||||
<a href="{{ .RelPermalink }}">Next in section</a>
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
{{% note %}}
|
||||
The navigation sort order may be different than the page collection sort order.
|
||||
{{% /note %}}
|
||||
|
||||
With the `PrevInSection` and `NextInSection` methods, the navigation sort order is fixed, using Hugo’s default sort order. In order of precedence:
|
||||
|
||||
1. Page [weight]
|
||||
2. Page [date] (descending)
|
||||
3. Page [linkTitle], falling back to page [title]
|
||||
4. Page file path if the page is backed by a file
|
||||
|
||||
For example, with a page collection sorted by title, the navigation sort order will use Hugo’s default sort order. This is probably not what you want or expect. For this reason, the Next and Prev methods on a Pages object are generally a better choice.
|
||||
|
||||
[date]: /methods/page/date/
|
||||
[weight]: /methods/page/weight/
|
||||
[linkTitle]: /methods/page/linktitle/
|
||||
[title]: /methods/page/title/
|
||||
{{% include "methods/page/_common/nextinsection-and-previnsection.md" %}}
|
||||
|
||||
@@ -6,6 +6,8 @@ keywords: []
|
||||
action:
|
||||
related:
|
||||
- methods/page/Content
|
||||
- methods/page/Summary
|
||||
- methods/page/ContentWithoutSummary
|
||||
- methods/page/Plain
|
||||
- methods/page/PlainWords
|
||||
- methods/page/RenderShortcodes
|
||||
|
||||
@@ -5,11 +5,13 @@ categories: []
|
||||
keywords: []
|
||||
action:
|
||||
related:
|
||||
- methods/page/RenderString
|
||||
- methods/page/Content
|
||||
- methods/page/Summary
|
||||
- methods/page/ContentWithoutSummary
|
||||
- methods/page/RawContent
|
||||
- methods/page/Plain
|
||||
- methods/page/PlainWords
|
||||
- methods/page/RenderString
|
||||
returnType: template.HTML
|
||||
signatures: [PAGE.RenderShortcodes]
|
||||
toc: true
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
# Do not remove front matter.
|
||||
---
|
||||
|
||||
Hugo determines the _next_ and _previous_ page by sorting the site's collection of regular pages according to this sorting hierarchy:
|
||||
|
||||
Field|Precedence|Sort direction
|
||||
:--|:--|:--
|
||||
[`weight`]|1|descending
|
||||
[`date`]|2|descending
|
||||
[`linkTitle`]|3|descending
|
||||
[`path`]|4|descending
|
||||
|
||||
[`date`]: /methods/page/date/
|
||||
[`weight`]: /methods/page/weight/
|
||||
[`linkTitle`]: /methods/page/linktitle/
|
||||
[`path`]: /methods/page/path/
|
||||
|
||||
The sorted page collection used to determine the _next_ and _previous_ page is independent of other page collections, which may lead to unexpected behavior.
|
||||
|
||||
For example, with this content structure:
|
||||
|
||||
```text
|
||||
content/
|
||||
├── pages/
|
||||
│ ├── _index.md
|
||||
│ ├── page-1.md <-- front matter: weight = 10
|
||||
│ ├── page-2.md <-- front matter: weight = 20
|
||||
│ └── page-3.md <-- front matter: weight = 30
|
||||
└── _index.md
|
||||
```
|
||||
|
||||
And these templates:
|
||||
|
||||
{{< code file=layouts/_default/list.html >}}
|
||||
{{ range .Pages.ByWeight }}
|
||||
<h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
|
||||
{{ end }}
|
||||
{{< /code >}}
|
||||
|
||||
{{< code file=layouts/_default/single.html >}}
|
||||
{{ with .Prev }}
|
||||
<a href="{{ .RelPermalink }}">Previous</a>
|
||||
{{ end }}
|
||||
|
||||
{{ with .Next }}
|
||||
<a href="{{ .RelPermalink }}">Next</a>
|
||||
{{ end }}
|
||||
{{< /code >}}
|
||||
|
||||
When you visit page-2:
|
||||
|
||||
- The `Prev` method points to page-3
|
||||
- The `Next` method points to page-1
|
||||
|
||||
To reverse the meaning of _next_ and _previous_ you can change the sort direction in your [site configuration], or use the [`Next`] and [`Prev`] methods on a `Pages` object for more flexibility.
|
||||
|
||||
[site configuration]: getting-started/configuration/#configure-page
|
||||
[`Next`]: /methods/pages/prev
|
||||
[`Prev`]: /methods/pages/prev
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
# Do not remove front matter.
|
||||
---
|
||||
|
||||
Hugo determines the _next_ and _previous_ page by sorting the current section's regular pages according to this sorting hierarchy:
|
||||
|
||||
Field|Precedence|Sort direction
|
||||
:--|:--|:--
|
||||
[`weight`]|1|descending
|
||||
[`date`]|2|descending
|
||||
[`linkTitle`]|3|descending
|
||||
[`path`]|4|descending
|
||||
|
||||
[`date`]: /methods/page/date/
|
||||
[`weight`]: /methods/page/weight/
|
||||
[`linkTitle`]: /methods/page/linktitle/
|
||||
[`path`]: /methods/page/path/
|
||||
|
||||
The sorted page collection used to determine the _next_ and _previous_ page is independent of other page collections, which may lead to unexpected behavior.
|
||||
|
||||
For example, with this content structure:
|
||||
|
||||
```text
|
||||
content/
|
||||
├── pages/
|
||||
│ ├── _index.md
|
||||
│ ├── page-1.md <-- front matter: weight = 10
|
||||
│ ├── page-2.md <-- front matter: weight = 20
|
||||
│ └── page-3.md <-- front matter: weight = 30
|
||||
└── _index.md
|
||||
```
|
||||
|
||||
And these templates:
|
||||
|
||||
{{< code file=layouts/_default/list.html >}}
|
||||
{{ range .Pages.ByWeight }}
|
||||
<h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
|
||||
{{ end }}
|
||||
{{< /code >}}
|
||||
|
||||
{{< code file=layouts/_default/single.html >}}
|
||||
{{ with .PrevInSection }}
|
||||
<a href="{{ .RelPermalink }}">Previous</a>
|
||||
{{ end }}
|
||||
|
||||
{{ with .NextInSection }}
|
||||
<a href="{{ .RelPermalink }}">Next</a>
|
||||
{{ end }}
|
||||
{{< /code >}}
|
||||
|
||||
When you visit page-2:
|
||||
|
||||
- The `PrevInSection` method points to page-3
|
||||
- The `NextInSection` method points to page-1
|
||||
|
||||
To reverse the meaning of _next_ and _previous_ you can change the sort direction in your [site configuration], or use the [`Next`] and [`Prev`] methods on a `Pages` object for more flexibility.
|
||||
|
||||
[site configuration]: getting-started/configuration/#configure-page
|
||||
[`Next`]: /methods/pages/prev
|
||||
[`Prev`]: /methods/pages/prev
|
||||
|
||||
## Example
|
||||
|
||||
Code defensively by checking for page existence:
|
||||
|
||||
```go-html-template
|
||||
{{ with .PrevInSection }}
|
||||
<a href="{{ .RelPermalink }}">Previous</a>
|
||||
{{ end }}
|
||||
|
||||
{{ with .NextInSection }}
|
||||
<a href="{{ .RelPermalink }}">Next</a>
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
## Alternative
|
||||
|
||||
Use the [`Next`] and [`Prev`] methods on a `Pages` object for more flexibility.
|
||||
@@ -1,55 +1,17 @@
|
||||
---
|
||||
title: Next
|
||||
description: Returns the next page in a local page collection, relative to the given page.
|
||||
description: Returns the next page in a page collection, relative to the given page.
|
||||
categories: []
|
||||
keywords: []
|
||||
action:
|
||||
related:
|
||||
- methods/pages/Prev
|
||||
- methods/page/Next
|
||||
- methods/page/NextInSection
|
||||
- methods/page/Prev
|
||||
- methods/page/NextInSection
|
||||
- methods/page/PrevInSection
|
||||
returnType: page.Page
|
||||
signatures: [PAGES.Next PAGE]
|
||||
toc: true
|
||||
---
|
||||
|
||||
The behavior of the `Prev` and `Next` methods on a `Pages` objects is probably the reverse of what you expect.
|
||||
|
||||
With this content structure and the page collection sorted by weight in ascending order:
|
||||
|
||||
```text
|
||||
content/
|
||||
├── pages/
|
||||
│ ├── _index.md
|
||||
│ ├── page-1.md <-- front matter: weight = 10
|
||||
│ ├── page-2.md <-- front matter: weight = 20
|
||||
│ └── page-3.md <-- front matter: weight = 30
|
||||
└── _index.md
|
||||
```
|
||||
|
||||
When you visit page-2:
|
||||
|
||||
- The `Prev` method points to page-3
|
||||
- The `Next` method points to page-1
|
||||
|
||||
{{% note %}}
|
||||
Use the opposite label in your navigation links as shown in the example below.
|
||||
{{% /note %}}
|
||||
|
||||
```go-html-template
|
||||
{{ $pages := where .Site.RegularPages.ByWeight "Section" "pages" }}
|
||||
|
||||
{{ with $pages.Next . }}
|
||||
<a href="{{ .RelPermalink }}">Previous</a>
|
||||
{{ end }}
|
||||
|
||||
{{ with $pages.Prev . }}
|
||||
<a href="{{ .RelPermalink }}">Next</a>
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
## Compare to Page methods
|
||||
|
||||
{{% include "methods/_common/next-prev-on-page-vs-next-prev-on-pages.md" %}}
|
||||
{{% include "methods/pages/_common/next-and-prev.md" %}}
|
||||
|
||||
@@ -1,55 +1,17 @@
|
||||
---
|
||||
title: Prev
|
||||
description: Returns the previous page in a local page collection, relative to the given page.
|
||||
description: Returns the previous page in a page collection, relative to the given page.
|
||||
categories: []
|
||||
keywords: []
|
||||
action:
|
||||
related:
|
||||
- methods/pages/Next
|
||||
- methods/page/Next
|
||||
- methods/page/NextInSection
|
||||
- methods/page/Prev
|
||||
- methods/page/NextInSection
|
||||
- methods/page/PrevInSection
|
||||
returnType: page.Pages
|
||||
signatures: [PAGES.Prev PAGE]
|
||||
toc: true
|
||||
---
|
||||
|
||||
The behavior of the `Prev` and `Next` methods on a `Pages` objects is probably the reverse of what you expect.
|
||||
|
||||
With this content structure and the page collection sorted by weight in ascending order:
|
||||
|
||||
```text
|
||||
content/
|
||||
├── pages/
|
||||
│ ├── _index.md
|
||||
│ ├── page-1.md <-- front matter: weight = 10
|
||||
│ ├── page-2.md <-- front matter: weight = 20
|
||||
│ └── page-3.md <-- front matter: weight = 30
|
||||
└── _index.md
|
||||
```
|
||||
|
||||
When you visit page-2:
|
||||
|
||||
- The `Prev` method points to page-3
|
||||
- The `Next` method points to page-1
|
||||
|
||||
{{% note %}}
|
||||
Use the opposite label in your navigation links as shown in the example below.
|
||||
{{% /note %}}
|
||||
|
||||
```go-html-template
|
||||
{{ $pages := where .Site.RegularPages.ByWeight "Section" "pages" }}
|
||||
|
||||
{{ with $pages.Next . }}
|
||||
<a href="{{ .RelPermalink }}">Previous</a>
|
||||
{{ end }}
|
||||
|
||||
{{ with $pages.Prev . }}
|
||||
<a href="{{ .RelPermalink }}">Next</a>
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
## Compare to Page methods
|
||||
|
||||
{{% include "methods/_common/next-prev-on-page-vs-next-prev-on-pages.md" %}}
|
||||
{{% include "methods/pages/_common/next-and-prev.md" %}}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
---
|
||||
# Do not remove front matter.
|
||||
---
|
||||
|
||||
Hugo determines the _next_ and _previous_ page by sorting the page collection according to this sorting hierarchy:
|
||||
|
||||
Field|Precedence|Sort direction
|
||||
:--|:--|:--
|
||||
[`weight`]|1|descending
|
||||
[`date`]|2|descending
|
||||
[`linkTitle`]|3|descending
|
||||
[`path`]|4|descending
|
||||
|
||||
[`date`]: /methods/page/date/
|
||||
[`weight`]: /methods/page/weight/
|
||||
[`linkTitle`]: /methods/page/linktitle/
|
||||
[`path`]: /methods/page/path/
|
||||
|
||||
The sorted page collection used to determine the _next_ and _previous_ page is independent of other page collections, which may lead to unexpected behavior.
|
||||
|
||||
For example, with this content structure:
|
||||
|
||||
```text
|
||||
content/
|
||||
├── pages/
|
||||
│ ├── _index.md
|
||||
│ ├── page-1.md <-- front matter: weight = 10
|
||||
│ ├── page-2.md <-- front matter: weight = 20
|
||||
│ └── page-3.md <-- front matter: weight = 30
|
||||
└── _index.md
|
||||
```
|
||||
|
||||
And these templates:
|
||||
|
||||
{{< code file=layouts/_default/list.html >}}
|
||||
{{ range .Pages.ByWeight}}
|
||||
<h2><a href="{{ .RelPermalink }}">{{ .LinkTitle }}</a></h2>
|
||||
{{ end }}
|
||||
{{< /code >}}
|
||||
|
||||
{{< code file=layouts/_default/single.html >}}
|
||||
{{ $pages := .CurrentSection.Pages.ByWeight }}
|
||||
|
||||
{{ with $pages.Prev . }}
|
||||
<a href="{{ .RelPermalink }}">Previous</a>
|
||||
{{ end }}
|
||||
|
||||
{{ with $pages.Next . }}
|
||||
<a href="{{ .RelPermalink }}">Next</a>
|
||||
{{ end }}
|
||||
{{< /code >}}
|
||||
|
||||
When you visit page-2:
|
||||
|
||||
- The `Prev` method points to page-3
|
||||
- The `Next` method points to page-1
|
||||
|
||||
To reverse the meaning of _next_ and _previous_ you can chain the [`Reverse`] method to the page collection definition:
|
||||
|
||||
{{< code file=layouts/_default/single.html >}}
|
||||
{{ $pages := .CurrentSection.Pages.ByWeight.Reverse }}
|
||||
|
||||
{{ with $pages.Prev . }}
|
||||
<a href="{{ .RelPermalink }}">Previous</a>
|
||||
{{ end }}
|
||||
|
||||
{{ with $pages.Next . }}
|
||||
<a href="{{ .RelPermalink }}">Next</a>
|
||||
{{ end }}
|
||||
{{< /code >}}
|
||||
|
||||
[`Reverse`]: /methods/pages/reverse/
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user