mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-30 18:22:37 +00:00
Compare commits
113 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cb359a75c1 | |||
| 82db039436 | |||
| 2d2289c79b | |||
| 6894f121b7 | |||
| 245212a5b7 | |||
| f3cd083961 | |||
| 407c24020e | |||
| c067f34558 | |||
| 72903be587 | |||
| 1c114d539b | |||
| e141294619 | |||
| 612dcc1944 | |||
| e50a8c7a14 | |||
| 7e76a6fd3b | |||
| 1b0780dbeb | |||
| 3cdf19e9b7 | |||
| 02f2735f68 | |||
| 22cd89adc4 | |||
| db4b7a5c67 | |||
| 2511498608 | |||
| 9df3736fec | |||
| 243694102a | |||
| 3153526161 | |||
| fdbef2a81c | |||
| 426ac9c18e | |||
| 84805a68ca | |||
| a2d81ce983 | |||
| 051fa343d0 | |||
| 23f69efb39 | |||
| e69da7a4cb | |||
| e7652180a1 | |||
| 7989210120 | |||
| 7f2ae3ef39 | |||
| 8a8ba63c7e | |||
| c1c04d74a0 | |||
| aa68205d16 | |||
| 94115888e3 | |||
| bf8aa4ac5a | |||
| 6d79beb5f6 | |||
| 8afd7d9ceb | |||
| 42fbf15fb7 | |||
| 288723a049 | |||
| f4b416bbef | |||
| 058f25146c | |||
| 3dd7e8b7a7 | |||
| 30c0d485ea | |||
| 14786c4d8f | |||
| 089fe49309 | |||
| 118b83d74b | |||
| adbd5bc47f | |||
| c1d325934e | |||
| d99db71ab5 | |||
| 503ca6de6c | |||
| b3daa1f4bf | |||
| df1677a6e8 | |||
| 05e42bc643 | |||
| 0a81a6b4ba | |||
| 60dfb9a6e0 | |||
| 2e0465764b | |||
| 6233ddf9d1 | |||
| e66d813bcb | |||
| f5ed04bd4a | |||
| 7730d683e8 | |||
| bb048d811d | |||
| 9299a16c99 | |||
| a9be687b81 | |||
| b32ffed6ab | |||
| 77cbd001ff | |||
| 764f1304e1 | |||
| d9a78b61ad | |||
| 23ba779fab | |||
| 550cec0b1f | |||
| b88a105a7c | |||
| b3443b3d0c | |||
| c97216e4f0 | |||
| bb04010cbf | |||
| 76dc811c65 | |||
| 488631fe0a | |||
| fdd62eb4c3 | |||
| b6f2e3b438 | |||
| c61998d3ac | |||
| 45ad8ac381 | |||
| 133cfd1710 | |||
| db1a5af15d | |||
| 9ccc958ce7 | |||
| 30e471b8c6 | |||
| f711b170e4 | |||
| 9536f7cd05 | |||
| 1ac47cd88a | |||
| ba0b22ef44 | |||
| c9c19d7945 | |||
| 1d52bfbb47 | |||
| 142ebba2c5 | |||
| bf633ea2f2 | |||
| 6faf47e8dd | |||
| 7954bc0f0f | |||
| c4bf03a558 | |||
| 3164103310 | |||
| 6a5170116c | |||
| 325009c3fd | |||
| bc53cd7b15 | |||
| 4e07b4144f | |||
| 89a3f47a21 | |||
| 35be07f7c8 | |||
| 6f84570d8f | |||
| 8964162573 | |||
| e939aaed8b | |||
| d2b3f00df7 | |||
| fa53b13ca0 | |||
| c3c10f2c7c | |||
| ad5ef43838 | |||
| 5109ed520f | |||
| 45e0908b86 |
@@ -1,7 +1,7 @@
|
||||
defaults: &defaults
|
||||
working_directory: /go/src/github.com/gohugoio
|
||||
docker:
|
||||
- image: bepsays/ci-goreleaser:0.34.2-2
|
||||
- image: bepsays/ci-goreleaser:0.34.2-6
|
||||
|
||||
version: 2
|
||||
jobs:
|
||||
@@ -12,10 +12,11 @@ jobs:
|
||||
path: hugo
|
||||
- run:
|
||||
command: |
|
||||
go get -d github.com/magefile/mage/...
|
||||
git clone git@github.com:gohugoio/hugoDocs.git
|
||||
cd hugo
|
||||
make vendor
|
||||
make check
|
||||
mage vendor
|
||||
mage check
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths: .
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 120
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 21
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- Keep
|
||||
- Security
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: Stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. The resources of the Hugo team are limited, and so we are asking for your help.
|
||||
|
||||
If this is a **bug** and you can still reproduce this error on the <code>master</code> branch, please reply with all of the information you have about it in order to keep the issue open.
|
||||
|
||||
If this is a **feature request**, and you feel that it is still relevant and valuable, please tell us why.
|
||||
|
||||
This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions.
|
||||
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
+2
-2
@@ -2,8 +2,8 @@ language: go
|
||||
sudo: required
|
||||
dist: precise
|
||||
go:
|
||||
- 1.8.4
|
||||
- 1.9.1
|
||||
- 1.8.5
|
||||
- 1.9.2
|
||||
- tip
|
||||
os:
|
||||
- linux
|
||||
|
||||
+11
-11
@@ -90,29 +90,29 @@ Fixes #1949
|
||||
|
||||
### Vendored Dependencies
|
||||
|
||||
Hugo uses [govendor](https://github.com/kardianos/govendor) to vendor dependencies, but we don't commit the vendored packages themselves to the Hugo git repository.
|
||||
Hugo uses [Go Dep](https://github.com/golang/dep) to vendor dependencies, but we don't commit the vendored packages themselves to the Hugo git repository.
|
||||
Therefore, a simple `go get` is not supported since `go get` is not vendor-aware.
|
||||
You **must use govendor** to fetch and manage Hugo's dependencies.
|
||||
|
||||
### Fetch the Sources From GitHub
|
||||
You **must use Go Dep** to fetch and manage Hugo's dependencies.
|
||||
|
||||
```
|
||||
go get -u github.com/kardianos/govendor
|
||||
govendor get github.com/gohugoio/hugo
|
||||
```
|
||||
|
||||
### Using Git Remotes
|
||||
### Fetch the Sources From GitHub
|
||||
|
||||
Due to the way Go handles package imports, the best approach for working on a
|
||||
Hugo fork is to use Git Remotes. Here's a simple walk-through for getting
|
||||
started:
|
||||
|
||||
1. Fetch the Hugo sources as described above.
|
||||
1. Install Go Dep and get the Hugo source:
|
||||
|
||||
1. Change to the Hugo source directory:
|
||||
```
|
||||
go get -u -v github.com/golang/dep/cmd/dep
|
||||
go get -u -v -d github.com/gohugoio/hugo
|
||||
```
|
||||
|
||||
1. Change to the Hugo source directory and fetch the dependencies:
|
||||
|
||||
```
|
||||
cd $HOME/go/src/github.com/gohugoio/hugo
|
||||
dep ensure
|
||||
```
|
||||
|
||||
1. Create a new branch for your changes (the branch name is arbitrary):
|
||||
|
||||
+2
-3
@@ -1,11 +1,10 @@
|
||||
FROM golang:1.9.0-alpine3.6 AS build
|
||||
|
||||
RUN apk add --no-cache --virtual git musl-dev
|
||||
RUN go get github.com/kardianos/govendor
|
||||
RUN go get github.com/golang/dep/cmd/dep
|
||||
|
||||
ADD vendor/vendor.json /go/src/github.com/gohugoio/hugo/vendor/vendor.json
|
||||
WORKDIR /go/src/github.com/gohugoio/hugo
|
||||
RUN govendor sync
|
||||
RUN dep ensure
|
||||
ADD . /go/src/github.com/gohugoio/hugo/
|
||||
RUN go install -ldflags '-s -w'
|
||||
|
||||
|
||||
Generated
+374
@@ -0,0 +1,374 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/BurntSushi/toml"
|
||||
packages = ["."]
|
||||
revision = "a368813c5e648fee92e5f6c30e3944ff9d5e8895"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/PuerkitoBio/purell"
|
||||
packages = ["."]
|
||||
revision = "0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/PuerkitoBio/urlesc"
|
||||
packages = ["."]
|
||||
revision = "de5bf2ad457846296e2031421a34e2568e304e35"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/alecthomas/chroma"
|
||||
packages = [
|
||||
".",
|
||||
"formatters",
|
||||
"formatters/html",
|
||||
"lexers",
|
||||
"styles"
|
||||
]
|
||||
revision = "v0.2.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/bep/gitmap"
|
||||
packages = ["."]
|
||||
revision = "de8030ebafb76c6e84d50ee6d143382637c00598"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/chaseadamsio/goorgeous"
|
||||
packages = ["."]
|
||||
revision = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/cpuguy83/go-md2man"
|
||||
packages = ["md2man"]
|
||||
revision = "1d903dcb749992f3741d744c0f8376b4bd7eb3e1"
|
||||
version = "v1.0.7"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/danwakefield/fnmatch"
|
||||
packages = ["."]
|
||||
revision = "cbb64ac3d964b81592e64f957ad53df015803288"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/davecgh/go-spew"
|
||||
packages = ["spew"]
|
||||
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/disintegration/imaging"
|
||||
packages = ["."]
|
||||
revision = "v1.2.4"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/dlclark/regexp2"
|
||||
packages = [
|
||||
".",
|
||||
"syntax"
|
||||
]
|
||||
revision = "487489b64fb796de2e55f4e8a4ad1e145f80e957"
|
||||
version = "v1.1.6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/eknkc/amber"
|
||||
packages = [
|
||||
".",
|
||||
"parser"
|
||||
]
|
||||
revision = "cdade1c073850f4ffc70a829e31235ea6892853b"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/fortytw2/leaktest"
|
||||
packages = ["."]
|
||||
revision = "7dad53304f9614c1c365755c1176a8e876fee3e8"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/fsnotify/fsnotify"
|
||||
packages = ["."]
|
||||
revision = "629574ca2a5df945712d3079857300b5e4da0236"
|
||||
version = "v1.4.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/websocket"
|
||||
packages = ["."]
|
||||
revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/go-immutable-radix"
|
||||
packages = ["."]
|
||||
revision = "8aac2701530899b64bdea735a1de8da899815220"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/golang-lru"
|
||||
packages = ["simplelru"]
|
||||
revision = "0a025b7e63adc15a622f29b0b2c4c3848243bbf6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/hcl"
|
||||
packages = [
|
||||
".",
|
||||
"hcl/ast",
|
||||
"hcl/parser",
|
||||
"hcl/scanner",
|
||||
"hcl/strconv",
|
||||
"hcl/token",
|
||||
"json/parser",
|
||||
"json/scanner",
|
||||
"json/token"
|
||||
]
|
||||
revision = "23c074d0eceb2b8a5bfdbb271ab780cde70f05a8"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/inconshreveable/mousetrap"
|
||||
packages = ["."]
|
||||
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
|
||||
version = "v1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/jdkato/prose"
|
||||
packages = [
|
||||
"internal/util",
|
||||
"transform"
|
||||
]
|
||||
revision = "20d3663d4bc9dd10d75abcde9d92e04b4861c674"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/kardianos/osext"
|
||||
packages = ["."]
|
||||
revision = "ae77be60afb1dcacde03767a8c37337fad28ac14"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/kyokomi/emoji"
|
||||
packages = ["."]
|
||||
revision = "7e06b236c489543f53868841f188a294e3383eab"
|
||||
version = "v1.5"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/magefile/mage"
|
||||
packages = [
|
||||
"mg",
|
||||
"sh"
|
||||
]
|
||||
revision = "2f974307b636f59c13b88704cf350a4772fef271"
|
||||
version = "v1.0.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/magiconair/properties"
|
||||
packages = ["."]
|
||||
revision = "be5ece7dd465ab0765a9682137865547526d1dfb"
|
||||
version = "v1.7.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/markbates/inflect"
|
||||
packages = ["."]
|
||||
revision = "54ffb37507cd7d2ccd4768855e84f9ff6c4352b6"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-runewidth"
|
||||
packages = ["."]
|
||||
revision = "9e777a8366cce605130a531d2cd6363d07ad7317"
|
||||
version = "v0.0.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/miekg/mmark"
|
||||
packages = ["."]
|
||||
revision = "fd2f6c1403b37925bd7fe13af05853b8ae58ee5f"
|
||||
version = "v1.3.6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mitchellh/mapstructure"
|
||||
packages = ["."]
|
||||
revision = "06020f85339e21b2478f756a78e295255ffa4d6a"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/nicksnyder/go-i18n"
|
||||
packages = [
|
||||
"i18n/bundle",
|
||||
"i18n/language",
|
||||
"i18n/translation"
|
||||
]
|
||||
revision = "0dc1626d56435e9d605a29875701721c54bc9bbd"
|
||||
version = "v1.10.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/olekukonko/tablewriter"
|
||||
packages = ["."]
|
||||
revision = "65fec0d89a572b4367094e2058d3ebe667de3b60"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pelletier/go-toml"
|
||||
packages = ["."]
|
||||
revision = "16398bac157da96aa88f98a2df640c7f32af1da2"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pmezard/go-difflib"
|
||||
packages = ["difflib"]
|
||||
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/russross/blackfriday"
|
||||
packages = ["."]
|
||||
revision = "4048872b16cc0fc2c5fd9eacf0ed2c2fedaa0c8c"
|
||||
version = "v1.5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/shurcooL/sanitized_anchor_name"
|
||||
packages = ["."]
|
||||
revision = "86672fcb3f950f35f2e675df2240550f2a50762f"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/afero"
|
||||
packages = [
|
||||
".",
|
||||
"mem"
|
||||
]
|
||||
revision = "ec3a3111d1e1bdff38a61e09d5a5f5e974905611"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/cast"
|
||||
packages = ["."]
|
||||
revision = "acbeb36b902d72a7a4c18e8f3241075e7ab763e4"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/cobra"
|
||||
packages = [
|
||||
".",
|
||||
"doc"
|
||||
]
|
||||
revision = "7b2c5ac9fc04fc5efafb60700713d4fa609b777b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/fsync"
|
||||
packages = ["."]
|
||||
revision = "12a01e648f05a938100a26858d2d59a120307a18"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/jwalterweatherman"
|
||||
packages = ["."]
|
||||
revision = "12bd96e66386c1960ab0f74ced1362f66f552f7b"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/nitro"
|
||||
packages = ["."]
|
||||
revision = "24d7ef30a12da0bdc5e2eb370a79c659ddccf0e8"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/pflag"
|
||||
packages = ["."]
|
||||
revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/viper"
|
||||
packages = ["."]
|
||||
revision = "25b30aa063fc18e48662b86996252eabdcf2f0c7"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/stretchr/testify"
|
||||
packages = [
|
||||
"assert",
|
||||
"require"
|
||||
]
|
||||
revision = "69483b4bd14f5845b5a1e55bca19e954e827f1d0"
|
||||
version = "v1.1.4"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/yosssi/ace"
|
||||
packages = ["."]
|
||||
revision = "ea038f4770b6746c3f8f84f14fa60d9fe1205b56"
|
||||
version = "v0.0.5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/image"
|
||||
packages = [
|
||||
"bmp",
|
||||
"riff",
|
||||
"tiff",
|
||||
"tiff/lzw",
|
||||
"vp8",
|
||||
"vp8l",
|
||||
"webp"
|
||||
]
|
||||
revision = "f7e31b4ea2e3413ab91b4e7d2dc83e5f8d19a44c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
"idna"
|
||||
]
|
||||
revision = "cd69bc3fc700721b709c3a59e16e24c67b58f6ff"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sync"
|
||||
packages = ["errgroup"]
|
||||
revision = "fd80eb99c8f653c847d294a001bdf2a3a6f768f5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
revision = "8dbc5d05d6edcc104950cc299a1ce6641235bc86"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"collate",
|
||||
"collate/build",
|
||||
"internal/colltab",
|
||||
"internal/gen",
|
||||
"internal/tag",
|
||||
"internal/triegen",
|
||||
"internal/ucd",
|
||||
"language",
|
||||
"secure/bidirule",
|
||||
"transform",
|
||||
"unicode/bidi",
|
||||
"unicode/cldr",
|
||||
"unicode/norm",
|
||||
"unicode/rangetable",
|
||||
"width"
|
||||
]
|
||||
revision = "c01e4764d870b77f8abe5096ee19ad20d80e8075"
|
||||
|
||||
[[projects]]
|
||||
branch = "v2"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
revision = "eb3733d160e74a9c7e442f435eb3bea458e1d19f"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "7259b4caf8e75db0b809f06d4897dc870261252e3aecd68ea1348c87a5da9d50"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/BurntSushi/toml"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/PuerkitoBio/purell"
|
||||
version = "1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/alecthomas/chroma"
|
||||
revision = "v0.2.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/bep/gitmap"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/chaseadamsio/goorgeous"
|
||||
revision = "v1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/disintegration/imaging"
|
||||
revision = "v1.2.4"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/magefile/mage"
|
||||
version = "v1"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/eknkc/amber"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/fortytw2/leaktest"
|
||||
version = "1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/fsnotify/fsnotify"
|
||||
version = "1.4.2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gorilla/websocket"
|
||||
version = "1.2.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/go-immutable-radix"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/jdkato/prose"
|
||||
version = "1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/kardianos/osext"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/kyokomi/emoji"
|
||||
version = "1.5.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/markbates/inflect"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/miekg/mmark"
|
||||
version = "1.3.6"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/mitchellh/mapstructure"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/nicksnyder/go-i18n"
|
||||
version = "1.10.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/russross/blackfriday"
|
||||
version = "1.5.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/afero"
|
||||
version = "1.0.1"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/cast"
|
||||
version = "1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/cobra"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/fsync"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/jwalterweatherman"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/nitro"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/pflag"
|
||||
version = "1.0.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/viper"
|
||||
version = "1.0.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/stretchr/testify"
|
||||
version = "1.1.4"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/olekukonko/tablewriter"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/yosssi/ace"
|
||||
version = "0.0.5"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/image"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/text"
|
||||
|
||||
[[constraint]]
|
||||
branch = "v2"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
@@ -1,86 +0,0 @@
|
||||
# A Self-Documenting Makefile: http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
|
||||
|
||||
PACKAGE = github.com/gohugoio/hugo
|
||||
COMMIT_HASH = `git rev-parse --short HEAD 2>/dev/null`
|
||||
BUILD_DATE = `date +%FT%T%z`
|
||||
LDFLAGS = -ldflags "-X ${PACKAGE}/hugolib.CommitHash=${COMMIT_HASH} -X ${PACKAGE}/hugolib.BuildDate=${BUILD_DATE}"
|
||||
NOGI_LDFLAGS = -ldflags "-X ${PACKAGE}/hugolib.BuildDate=${BUILD_DATE}"
|
||||
|
||||
# allow user to override go executable by running as GOEXE=xxx make ... on unix-like systems
|
||||
GOEXE ?= go
|
||||
|
||||
.PHONY: vendor docker check fmt lint test test-race vet test-cover-html help
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
vendor: ## Install govendor and sync Hugo's vendored dependencies
|
||||
${GOEXE} get github.com/kardianos/govendor
|
||||
govendor sync ${PACKAGE}
|
||||
|
||||
hugo: vendor ## Build hugo binary
|
||||
${GOEXE} build ${LDFLAGS} ${PACKAGE}
|
||||
|
||||
hugo-race: vendor ## Build hugo binary with race detector enabled
|
||||
${GOEXE} build -race ${LDFLAGS} ${PACKAGE}
|
||||
|
||||
install: vendor ## Install hugo binary
|
||||
${GOEXE} install ${LDFLAGS} ${PACKAGE}
|
||||
|
||||
hugo-no-gitinfo: LDFLAGS = ${NOGI_LDFLAGS}
|
||||
hugo-no-gitinfo: vendor hugo ## Build hugo without git info
|
||||
|
||||
docker: ## Build hugo Docker container
|
||||
docker build -t hugo .
|
||||
docker rm -f hugo-build || true
|
||||
docker run --name hugo-build hugo ls /go/bin
|
||||
docker cp hugo-build:/go/bin/hugo .
|
||||
docker rm hugo-build
|
||||
|
||||
govendor: vendor # Deprecated: use "vendor" target
|
||||
get: vendor # Deprecated: use "vendor"
|
||||
gitinfo: hugo # Deprecated: use "hugo" target
|
||||
install-gitinfo: install # Deprecated: use "install" target
|
||||
no-git-info: hugo-no-gitinfo # Deprecated: use "hugo-no-gitinfo" target
|
||||
|
||||
check: test-race test386 fmt vet ## Run tests and linters
|
||||
|
||||
test386: ## Run tests in 32-bit mode
|
||||
GOARCH=386 govendor test +local
|
||||
|
||||
test: ## Run tests
|
||||
govendor test +local
|
||||
|
||||
test-race: ## Run tests with race detector
|
||||
govendor test -race +local
|
||||
|
||||
fmt: ## Run gofmt linter
|
||||
@for d in `govendor list -no-status +local | sed 's/github.com.gohugoio.hugo/./'` ; do \
|
||||
if [ "`gofmt -l $$d/*.go | tee /dev/stderr`" ]; then \
|
||||
echo "^ improperly formatted go files" && echo && exit 1; \
|
||||
fi \
|
||||
done
|
||||
|
||||
lint: ## Run golint linter
|
||||
@for d in `govendor list -no-status +local | sed 's/github.com.gohugoio.hugo/./'` ; do \
|
||||
if [ "`golint $$d | tee /dev/stderr`" ]; then \
|
||||
echo "^ golint errors!" && echo && exit 1; \
|
||||
fi \
|
||||
done
|
||||
|
||||
vet: ## Run go vet linter
|
||||
@if [ "`govendor vet +local | tee /dev/stderr`" ]; then \
|
||||
echo "^ go vet errors!" && echo && exit 1; \
|
||||
fi
|
||||
|
||||
test-cover-html: PACKAGES = $(shell govendor list -no-status +local | sed 's/github.com.gohugoio.hugo/./')
|
||||
test-cover-html: ## Generate test coverage report
|
||||
echo "mode: count" > coverage-all.out
|
||||
$(foreach pkg,$(PACKAGES),\
|
||||
govendor test -coverprofile=coverage.out -covermode=count $(pkg);\
|
||||
tail -n +2 coverage.out >> coverage-all.out;)
|
||||
${GOEXE} tool cover -html=coverage-all.out
|
||||
|
||||
check-vendor: ## Verify that vendored packages match git HEAD
|
||||
@git diff-index --quiet HEAD vendor/ || (echo "check-vendor target failed: vendored packages out of sync" && echo && git diff vendor/ && exit 1)
|
||||
|
||||
help:
|
||||
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||
@@ -99,6 +99,7 @@ When reporting the issue, please provide the version of Hugo in use (`hugo versi
|
||||
The Hugo project welcomes all contributors and contributions regardless of skill or experience level.
|
||||
If you are interested in helping with the project, we will help you with your contribution.
|
||||
Hugo is a very active project with many contributions happening daily.
|
||||
|
||||
Because we want to create the best possible product for our users and the best contribution experience for our developers,
|
||||
we have a set of guidelines which ensure that all contributions are acceptable.
|
||||
The guidelines are not intended as a filter or barrier to participation.
|
||||
|
||||
+1
-1
@@ -9,4 +9,4 @@ GOEXE="${GOEXE-go}"
|
||||
|
||||
echo "Running with BenchmarkSiteBuilding/${1}"
|
||||
|
||||
"${GOEXE}" test -run="NONE" -bench="BenchmarkSiteBuilding/${1}$" -test.benchmem=true ./hugolib -memprofile mem.prof -cpuprofile cpu.prof
|
||||
"${GOEXE}" test -run="NONE" -bench="BenchmarkSiteBuilding/${1}" -test.benchmem=true ./hugolib -memprofile mem.prof -cpuprofile cpu.prof
|
||||
|
||||
@@ -48,12 +48,7 @@ func init() {
|
||||
}
|
||||
|
||||
func benchmark(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig(benchmarkCmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
c, err := InitializeConfig(false, nil, benchmarkCmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -84,7 +79,7 @@ func benchmark(cmd *cobra.Command, args []string) error {
|
||||
|
||||
t := time.Now()
|
||||
for i := 0; i < benchmarkTimes; i++ {
|
||||
if err = c.resetAndBuildSites(false); err != nil {
|
||||
if err = c.resetAndBuildSites(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
+25
-10
@@ -18,13 +18,20 @@ import (
|
||||
"github.com/gohugoio/hugo/deps"
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/gohugoio/hugo/hugofs"
|
||||
src "github.com/gohugoio/hugo/source"
|
||||
)
|
||||
|
||||
type commandeer struct {
|
||||
*deps.DepsCfg
|
||||
pathSpec *helpers.PathSpec
|
||||
visitedURLs *types.EvictingStringQueue
|
||||
configured bool
|
||||
|
||||
staticDirsConfig []*src.Dirs
|
||||
|
||||
serverPorts []int
|
||||
languages helpers.Languages
|
||||
|
||||
configured bool
|
||||
}
|
||||
|
||||
func (c *commandeer) Set(key string, value interface{}) {
|
||||
@@ -48,18 +55,26 @@ func (c *commandeer) initFs(fs *hugofs.Fs) error {
|
||||
return err
|
||||
}
|
||||
c.pathSpec = ps
|
||||
|
||||
dirsConfig, err := c.createStaticDirsConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.staticDirsConfig = dirsConfig
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func newCommandeer(cfg *deps.DepsCfg) (*commandeer, error) {
|
||||
l := cfg.Language
|
||||
if l == nil {
|
||||
l = helpers.NewDefaultLanguage(cfg.Cfg)
|
||||
}
|
||||
ps, err := helpers.NewPathSpec(cfg.Fs, l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func newCommandeer(cfg *deps.DepsCfg, running bool) (*commandeer, error) {
|
||||
cfg.Running = running
|
||||
|
||||
var languages helpers.Languages
|
||||
|
||||
if l, ok := cfg.Cfg.Get("languagesSorted").(helpers.Languages); ok {
|
||||
languages = l
|
||||
}
|
||||
|
||||
return &commandeer{DepsCfg: cfg, pathSpec: ps, visitedURLs: types.NewEvictingStringQueue(10)}, nil
|
||||
c := &commandeer{DepsCfg: cfg, languages: languages, visitedURLs: types.NewEvictingStringQueue(10)}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
+90
-65
@@ -14,12 +14,15 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
src "github.com/gohugoio/hugo/source"
|
||||
|
||||
"github.com/gohugoio/hugo/hugolib"
|
||||
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gohugoio/hugo/parser"
|
||||
"github.com/spf13/cast"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -78,81 +81,103 @@ func init() {
|
||||
}
|
||||
|
||||
func convertContents(mark rune) error {
|
||||
cfg, err := InitializeConfig()
|
||||
if outputDir == "" && !unsafe {
|
||||
return newUserError("Unsafe operation not allowed, use --unsafe or set a different output path")
|
||||
}
|
||||
|
||||
c, err := InitializeConfig(false, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h, err := hugolib.NewHugoSites(*cfg)
|
||||
h, err := hugolib.NewHugoSites(*c.DepsCfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := h.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
site := h.Sites[0]
|
||||
|
||||
if err = site.Initialise(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if site.Source == nil {
|
||||
panic("site.Source not set")
|
||||
}
|
||||
if len(site.Source.Files()) < 1 {
|
||||
return errors.New("No source files found")
|
||||
}
|
||||
|
||||
contentDir := site.PathSpec.AbsPathify(site.Cfg.GetString("contentDir"))
|
||||
site.Log.FEEDBACK.Println("processing", len(site.Source.Files()), "content files")
|
||||
for _, file := range site.Source.Files() {
|
||||
site.Log.INFO.Println("Attempting to convert", file.LogicalName())
|
||||
page, err := site.NewPage(file.LogicalName())
|
||||
if err != nil {
|
||||
site.Log.FEEDBACK.Println("processing", len(site.AllPages), "content files")
|
||||
for _, p := range site.AllPages {
|
||||
if err := convertAndSavePage(p, site, mark); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
psr, err := parser.ReadFrom(file.Contents)
|
||||
if err != nil {
|
||||
site.Log.ERROR.Println("Error processing file:", file.Path())
|
||||
return err
|
||||
}
|
||||
metadata, err := psr.Metadata()
|
||||
if err != nil {
|
||||
site.Log.ERROR.Println("Error processing file:", file.Path())
|
||||
return err
|
||||
}
|
||||
|
||||
// better handling of dates in formats that don't have support for them
|
||||
if mark == parser.FormatToLeadRune("json") || mark == parser.FormatToLeadRune("yaml") || mark == parser.FormatToLeadRune("toml") {
|
||||
newMetadata := cast.ToStringMap(metadata)
|
||||
for k, v := range newMetadata {
|
||||
switch vv := v.(type) {
|
||||
case time.Time:
|
||||
newMetadata[k] = vv.Format(time.RFC3339)
|
||||
}
|
||||
}
|
||||
metadata = newMetadata
|
||||
}
|
||||
|
||||
page.SetDir(filepath.Join(contentDir, file.Dir()))
|
||||
page.SetSourceContent(psr.Content())
|
||||
if err = page.SetSourceMetaData(metadata, mark); err != nil {
|
||||
site.Log.ERROR.Printf("Failed to set source metadata for file %q: %s. For more info see For more info see https://github.com/gohugoio/hugo/issues/2458", page.FullFilePath(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
if outputDir != "" {
|
||||
if err = page.SaveSourceAs(filepath.Join(outputDir, page.FullFilePath())); err != nil {
|
||||
return fmt.Errorf("Failed to save file %q: %s", page.FullFilePath(), err)
|
||||
}
|
||||
} else {
|
||||
if unsafe {
|
||||
if err = page.SaveSource(); err != nil {
|
||||
return fmt.Errorf("Failed to save file %q: %s", page.FullFilePath(), err)
|
||||
}
|
||||
} else {
|
||||
site.Log.FEEDBACK.Println("Unsafe operation not allowed, use --unsafe or set a different output path")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertAndSavePage(p *hugolib.Page, site *hugolib.Site, mark rune) error {
|
||||
// The resources are not in .Site.AllPages.
|
||||
for _, r := range p.Resources.ByType("page") {
|
||||
if err := convertAndSavePage(r.(*hugolib.Page), site, mark); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if p.Filename() == "" {
|
||||
// No content file.
|
||||
return nil
|
||||
}
|
||||
|
||||
site.Log.INFO.Println("Attempting to convert", p.LogicalName())
|
||||
newPage, err := site.NewPage(p.LogicalName())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, _ := p.File.(src.ReadableFile)
|
||||
file, err := f.Open()
|
||||
if err != nil {
|
||||
site.Log.ERROR.Println("Error reading file:", p.Path())
|
||||
file.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
psr, err := parser.ReadFrom(file)
|
||||
if err != nil {
|
||||
site.Log.ERROR.Println("Error processing file:", p.Path())
|
||||
file.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
file.Close()
|
||||
|
||||
metadata, err := psr.Metadata()
|
||||
if err != nil {
|
||||
site.Log.ERROR.Println("Error processing file:", p.Path())
|
||||
return err
|
||||
}
|
||||
|
||||
// better handling of dates in formats that don't have support for them
|
||||
if mark == parser.FormatToLeadRune("json") || mark == parser.FormatToLeadRune("yaml") || mark == parser.FormatToLeadRune("toml") {
|
||||
newMetadata := cast.ToStringMap(metadata)
|
||||
for k, v := range newMetadata {
|
||||
switch vv := v.(type) {
|
||||
case time.Time:
|
||||
newMetadata[k] = vv.Format(time.RFC3339)
|
||||
}
|
||||
}
|
||||
metadata = newMetadata
|
||||
}
|
||||
|
||||
newPage.SetSourceContent(psr.Content())
|
||||
if err = newPage.SetSourceMetaData(metadata, mark); err != nil {
|
||||
site.Log.ERROR.Printf("Failed to set source metadata for file %q: %s. For more info see For more info see https://github.com/gohugoio/hugo/issues/2458", newPage.FullFilePath(), err)
|
||||
return nil
|
||||
}
|
||||
|
||||
newFilename := p.Filename()
|
||||
if outputDir != "" {
|
||||
newFilename = filepath.Join(outputDir, p.Dir(), newPage.LogicalName())
|
||||
}
|
||||
|
||||
if err = newPage.SaveSourceAs(newFilename); err != nil {
|
||||
return fmt.Errorf("Failed to save file %q: %s", newFilename, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+416
-283
@@ -18,11 +18,14 @@ package commands
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"sort"
|
||||
"sync/atomic"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/gohugoio/hugo/hugofs"
|
||||
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@@ -30,6 +33,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
src "github.com/gohugoio/hugo/source"
|
||||
|
||||
"github.com/gohugoio/hugo/config"
|
||||
|
||||
"github.com/gohugoio/hugo/parser"
|
||||
@@ -57,6 +62,13 @@ import (
|
||||
// provide a cleaner external API, but until then, this is it.
|
||||
var Hugo *hugolib.HugoSites
|
||||
|
||||
const (
|
||||
ansiEsc = "\u001B"
|
||||
clearLine = "\r\033[K"
|
||||
hideCursor = ansiEsc + "[?25l"
|
||||
showCursor = ansiEsc + "[?25h"
|
||||
)
|
||||
|
||||
// Reset resets Hugo ready for a new full build. This is mainly only useful
|
||||
// for benchmark testing etc. via the CLI commands.
|
||||
func Reset() error {
|
||||
@@ -115,18 +127,20 @@ built with love by spf13 and friends in Go.
|
||||
|
||||
Complete documentation is available at http://gohugo.io/.`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
cfgInit := func(c *commandeer) error {
|
||||
if buildWatch {
|
||||
c.Set("disableLiveReload", true)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
c, err := InitializeConfig(buildWatch, cfgInit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if buildWatch {
|
||||
cfg.Cfg.Set("disableLiveReload", true)
|
||||
c.watchConfig()
|
||||
}
|
||||
|
||||
@@ -148,6 +162,7 @@ var (
|
||||
)
|
||||
|
||||
var (
|
||||
gc bool
|
||||
baseURL string
|
||||
cacheDir string
|
||||
contentDir string
|
||||
@@ -200,6 +215,7 @@ func AddCommands() {
|
||||
genCmd.AddCommand(genmanCmd)
|
||||
genCmd.AddCommand(createGenDocsHelper().cmd)
|
||||
genCmd.AddCommand(createGenChromaStyles().cmd)
|
||||
|
||||
}
|
||||
|
||||
// initHugoBuilderFlags initializes all common flags, typically used by the
|
||||
@@ -239,6 +255,7 @@ func initHugoBuildCommonFlags(cmd *cobra.Command) {
|
||||
cmd.Flags().Bool("canonifyURLs", false, "if true, all relative URLs will be canonicalized using baseURL")
|
||||
cmd.Flags().StringVarP(&baseURL, "baseURL", "b", "", "hostname (and path) to the root, e.g. http://spf13.com/")
|
||||
cmd.Flags().Bool("enableGitInfo", false, "add Git revision, date and author info to the pages")
|
||||
cmd.Flags().BoolVar(&gc, "gc", false, "enable to run some cleanup tasks (remove unused cache files) after the build")
|
||||
|
||||
cmd.Flags().BoolVar(&nitro.AnalysisOn, "stepAnalysis", false, "display memory and timing of different steps of the program")
|
||||
cmd.Flags().Bool("templateMetrics", false, "display metrics about template executions")
|
||||
@@ -284,7 +301,7 @@ func init() {
|
||||
}
|
||||
|
||||
// InitializeConfig initializes a config file with sensible default configuration flags.
|
||||
func InitializeConfig(subCmdVs ...*cobra.Command) (*deps.DepsCfg, error) {
|
||||
func InitializeConfig(running bool, doWithCommandeer func(c *commandeer) error, subCmdVs ...*cobra.Command) (*commandeer, error) {
|
||||
|
||||
var cfg *deps.DepsCfg = &deps.DepsCfg{}
|
||||
|
||||
@@ -293,13 +310,13 @@ func InitializeConfig(subCmdVs ...*cobra.Command) (*deps.DepsCfg, error) {
|
||||
|
||||
config, err := hugolib.LoadConfig(osFs, source, cfgFile)
|
||||
if err != nil {
|
||||
return cfg, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Init file systems. This may be changed at a later point.
|
||||
cfg.Cfg = config
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
c, err := newCommandeer(cfg, running)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -308,23 +325,29 @@ func InitializeConfig(subCmdVs ...*cobra.Command) (*deps.DepsCfg, error) {
|
||||
c.initializeFlags(cmdV)
|
||||
}
|
||||
|
||||
if baseURL != "" {
|
||||
config.Set("baseURL", baseURL)
|
||||
}
|
||||
|
||||
if doWithCommandeer != nil {
|
||||
if err := doWithCommandeer(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if len(disableKinds) > 0 {
|
||||
c.Set("disableKinds", disableKinds)
|
||||
}
|
||||
|
||||
logger, err := createLogger(cfg.Cfg)
|
||||
if err != nil {
|
||||
return cfg, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg.Logger = logger
|
||||
|
||||
config.Set("logI18nWarnings", logI18nWarnings)
|
||||
|
||||
if baseURL != "" {
|
||||
config.Set("baseURL", baseURL)
|
||||
}
|
||||
|
||||
if !config.GetBool("relativeURLs") && config.GetString("baseURL") == "" {
|
||||
cfg.Logger.ERROR.Println("No 'baseURL' set in configuration or as a flag. Features like page menus will not work without one.")
|
||||
}
|
||||
@@ -349,17 +372,6 @@ func InitializeConfig(subCmdVs ...*cobra.Command) (*deps.DepsCfg, error) {
|
||||
}
|
||||
config.Set("workingDir", dir)
|
||||
|
||||
fs := hugofs.NewFrom(osFs, config)
|
||||
|
||||
// Hugo writes the output to memory instead of the disk.
|
||||
// This is only used for benchmark testing. Cause the content is only visible
|
||||
// in memory.
|
||||
if renderToMemory {
|
||||
fs.Destination = new(afero.MemMapFs)
|
||||
// Rendering to memoryFS, publish to Root regardless of publishDir.
|
||||
c.Set("publishDir", "/")
|
||||
}
|
||||
|
||||
if contentDir != "" {
|
||||
config.Set("contentDir", contentDir)
|
||||
}
|
||||
@@ -372,6 +384,17 @@ func InitializeConfig(subCmdVs ...*cobra.Command) (*deps.DepsCfg, error) {
|
||||
config.Set("cacheDir", cacheDir)
|
||||
}
|
||||
|
||||
fs := hugofs.NewFrom(osFs, config)
|
||||
|
||||
// Hugo writes the output to memory instead of the disk.
|
||||
// This is only used for benchmark testing. Cause the content is only visible
|
||||
// in memory.
|
||||
if config.GetBool("renderToMemory") {
|
||||
fs.Destination = new(afero.MemMapFs)
|
||||
// Rendering to memoryFS, publish to Root regardless of publishDir.
|
||||
config.Set("publishDir", "/")
|
||||
}
|
||||
|
||||
cacheDir = config.GetString("cacheDir")
|
||||
if cacheDir != "" {
|
||||
if helpers.FilePathSeparator != cacheDir[len(cacheDir)-1:] {
|
||||
@@ -396,7 +419,7 @@ func InitializeConfig(subCmdVs ...*cobra.Command) (*deps.DepsCfg, error) {
|
||||
themeDir := c.PathSpec().GetThemeDir()
|
||||
if themeDir != "" {
|
||||
if _, err := cfg.Fs.Source.Stat(themeDir); os.IsNotExist(err) {
|
||||
return cfg, newSystemError("Unable to find theme Directory:", themeDir)
|
||||
return nil, newSystemError("Unable to find theme Directory:", themeDir)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,7 +430,7 @@ func InitializeConfig(subCmdVs ...*cobra.Command) (*deps.DepsCfg, error) {
|
||||
helpers.CurrentHugoVersion.ReleaseVersion(), minVersion)
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
return c, nil
|
||||
|
||||
}
|
||||
|
||||
@@ -481,17 +504,17 @@ func (c *commandeer) initializeFlags(cmd *cobra.Command) {
|
||||
"templateMetricsHints",
|
||||
}
|
||||
|
||||
// Remove these in Hugo 0.23.
|
||||
// Remove these in Hugo 0.33.
|
||||
if cmd.Flags().Changed("disable404") {
|
||||
helpers.Deprecated("command line", "--disable404", "Use --disableKinds=404", false)
|
||||
helpers.Deprecated("command line", "--disable404", "Use --disableKinds=404", true)
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("disableRSS") {
|
||||
helpers.Deprecated("command line", "--disableRSS", "Use --disableKinds=RSS", false)
|
||||
helpers.Deprecated("command line", "--disableRSS", "Use --disableKinds=RSS", true)
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("disableSitemap") {
|
||||
helpers.Deprecated("command line", "--disableSitemap", "Use --disableKinds=sitemap", false)
|
||||
helpers.Deprecated("command line", "--disableSitemap", "Use --disableKinds=sitemap", true)
|
||||
}
|
||||
|
||||
for _, key := range persFlagKeys {
|
||||
@@ -524,93 +547,181 @@ func (c *commandeer) watchConfig() {
|
||||
})
|
||||
}
|
||||
|
||||
func (c *commandeer) fullBuild(watches ...bool) error {
|
||||
var (
|
||||
g errgroup.Group
|
||||
langCount map[string]uint64
|
||||
)
|
||||
|
||||
if !quiet {
|
||||
fmt.Print(hideCursor + "Building sites … ")
|
||||
defer func() {
|
||||
fmt.Print(showCursor + clearLine)
|
||||
}()
|
||||
}
|
||||
|
||||
g.Go(func() error {
|
||||
cnt, err := c.copyStatic()
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error copying static files: %s", err)
|
||||
}
|
||||
langCount = cnt
|
||||
return nil
|
||||
})
|
||||
|
||||
g.Go(func() error {
|
||||
if err := c.buildSites(); err != nil {
|
||||
return fmt.Errorf("Error building site: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err := g.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, s := range Hugo.Sites {
|
||||
s.ProcessingStats.Static = langCount[s.Language.Lang]
|
||||
}
|
||||
|
||||
if gc {
|
||||
count, err := Hugo.GC()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, s := range Hugo.Sites {
|
||||
// We have no way of knowing what site the garbage belonged to.
|
||||
s.ProcessingStats.Cleaned = uint64(count)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
func (c *commandeer) build(watches ...bool) error {
|
||||
if err := c.copyStatic(); err != nil {
|
||||
return fmt.Errorf("Error copying static files to %s: %s", c.PathSpec().AbsPathify(c.Cfg.GetString("publishDir")), err)
|
||||
defer c.timeTrack(time.Now(), "Total")
|
||||
|
||||
if err := c.fullBuild(watches...); err != nil {
|
||||
return err
|
||||
}
|
||||
watch := false
|
||||
if len(watches) > 0 && watches[0] {
|
||||
watch = true
|
||||
}
|
||||
if err := c.buildSites(buildWatch || watch); err != nil {
|
||||
return fmt.Errorf("Error building site: %s", err)
|
||||
|
||||
// TODO(bep) Feedback?
|
||||
if !quiet {
|
||||
fmt.Println()
|
||||
Hugo.PrintProcessingStats(os.Stdout)
|
||||
fmt.Println()
|
||||
}
|
||||
|
||||
if buildWatch {
|
||||
watchDirs, err := c.getDirList()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Logger.FEEDBACK.Println("Watching for changes in", c.PathSpec().AbsPathify(c.Cfg.GetString("contentDir")))
|
||||
c.Logger.FEEDBACK.Println("Press Ctrl+C to stop")
|
||||
utils.CheckErr(c.Logger, c.newWatcher(0))
|
||||
utils.CheckErr(c.Logger, c.newWatcher(false, watchDirs...))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *commandeer) getStaticSourceFs() afero.Fs {
|
||||
source := c.Fs.Source
|
||||
themeDir, err := c.PathSpec().GetThemeStaticDirPath()
|
||||
staticDir := c.PathSpec().GetStaticDirPath() + helpers.FilePathSeparator
|
||||
useTheme := true
|
||||
useStatic := true
|
||||
|
||||
if err != nil {
|
||||
if err != helpers.ErrThemeUndefined {
|
||||
c.Logger.WARN.Println(err)
|
||||
}
|
||||
useTheme = false
|
||||
} else {
|
||||
if _, err := source.Stat(themeDir); os.IsNotExist(err) {
|
||||
c.Logger.WARN.Println("Unable to find Theme Static Directory:", themeDir)
|
||||
useTheme = false
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := source.Stat(staticDir); os.IsNotExist(err) {
|
||||
c.Logger.WARN.Println("Unable to find Static Directory:", staticDir)
|
||||
useStatic = false
|
||||
}
|
||||
|
||||
if !useStatic && !useTheme {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !useStatic {
|
||||
c.Logger.INFO.Println(themeDir, "is the only static directory available to sync from")
|
||||
return afero.NewReadOnlyFs(afero.NewBasePathFs(source, themeDir))
|
||||
}
|
||||
|
||||
if !useTheme {
|
||||
c.Logger.INFO.Println(staticDir, "is the only static directory available to sync from")
|
||||
return afero.NewReadOnlyFs(afero.NewBasePathFs(source, staticDir))
|
||||
}
|
||||
|
||||
c.Logger.INFO.Println("using a UnionFS for static directory comprised of:")
|
||||
c.Logger.INFO.Println("Base:", themeDir)
|
||||
c.Logger.INFO.Println("Overlay:", staticDir)
|
||||
base := afero.NewReadOnlyFs(afero.NewBasePathFs(source, themeDir))
|
||||
overlay := afero.NewReadOnlyFs(afero.NewBasePathFs(source, staticDir))
|
||||
return afero.NewCopyOnWriteFs(base, overlay)
|
||||
func (c *commandeer) copyStatic() (map[string]uint64, error) {
|
||||
return c.doWithPublishDirs(c.copyStaticTo)
|
||||
}
|
||||
|
||||
func (c *commandeer) copyStatic() error {
|
||||
publishDir := c.PathSpec().AbsPathify(c.Cfg.GetString("publishDir")) + helpers.FilePathSeparator
|
||||
func (c *commandeer) createStaticDirsConfig() ([]*src.Dirs, error) {
|
||||
var dirsConfig []*src.Dirs
|
||||
|
||||
if !c.languages.IsMultihost() {
|
||||
dirs, err := src.NewDirs(c.Fs, c.Cfg, c.DepsCfg.Logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dirsConfig = append(dirsConfig, dirs)
|
||||
} else {
|
||||
for _, l := range c.languages {
|
||||
dirs, err := src.NewDirs(c.Fs, l, c.DepsCfg.Logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dirsConfig = append(dirsConfig, dirs)
|
||||
}
|
||||
}
|
||||
|
||||
return dirsConfig, nil
|
||||
|
||||
}
|
||||
|
||||
func (c *commandeer) doWithPublishDirs(f func(dirs *src.Dirs, publishDir string) (uint64, error)) (map[string]uint64, error) {
|
||||
|
||||
langCount := make(map[string]uint64)
|
||||
|
||||
for _, dirs := range c.staticDirsConfig {
|
||||
|
||||
cnt, err := f(dirs, c.pathSpec.PublishDir)
|
||||
if err != nil {
|
||||
return langCount, err
|
||||
}
|
||||
|
||||
if dirs.Language == nil {
|
||||
// Not multihost
|
||||
for _, l := range c.languages {
|
||||
langCount[l.Lang] = cnt
|
||||
}
|
||||
} else {
|
||||
langCount[dirs.Language.Lang] = cnt
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return langCount, nil
|
||||
}
|
||||
|
||||
type countingStatFs struct {
|
||||
afero.Fs
|
||||
statCounter uint64
|
||||
}
|
||||
|
||||
func (fs *countingStatFs) Stat(name string) (os.FileInfo, error) {
|
||||
f, err := fs.Fs.Stat(name)
|
||||
if err == nil {
|
||||
if !f.IsDir() {
|
||||
atomic.AddUint64(&fs.statCounter, 1)
|
||||
}
|
||||
}
|
||||
return f, err
|
||||
}
|
||||
|
||||
func (c *commandeer) copyStaticTo(dirs *src.Dirs, publishDir string) (uint64, error) {
|
||||
|
||||
// If root, remove the second '/'
|
||||
if publishDir == "//" {
|
||||
publishDir = helpers.FilePathSeparator
|
||||
}
|
||||
|
||||
// Includes both theme/static & /static
|
||||
staticSourceFs := c.getStaticSourceFs()
|
||||
if dirs.Language != nil {
|
||||
// Multihost setup.
|
||||
publishDir = filepath.Join(publishDir, dirs.Language.Lang)
|
||||
}
|
||||
|
||||
staticSourceFs, err := dirs.CreateStaticFs()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if staticSourceFs == nil {
|
||||
c.Logger.WARN.Println("No static directories found to sync")
|
||||
return nil
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
fs := &countingStatFs{Fs: staticSourceFs}
|
||||
|
||||
syncer := fsync.NewSyncer()
|
||||
syncer.NoTimes = c.Cfg.GetBool("noTimes")
|
||||
syncer.NoChmod = c.Cfg.GetBool("noChmod")
|
||||
syncer.SrcFs = staticSourceFs
|
||||
syncer.SrcFs = fs
|
||||
syncer.DestFs = c.Fs.Destination
|
||||
// Now that we are using a unionFs for the static directories
|
||||
// We can effectively clean the publishDir on initial sync
|
||||
@@ -627,97 +738,156 @@ func (c *commandeer) copyStatic() error {
|
||||
|
||||
// because we are using a baseFs (to get the union right).
|
||||
// set sync src to root
|
||||
return syncer.Sync(publishDir, helpers.FilePathSeparator)
|
||||
err = syncer.Sync(publishDir, helpers.FilePathSeparator)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// Sync runs Stat 3 times for every source file (which sounds much)
|
||||
numFiles := fs.statCounter / 3
|
||||
|
||||
return numFiles, err
|
||||
}
|
||||
|
||||
func (c *commandeer) timeTrack(start time.Time, name string) {
|
||||
elapsed := time.Since(start)
|
||||
c.Logger.FEEDBACK.Printf("%s in %v ms", name, int(1000*elapsed.Seconds()))
|
||||
}
|
||||
|
||||
// getDirList provides NewWatcher() with a list of directories to watch for changes.
|
||||
func (c *commandeer) getDirList() []string {
|
||||
func (c *commandeer) getDirList() ([]string, error) {
|
||||
var a []string
|
||||
|
||||
// To handle nested symlinked content dirs
|
||||
var seen = make(map[string]bool)
|
||||
var nested []string
|
||||
|
||||
dataDir := c.PathSpec().AbsPathify(c.Cfg.GetString("dataDir"))
|
||||
i18nDir := c.PathSpec().AbsPathify(c.Cfg.GetString("i18nDir"))
|
||||
layoutDir := c.PathSpec().GetLayoutDirPath()
|
||||
staticDir := c.PathSpec().GetStaticDirPath()
|
||||
|
||||
walker := func(path string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
if path == dataDir && os.IsNotExist(err) {
|
||||
c.Logger.WARN.Println("Skip dataDir:", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if path == i18nDir && os.IsNotExist(err) {
|
||||
c.Logger.WARN.Println("Skip i18nDir:", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if path == layoutDir && os.IsNotExist(err) {
|
||||
c.Logger.WARN.Println("Skip layoutDir:", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if path == staticDir && os.IsNotExist(err) {
|
||||
c.Logger.WARN.Println("Skip staticDir:", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
// Ignore.
|
||||
return nil
|
||||
}
|
||||
|
||||
c.Logger.ERROR.Println("Walker: ", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Skip .git directories.
|
||||
// Related to https://github.com/gohugoio/hugo/issues/3468.
|
||||
if fi.Name() == ".git" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||
link, err := filepath.EvalSymlinks(path)
|
||||
if err != nil {
|
||||
c.Logger.ERROR.Printf("Cannot read symbolic link '%s', error was: %s", path, err)
|
||||
return nil
|
||||
}
|
||||
linkfi, err := c.Fs.Source.Stat(link)
|
||||
if err != nil {
|
||||
c.Logger.ERROR.Printf("Cannot stat '%s', error was: %s", link, err)
|
||||
return nil
|
||||
}
|
||||
if !linkfi.Mode().IsRegular() {
|
||||
c.Logger.ERROR.Printf("Symbolic links for directories not supported, skipping '%s'", path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
if fi.Name() == ".git" ||
|
||||
fi.Name() == "node_modules" || fi.Name() == "bower_components" {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
a = append(a, path)
|
||||
}
|
||||
return nil
|
||||
staticSyncer, err := newStaticSyncer(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
layoutDir := c.PathSpec().GetLayoutDirPath()
|
||||
staticDirs := staticSyncer.d.AbsStaticDirs
|
||||
|
||||
newWalker := func(allowSymbolicDirs bool) func(path string, fi os.FileInfo, err error) error {
|
||||
return func(path string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
if path == dataDir && os.IsNotExist(err) {
|
||||
c.Logger.WARN.Println("Skip dataDir:", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if path == i18nDir && os.IsNotExist(err) {
|
||||
c.Logger.WARN.Println("Skip i18nDir:", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if path == layoutDir && os.IsNotExist(err) {
|
||||
c.Logger.WARN.Println("Skip layoutDir:", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if os.IsNotExist(err) {
|
||||
for _, staticDir := range staticDirs {
|
||||
if path == staticDir && os.IsNotExist(err) {
|
||||
c.Logger.WARN.Println("Skip staticDir:", err)
|
||||
}
|
||||
}
|
||||
// Ignore.
|
||||
return nil
|
||||
}
|
||||
|
||||
c.Logger.ERROR.Println("Walker: ", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Skip .git directories.
|
||||
// Related to https://github.com/gohugoio/hugo/issues/3468.
|
||||
if fi.Name() == ".git" {
|
||||
return nil
|
||||
}
|
||||
|
||||
if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||
link, err := filepath.EvalSymlinks(path)
|
||||
if err != nil {
|
||||
c.Logger.ERROR.Printf("Cannot read symbolic link '%s', error was: %s", path, err)
|
||||
return nil
|
||||
}
|
||||
linkfi, err := helpers.LstatIfOs(c.Fs.Source, link)
|
||||
if err != nil {
|
||||
c.Logger.ERROR.Printf("Cannot stat %q: %s", link, err)
|
||||
return nil
|
||||
}
|
||||
if !allowSymbolicDirs && !linkfi.Mode().IsRegular() {
|
||||
c.Logger.ERROR.Printf("Symbolic links for directories not supported, skipping %q", path)
|
||||
return nil
|
||||
}
|
||||
|
||||
if allowSymbolicDirs && linkfi.IsDir() {
|
||||
// afero.Walk will not walk symbolic links, so wee need to do it.
|
||||
if !seen[path] {
|
||||
seen[path] = true
|
||||
nested = append(nested, path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
fi = linkfi
|
||||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
if fi.Name() == ".git" ||
|
||||
fi.Name() == "node_modules" || fi.Name() == "bower_components" {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
a = append(a, path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
symLinkWalker := newWalker(true)
|
||||
regularWalker := newWalker(false)
|
||||
|
||||
// SymbolicWalk will log anny ERRORs
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, dataDir, walker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, c.PathSpec().AbsPathify(c.Cfg.GetString("contentDir")), walker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, i18nDir, walker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, layoutDir, walker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, staticDir, walker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, dataDir, regularWalker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, c.PathSpec().AbsPathify(c.Cfg.GetString("contentDir")), symLinkWalker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, i18nDir, regularWalker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, layoutDir, regularWalker)
|
||||
for _, staticDir := range staticDirs {
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, staticDir, regularWalker)
|
||||
}
|
||||
|
||||
if c.PathSpec().ThemeSet() {
|
||||
themesDir := c.PathSpec().GetThemeDir()
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, filepath.Join(themesDir, "layouts"), walker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, filepath.Join(themesDir, "static"), walker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, filepath.Join(themesDir, "i18n"), walker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, filepath.Join(themesDir, "data"), walker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, filepath.Join(themesDir, "layouts"), regularWalker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, filepath.Join(themesDir, "i18n"), regularWalker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, filepath.Join(themesDir, "data"), regularWalker)
|
||||
}
|
||||
|
||||
return a
|
||||
if len(nested) > 0 {
|
||||
for {
|
||||
|
||||
toWalk := nested
|
||||
nested = nested[:0]
|
||||
|
||||
for _, d := range toWalk {
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, d, symLinkWalker)
|
||||
}
|
||||
|
||||
if len(nested) == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
a = helpers.UniqueStrings(a)
|
||||
sort.Strings(a)
|
||||
|
||||
return a, nil
|
||||
}
|
||||
|
||||
func (c *commandeer) recreateAndBuildSites(watching bool) (err error) {
|
||||
@@ -727,17 +897,17 @@ func (c *commandeer) recreateAndBuildSites(watching bool) (err error) {
|
||||
if !quiet {
|
||||
c.Logger.FEEDBACK.Println("Started building sites ...")
|
||||
}
|
||||
return Hugo.Build(hugolib.BuildCfg{CreateSitesFromConfig: true, Watching: watching, PrintStats: !quiet})
|
||||
return Hugo.Build(hugolib.BuildCfg{CreateSitesFromConfig: true})
|
||||
}
|
||||
|
||||
func (c *commandeer) resetAndBuildSites(watching bool) (err error) {
|
||||
func (c *commandeer) resetAndBuildSites() (err error) {
|
||||
if err = c.initSites(); err != nil {
|
||||
return
|
||||
}
|
||||
if !quiet {
|
||||
c.Logger.FEEDBACK.Println("Started building sites ...")
|
||||
}
|
||||
return Hugo.Build(hugolib.BuildCfg{ResetState: true, Watching: watching, PrintStats: !quiet})
|
||||
return Hugo.Build(hugolib.BuildCfg{ResetState: true})
|
||||
}
|
||||
|
||||
func (c *commandeer) initSites() error {
|
||||
@@ -754,34 +924,50 @@ func (c *commandeer) initSites() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *commandeer) buildSites(watching bool) (err error) {
|
||||
func (c *commandeer) buildSites() (err error) {
|
||||
if err := c.initSites(); err != nil {
|
||||
return err
|
||||
}
|
||||
if !quiet {
|
||||
c.Logger.FEEDBACK.Println("Started building sites ...")
|
||||
}
|
||||
return Hugo.Build(hugolib.BuildCfg{Watching: watching, PrintStats: !quiet})
|
||||
return Hugo.Build(hugolib.BuildCfg{})
|
||||
}
|
||||
|
||||
func (c *commandeer) rebuildSites(events []fsnotify.Event) error {
|
||||
defer c.timeTrack(time.Now(), "Total")
|
||||
|
||||
if err := c.initSites(); err != nil {
|
||||
return err
|
||||
}
|
||||
visited := c.visitedURLs.PeekAllSet()
|
||||
if !c.Cfg.GetBool("disableFastRender") {
|
||||
// Make sure we always render the home page
|
||||
visited["/"] = true
|
||||
doLiveReload := !buildWatch && !c.Cfg.GetBool("disableLiveReload")
|
||||
if doLiveReload && !c.Cfg.GetBool("disableFastRender") {
|
||||
|
||||
// Make sure we always render the home pages
|
||||
for _, l := range c.languages {
|
||||
langPath := c.PathSpec().GetLangSubDir(l.Lang)
|
||||
if langPath != "" {
|
||||
langPath = langPath + "/"
|
||||
}
|
||||
home := c.pathSpec.PrependBasePath("/" + langPath)
|
||||
visited[home] = true
|
||||
}
|
||||
|
||||
}
|
||||
return Hugo.Build(hugolib.BuildCfg{PrintStats: !quiet, Watching: true, RecentlyVisited: visited}, events...)
|
||||
return Hugo.Build(hugolib.BuildCfg{RecentlyVisited: visited}, events...)
|
||||
}
|
||||
|
||||
// newWatcher creates a new watcher to watch filesystem events.
|
||||
func (c *commandeer) newWatcher(port int) error {
|
||||
// if serve is set it will also start one or more HTTP servers to serve those
|
||||
// files.
|
||||
func (c *commandeer) newWatcher(serve bool, dirList ...string) error {
|
||||
if runtime.GOOS == "darwin" {
|
||||
tweakLimit()
|
||||
}
|
||||
|
||||
staticSyncer, err := newStaticSyncer(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
watcher, err := watcher.New(1 * time.Second)
|
||||
var wg sync.WaitGroup
|
||||
|
||||
@@ -793,7 +979,7 @@ func (c *commandeer) newWatcher(port int) error {
|
||||
|
||||
wg.Add(1)
|
||||
|
||||
for _, d := range c.getDirList() {
|
||||
for _, d := range dirList {
|
||||
if d != "" {
|
||||
_ = watcher.Add(d)
|
||||
}
|
||||
@@ -808,6 +994,37 @@ func (c *commandeer) newWatcher(port int) error {
|
||||
staticEvents := []fsnotify.Event{}
|
||||
dynamicEvents := []fsnotify.Event{}
|
||||
|
||||
// Special handling for symbolic links inside /content.
|
||||
filtered := []fsnotify.Event{}
|
||||
for _, ev := range evs {
|
||||
// Check the most specific first, i.e. files.
|
||||
contentMapped := Hugo.ContentChanges.GetSymbolicLinkMappings(ev.Name)
|
||||
if len(contentMapped) > 0 {
|
||||
for _, mapped := range contentMapped {
|
||||
filtered = append(filtered, fsnotify.Event{Name: mapped, Op: ev.Op})
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Check for any symbolic directory mapping.
|
||||
|
||||
dir, name := filepath.Split(ev.Name)
|
||||
|
||||
contentMapped = Hugo.ContentChanges.GetSymbolicLinkMappings(dir)
|
||||
|
||||
if len(contentMapped) == 0 {
|
||||
filtered = append(filtered, ev)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, mapped := range contentMapped {
|
||||
mappedFilename := filepath.Join(mapped, name)
|
||||
filtered = append(filtered, fsnotify.Event{Name: mappedFilename, Op: ev.Op})
|
||||
}
|
||||
}
|
||||
|
||||
evs = filtered
|
||||
|
||||
for _, ev := range evs {
|
||||
ext := filepath.Ext(ev.Name)
|
||||
baseName := filepath.Base(ev.Name)
|
||||
@@ -853,7 +1070,7 @@ func (c *commandeer) newWatcher(port int) error {
|
||||
if err := watcher.Add(path); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if !c.isStatic(path) {
|
||||
} else if !staticSyncer.isStatic(path) {
|
||||
// Hugo's rebuilding logic is entirely file based. When you drop a new folder into
|
||||
// /content on OSX, the above logic will handle future watching of those files,
|
||||
// but the initial CREATE is lost.
|
||||
@@ -870,7 +1087,7 @@ func (c *commandeer) newWatcher(port int) error {
|
||||
}
|
||||
}
|
||||
|
||||
if c.isStatic(ev.Name) {
|
||||
if staticSyncer.isStatic(ev.Name) {
|
||||
staticEvents = append(staticEvents, ev)
|
||||
} else {
|
||||
dynamicEvents = append(dynamicEvents, ev)
|
||||
@@ -878,99 +1095,20 @@ func (c *commandeer) newWatcher(port int) error {
|
||||
}
|
||||
|
||||
if len(staticEvents) > 0 {
|
||||
publishDir := c.PathSpec().AbsPathify(c.Cfg.GetString("publishDir")) + helpers.FilePathSeparator
|
||||
|
||||
// If root, remove the second '/'
|
||||
if publishDir == "//" {
|
||||
publishDir = helpers.FilePathSeparator
|
||||
}
|
||||
|
||||
c.Logger.FEEDBACK.Println("\nStatic file changes detected")
|
||||
const layout = "2006-01-02 15:04 -0700"
|
||||
const layout = "2006-01-02 15:04:05.000 -0700"
|
||||
c.Logger.FEEDBACK.Println(time.Now().Format(layout))
|
||||
|
||||
if c.Cfg.GetBool("forceSyncStatic") {
|
||||
c.Logger.FEEDBACK.Printf("Syncing all static files\n")
|
||||
err := c.copyStatic()
|
||||
_, err := c.copyStatic()
|
||||
if err != nil {
|
||||
utils.StopOnErr(c.Logger, err, fmt.Sprintf("Error copying static files to %s", publishDir))
|
||||
utils.StopOnErr(c.Logger, err, "Error copying static files to publish dir")
|
||||
}
|
||||
} else {
|
||||
staticSourceFs := c.getStaticSourceFs()
|
||||
|
||||
if staticSourceFs == nil {
|
||||
c.Logger.WARN.Println("No static directories found to sync")
|
||||
return
|
||||
}
|
||||
|
||||
syncer := fsync.NewSyncer()
|
||||
syncer.NoTimes = c.Cfg.GetBool("noTimes")
|
||||
syncer.NoChmod = c.Cfg.GetBool("noChmod")
|
||||
syncer.SrcFs = staticSourceFs
|
||||
syncer.DestFs = c.Fs.Destination
|
||||
|
||||
// prevent spamming the log on changes
|
||||
logger := helpers.NewDistinctFeedbackLogger()
|
||||
|
||||
for _, ev := range staticEvents {
|
||||
// Due to our approach of layering both directories and the content's rendered output
|
||||
// into one we can't accurately remove a file not in one of the source directories.
|
||||
// If a file is in the local static dir and also in the theme static dir and we remove
|
||||
// it from one of those locations we expect it to still exist in the destination
|
||||
//
|
||||
// If Hugo generates a file (from the content dir) over a static file
|
||||
// the content generated file should take precedence.
|
||||
//
|
||||
// Because we are now watching and handling individual events it is possible that a static
|
||||
// event that occupies the same path as a content generated file will take precedence
|
||||
// until a regeneration of the content takes places.
|
||||
//
|
||||
// Hugo assumes that these cases are very rare and will permit this bad behavior
|
||||
// The alternative is to track every single file and which pipeline rendered it
|
||||
// and then to handle conflict resolution on every event.
|
||||
|
||||
fromPath := ev.Name
|
||||
|
||||
// If we are here we already know the event took place in a static dir
|
||||
relPath, err := c.PathSpec().MakeStaticPathRelative(fromPath)
|
||||
if err != nil {
|
||||
c.Logger.ERROR.Println(err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Remove || rename is harder and will require an assumption.
|
||||
// Hugo takes the following approach:
|
||||
// If the static file exists in any of the static source directories after this event
|
||||
// Hugo will re-sync it.
|
||||
// If it does not exist in all of the static directories Hugo will remove it.
|
||||
//
|
||||
// This assumes that Hugo has not generated content on top of a static file and then removed
|
||||
// the source of that static file. In this case Hugo will incorrectly remove that file
|
||||
// from the published directory.
|
||||
if ev.Op&fsnotify.Rename == fsnotify.Rename || ev.Op&fsnotify.Remove == fsnotify.Remove {
|
||||
if _, err := staticSourceFs.Stat(relPath); os.IsNotExist(err) {
|
||||
// If file doesn't exist in any static dir, remove it
|
||||
toRemove := filepath.Join(publishDir, relPath)
|
||||
logger.Println("File no longer exists in static dir, removing", toRemove)
|
||||
_ = c.Fs.Destination.RemoveAll(toRemove)
|
||||
} else if err == nil {
|
||||
// If file still exists, sync it
|
||||
logger.Println("Syncing", relPath, "to", publishDir)
|
||||
if err := syncer.Sync(filepath.Join(publishDir, relPath), relPath); err != nil {
|
||||
c.Logger.ERROR.Println(err)
|
||||
}
|
||||
} else {
|
||||
c.Logger.ERROR.Println(err)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// For all other event operations Hugo will sync static.
|
||||
logger.Println("Syncing", relPath, "to", publishDir)
|
||||
if err := syncer.Sync(filepath.Join(publishDir, relPath), relPath); err != nil {
|
||||
c.Logger.ERROR.Println(err)
|
||||
}
|
||||
if err := staticSyncer.syncsStaticEvents(staticEvents); err != nil {
|
||||
c.Logger.ERROR.Println(err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -980,7 +1118,7 @@ func (c *commandeer) newWatcher(port int) error {
|
||||
// force refresh when more than one file
|
||||
if len(staticEvents) > 0 {
|
||||
for _, ev := range staticEvents {
|
||||
path, _ := c.PathSpec().MakeStaticPathRelative(ev.Name)
|
||||
path := staticSyncer.d.MakeStaticPathRelative(ev.Name)
|
||||
livereload.RefreshPath(path)
|
||||
}
|
||||
|
||||
@@ -1001,8 +1139,9 @@ func (c *commandeer) newWatcher(port int) error {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
c.Logger.FEEDBACK.Println("\nChange detected, rebuilding site")
|
||||
const layout = "2006-01-02 15:04 -0700"
|
||||
const layout = "2006-01-02 15:04:05.000 -0700"
|
||||
c.Logger.FEEDBACK.Println(time.Now().Format(layout))
|
||||
|
||||
if err := c.rebuildSites(dynamicEvents); err != nil {
|
||||
@@ -1019,10 +1158,11 @@ func (c *commandeer) newWatcher(port int) error {
|
||||
if onePageName != "" {
|
||||
p = Hugo.GetContentPage(onePageName)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if p != nil {
|
||||
livereload.NavigateToPath(p.RelPermalink())
|
||||
livereload.NavigateToPathForPort(p.RelPermalink(), p.Site.ServerPort())
|
||||
} else {
|
||||
livereload.ForceRefresh()
|
||||
}
|
||||
@@ -1036,14 +1176,8 @@ func (c *commandeer) newWatcher(port int) error {
|
||||
}
|
||||
}()
|
||||
|
||||
if port > 0 {
|
||||
if !c.Cfg.GetBool("disableLiveReload") {
|
||||
livereload.Initialize()
|
||||
http.HandleFunc("/livereload.js", livereload.ServeJS)
|
||||
http.HandleFunc("/livereload", livereload.Handler)
|
||||
}
|
||||
|
||||
go c.serve(port)
|
||||
if serve {
|
||||
go c.serve()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
@@ -1053,6 +1187,9 @@ func (c *commandeer) newWatcher(port int) error {
|
||||
func pickOneWriteOrCreatePath(events []fsnotify.Event) string {
|
||||
name := ""
|
||||
|
||||
// Some editors (for example notepad.exe on Windows) triggers a change
|
||||
// both for directory and file. So we pick the longest path, which should
|
||||
// be the file itself.
|
||||
for _, ev := range events {
|
||||
if (ev.Op&fsnotify.Write == fsnotify.Write || ev.Op&fsnotify.Create == fsnotify.Create) && len(ev.Name) > len(name) {
|
||||
name = ev.Name
|
||||
@@ -1062,10 +1199,6 @@ func pickOneWriteOrCreatePath(events []fsnotify.Event) string {
|
||||
return name
|
||||
}
|
||||
|
||||
func (c *commandeer) isStatic(path string) bool {
|
||||
return strings.HasPrefix(path, c.PathSpec().GetStaticDirPath()) || (len(c.PathSpec().GetThemesDirPath()) > 0 && strings.HasPrefix(path, c.PathSpec().GetThemesDirPath()))
|
||||
}
|
||||
|
||||
// isThemeVsHugoVersionMismatch returns whether the current Hugo version is
|
||||
// less than the theme's min_version.
|
||||
func (c *commandeer) isThemeVsHugoVersionMismatch() (mismatch bool, requiredMinVersion string) {
|
||||
|
||||
@@ -468,7 +468,6 @@ func convertJekyllPost(s *hugolib.Site, path, relPath, targetDir string, draft b
|
||||
return err
|
||||
}
|
||||
|
||||
page.SetDir(targetParentDir)
|
||||
page.SetSourceContent([]byte(content))
|
||||
page.SetSourceMetaData(newmetadata, parser.FormatToLeadRune("yaml"))
|
||||
page.SaveSourceAs(targetFile)
|
||||
|
||||
+18
-30
@@ -43,20 +43,16 @@ var listDraftsCmd = &cobra.Command{
|
||||
Short: "List all drafts",
|
||||
Long: `List all of the drafts in your content directory.`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
cfg, err := InitializeConfig()
|
||||
cfgInit := func(c *commandeer) error {
|
||||
c.Set("buildDrafts", true)
|
||||
return nil
|
||||
}
|
||||
c, err := InitializeConfig(false, cfgInit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Set("buildDrafts", true)
|
||||
|
||||
sites, err := hugolib.NewHugoSites(*cfg)
|
||||
sites, err := hugolib.NewHugoSites(*c.DepsCfg)
|
||||
|
||||
if err != nil {
|
||||
return newSystemError("Error creating sites", err)
|
||||
@@ -84,20 +80,16 @@ var listFutureCmd = &cobra.Command{
|
||||
Long: `List all of the posts in your content directory which will be
|
||||
posted in the future.`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
cfg, err := InitializeConfig()
|
||||
cfgInit := func(c *commandeer) error {
|
||||
c.Set("buildFuture", true)
|
||||
return nil
|
||||
}
|
||||
c, err := InitializeConfig(false, cfgInit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Set("buildFuture", true)
|
||||
|
||||
sites, err := hugolib.NewHugoSites(*cfg)
|
||||
sites, err := hugolib.NewHugoSites(*c.DepsCfg)
|
||||
|
||||
if err != nil {
|
||||
return newSystemError("Error creating sites", err)
|
||||
@@ -125,20 +117,16 @@ var listExpiredCmd = &cobra.Command{
|
||||
Long: `List all of the posts in your content directory which has already
|
||||
expired.`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
cfg, err := InitializeConfig()
|
||||
cfgInit := func(c *commandeer) error {
|
||||
c.Set("buildExpired", true)
|
||||
return nil
|
||||
}
|
||||
c, err := InitializeConfig(false, cfgInit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Set("buildExpired", true)
|
||||
|
||||
sites, err := hugolib.NewHugoSites(*cfg)
|
||||
sites, err := hugolib.NewHugoSites(*c.DepsCfg)
|
||||
|
||||
if err != nil {
|
||||
return newSystemError("Error creating sites", err)
|
||||
|
||||
@@ -33,7 +33,7 @@ func init() {
|
||||
}
|
||||
|
||||
func printConfig(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig(configCmd)
|
||||
cfg, err := InitializeConfig(false, nil, configCmd)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+20
-19
@@ -86,21 +86,19 @@ as you see fit.`,
|
||||
|
||||
// NewContent adds new content to a Hugo site.
|
||||
func NewContent(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig()
|
||||
cfgInit := func(c *commandeer) error {
|
||||
if cmd.Flags().Changed("editor") {
|
||||
c.Set("newContentEditor", contentEditor)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
c, err := InitializeConfig(false, cfgInit)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("editor") {
|
||||
c.Set("newContentEditor", contentEditor)
|
||||
}
|
||||
|
||||
if len(args) < 1 {
|
||||
return newUserError("path needs to be provided")
|
||||
}
|
||||
@@ -115,6 +113,8 @@ func NewContent(cmd *cobra.Command, args []string) error {
|
||||
kind = contentType
|
||||
}
|
||||
|
||||
cfg := c.DepsCfg
|
||||
|
||||
ps, err := helpers.NewPathSpec(cfg.Fs, cfg.Cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -130,7 +130,7 @@ func NewContent(cmd *cobra.Command, args []string) error {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := Hugo.Build(hugolib.BuildCfg{SkipRender: true, PrintStats: false}); err != nil {
|
||||
if err := Hugo.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ func NewSite(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// NewTheme creates a new Hugo theme.
|
||||
func NewTheme(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig()
|
||||
c, err := InitializeConfig(false, nil)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -250,14 +250,11 @@ func NewTheme(cmd *cobra.Command, args []string) error {
|
||||
return newUserError("theme name needs to be provided")
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
createpath := c.PathSpec().AbsPathify(filepath.Join(c.Cfg.GetString("themesDir"), args[0]))
|
||||
jww.INFO.Println("creating theme at", createpath)
|
||||
|
||||
cfg := c.DepsCfg
|
||||
|
||||
if x, _ := helpers.Exists(createpath, cfg.Fs.Source); x {
|
||||
return newUserError(createpath, "already exists")
|
||||
}
|
||||
@@ -347,7 +344,7 @@ description = ""
|
||||
homepage = "http://example.com/"
|
||||
tags = []
|
||||
features = []
|
||||
min_version = "0.30"
|
||||
min_version = "0.32"
|
||||
|
||||
[author]
|
||||
name = ""
|
||||
@@ -375,7 +372,11 @@ func newContentPathSection(path string) (string, string) {
|
||||
var section string
|
||||
// assume the first directory is the section (kind)
|
||||
if strings.Contains(createpath[1:], helpers.FilePathSeparator) {
|
||||
section = helpers.GuessSection(createpath)
|
||||
parts := strings.Split(strings.TrimPrefix(createpath, helpers.FilePathSeparator), helpers.FilePathSeparator)
|
||||
if len(parts) > 0 {
|
||||
section = parts[0]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return createpath, section
|
||||
|
||||
+199
-105
@@ -19,12 +19,16 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gohugoio/hugo/livereload"
|
||||
|
||||
"github.com/gohugoio/hugo/config"
|
||||
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -106,80 +110,94 @@ func init() {
|
||||
}
|
||||
|
||||
func server(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig(serverCmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("disableLiveReload") {
|
||||
c.Set("disableLiveReload", disableLiveReload)
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("navigateToChanged") {
|
||||
c.Set("navigateToChanged", navigateToChanged)
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("disableFastRender") {
|
||||
c.Set("disableFastRender", disableFastRender)
|
||||
}
|
||||
|
||||
if serverWatch {
|
||||
c.Set("watch", true)
|
||||
}
|
||||
|
||||
if c.Cfg.GetBool("watch") {
|
||||
serverWatch = true
|
||||
c.watchConfig()
|
||||
}
|
||||
|
||||
l, err := net.Listen("tcp", net.JoinHostPort(serverInterface, strconv.Itoa(serverPort)))
|
||||
if err == nil {
|
||||
l.Close()
|
||||
} else {
|
||||
if serverCmd.Flags().Changed("port") {
|
||||
// port set explicitly by user -- he/she probably meant it!
|
||||
return newSystemErrorF("Server startup failed: %s", err)
|
||||
}
|
||||
jww.ERROR.Println("port", serverPort, "already in use, attempting to use an available port")
|
||||
sp, err := helpers.FindAvailablePort()
|
||||
if err != nil {
|
||||
return newSystemError("Unable to find alternative port to use:", err)
|
||||
}
|
||||
serverPort = sp.Port
|
||||
}
|
||||
|
||||
c.Set("port", serverPort)
|
||||
if liveReloadPort != -1 {
|
||||
c.Set("liveReloadPort", liveReloadPort)
|
||||
} else {
|
||||
c.Set("liveReloadPort", serverPort)
|
||||
}
|
||||
|
||||
baseURL, err = fixURL(c.Cfg, baseURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Set("baseURL", baseURL)
|
||||
|
||||
if err := memStats(); err != nil {
|
||||
jww.ERROR.Println("memstats error:", err)
|
||||
}
|
||||
|
||||
// If a Destination is provided via flag write to disk
|
||||
if destination != "" {
|
||||
renderToDisk = true
|
||||
}
|
||||
|
||||
// Hugo writes the output to memory instead of the disk
|
||||
if !renderToDisk {
|
||||
cfg.Fs.Destination = new(afero.MemMapFs)
|
||||
// Rendering to memoryFS, publish to Root regardless of publishDir.
|
||||
c.Set("publishDir", "/")
|
||||
cfgInit := func(c *commandeer) error {
|
||||
c.Set("renderToMemory", !renderToDisk)
|
||||
if cmd.Flags().Changed("navigateToChanged") {
|
||||
c.Set("navigateToChanged", navigateToChanged)
|
||||
}
|
||||
if cmd.Flags().Changed("disableLiveReload") {
|
||||
c.Set("disableLiveReload", disableLiveReload)
|
||||
}
|
||||
if cmd.Flags().Changed("disableFastRender") {
|
||||
c.Set("disableFastRender", disableFastRender)
|
||||
}
|
||||
if serverWatch {
|
||||
c.Set("watch", true)
|
||||
}
|
||||
|
||||
serverPorts := make([]int, 1)
|
||||
|
||||
if c.languages.IsMultihost() {
|
||||
if !serverAppend {
|
||||
return newSystemError("--appendPort=false not supported when in multihost mode")
|
||||
}
|
||||
serverPorts = make([]int, len(c.languages))
|
||||
}
|
||||
|
||||
currentServerPort := serverPort
|
||||
|
||||
for i := 0; i < len(serverPorts); i++ {
|
||||
l, err := net.Listen("tcp", net.JoinHostPort(serverInterface, strconv.Itoa(currentServerPort)))
|
||||
if err == nil {
|
||||
l.Close()
|
||||
serverPorts[i] = currentServerPort
|
||||
} else {
|
||||
if i == 0 && serverCmd.Flags().Changed("port") {
|
||||
// port set explicitly by user -- he/she probably meant it!
|
||||
return newSystemErrorF("Server startup failed: %s", err)
|
||||
}
|
||||
jww.ERROR.Println("port", serverPort, "already in use, attempting to use an available port")
|
||||
sp, err := helpers.FindAvailablePort()
|
||||
if err != nil {
|
||||
return newSystemError("Unable to find alternative port to use:", err)
|
||||
}
|
||||
serverPorts[i] = sp.Port
|
||||
}
|
||||
|
||||
currentServerPort = serverPorts[i] + 1
|
||||
}
|
||||
|
||||
c.serverPorts = serverPorts
|
||||
|
||||
c.Set("port", serverPort)
|
||||
if liveReloadPort != -1 {
|
||||
c.Set("liveReloadPort", liveReloadPort)
|
||||
} else {
|
||||
c.Set("liveReloadPort", serverPorts[0])
|
||||
}
|
||||
|
||||
if c.languages.IsMultihost() {
|
||||
for i, language := range c.languages {
|
||||
baseURL, err := fixURL(language, baseURL, serverPorts[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
language.Set("baseURL", baseURL)
|
||||
}
|
||||
} else {
|
||||
baseURL, err := fixURL(c.Cfg, baseURL, serverPorts[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Set("baseURL", baseURL)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
if err := memStats(); err != nil {
|
||||
jww.ERROR.Println("memstats error:", err)
|
||||
}
|
||||
|
||||
c, err := InitializeConfig(true, cfgInit, serverCmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.build(serverWatch); err != nil {
|
||||
@@ -190,46 +208,80 @@ func server(cmd *cobra.Command, args []string) error {
|
||||
s.RegisterMediaTypes()
|
||||
}
|
||||
|
||||
if serverWatch {
|
||||
c.watchConfig()
|
||||
}
|
||||
|
||||
// Watch runs its own server as part of the routine
|
||||
if serverWatch {
|
||||
watchDirs := c.getDirList()
|
||||
baseWatchDir := c.Cfg.GetString("workingDir")
|
||||
for i, dir := range watchDirs {
|
||||
watchDirs[i], _ = helpers.GetRelativePath(dir, baseWatchDir)
|
||||
|
||||
watchDirs, err := c.getDirList()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rootWatchDirs := strings.Join(helpers.UniqueStrings(helpers.ExtractRootPaths(watchDirs)), ",")
|
||||
baseWatchDir := c.Cfg.GetString("workingDir")
|
||||
relWatchDirs := make([]string, len(watchDirs))
|
||||
for i, dir := range watchDirs {
|
||||
relWatchDirs[i], _ = helpers.GetRelativePath(dir, baseWatchDir)
|
||||
}
|
||||
|
||||
rootWatchDirs := strings.Join(helpers.UniqueStrings(helpers.ExtractRootPaths(relWatchDirs)), ",")
|
||||
|
||||
jww.FEEDBACK.Printf("Watching for changes in %s%s{%s}\n", baseWatchDir, helpers.FilePathSeparator, rootWatchDirs)
|
||||
err := c.newWatcher(serverPort)
|
||||
err = c.newWatcher(true, watchDirs...)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
c.serve(serverPort)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *commandeer) serve(port int) {
|
||||
if renderToDisk {
|
||||
jww.FEEDBACK.Println("Serving pages from " + c.PathSpec().AbsPathify(c.Cfg.GetString("publishDir")))
|
||||
} else {
|
||||
jww.FEEDBACK.Println("Serving pages from memory")
|
||||
type fileServer struct {
|
||||
baseURLs []string
|
||||
roots []string
|
||||
c *commandeer
|
||||
}
|
||||
|
||||
func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, error) {
|
||||
baseURL := f.baseURLs[i]
|
||||
root := f.roots[i]
|
||||
port := f.c.serverPorts[i]
|
||||
|
||||
publishDir := f.c.Cfg.GetString("publishDir")
|
||||
|
||||
if root != "" {
|
||||
publishDir = filepath.Join(publishDir, root)
|
||||
}
|
||||
|
||||
httpFs := afero.NewHttpFs(c.Fs.Destination)
|
||||
fs := filesOnlyFs{httpFs.Dir(c.PathSpec().AbsPathify(c.Cfg.GetString("publishDir")))}
|
||||
absPublishDir := f.c.PathSpec().AbsPathify(publishDir)
|
||||
|
||||
doLiveReload := !buildWatch && !c.Cfg.GetBool("disableLiveReload")
|
||||
fastRenderMode := doLiveReload && !c.Cfg.GetBool("disableFastRender")
|
||||
if i == 0 {
|
||||
if renderToDisk {
|
||||
jww.FEEDBACK.Println("Serving pages from " + absPublishDir)
|
||||
} else {
|
||||
jww.FEEDBACK.Println("Serving pages from memory")
|
||||
}
|
||||
}
|
||||
|
||||
if fastRenderMode {
|
||||
httpFs := afero.NewHttpFs(f.c.Fs.Destination)
|
||||
fs := filesOnlyFs{httpFs.Dir(absPublishDir)}
|
||||
|
||||
doLiveReload := !buildWatch && !f.c.Cfg.GetBool("disableLiveReload")
|
||||
fastRenderMode := doLiveReload && !f.c.Cfg.GetBool("disableFastRender")
|
||||
|
||||
if i == 0 && fastRenderMode {
|
||||
jww.FEEDBACK.Println("Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender")
|
||||
}
|
||||
|
||||
// We're only interested in the path
|
||||
u, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return nil, "", "", fmt.Errorf("Invalid baseURL: %s", err)
|
||||
}
|
||||
|
||||
decorate := func(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if noHTTPCache {
|
||||
@@ -238,9 +290,9 @@ func (c *commandeer) serve(port int) {
|
||||
}
|
||||
|
||||
if fastRenderMode {
|
||||
p := r.URL.Path
|
||||
p := r.RequestURI
|
||||
if strings.HasSuffix(p, "/") || strings.HasSuffix(p, "html") || strings.HasSuffix(p, "htm") {
|
||||
c.visitedURLs.Add(p)
|
||||
f.c.visitedURLs.Add(p)
|
||||
}
|
||||
}
|
||||
h.ServeHTTP(w, r)
|
||||
@@ -248,32 +300,74 @@ func (c *commandeer) serve(port int) {
|
||||
}
|
||||
|
||||
fileserver := decorate(http.FileServer(fs))
|
||||
mu := http.NewServeMux()
|
||||
|
||||
// We're only interested in the path
|
||||
u, err := url.Parse(c.Cfg.GetString("baseURL"))
|
||||
if err != nil {
|
||||
jww.ERROR.Fatalf("Invalid baseURL: %s", err)
|
||||
}
|
||||
if u.Path == "" || u.Path == "/" {
|
||||
http.Handle("/", fileserver)
|
||||
mu.Handle("/", fileserver)
|
||||
} else {
|
||||
http.Handle(u.Path, http.StripPrefix(u.Path, fileserver))
|
||||
mu.Handle(u.Path, http.StripPrefix(u.Path, fileserver))
|
||||
}
|
||||
|
||||
jww.FEEDBACK.Printf("Web Server is available at %s (bind address %s)\n", u.String(), serverInterface)
|
||||
jww.FEEDBACK.Println("Press Ctrl+C to stop")
|
||||
|
||||
endpoint := net.JoinHostPort(serverInterface, strconv.Itoa(port))
|
||||
err = http.ListenAndServe(endpoint, nil)
|
||||
if err != nil {
|
||||
jww.ERROR.Printf("Error: %s\n", err.Error())
|
||||
os.Exit(1)
|
||||
|
||||
return mu, u.String(), endpoint, nil
|
||||
}
|
||||
|
||||
func (c *commandeer) serve() {
|
||||
|
||||
isMultiHost := Hugo.IsMultihost()
|
||||
|
||||
var (
|
||||
baseURLs []string
|
||||
roots []string
|
||||
)
|
||||
|
||||
if isMultiHost {
|
||||
for _, s := range Hugo.Sites {
|
||||
baseURLs = append(baseURLs, s.BaseURL.String())
|
||||
roots = append(roots, s.Language.Lang)
|
||||
}
|
||||
} else {
|
||||
s := Hugo.Sites[0]
|
||||
baseURLs = []string{s.BaseURL.String()}
|
||||
roots = []string{""}
|
||||
}
|
||||
|
||||
srv := &fileServer{
|
||||
baseURLs: baseURLs,
|
||||
roots: roots,
|
||||
c: c,
|
||||
}
|
||||
|
||||
doLiveReload := !c.Cfg.GetBool("disableLiveReload")
|
||||
|
||||
if doLiveReload {
|
||||
livereload.Initialize()
|
||||
}
|
||||
|
||||
for i, _ := range baseURLs {
|
||||
mu, serverURL, endpoint, err := srv.createEndpoint(i)
|
||||
|
||||
if doLiveReload {
|
||||
mu.HandleFunc("/livereload.js", livereload.ServeJS)
|
||||
mu.HandleFunc("/livereload", livereload.Handler)
|
||||
}
|
||||
jww.FEEDBACK.Printf("Web Server is available at %s (bind address %s)\n", serverURL, serverInterface)
|
||||
go func() {
|
||||
err = http.ListenAndServe(endpoint, mu)
|
||||
if err != nil {
|
||||
jww.ERROR.Printf("Error: %s\n", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
jww.FEEDBACK.Println("Press Ctrl+C to stop")
|
||||
}
|
||||
|
||||
// fixURL massages the baseURL into a form needed for serving
|
||||
// all pages correctly.
|
||||
func fixURL(cfg config.Provider, s string) (string, error) {
|
||||
func fixURL(cfg config.Provider, s string, port int) (string, error) {
|
||||
useLocalhost := false
|
||||
if s == "" {
|
||||
s = cfg.GetString("baseURL")
|
||||
@@ -315,7 +409,7 @@ func fixURL(cfg config.Provider, s string) (string, error) {
|
||||
return "", fmt.Errorf("Failed to split baseURL hostpost: %s", err)
|
||||
}
|
||||
}
|
||||
u.Host += fmt.Sprintf(":%d", serverPort)
|
||||
u.Host += fmt.Sprintf(":%d", port)
|
||||
}
|
||||
|
||||
return u.String(), nil
|
||||
|
||||
@@ -47,7 +47,7 @@ func TestFixURL(t *testing.T) {
|
||||
v.Set("baseURL", test.CfgBaseURL)
|
||||
serverAppend = test.AppendPort
|
||||
serverPort = test.Port
|
||||
result, err := fixURL(v, baseURL)
|
||||
result, err := fixURL(v, baseURL, serverPort)
|
||||
if err != nil {
|
||||
t.Errorf("Test #%d %s: unexpected error %s", i, test.TestName, err)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
// Copyright 2017 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
src "github.com/gohugoio/hugo/source"
|
||||
"github.com/spf13/fsync"
|
||||
)
|
||||
|
||||
type staticSyncer struct {
|
||||
c *commandeer
|
||||
d *src.Dirs
|
||||
}
|
||||
|
||||
func newStaticSyncer(c *commandeer) (*staticSyncer, error) {
|
||||
dirs, err := src.NewDirs(c.Fs, c.Cfg, c.DepsCfg.Logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &staticSyncer{c: c, d: dirs}, nil
|
||||
}
|
||||
|
||||
func (s *staticSyncer) isStatic(path string) bool {
|
||||
return s.d.IsStatic(path)
|
||||
}
|
||||
|
||||
func (s *staticSyncer) syncsStaticEvents(staticEvents []fsnotify.Event) error {
|
||||
c := s.c
|
||||
|
||||
syncFn := func(dirs *src.Dirs, publishDir string) (uint64, error) {
|
||||
staticSourceFs, err := dirs.CreateStaticFs()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if dirs.Language != nil {
|
||||
// Multihost setup
|
||||
publishDir = filepath.Join(publishDir, dirs.Language.Lang)
|
||||
}
|
||||
|
||||
if staticSourceFs == nil {
|
||||
c.Logger.WARN.Println("No static directories found to sync")
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
syncer := fsync.NewSyncer()
|
||||
syncer.NoTimes = c.Cfg.GetBool("noTimes")
|
||||
syncer.NoChmod = c.Cfg.GetBool("noChmod")
|
||||
syncer.SrcFs = staticSourceFs
|
||||
syncer.DestFs = c.Fs.Destination
|
||||
|
||||
// prevent spamming the log on changes
|
||||
logger := helpers.NewDistinctFeedbackLogger()
|
||||
|
||||
for _, ev := range staticEvents {
|
||||
// Due to our approach of layering both directories and the content's rendered output
|
||||
// into one we can't accurately remove a file not in one of the source directories.
|
||||
// If a file is in the local static dir and also in the theme static dir and we remove
|
||||
// it from one of those locations we expect it to still exist in the destination
|
||||
//
|
||||
// If Hugo generates a file (from the content dir) over a static file
|
||||
// the content generated file should take precedence.
|
||||
//
|
||||
// Because we are now watching and handling individual events it is possible that a static
|
||||
// event that occupies the same path as a content generated file will take precedence
|
||||
// until a regeneration of the content takes places.
|
||||
//
|
||||
// Hugo assumes that these cases are very rare and will permit this bad behavior
|
||||
// The alternative is to track every single file and which pipeline rendered it
|
||||
// and then to handle conflict resolution on every event.
|
||||
|
||||
fromPath := ev.Name
|
||||
|
||||
// If we are here we already know the event took place in a static dir
|
||||
relPath := dirs.MakeStaticPathRelative(fromPath)
|
||||
if relPath == "" {
|
||||
// Not member of this virtual host.
|
||||
continue
|
||||
}
|
||||
|
||||
// Remove || rename is harder and will require an assumption.
|
||||
// Hugo takes the following approach:
|
||||
// If the static file exists in any of the static source directories after this event
|
||||
// Hugo will re-sync it.
|
||||
// If it does not exist in all of the static directories Hugo will remove it.
|
||||
//
|
||||
// This assumes that Hugo has not generated content on top of a static file and then removed
|
||||
// the source of that static file. In this case Hugo will incorrectly remove that file
|
||||
// from the published directory.
|
||||
if ev.Op&fsnotify.Rename == fsnotify.Rename || ev.Op&fsnotify.Remove == fsnotify.Remove {
|
||||
if _, err := staticSourceFs.Stat(relPath); os.IsNotExist(err) {
|
||||
// If file doesn't exist in any static dir, remove it
|
||||
toRemove := filepath.Join(publishDir, relPath)
|
||||
|
||||
logger.Println("File no longer exists in static dir, removing", toRemove)
|
||||
_ = c.Fs.Destination.RemoveAll(toRemove)
|
||||
} else if err == nil {
|
||||
// If file still exists, sync it
|
||||
logger.Println("Syncing", relPath, "to", publishDir)
|
||||
|
||||
if err := syncer.Sync(filepath.Join(publishDir, relPath), relPath); err != nil {
|
||||
c.Logger.ERROR.Println(err)
|
||||
}
|
||||
} else {
|
||||
c.Logger.ERROR.Println(err)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// For all other event operations Hugo will sync static.
|
||||
logger.Println("Syncing", relPath, "to", publishDir)
|
||||
if err := syncer.Sync(filepath.Join(publishDir, relPath), relPath); err != nil {
|
||||
c.Logger.ERROR.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
_, err := c.doWithPublishDirs(syncFn)
|
||||
return err
|
||||
|
||||
}
|
||||
+3
-1
@@ -36,7 +36,7 @@ If the content's draft status is 'False', nothing is done.`,
|
||||
// to false and setting its publish date to now. If the specified content is
|
||||
// not a draft, it will log an error.
|
||||
func Undraft(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig()
|
||||
c, err := InitializeConfig(false, nil)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -46,6 +46,8 @@ func Undraft(cmd *cobra.Command, args []string) error {
|
||||
return newUserError("a piece of content needs to be specified")
|
||||
}
|
||||
|
||||
cfg := c.DepsCfg
|
||||
|
||||
location := args[0]
|
||||
// open the file
|
||||
f, err := cfg.Fs.Source.Open(location)
|
||||
|
||||
@@ -45,7 +45,7 @@ type ArchetypeFileData struct {
|
||||
|
||||
// The target content file. Note that the .Content will be empty, as that
|
||||
// has not been created yet.
|
||||
*source.File
|
||||
source.File
|
||||
}
|
||||
|
||||
const (
|
||||
@@ -82,7 +82,7 @@ func executeArcheTypeAsTemplate(s *hugolib.Site, kind, targetPath, archetypeFile
|
||||
)
|
||||
|
||||
sp := source.NewSourceSpec(s.Deps.Cfg, s.Deps.Fs)
|
||||
f := sp.NewFile(targetPath)
|
||||
f := sp.NewFileInfo("", targetPath, nil)
|
||||
|
||||
data := ArchetypeFileData{
|
||||
Type: kind,
|
||||
|
||||
Vendored
+10
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/gohugoio/hugo/hugofs"
|
||||
"github.com/gohugoio/hugo/metrics"
|
||||
"github.com/gohugoio/hugo/output"
|
||||
"github.com/gohugoio/hugo/source"
|
||||
"github.com/gohugoio/hugo/tpl"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
@@ -33,6 +34,9 @@ type Deps struct {
|
||||
// The ContentSpec to use
|
||||
*helpers.ContentSpec `json:"-"`
|
||||
|
||||
// The SourceSpec to use
|
||||
SourceSpec *source.SourceSpec `json:"-"`
|
||||
|
||||
// The configuration to use
|
||||
Cfg config.Provider `json:"-"`
|
||||
|
||||
@@ -122,6 +126,8 @@ func New(cfg DepsCfg) (*Deps, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sp := source.NewSourceSpec(cfg.Language, fs)
|
||||
|
||||
d := &Deps{
|
||||
Fs: fs,
|
||||
Log: logger,
|
||||
@@ -130,6 +136,7 @@ func New(cfg DepsCfg) (*Deps, error) {
|
||||
WithTemplate: cfg.WithTemplate,
|
||||
PathSpec: ps,
|
||||
ContentSpec: contentSpec,
|
||||
SourceSpec: sp,
|
||||
Cfg: cfg.Language,
|
||||
Language: cfg.Language,
|
||||
}
|
||||
@@ -194,4 +201,7 @@ type DepsCfg struct {
|
||||
|
||||
// i18n handling.
|
||||
TranslationProvider ResourceProvider
|
||||
|
||||
// Whether we are in running (server) mode
|
||||
Running bool
|
||||
}
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@ twitter = "GoHugoIO"
|
||||
[params]
|
||||
description = "The world’s fastest framework for building websites"
|
||||
## Used for views in rendered HTML (i.e., rather than using the .Hugo variable)
|
||||
release = "0.30"
|
||||
release = "0.32"
|
||||
## Setting this to true will add a "noindex" to *EVERY* page on the site
|
||||
removefromexternalsearch = false
|
||||
## Gh repo for site footer (include trailing slash)
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
---
|
||||
title: Hugo 0.32 HOWTO
|
||||
description: About page bundles, image processing and more.
|
||||
date: 2017-12-28
|
||||
keywords: [ssg,static,performance,security]
|
||||
menu:
|
||||
docs:
|
||||
parent: "about"
|
||||
weight: 10
|
||||
weight: 10
|
||||
sections_weight: 10
|
||||
draft: false
|
||||
aliases: []
|
||||
toc: true
|
||||
---
|
||||
|
||||
|
||||
{{% note %}}
|
||||
This documentation belongs in other places in this documentation site, but is put here first ... to get something up and running fast.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
Also see this demo project from [bep](https://github.com/bep/), the clever Norwegian behind these new features:
|
||||
|
||||
* http://hugotest.bep.is/
|
||||
* https://github.com/bep/hugotest (source)
|
||||
|
||||
## Page Resources
|
||||
|
||||
### Organize Your Content
|
||||
|
||||
{{< figure src="/images/hugo-content-bundles.png" title="Pages with image resources" >}}
|
||||
|
||||
The content folder above shows a mix of content pages (`md` (i.e. markdown) files) and image resources.
|
||||
|
||||
{{% note %}}
|
||||
You can use any file type as a content resource as long as it is a MIME type recognized by Hugo (`json` files will, as one example, work fine). If you want to get exotic, you can define your [own media type](/templates/output-formats/#media-types).
|
||||
{{% /note %}}
|
||||
|
||||
The 3 page bundles marked in red explained from top to bottom:
|
||||
|
||||
1. The home page with one image resource (`1-logo.png`)
|
||||
2. The blog section with two images resources and two pages resources (`content1.md`, `content2.md`). Note that the `_index.md` represents the URL for this section.
|
||||
3. An article (`hugo-is-cool`) with a folder with some images and one content resource (`cats-info.md`). Note that the `index.md` represents the URL for this article.
|
||||
|
||||
The content files below `blog/posts` are just regular standalone pages.
|
||||
|
||||
{{% note %}}
|
||||
Note that changes to any resource inside the `content` folder will trigger a reload when running in watch (aka server or live reload mode), it will even work with `--navigateToChanged`.
|
||||
{{% /note %}}
|
||||
|
||||
#### Sort Order
|
||||
|
||||
* Pages are sorted according to standard Hugo page sorting rules.
|
||||
* Images and other resources are sorted in lexicographical order.
|
||||
|
||||
### Handle Page Resources in Templates
|
||||
|
||||
|
||||
#### List all Resources
|
||||
|
||||
```html
|
||||
{{ range .Resources }}
|
||||
<li><a href="{{ .RelPermalink }}">{{ .ResourceType | title }}</a></li>
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
For an absolute URL, use `.Permalink`.
|
||||
|
||||
**Note:** The permalink will be relative to the content page, respecting permalink settings. Also, included page resources will not have a value for `RelPermalink`.
|
||||
|
||||
#### List All Resources by Type
|
||||
|
||||
```html
|
||||
{{ with .Resources.ByType "image" }}
|
||||
{{ end }}
|
||||
|
||||
```
|
||||
|
||||
Type here is `page` for pages, else the main type in the MIME type, so `image`, `json` etc.
|
||||
|
||||
#### Get a Specific Resource
|
||||
|
||||
```html
|
||||
{{ $logo := .Resources.GetByPrefix "logo" }}
|
||||
{{ with $logo }}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
#### Include Page Resource Content
|
||||
|
||||
```html
|
||||
{{ with .Resources.ByType "page" }}
|
||||
{{ range . }}
|
||||
<h3>{{ .Title }}</h3>
|
||||
{{ .Content }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Image Processing
|
||||
|
||||
The `image` resource implements the methods `Resize`, `Fit` and `Fill`:
|
||||
|
||||
Resize
|
||||
: Resize to the given dimension, `{{ $logo.Resize "200x" }}` will resize to 200 pixels wide and preserve the aspect ratio. Use `{{ $logo.Resize "200x100" }}` to control both height and width.
|
||||
|
||||
Fit
|
||||
: Scale down the image to fit the given dimensions, e.g. `{{ $logo.Fit "200x100" }}` will fit the image inside a box that is 200 pixels wide and 100 pixels high.
|
||||
|
||||
Fill
|
||||
: Resize and crop the image given dimensions, e.g. `{{ $logo.Fill "200x100" }}` will resize and crop to width 200 and height 100
|
||||
|
||||
|
||||
{{% note %}}
|
||||
Image operations in Hugo currently **do not preserve EXIF data** as this is not supported by Go's [image package](https://github.com/golang/go/search?q=exif&type=Issues&utf8=%E2%9C%93). This will be improved on in the future.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
### Image Processing Options
|
||||
|
||||
In addition to the dimensions (e.g. `200x100`) where either height or width can be omitted, Hugo supports a set of additional image options:
|
||||
|
||||
Anchor
|
||||
: Only relevant for `Fill`. This is useful for thumbnail generation where the main motive is located in, say, the left corner. Valid are `Center`, `TopLeft`, `Top`, `TopRight`, `Left`, `Right`, `BottomLeft`, `Bottom`, `BottomRight`. Example: `{{ $logo.Fill "200x100 BottomLeft" }}`
|
||||
|
||||
JPEG Quality
|
||||
: Only relevant for JPEG images, values 1 to 100 inclusive, higher is better. Default is 75. `{{ $logo.Resize "200x q50" }}`
|
||||
|
||||
Rotate
|
||||
: Rotates an image by the given angle counter-clockwise. The rotation will be performed first to get the dimensions correct. `{{ $logo.Resize "200x r90" }}`. The main use of this is to be able to manually correct for [EXIF orientation](https://github.com/golang/go/issues/4341) of JPEG images.
|
||||
|
||||
Resample Filter
|
||||
: Filter used in resizing. Default is `Box`, a simple and fast resampling filter appropriate for downscaling. See https://github.com/disintegration/imaging for more. If you want to trade quality for faster processing, this may be a option to test.
|
||||
|
||||
|
||||
|
||||
### Performance
|
||||
|
||||
Processed images are stored below `<project-dir>/resources` (can be set with `resourceDir` config setting). This folder is deliberately placed in the project, as it is recommended to check these into source control as part of the project. These images are not "Hugo fast" to generate, but once generated they can be reused.
|
||||
|
||||
If you change your image settings (e.g. size), remove or rename images etc., you will end up with unused images taking up space and cluttering your project.
|
||||
|
||||
To clean up, run:
|
||||
|
||||
```bash
|
||||
hugo --gc
|
||||
```
|
||||
|
||||
|
||||
{{% note %}}
|
||||
**GC** is short for **Garbage Collection**.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
### Default Image Processing Config
|
||||
|
||||
You can configure an `imaging` section in `config.toml` with default image processing options:
|
||||
|
||||
```toml
|
||||
[imaging]
|
||||
# Default resample filter used for resizing. Default is Box,
|
||||
# a simple and fast averaging filter appropriate for downscaling.
|
||||
# See https://github.com/disintegration/imaging
|
||||
resampleFilter = "box"
|
||||
|
||||
# Defatult JPEG quality setting. Default is 75.
|
||||
quality = 68
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
title: Roadmap
|
||||
linktitle: Roadmap
|
||||
description: Take a look at what's in the pipeline for future versions of the Hugo project.
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
lastmod: 2017-02-01
|
||||
categories: [about hugo]
|
||||
keywords: [about,contribute,roadmap]
|
||||
menu:
|
||||
docs:
|
||||
parent: "about"
|
||||
weight: 50
|
||||
weight: 50
|
||||
sections_weight: 50
|
||||
draft: false
|
||||
aliases: [/meta/roadmap]
|
||||
toc: false
|
||||
---
|
||||
|
||||
To track Hugo's progress, see our [GitHub Milestones][milestones].
|
||||
|
||||
In no particular order, here are some other features currently being worked on:
|
||||
|
||||
* Even easier deployment to S3, SSH, GitHub, rsync. Give the [hosting and deployment][] section a shot.
|
||||
* Import from other website systems. There are already [existing migration tools][migrate], but they don’t cover all major platforms.
|
||||
* An interactive web-based editor (See the [related forum thread][])
|
||||
* Additional [themes][], which are always ongoing and [contributions are welcome][themescontrib]!
|
||||
* Dynamic image resizing via shortcodes ({{< gh 1014 >}})
|
||||
* Native support for additional content formats (AsciiDoc {{< gh 1435>}}, reST {{< gh 1436 >}})
|
||||
* And, last but not least, [***your*** best ideas!][]
|
||||
|
||||
## Contributions Welcome
|
||||
|
||||
Feel free to [contribute to Hugo's development][devcontribute], [improve Hugo's documentation][doccontribute], or [open a new issue][newissue] if you have an idea for a new feature.
|
||||
|
||||
[#98]: https://github.com/gohugoio/hugo/issues/98
|
||||
[#1014]: https://github.com/gohugoio/hugo/issues/1014
|
||||
[#1435]: https://github.com/gohugoio/hugo/issues/1435
|
||||
[#1436]: https://github.com/gohugoio/hugo/issues/1436
|
||||
[devcontribute]: /contribute/development/
|
||||
[doccontribute]: /contribute/documentation/
|
||||
[hosting and deployment]: /hosting-and-deployment/
|
||||
[migrate]: /tools/migrations/
|
||||
[milestones]: https://github.com/gohugoio/hugo/milestones/
|
||||
[newissue]: https://github.com/gohugoio/hugo/issues/
|
||||
[related forum thread]: https://discourse.gohugo.io/t/web-based-editor/155
|
||||
[themes]: /themes/
|
||||
[themescontrib]: /contribute/themes/
|
||||
[tutorials]: /tutorials
|
||||
[***your*** best ideas!]: /contribute/
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo"
|
||||
slug: hugo
|
||||
url: /commands/hugo/
|
||||
@@ -25,45 +25,46 @@ hugo [flags]
|
||||
### Options
|
||||
|
||||
```
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. http://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. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir remove files from destination not found in static directories
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
--debug debug output
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 do not render 404 page
|
||||
--disableKinds strings disable different kind of pages (home, RSS etc.)
|
||||
--disableRSS do not build RSS files
|
||||
--disableSitemap do not build Sitemap file
|
||||
--enableGitInfo add Git revision, date and author info to the pages
|
||||
--forceSyncStatic copy all files when static is changed.
|
||||
-h, --help help for hugo
|
||||
--i18n-warnings print missing translations
|
||||
--ignoreCache ignores the cache directory
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--noChmod don't sync permission mode of files
|
||||
--noTimes don't sync modification time of files
|
||||
--pluralizeListTitles pluralize titles in lists using inflect (default true)
|
||||
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--quiet build in quiet mode
|
||||
--renderToMemory render to memory (only useful for benchmark testing)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
--templateMetrics display metrics about template executions
|
||||
--templateMetricsHints calculate some improvement hints when combined with --templateMetrics
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--themesDir string filesystem path to themes directory
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
-w, --watch watch filesystem for changes and recreate as needed
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. http://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. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir remove files from destination not found in static directories
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
--debug debug output
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 do not render 404 page
|
||||
--disableKinds stringSlice disable different kind of pages (home, RSS etc.)
|
||||
--disableRSS do not build RSS files
|
||||
--disableSitemap do not build Sitemap file
|
||||
--enableGitInfo add Git revision, date and author info to the pages
|
||||
--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 hugo
|
||||
--i18n-warnings print missing translations
|
||||
--ignoreCache ignores the cache directory
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--noChmod don't sync permission mode of files
|
||||
--noTimes don't sync modification time of files
|
||||
--pluralizeListTitles pluralize titles in lists using inflect (default true)
|
||||
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--quiet build in quiet mode
|
||||
--renderToMemory render to memory (only useful for benchmark testing)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
--templateMetrics display metrics about template executions
|
||||
--templateMetricsHints calculate some improvement hints when combined with --templateMetrics
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--themesDir string filesystem path to themes directory
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
-w, --watch watch filesystem for changes and recreate as needed
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
@@ -80,4 +81,4 @@ hugo [flags]
|
||||
* [hugo undraft](/commands/hugo_undraft/) - Undraft resets the content's draft status
|
||||
* [hugo version](/commands/hugo_version/) - Print the version number of Hugo
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo benchmark"
|
||||
slug: hugo_benchmark
|
||||
url: /commands/hugo_benchmark/
|
||||
@@ -21,40 +21,41 @@ hugo benchmark [flags]
|
||||
### Options
|
||||
|
||||
```
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. http://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. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir remove files from destination not found in static directories
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
-n, --count int number of times to build the site (default 13)
|
||||
--cpuprofile string path/filename for the CPU profile file
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 do not render 404 page
|
||||
--disableKinds strings disable different kind of pages (home, RSS etc.)
|
||||
--disableRSS do not build RSS files
|
||||
--disableSitemap do not build Sitemap file
|
||||
--enableGitInfo add Git revision, date and author info to the pages
|
||||
--forceSyncStatic copy all files when static is changed.
|
||||
-h, --help help for benchmark
|
||||
--i18n-warnings print missing translations
|
||||
--ignoreCache ignores the cache directory
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--memprofile string path/filename for the memory profile file
|
||||
--noChmod don't sync permission mode of files
|
||||
--noTimes don't sync modification time of files
|
||||
--pluralizeListTitles pluralize titles in lists using inflect (default true)
|
||||
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--renderToMemory render to memory (only useful for benchmark testing)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
--templateMetrics display metrics about template executions
|
||||
--templateMetricsHints calculate some improvement hints when combined with --templateMetrics
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--themesDir string filesystem path to themes directory
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. http://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. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir remove files from destination not found in static directories
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
-n, --count int number of times to build the site (default 13)
|
||||
--cpuprofile string path/filename for the CPU profile file
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 do not render 404 page
|
||||
--disableKinds stringSlice disable different kind of pages (home, RSS etc.)
|
||||
--disableRSS do not build RSS files
|
||||
--disableSitemap do not build Sitemap file
|
||||
--enableGitInfo add Git revision, date and author info to the pages
|
||||
--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 benchmark
|
||||
--i18n-warnings print missing translations
|
||||
--ignoreCache ignores the cache directory
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--memprofile string path/filename for the memory profile file
|
||||
--noChmod don't sync permission mode of files
|
||||
--noTimes don't sync modification time of files
|
||||
--pluralizeListTitles pluralize titles in lists using inflect (default true)
|
||||
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--renderToMemory render to memory (only useful for benchmark testing)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
--templateMetrics display metrics about template executions
|
||||
--templateMetricsHints calculate some improvement hints when combined with --templateMetrics
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--themesDir string filesystem path to themes directory
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
@@ -72,4 +73,4 @@ hugo benchmark [flags]
|
||||
### SEE ALSO
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo check"
|
||||
slug: hugo_check
|
||||
url: /commands/hugo_check/
|
||||
@@ -35,4 +35,4 @@ Contains some verification checks
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo check ulimit](/commands/hugo_check_ulimit/) - Check system ulimit settings
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo check ulimit"
|
||||
slug: hugo_check_ulimit
|
||||
url: /commands/hugo_check_ulimit/
|
||||
@@ -39,4 +39,4 @@ hugo check ulimit [flags]
|
||||
### SEE ALSO
|
||||
* [hugo check](/commands/hugo_check/) - Contains some verification checks
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo config"
|
||||
slug: hugo_config
|
||||
url: /commands/hugo_config/
|
||||
@@ -38,4 +38,4 @@ hugo config [flags]
|
||||
### SEE ALSO
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo convert"
|
||||
slug: hugo_convert
|
||||
url: /commands/hugo_convert/
|
||||
@@ -42,4 +42,4 @@ See convert's subcommands toJSON, toTOML and toYAML for more information.
|
||||
* [hugo convert toTOML](/commands/hugo_convert_totoml/) - Convert front matter to TOML
|
||||
* [hugo convert toYAML](/commands/hugo_convert_toyaml/) - Convert front matter to YAML
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo convert toJSON"
|
||||
slug: hugo_convert_toJSON
|
||||
url: /commands/hugo_convert_tojson/
|
||||
@@ -42,4 +42,4 @@ hugo convert toJSON [flags]
|
||||
### SEE ALSO
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo convert toTOML"
|
||||
slug: hugo_convert_toTOML
|
||||
url: /commands/hugo_convert_totoml/
|
||||
@@ -42,4 +42,4 @@ hugo convert toTOML [flags]
|
||||
### SEE ALSO
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo convert toYAML"
|
||||
slug: hugo_convert_toYAML
|
||||
url: /commands/hugo_convert_toyaml/
|
||||
@@ -42,4 +42,4 @@ hugo convert toYAML [flags]
|
||||
### SEE ALSO
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo env"
|
||||
slug: hugo_env
|
||||
url: /commands/hugo_env/
|
||||
@@ -38,4 +38,4 @@ hugo env [flags]
|
||||
### SEE ALSO
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo gen"
|
||||
slug: hugo_gen
|
||||
url: /commands/hugo_gen/
|
||||
@@ -38,4 +38,4 @@ A collection of several useful generators.
|
||||
* [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
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo gen autocomplete"
|
||||
slug: hugo_gen_autocomplete
|
||||
url: /commands/hugo_gen_autocomplete/
|
||||
@@ -56,4 +56,4 @@ hugo gen autocomplete [flags]
|
||||
### SEE ALSO
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo gen chromastyles"
|
||||
slug: hugo_gen_chromastyles
|
||||
url: /commands/hugo_gen_chromastyles/
|
||||
@@ -43,4 +43,4 @@ hugo gen chromastyles [flags]
|
||||
### SEE ALSO
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo gen doc"
|
||||
slug: hugo_gen_doc
|
||||
url: /commands/hugo_gen_doc/
|
||||
@@ -45,4 +45,4 @@ hugo gen doc [flags]
|
||||
### SEE ALSO
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo gen man"
|
||||
slug: hugo_gen_man
|
||||
url: /commands/hugo_gen_man/
|
||||
@@ -41,4 +41,4 @@ hugo gen man [flags]
|
||||
### SEE ALSO
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo import"
|
||||
slug: hugo_import
|
||||
url: /commands/hugo_import/
|
||||
@@ -37,4 +37,4 @@ Import requires a subcommand, e.g. `hugo import jekyll jekyll_root_path target_p
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo import jekyll](/commands/hugo_import_jekyll/) - hugo import from Jekyll
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo import jekyll"
|
||||
slug: hugo_import_jekyll
|
||||
url: /commands/hugo_import_jekyll/
|
||||
@@ -41,4 +41,4 @@ hugo import jekyll [flags]
|
||||
### SEE ALSO
|
||||
* [hugo import](/commands/hugo_import/) - Import your site from others.
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo list"
|
||||
slug: hugo_list
|
||||
url: /commands/hugo_list/
|
||||
@@ -40,4 +40,4 @@ List requires a subcommand, e.g. `hugo list drafts`.
|
||||
* [hugo list expired](/commands/hugo_list_expired/) - List all posts already expired
|
||||
* [hugo list future](/commands/hugo_list_future/) - List all posts dated in the future
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo list drafts"
|
||||
slug: hugo_list_drafts
|
||||
url: /commands/hugo_list_drafts/
|
||||
@@ -39,4 +39,4 @@ hugo list drafts [flags]
|
||||
### SEE ALSO
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo list expired"
|
||||
slug: hugo_list_expired
|
||||
url: /commands/hugo_list_expired/
|
||||
@@ -40,4 +40,4 @@ hugo list expired [flags]
|
||||
### SEE ALSO
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo list future"
|
||||
slug: hugo_list_future
|
||||
url: /commands/hugo_list_future/
|
||||
@@ -40,4 +40,4 @@ hugo list future [flags]
|
||||
### SEE ALSO
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo new"
|
||||
slug: hugo_new
|
||||
url: /commands/hugo_new/
|
||||
@@ -48,4 +48,4 @@ hugo new [path] [flags]
|
||||
* [hugo new site](/commands/hugo_new_site/) - Create a new site (skeleton)
|
||||
* [hugo new theme](/commands/hugo_new_theme/) - Create a new theme
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo new site"
|
||||
slug: hugo_new_site
|
||||
url: /commands/hugo_new_site/
|
||||
@@ -43,4 +43,4 @@ hugo new site [path] [flags]
|
||||
### SEE ALSO
|
||||
* [hugo new](/commands/hugo_new/) - Create new content for your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo new theme"
|
||||
slug: hugo_new_theme
|
||||
url: /commands/hugo_new_theme/
|
||||
@@ -42,4 +42,4 @@ hugo new theme [name] [flags]
|
||||
### SEE ALSO
|
||||
* [hugo new](/commands/hugo_new/) - Create new content for your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo server"
|
||||
slug: hugo_server
|
||||
url: /commands/hugo_server/
|
||||
@@ -31,48 +31,49 @@ hugo server [flags]
|
||||
### Options
|
||||
|
||||
```
|
||||
--appendPort append port to baseURL (default true)
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. http://spf13.com/
|
||||
--bind string interface to which the server will bind (default "127.0.0.1")
|
||||
-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. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir remove files from destination not found in static directories
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 do not render 404 page
|
||||
--disableFastRender enables full re-renders on changes
|
||||
--disableKinds strings disable different kind of pages (home, RSS etc.)
|
||||
--disableLiveReload watch without enabling live browser reload on rebuild
|
||||
--disableRSS do not build RSS files
|
||||
--disableSitemap do not build Sitemap file
|
||||
--enableGitInfo add Git revision, date and author info to the pages
|
||||
--forceSyncStatic copy all files when static is changed.
|
||||
-h, --help help for server
|
||||
--i18n-warnings print missing translations
|
||||
--ignoreCache ignores the cache directory
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--liveReloadPort int port for live reloading (i.e. 443 in HTTPS proxy situations) (default -1)
|
||||
--meminterval string interval to poll memory usage (requires --memstats), valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". (default "100ms")
|
||||
--memstats string log memory usage to this file
|
||||
--navigateToChanged navigate to changed content file on live browser reload
|
||||
--noChmod don't sync permission mode of files
|
||||
--noHTTPCache prevent HTTP caching
|
||||
--noTimes don't sync modification time of files
|
||||
--pluralizeListTitles pluralize titles in lists using inflect (default true)
|
||||
-p, --port int port on which the server will listen (default 1313)
|
||||
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--renderToDisk render to Destination path (default is render to memory & serve from there)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
--templateMetrics display metrics about template executions
|
||||
--templateMetricsHints calculate some improvement hints when combined with --templateMetrics
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--themesDir string filesystem path to themes directory
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
-w, --watch watch filesystem for changes and recreate as needed (default true)
|
||||
--appendPort append port to baseURL (default true)
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. http://spf13.com/
|
||||
--bind string interface to which the server will bind (default "127.0.0.1")
|
||||
-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. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir remove files from destination not found in static directories
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 do not render 404 page
|
||||
--disableFastRender enables full re-renders on changes
|
||||
--disableKinds stringSlice disable different kind of pages (home, RSS etc.)
|
||||
--disableLiveReload watch without enabling live browser reload on rebuild
|
||||
--disableRSS do not build RSS files
|
||||
--disableSitemap do not build Sitemap file
|
||||
--enableGitInfo add Git revision, date and author info to the pages
|
||||
--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 server
|
||||
--i18n-warnings print missing translations
|
||||
--ignoreCache ignores the cache directory
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--liveReloadPort int port for live reloading (i.e. 443 in HTTPS proxy situations) (default -1)
|
||||
--meminterval string interval to poll memory usage (requires --memstats), valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". (default "100ms")
|
||||
--memstats string log memory usage to this file
|
||||
--navigateToChanged navigate to changed content file on live browser reload
|
||||
--noChmod don't sync permission mode of files
|
||||
--noHTTPCache prevent HTTP caching
|
||||
--noTimes don't sync modification time of files
|
||||
--pluralizeListTitles pluralize titles in lists using inflect (default true)
|
||||
-p, --port int port on which the server will listen (default 1313)
|
||||
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--renderToDisk render to Destination path (default is render to memory & serve from there)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
--templateMetrics display metrics about template executions
|
||||
--templateMetricsHints calculate some improvement hints when combined with --templateMetrics
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--themesDir string filesystem path to themes directory
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
-w, --watch watch filesystem for changes and recreate as needed (default true)
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
@@ -90,4 +91,4 @@ hugo server [flags]
|
||||
### SEE ALSO
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo undraft"
|
||||
slug: hugo_undraft
|
||||
url: /commands/hugo_undraft/
|
||||
@@ -40,4 +40,4 @@ hugo undraft path/to/content [flags]
|
||||
### SEE ALSO
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-10-15T10:19:48+02:00
|
||||
date: 2017-12-28T18:49:29+01:00
|
||||
title: "hugo version"
|
||||
slug: hugo_version
|
||||
url: /commands/hugo_version/
|
||||
@@ -38,4 +38,4 @@ hugo version [flags]
|
||||
### SEE ALSO
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 15-Oct-2017
|
||||
###### Auto generated by spf13/cobra on 28-Dec-2017
|
||||
|
||||
@@ -6,7 +6,7 @@ date: 2017-01-10
|
||||
publishdate: 2017-01-10
|
||||
lastmod: 2017-04-06
|
||||
categories: [content management]
|
||||
keywords: [markdown,asciidoc,mmark,content format]
|
||||
keywords: [markdown,asciidoc,mmark,pandoc,content format]
|
||||
menu:
|
||||
docs:
|
||||
parent: "content-management"
|
||||
@@ -195,12 +195,19 @@ With this setup, everything is in place for a natural usage of MathJax on pages
|
||||
|
||||
## Additional Formats Through External Helpers
|
||||
|
||||
Hugo has new concept called _external helpers_. It means that you can write your content using [Asciidoc][ascii], [reStructuredText][rest]. If you have files with associated extensions, Hugo will call external commands to generate the content. ([See the Hugo source code for external helpers][helperssource].)
|
||||
Hugo has a new concept called _external helpers_. It means that you can write your content using [Asciidoc][ascii], [reStructuredText][rest], or [pandoc]. If you have files with associated extensions, Hugo will call external commands to generate the content. ([See the Hugo source code for external helpers][helperssource].)
|
||||
|
||||
For example, for Asciidoc files, Hugo will try to call the `asciidoctor` or `asciidoc` command. This means that you will have to install the associated tool on your machine to be able to use these formats. ([See the Asciidoctor docs for installation instructions](http://asciidoctor.org/docs/install-toolchain/)).
|
||||
|
||||
To use these formats, just use the standard extension and the front matter exactly as you would do with natively supported `.md` files.
|
||||
|
||||
Hugo passes reasonable default arguments to these external helpers by default:
|
||||
|
||||
- `asciidoc`: `--no-header-footer --safe -`
|
||||
- `asciidoctor`: `--no-header-footer --safe --trace -`
|
||||
- `rst2html`: `--leave-comments --initial-header-level=2`
|
||||
- `pandoc`: `--mathjax`
|
||||
|
||||
{{% warning "Performance of External Helpers" %}}
|
||||
Because additional formats are external commands generation performance will rely heavily on the performance of the external tool you are using. As this feature is still in its infancy, feedback is welcome.
|
||||
{{% /warning %}}
|
||||
@@ -235,6 +242,7 @@ Markdown syntax is simple enough to learn in a single sitting. The following are
|
||||
[mmark]: https://github.com/miekg/mmark
|
||||
[mmarkgh]: https://github.com/miekg/mmark/wiki/Syntax
|
||||
[org]: http://orgmode.org/
|
||||
[pandoc]: http://www.pandoc.org/
|
||||
[Pygments]: http://pygments.org/
|
||||
[rest]: http://docutils.sourceforge.net/rst.html
|
||||
[sc]: /content-management/shortcodes/
|
||||
|
||||
@@ -59,6 +59,52 @@ If you want all of the languages to be put below their respective language code,
|
||||
|
||||
Only the obvious non-global options can be overridden per language. Examples of global options are `baseURL`, `buildDrafts`, etc.
|
||||
|
||||
## Configure Multilingual Multihost
|
||||
|
||||
From **Hugo 0.31** we support multiple languages in a multihost configuration. See [this issue](https://github.com/gohugoio/hugo/issues/4027) for details.
|
||||
|
||||
This means that you can now configure a `baseURL` per `language`:
|
||||
|
||||
|
||||
> If a `baseURL` is set on the `language` level, then all languages must have one and they must all be different.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
[languages]
|
||||
[languages.no]
|
||||
baseURL = "https://example.no"
|
||||
languageName = "Norsk"
|
||||
weight = 1
|
||||
title = "På norsk"
|
||||
|
||||
[languages.en]
|
||||
baseURL = "https://example.com"
|
||||
languageName = "English"
|
||||
weight = 2
|
||||
title = "In English"
|
||||
```
|
||||
|
||||
With the above, the two sites will be generated into `public` with their own root:
|
||||
|
||||
```bash
|
||||
public
|
||||
├── en
|
||||
└── no
|
||||
```
|
||||
|
||||
**All URLs (i.e `.Permalink` etc.) will be generated from that root. So the English home page above will have its `.Permalink` set to `https://example.com/`.**
|
||||
|
||||
When you run `hugo server` we will start multiple HTTP servers. You will typlically see something like this in the console:
|
||||
|
||||
```bash
|
||||
Web Server is available at 127.0.0.1:1313 (bind address 127.0.0.1)
|
||||
Web Server is available at 127.0.0.1:1314 (bind address 127.0.0.1)
|
||||
Press Ctrl+C to stop
|
||||
```
|
||||
|
||||
Live reload and `--navigateToChanged` between the servers work as expected.
|
||||
|
||||
## Taxonomies and Blackfriday
|
||||
|
||||
Taxonomies and [Blackfriday configuration][config] can also be set per language:
|
||||
@@ -102,22 +148,28 @@ In this example, the `about.md` will be assigned the configured `defaultContentL
|
||||
|
||||
This way, you can slowly start to translate your current content without having to rename everything. If left unspecified, the default value for `defaultContentLanguage` is `en`.
|
||||
|
||||
By having the same *base filename*, the content pieces are linked together as translated pieces.
|
||||
By having the same **directory and base filename**, the content pieces are linked together as translated pieces.
|
||||
|
||||
You can also set the key used to link the translations explicitly in front matter:
|
||||
|
||||
```yaml
|
||||
translationKey: "my-story"
|
||||
```
|
||||
|
||||
|
||||
{{% note %}}
|
||||
**Before Hugo 0.31**, the file's directory was not considered when looking for translations. This did not work when you named all of your content files, say, `index.md`. Now we use the full content path.
|
||||
{{% /note %}}
|
||||
|
||||
If you need distinct URLs per language, you can set the slug in the non-default language file. For example, you can define a custom slug for a French translation in the front matter of `content/about.fr.md` as follows:
|
||||
|
||||
```
|
||||
```yaml
|
||||
slug: "a-propos"
|
||||
|
||||
```
|
||||
|
||||
At render, Hugo will build both `/about/` and `/a-propos/` as properly linked translated pages.
|
||||
|
||||
{{%note %}}
|
||||
Hugo currently uses the base filename as the translation key, which can be an issue with identical filenames in different sections.
|
||||
We will fix this in https://github.com/gohugoio/hugo/issues/2699
|
||||
{{% /note %}}
|
||||
{{< todo >}}Rewrite/remove the above one issue is fixed.{{< /todo >}}
|
||||
|
||||
## Link to Translated Content
|
||||
|
||||
@@ -140,12 +192,32 @@ The above can be put in a `partial` (i.e., inside `layouts/partials/`) and inclu
|
||||
|
||||
The above also uses the [`i18n` function][i18func] described in the next section.
|
||||
|
||||
## List All Available Languages
|
||||
|
||||
`.AllTranslations` on a `Page` can be used to list all translations, including itself. Called on the home page it can be used to build a language navigator:
|
||||
|
||||
|
||||
{{< code file="layouts/partials/allLanguages.html" >}}
|
||||
<ul>
|
||||
{{ range $.Site.Home.AllTranslations }}
|
||||
<li><a href="{{ .}}">{{ .Language.LanguageName }}</a></li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{< /code >}}
|
||||
|
||||
## Translation of Strings
|
||||
|
||||
Hugo uses [go-i18n][] to support string translations. [See the project's source repository][go-i18n-source] to find tools that will help you manage your translation workflows.
|
||||
|
||||
Translations are collected from the `themes/<THEME>/i18n/` folder (built into the theme), as well as translations present in `i18n/` at the root of your project. In the `i18n`, the translations will be merged and take precedence over what is in the theme folder. Language files should be named according to [RFC 5646][] with names such as `en-US.toml`, `fr.toml`, etc.
|
||||
|
||||
{{% note %}}
|
||||
From **Hugo 0.31** you no longer need to use a valid language code. It _can be_ anything.
|
||||
|
||||
See https://github.com/gohugoio/hugo/issues/3564
|
||||
|
||||
{{% /note %}}
|
||||
|
||||
From within your templates, use the `i18n` function like this:
|
||||
|
||||
```
|
||||
|
||||
@@ -17,20 +17,15 @@ aliases: [/content/sections/]
|
||||
toc: true
|
||||
---
|
||||
|
||||
{{% note %}}
|
||||
This section is not updated with the new nested sections support in Hugo 0.24, see https://github.com/gohugoio/hugoDocs/issues/36
|
||||
{{% /note %}}
|
||||
{{% todo %}}
|
||||
See above
|
||||
{{% /todo %}}
|
||||
|
||||
{{< youtube 0GZxidrlaRM >}}
|
||||
|
||||
## Organization of Content Source
|
||||
|
||||
In Hugo, your content should be organized in a manner that reflects the rendered website.
|
||||
|
||||
While Hugo supports content nested at any level, the top levels (i.e. `content/<DIRECTORIES>`) are special in Hugo and are considered the content [sections][]. Without any additional configuration, the following will just work:
|
||||
While Hugo supports content nested at any level, the top levels (i.e. `content/<DIRECTORIES>`) are special in Hugo and are considered the content type used to determine layouts etc. To read more about sections, including how to nest them, see [sections][].
|
||||
|
||||
Without any additional configuration, the following will just work:
|
||||
|
||||
```
|
||||
.
|
||||
@@ -49,11 +44,16 @@ While Hugo supports content nested at any level, the top levels (i.e. `content/<
|
||||
|
||||
## Path Breakdown in Hugo
|
||||
|
||||
|
||||
The following demonstrates the relationships between your content organization and the output URL structure for your Hugo website when it renders. These examples assume you are [using pretty URLs][pretty], which is the default behavior for Hugo. The examples also assume a key-value of `baseurl = "https://example.com"` in your [site's configuration file][config].
|
||||
|
||||
### Index Pages: `_index.md`
|
||||
|
||||
`_index.md` has a special role in Hugo. It allows you to add front matter and content to your [list templates][lists] as of v0.18. These templates include those for [section templates][], [taxonomy templates][], [taxonomy terms templates][], and your [homepage template][]. In your templates, you can grab information from `_index.md` using the [`.Site.GetPage` function][getpage].
|
||||
`_index.md` has a special role in Hugo. It allows you to add front matter and content to your [list templates][lists]. These templates include those for [section templates][], [taxonomy templates][], [taxonomy terms templates][], and your [homepage template][].
|
||||
|
||||
{{% note %}}
|
||||
**Tip:** You can get a reference to the content and metadata in `_index.md` using the [`.Site.GetPage` function](/functions/getpage/).
|
||||
{{% /note %}}
|
||||
|
||||
You can keep one `_index.md` for your homepage and one in each of your content sections, taxonomies, and taxonomy terms. The following shows typical placement of an `_index.md` that would contain content and front matter for a `posts` section list page on a Hugo website:
|
||||
|
||||
@@ -81,6 +81,9 @@ At build, this will output to the following destination with the associated valu
|
||||
https://example.com/posts/index.html
|
||||
```
|
||||
|
||||
The [sections][] can be nested as deeply as you need. The important part to understand is, that to make the section tree fully navigational, at least the lower-most section needs a content file. (i.e. `_index.md`).
|
||||
|
||||
|
||||
### Single Pages in Sections
|
||||
|
||||
Single content files in each of your sections are going to be rendered as [single page templates][singles]. Here is an example of a single `post` within `posts`:
|
||||
@@ -107,27 +110,6 @@ At the time Hugo builds your site, the content will be output to the following d
|
||||
https://example.com/posts/my-first-hugo-post/index.html
|
||||
```
|
||||
|
||||
### Section with Nested Directories
|
||||
|
||||
To continue the example, the following demonstrates destination paths for a file located at `content/events/chicago/lollapalooza.md` in the same site:
|
||||
|
||||
|
||||
```
|
||||
section
|
||||
⊢--^--⊣
|
||||
url
|
||||
⊢-------------^------------⊣
|
||||
|
||||
baseURL path slug
|
||||
⊢--------^--------⊣ ⊢------^-----⊣⊢----^------⊣
|
||||
permalink
|
||||
⊢----------------------^-----------------------⊣
|
||||
https://example.com/events/chicago/lollapalooza/
|
||||
```
|
||||
|
||||
{{% note %}}
|
||||
As of v0.20, Hugo does not recognize nested sections. While you can nest as many content *directories* as you'd like, any child directory of a section will still be considered the same section as that of its parents. Therefore, in the above example, `{{.Section}}` for `lollapalooza.md` is `events` and *not* `chicago`. See the [related issue on GitHub](https://github.com/gohugoio/hugo/issues/465).
|
||||
{{% /note %}}
|
||||
|
||||
## Paths Explained
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: Content Sections
|
||||
linktitle: Sections
|
||||
description: Hugo supports content sections, which according to Hugo's default behavior, will reflect the structure of the rendered website.
|
||||
description: "Hugo generates a **section tree** that matches your content."
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
lastmod: 2017-02-01
|
||||
@@ -17,53 +17,65 @@ aliases: [/content/sections/]
|
||||
toc: true
|
||||
---
|
||||
|
||||
|
||||
## Nested Sections
|
||||
|
||||
The sections can be nested as deeply as you need.
|
||||
|
||||
```bash
|
||||
blog
|
||||
├── funny-cats
|
||||
│ └── kittens
|
||||
│ └── _index.md
|
||||
└── tech
|
||||
└── _index.md
|
||||
```
|
||||
|
||||
|
||||
**The important part to understand is, that to make the section tree fully navigational, at least the lower-most section needs a content file. (e.g. `_index.md`).**
|
||||
|
||||
|
||||
{{% note %}}
|
||||
This section is not updated with the new nested sections support in Hugo 0.24, see https://github.com/gohugoio/hugoDocs/issues/36
|
||||
When we talk about a **section** in correlation with template selection, it is currently always the root section only (`/blog/funny/mypost/ => blog`).
|
||||
|
||||
It is currently not possible to add a specific layout for one of the sub-sections.
|
||||
{{% /note %}}
|
||||
{{% todo %}}
|
||||
See above
|
||||
{{% /todo %}}
|
||||
|
||||
Hugo believes that you organize your content with a purpose. The same structure that works to organize your source content is used to organize the rendered site (see [directory structure][]).
|
||||
|
||||
Following this pattern, Hugo uses the top level of your content organization as the content **section**.
|
||||
## Example: Breadcrumb Navigation
|
||||
|
||||
The following example shows a content directory structure for a website that has three sections: "authors," "events," and "posts":
|
||||
With the available [section variables and methods](#section-page-variables-and-methods) you can build powerful navigation. One common example would be a partial to show Breadcrumb navigation:
|
||||
|
||||
```
|
||||
.
|
||||
└── content
|
||||
├── authors
|
||||
| ├── _index.md // <- example.com/authors/
|
||||
| ├── john-doe.md // <- example.com/authors/john-doe/
|
||||
| └── jane-doe.md // <- example.com/authors/jane-doe/
|
||||
└── events
|
||||
| ├── _index.md // <- example.com/events/
|
||||
| ├── event-1.md // <- example.com/events/event-1/
|
||||
| ├── event-2.md // <- example.com/events/event-2/
|
||||
| └── event-3.md // <- example.com/events/event-3/
|
||||
└── posts
|
||||
| ├── _index.md // <- example.com/posts/
|
||||
| ├── post-1.md // <- example.com/posts/post-1/
|
||||
| ├── post-2.md // <- example.com/posts/post-2/
|
||||
| ├── post-3.md // <- example.com/posts/post-3/
|
||||
| ├── post-4.md // <- example.com/posts/post-4/
|
||||
| └── post-5.md // <- example.com/posts/post-5/
|
||||
```
|
||||
|
||||
{{< code file="layouts/partials/breadcrumb.html" download="breadcrumb.html" >}}
|
||||
<ol class="nav navbar-nav">
|
||||
{{ template "breadcrumbnav" (dict "p1" . "p2" .) }}
|
||||
</ol>
|
||||
{{ define "breadcrumbnav" }}
|
||||
{{ if .p1.Parent }}
|
||||
{{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 ) }}
|
||||
{{ else if not .p1.IsHome }}
|
||||
{{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 ) }}
|
||||
{{ end }}
|
||||
<li{{ if eq .p1 .p2 }} class="active"{{ end }}>
|
||||
<a href="{{ .p1.Permalink }}">{{ .p1.Title }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
{{< /code >}}
|
||||
|
||||
## Section Page Variables and Methods
|
||||
|
||||
Also see [Page Variables](/variables/page/).
|
||||
|
||||
{{< readfile file="/content/readfiles/sectionvars.md" markdown="true" >}}
|
||||
|
||||
## Content Section Lists
|
||||
|
||||
Hugo will automatically create pages for each section root that list all of the content in that section. See the documentation on [section templates][] for details on customizing the way these pages are rendered.
|
||||
|
||||
As of Hugo v0.18, section pages can also have a content file and front matter. These section content files must be placed in their corresponding section folder and named `_index.md` in order for Hugo to correctly render the front matter and content.
|
||||
|
||||
{{% warning "`index.md` vs `_index.md`" %}}
|
||||
Hugo themes developed before v0.18 often used an `index.md`(i.e., without the leading underscore [`_`]) in a content section as a hack to emulate the behavior of `_index.md`. The hack may work...*sometimes*; however, the order of page rendering can be unpredictable in Hugo. What works now may fail to render appropriately as your site grows. It is **strongly advised** to use `_index.md` as content for your section index pages. **Note:** `_index.md`'s layout, as representative of a section, is a [list page template](/templates/section-templates/) and *not* a [single page template](/templates/single-page-templates/). If you want to alter the new default behavior for `_index.md`, configure `disableKinds` accordingly in your [site's configuration](/getting-started/configuration/).
|
||||
{{% /warning %}}
|
||||
|
||||
## Content *Section* vs Content *Type*
|
||||
|
||||
By default, everything created within a section will use the [content type][] that matches the section name. For example, Hugo will assume that `posts/post-1.md` has a `posts` content type. If you are using an [archetype][] for your posts section, Hugo will generate front matter according to what it finds in `archetypes/posts.md`.
|
||||
By default, everything created within a section will use the [content type][] that matches the root section name. For example, Hugo will assume that `posts/post-1.md` has a `posts` content type. If you are using an [archetype][] for your posts section, Hugo will generate front matter according to what it finds in `archetypes/posts.md`.
|
||||
|
||||
[archetype]: /content-management/archetypes/
|
||||
[content type]: /content-management/types/
|
||||
|
||||
@@ -88,6 +88,7 @@ The `figure` shortcode can use the following named parameters:
|
||||
* `attr` (i.e., attribution)
|
||||
* `attrlink`
|
||||
* `alt`
|
||||
* `width`
|
||||
|
||||
#### Example `figure` Input
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: Static Files
|
||||
description: "The `static` folder is where you place all your **static files**."
|
||||
date: 2017-11-18
|
||||
categories: [content management]
|
||||
keywords: [source, directories]
|
||||
menu:
|
||||
docs:
|
||||
parent: "content-management"
|
||||
weight: 130
|
||||
weight: 130 #rem
|
||||
aliases: [/static-files]
|
||||
toc: true
|
||||
---
|
||||
|
||||
The `static` folder is where you place all your **static files**, e.g. stylesheets, JavaScript, images etc.
|
||||
|
||||
You can set the name of the static folder to use in your configuration file, for example `config.toml`. From **Hugo 0.31** you can configure as many static directories as you need. All the files in all the static directories will form a union filesystem.
|
||||
|
||||
Example:
|
||||
|
||||
```toml
|
||||
staticDir = ["static1", "static2"]
|
||||
[languages]
|
||||
[languages.no]
|
||||
staticDir = ["staticDir_override", "static_no"]
|
||||
baseURL = "https://example.no"
|
||||
languageName = "Norsk"
|
||||
weight = 1
|
||||
title = "På norsk"
|
||||
|
||||
[languages.en]
|
||||
staticDir2 = "static_en"
|
||||
baseURL = "https://example.com"
|
||||
languageName = "English"
|
||||
weight = 2
|
||||
title = "In English"
|
||||
```
|
||||
|
||||
In the above, with no theme used:
|
||||
|
||||
* The English site will get its static files as a union of "static1", "static2" and "static_en". On file duplicates, the right-most version will win.
|
||||
* The Norwegian site will get its static files as a union of "staticDir_override" and "static_no".
|
||||
|
||||
**Note:** The `2` `static2` (can be a number between 0 and 10) is added to tell Hugo that you want to **add** this directory to the global set of static directories. Using `staticDir` on the language level would replace the global value.
|
||||
|
||||
|
||||
**Note:** The example above is a [multihost setup](/content-management/multilingual/#configure-multilingual-multihost). In a regular setup, all the static directories will be available to all sites.
|
||||
@@ -101,7 +101,7 @@ hl_lines
|
||||
: Highlight a space separated list of line numbers. For Chroma, you can provide a list of ranges, i.e. "3-8 10-20".
|
||||
|
||||
|
||||
The full set of supported options for Pygments is: `encoding`, `outencoding`, `nowrap`, `full`, `title`, `style`, `noclasses`, `classprefix`, `cssclass`, `cssstyles`, `prestyles`, `linenos`, `hl_lines`, `linenostart`, `linenostep`, `linenospecial`, `nobackground`, `lineseparator`, `lineanchors`, `linespans`, `anchorlinenos`, `startinline`. See the [Pygments Documentation](http://pygments.org/) for details.
|
||||
The full set of supported options for Pygments is: `encoding`, `outencoding`, `nowrap`, `full`, `title`, `style`, `noclasses`, `classprefix`, `cssclass`, `cssstyles`, `prestyles`, `linenos`, `hl_lines`, `linenostart`, `linenostep`, `linenospecial`, `nobackground`, `lineseparator`, `lineanchors`, `linespans`, `anchorlinenos`, `startinline`. See the [Pygments HTML Formatter Documentation](http://pygments.org/docs/formatters/#HtmlFormatter) for details.
|
||||
|
||||
|
||||
## Generate Syntax Highlighter CSS
|
||||
|
||||
@@ -54,26 +54,26 @@ To continue with the example of a movie site, the following demonstrates content
|
||||
```
|
||||
Actor <- Taxonomy
|
||||
Bruce Willis <- Term
|
||||
The Sixth Sense <- Content
|
||||
Unbreakable <- Content
|
||||
Moonrise Kingdom <- Content
|
||||
The Sixth Sense <- Value
|
||||
Unbreakable <- Value
|
||||
Moonrise Kingdom <- Value
|
||||
Samuel L. Jackson <- Term
|
||||
Unbreakable <- Content
|
||||
The Avengers <- Content
|
||||
xXx <- Content
|
||||
Unbreakable <- Value
|
||||
The Avengers <- Value
|
||||
xXx <- Value
|
||||
```
|
||||
|
||||
From the perspective of the content, the relationships would appear differently, although the data and labels used are the same:
|
||||
|
||||
```
|
||||
Unbreakable <- Content
|
||||
Unbreakable <- Value
|
||||
Actors <- Taxonomy
|
||||
Bruce Willis <- Term
|
||||
Samuel L. Jackson <- Term
|
||||
Director <- Taxonomy
|
||||
M. Night Shyamalan <- Term
|
||||
...
|
||||
Moonrise Kingdom <- Content
|
||||
Moonrise Kingdom <- Value
|
||||
Actors <- Taxonomy
|
||||
Bruce Willis <- Term
|
||||
Bill Murray <- Term
|
||||
@@ -132,7 +132,7 @@ Note that if you use `preserveTaxonomyNames` and intend to manually construct UR
|
||||
{{% note %}}
|
||||
You can add content and front matter to your taxonomy list and taxonomy terms pages. See [Content Organization](/content-management/organization/) for more information on how to add an `_index.md` for this purpose.
|
||||
|
||||
Note also that taxonomy [permalinks](/content-management/urls/) are *not* configurable.
|
||||
Much like regular pages, taxonomy list [permalinks](/content-management/urls/) are configurable, but taxonomy term page permalinks are not.
|
||||
{{% /note %}}
|
||||
|
||||
## Add Taxonomies to Content
|
||||
|
||||
@@ -43,7 +43,9 @@ permalinks:
|
||||
post = "/:year/:month/:title/"
|
||||
{{< /code >}}
|
||||
|
||||
Only the content under `post/` will have the new URL structure. For example, the file `content/post/sample-entry.md` with `date: 2017-02-27T19:20:00-05:00` in its front matter will render to `public/2017/02/sample-entry/index.html` at build time and therefore be reachable at `https://example.com/2013/11/sample-entry/`.
|
||||
Only the content under `post/` will have the new URL structure. For example, the file `content/post/sample-entry.md` with `date: 2017-02-27T19:20:00-05:00` in its front matter will render to `public/2017/02/sample-entry/index.html` at build time and therefore be reachable at `https://example.com/2017/02/sample-entry/`.
|
||||
|
||||
You can also configure permalinks of taxonomies with the same syntax, by using the plural form of the taxonomy instead of the section. You will probably only want to use the configuration values `:slug` or `:title`.
|
||||
|
||||
### Permalink Configuration Values
|
||||
|
||||
@@ -73,6 +75,9 @@ The following is a list of values that can be used in a `permalink` definition i
|
||||
`:section`
|
||||
: the content's section
|
||||
|
||||
`:sections`
|
||||
: the content's sections hierarchy
|
||||
|
||||
`:title`
|
||||
: the content's title
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ min_version = 0.13
|
||||
|
||||
{{% note %}}
|
||||
1. This is different from the `theme.toml` file created by `hugo new theme` in Hugo versions before v0.14.
|
||||
2. Only `theme.toml` is accepted; ie. not `theme.yaml` andnot `theme.json`.
|
||||
2. Only `theme.toml` is accepted; ie. not `theme.yaml` and `theme.json`.
|
||||
{{% /note %}}
|
||||
|
||||
### Images
|
||||
@@ -147,4 +147,4 @@ If you add screenshots to the README, please make use of absolute file paths ins
|
||||
{{% /note %}}
|
||||
|
||||
[artistexample]: https://github.com/digitalcraftsman/hugo-artists-theme/tree/master/exampleSite
|
||||
[themeissuenew]: https://github.com/gohugoio/hugoThemes/issues/new
|
||||
[themeissuenew]: https://github.com/gohugoio/hugoThemes/issues/new
|
||||
|
||||
@@ -11,7 +11,7 @@ menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
keywords: [cross references, anchors]
|
||||
signature: ["ref CONTENT"]
|
||||
signature: ["ref . CONTENT"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: [relref]
|
||||
@@ -19,12 +19,16 @@ deprecated: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
`ref` and `relRef` look up a content page by relative path (`relref`) or logical name (`ref`) to return the permalink:
|
||||
`ref` and `relref` look up a content page by logical name (`ref`) or relative path (`relref`) to return the permalink:
|
||||
|
||||
```
|
||||
{{ ref "about.md" }}
|
||||
{{ ref . "about.md" }}
|
||||
```
|
||||
|
||||
{{% note "Usage Note" %}}
|
||||
`ref` looks up Hugo "Regular Pages" only. It can't be used for the homepage, section pages, etc.
|
||||
{{% /note %}}
|
||||
|
||||
These functions are used in two of Hugo's built-in shortcodes. You can see basic usage examples of both `ref` and `relref` in the [shortcode documentation](/content-management/shortcodes/#ref-and-relref).
|
||||
|
||||
For an extensive explanation of how to leverage `ref` and `relref` for content management, see [Cross References](/content-management/cross-references/).
|
||||
|
||||
@@ -11,20 +11,24 @@ menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
keywords: [cross references, anchors]
|
||||
signature: ["relref CONTENT"]
|
||||
signature: ["relref . CONTENT"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: [relref]
|
||||
relatedfuncs: [ref]
|
||||
deprecated: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
`ref` and `relRef` look up a content page by relative path (`relref`) or logical name (`ref`) to return the permalink:
|
||||
`ref` and `relref` look up a content page by logical name (`ref`) or relative path (`relref`) to return the permalink:
|
||||
|
||||
```
|
||||
{{ relref "about.md" }}
|
||||
{{ relref . "about.md" }}
|
||||
```
|
||||
|
||||
{{% note "Usage Note" %}}
|
||||
`relref` looks up Hugo "Regular Pages" only. It can't be used for the homepage, section pages, etc.
|
||||
{{% /note %}}
|
||||
|
||||
These functions are used in two of Hugo's built-in shortcodes. You can see basic usage examples of both `ref` and `relref` in the [shortcode documentation](/content-management/shortcodes/#ref-and-relref).
|
||||
|
||||
For an extensive explanation of how to leverage `ref` and `relref` for content management, see [Cross References](/content-management/cross-references/).
|
||||
|
||||
@@ -252,7 +252,7 @@ googleAnalytics = ""
|
||||
hasCJKLanguage = false
|
||||
languageCode = ""
|
||||
# the length of text to show in a .Summary
|
||||
summaryLength: 70
|
||||
summaryLength = 70
|
||||
layoutDir = "layouts"
|
||||
# Enable Logging
|
||||
log = false
|
||||
@@ -288,8 +288,7 @@ pygmentsUseClasses = false
|
||||
SectionPagesMenu =
|
||||
# default sitemap configuration map
|
||||
sitemap =
|
||||
# filesystem path to read files relative from
|
||||
source = ""
|
||||
# filesystem path to read static files relative from
|
||||
staticDir = "static"
|
||||
# display memory and timing of different steps of the program
|
||||
stepAnalysis = false
|
||||
|
||||
@@ -57,9 +57,13 @@ used by Hugo when generating your website. You can write these files in YAML, JS
|
||||
[`layouts`][]
|
||||
: Stores templates in the form of `.html` files that specify how views of your content will be rendered into a static website. Templates include [list pages][lists], your [homepage][], [taxonomy templates][], [partials][], [single page templates][singles], and more.
|
||||
|
||||
`static`
|
||||
[`static`][]
|
||||
: stores all the static content for your future website: images, CSS, JavaScript, etc. When Hugo builds your site, all assets inside your static directory are copied over as-is. A good example of using the `static` folder is for [verifying site ownership on Google Search Console][searchconsole], where you want Hugo to copy over a complete HTML file without modifying its content.
|
||||
|
||||
{{% note %}}
|
||||
From **Hugo 0.31** you can have multiple static directories.
|
||||
{{% /note %}}
|
||||
|
||||
{{% note %}}
|
||||
Hugo does not currently ship with an asset pipeline ([#3207](https://github.com/gohugoio/hugo/issues/3207)). You can solicit support from the community in the [Hugo forums](https://discourse.gohugo.io) or check out a few of the [Hugo starter kits](/tools/starter-kits/) for examples of how Hugo developers are managing static assets.
|
||||
{{% /note %}}
|
||||
@@ -73,6 +77,7 @@ Hugo does not currently ship with an asset pipeline ([#3207](https://github.com/
|
||||
[data templates]: /templates/data-templates/
|
||||
[homepage]: /templates/homepage/
|
||||
[`layouts`]: /templates/
|
||||
[`static`]: /content-management/static-files/
|
||||
[lists]: /templates/list/
|
||||
[pagevars]: /variables/page/
|
||||
[partials]: /templates/partials/
|
||||
|
||||
@@ -424,10 +424,6 @@ In any of the [Linux distributions that support snaps][snaps]:
|
||||
snap install hugo
|
||||
```
|
||||
|
||||
{{% note %}}
|
||||
Hugo-as-a-snap can write only inside the user’s `$HOME` directory---and gvfs-mounted directories owned by the user---because of Snaps’ confinement and security model. More information is also available [in this related GitHub issue](https://github.com/gohugoio/hugo/issues/3143).
|
||||
{{% /note %}}
|
||||
|
||||
### Debian and Ubuntu
|
||||
|
||||
Debian and Ubuntu provide a `hugo` version via `apt-get`:
|
||||
@@ -445,6 +441,10 @@ sudo apt-get install hugo
|
||||
|
||||
* Might not be the latest version, especially if you are using an older, stable version (e.g., Ubuntu 16.04 LTS). Until backports and PPA are available, you may consider installing the Hugo snap package to get the latest version of Hugo.
|
||||
|
||||
{{% note %}}
|
||||
Hugo-as-a-snap can write only inside the user’s `$HOME` directory---and gvfs-mounted directories owned by the user---because of Snaps’ confinement and security model. More information is also available [in this related GitHub issue](https://github.com/gohugoio/hugo/issues/3143). Use ```sudo apt-get install hugo --classic``` to disable the default security model if you want hugo to be able to have write access in other paths besides the user’s `$HOME` directory.
|
||||
{{% /note %}}
|
||||
|
||||
### Arch Linux
|
||||
|
||||
You can also install Hugo from the Arch Linux [community](https://www.archlinux.org/packages/community/x86_64/hugo/) repository. Applies also for derivatives such as Manjaro.
|
||||
@@ -455,12 +455,10 @@ sudo pacman -Sy hugo
|
||||
|
||||
### Fedora, CentOS, and Red Hat
|
||||
|
||||
* <https://copr.fedorainfracloud.org/coprs/spf13/Hugo/> (updated to Hugo v0.16)
|
||||
* <https://copr.fedorainfracloud.org/coprs/daftaupe/hugo/> (updated to Hugo v0.22); usually released a few days after the official Hugo release.
|
||||
* <https://copr.fedorainfracloud.org/coprs/daftaupe/hugo/>
|
||||
|
||||
See the [related discussion in the Hugo forums][redhatforum].
|
||||
|
||||
|
||||
## Upgrade Hugo
|
||||
|
||||
Upgrading Hugo is as easy as downloading and replacing the executable you’ve placed in your `PATH` or run `brew upgrade hugo` if using Homebrew.
|
||||
|
||||
@@ -21,8 +21,6 @@ toc: true
|
||||
|
||||

|
||||
|
||||
## Before You Begin
|
||||
|
||||
Nanobox provides an entire end-to-end workflow for developing and deploying applications. Using Nanobox to deploy also means you'll use it to develop your application.
|
||||
|
||||
{{% note %}}
|
||||
@@ -39,14 +37,15 @@ To get started you'll just need the following three items:
|
||||
* [A Nanobox Account](https://nanobox.io) - Signup is free
|
||||
* [Nanobox Desktop](https://dashboard.nanobox.io/download) - The free desktop development tool
|
||||
* An account with a hosting provider such as:
|
||||
- [AWS](https://aws.amazon.com/)
|
||||
- [DigitalOcean](https://www.digitalocean.com/)
|
||||
- [Linode](https://www.linode.com/)
|
||||
- Azure (coming)
|
||||
- Google (coming)
|
||||
- [AWS](https://docs.nanobox.io/providers/hosting-accounts/aws/)
|
||||
- [Google](https://docs.nanobox.io/providers/hosting-accounts/gcp/)
|
||||
- [Azure](https://docs.nanobox.io/providers/hosting-accounts/azure/)
|
||||
- [DigitalOcean](https://docs.nanobox.io/providers/hosting-accounts/digitalocean/)
|
||||
- [Linode](https://docs.nanobox.io/providers/hosting-accounts/linode/)
|
||||
- [More...](https://docs.nanobox.io/providers/hosting-accounts/)
|
||||
- [Roll Your Own](https://docs.nanobox.io/providers/create/)
|
||||
|
||||
### Before We Begin
|
||||
### Before You Begin
|
||||
|
||||
There are a few things to get out of the way before diving into the guide. To deploy, you'll need to make sure you have connected a host account to your Nanobox account, and launched a new application.
|
||||
|
||||
@@ -56,7 +55,7 @@ Nanobox lets you choose where to host your application (AWS, DigitalOcean, Googl
|
||||
|
||||
#### Launch a New Application on Nanobox
|
||||
|
||||
[Launching a new app on Nanobox](https://docs.nanobox.io/workflow/launch-app/) is very simple. Navigate to [Launch New App](https://dashboard.nanobox.io/apps/new) in the dashboard, and follow the steps there. You'll be asked to name your app, and select a host and region.
|
||||
[Launching a new app on Nanobox](https://docs.nanobox.io/workflow/launch-app/) is very simple. Navigate to [Launch New App](https://dashboard.nanobox.io/apps/new) in the dashboard, and follow the steps there. You'll be asked to name your app, and to select a host and region.
|
||||
|
||||
With those out of the way you're ready to get started!
|
||||
|
||||
@@ -67,7 +66,7 @@ With those out of the way you're ready to get started!
|
||||
If you already have a functioning Hugo app, you can skip to [Configure Hugo to run with Nanobox](#configure-hugo-to-run-with-nanobox)
|
||||
{{% /note %}}
|
||||
|
||||
To get started, all you'll need an empty project directory. Create a directory wherever you want your application to live and `cd` into it:
|
||||
To get started, all you'll need is an empty project directory. Create a directory wherever you want your application to live and `cd` into it:
|
||||
|
||||
`mkdir path/to/project && cd path/to/project`
|
||||
|
||||
@@ -101,14 +100,14 @@ deploy.config:
|
||||
{{< /code >}}
|
||||
|
||||
{{% note %}}
|
||||
If you already have a functioning Hugo app, which should now be configured, you can skip to [Deploying Hugo with Nanobox](#deploying-hugo-with-nanobox).
|
||||
If you already have a functioning Hugo app, after adding the boxfile, you can skip to [Deploying Hugo with Nanobox](#deploying-hugo-with-nanobox).
|
||||
{{% /note %}}
|
||||
|
||||
### Installing Hugo
|
||||
|
||||
Nanobox uses Docker to create instant, isolated, development environments. Because of this, you'll need to make sure that during development you have Hugo available.
|
||||
|
||||
Do this by add a custom install script at the root of your project that will install Hugo automatically for you:
|
||||
Do this by adding a custom install script at the root of your project that will install Hugo automatically for you:
|
||||
|
||||
{{< code file="install.sh" >}}
|
||||
|
||||
@@ -131,7 +130,7 @@ If the install script fails during `nanobox run` you may need to make it executa
|
||||
|
||||
### Generating a New Hugo App
|
||||
|
||||
You'll generate your new application from inside a Nanobox console (this is why you don't need to worry about having Golang or Hugo installed).
|
||||
You'll generate your new application from inside the Nanobox VM (this is why you don't need to worry about having Golang or Hugo installed).
|
||||
|
||||
Run the following command to drop into a Nanobox console (inside the VM) where your codebase is mounted:
|
||||
|
||||
@@ -141,7 +140,7 @@ nanobox run
|
||||
|
||||

|
||||
|
||||
Once inside here use the following steps to create a new Hugo application:
|
||||
Once inside the console use the following steps to create a new Hugo application:
|
||||
|
||||
```
|
||||
# cd into the /tmp dir to create an app
|
||||
|
||||
@@ -4,7 +4,7 @@ linktitle: Host on GitLab
|
||||
description: GitLab makes it incredibly easy to build, deploy, and host your Hugo website via their free GitLab Pages service, which provides native support for Hugo.
|
||||
date: 2016-06-23
|
||||
publishdate: 2016-06-23
|
||||
lastmod: 2016-06-23
|
||||
lastmod: 2017-11-16
|
||||
categories: [hosting and deployment]
|
||||
keywords: [hosting,deployment,git,gitlab]
|
||||
authors: [Riku-Pekka Silvola]
|
||||
@@ -40,9 +40,8 @@ In the root directory of your Hugo site, create a `.gitlab-ci.yml` file. The `.g
|
||||
{{< code file="gitlab-ci.yml" >}}
|
||||
image: monachus/hugo
|
||||
|
||||
before_script:
|
||||
- git submodule init
|
||||
- git submodule update --force
|
||||
variables:
|
||||
GIT_SUBMODULE_STRATEGY: recursive
|
||||
|
||||
pages:
|
||||
script:
|
||||
|
||||
@@ -4,6 +4,10 @@ date: 2017-09-12
|
||||
description: "Accelerate your Hugo site globally with a KeyCDN integration. This tutorial shows you how to setup your static site as a GitLab page behind a KeyCDN pull zone."
|
||||
categories: [hosting and deployment]
|
||||
keywords: [keycdn,hosting,deployment,cdn]
|
||||
menu:
|
||||
docs:
|
||||
parent: "hosting-and-deployment"
|
||||
weight: 40
|
||||
slug: ""
|
||||
aliases: []
|
||||
toc: false
|
||||
|
||||
@@ -114,6 +114,22 @@ cd themes
|
||||
git submodule add https://github.com/<THEMECREATOR>/<THEMENAME>
|
||||
```
|
||||
|
||||
It is recommended to only use stable versions of a theme (if it’s versioned) and always check the changelog. This can be done by checking out a specific release within the theme's directory.
|
||||
|
||||
Switch to the theme's directory and list all available versions:
|
||||
|
||||
```
|
||||
cd themes/<theme>
|
||||
git tag
|
||||
# exit with q
|
||||
```
|
||||
|
||||
You can checkout a specific version as follows:
|
||||
|
||||
```
|
||||
git checkout tags/<version-name>
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
You now have a live website served over https, distributed through CDN, and configured for continuous deployment. Dig deeper into the Netlify documentation:
|
||||
|
||||
@@ -1,20 +1,23 @@
|
||||
|
||||
---
|
||||
date: 2017-10-16
|
||||
title: "0.30"
|
||||
description: "0.30"
|
||||
title: "Hugo 0.30: Race Car Edition!"
|
||||
description: "Fast Render Mode boosts live reloading!"
|
||||
categories: ["Releases"]
|
||||
slug: "0.30-relnotes"
|
||||
images:
|
||||
- images/blog/hugo-30-poster.png
|
||||
---
|
||||
|
||||
|
||||
Hugo `0.30` is the **Race Car Edition**. Hugo is already very very fast, but much wants more. So we added **Fast Render Mode**. It is hard to explain, so start the Hugo development server with `hugo server` and start editing. Live reloads just got so much faster! The "how and what" is discussed in lenghts [other places](https://github.com/gohugoio/hugo/pull/3959), but the short version is that we now re-render only the parts of the site that you are working on.
|
||||
Hugo `0.30` is the **Race Car Edition**. Hugo is already very very fast, but much wants more. So we added **Fast Render Mode**. It is hard to explain, so start the Hugo development server with `hugo server` and start editing. Live reloads just got so much faster! The "how and what" is discussed at length in [other places](https://github.com/gohugoio/hugo/pull/3959), but the short version is that we now re-render only the parts of the site that you are working on.
|
||||
|
||||
The second performance related feature is a follow up to the Template Metrics added in Hugo `0.29`. Now, if you add the flag `--templateMetricsHints`, we will calculate a score for how your partials can be cached (with the `partialCached` template func).
|
||||
The second performance-related feature is a follow-up to the Template Metrics added in Hugo `0.29`. Now, if you add the flag `--templateMetricsHints`, we will calculate a score for how your partials can be cached (with the `partialCached` template func).
|
||||
|
||||
This release also more or less makes the really fast Chroma highlighter a complete alternative to Pygments. Most noteable is the new table `linenos` support ([7c30e2cb](https://github.com/gohugoio/hugo/commit/7c30e2cbb08fdf0e61f80c7f1aa29909aeca4211) [@bep](https://github.com/bep) [#3915](https://github.com/gohugoio/hugo/issues/3915)), which makes copy-and-paste code blocks much easier.
|
||||
|
||||
This release represents **31 contributions by 10 contributors** to the main Hugo code base.
|
||||
[@bep](https://github.com/bep) leads the Hugo development with a significant amount of contributions, but also a big shoutout to [@moorereason](https://github.com/moorereason), [@digitalcraftsman](https://github.com/digitalcraftsman), and [@bmon](https://github.com/bmon) for their ongoing contributions.
|
||||
[@bep](https://github.com/bep) leads the Hugo development with a significant amount of contribution, but also a big shoutout to [@moorereason](https://github.com/moorereason), [@digitalcraftsman](https://github.com/digitalcraftsman), and [@bmon](https://github.com/bmon) for their ongoing contributions.
|
||||
And as always a big thanks to [@digitalcraftsman](https://github.com/digitalcraftsman) for his relentless work on keeping the documentation and the themes site in pristine condition.
|
||||
|
||||
Many have also been busy writing and fixing the documentation in [hugoDocs](https://github.com/gohugoio/hugoDocs),
|
||||
@@ -29,7 +32,7 @@ Hugo now has:
|
||||
## Notes
|
||||
|
||||
* Running `hugo server` will now run with the new "Fast Render Mode" default on. To turn it off, run `hugo server --disableFastRender` or set `disableFastRender=true` in your site config.
|
||||
* There have been several fixes and enhancements in the Chroma highlighter. One is that it now creates Pygments compatible CSS classes, which means that you may want ot re-generate the stylesheet. See the [Syntax Highlighting Doc](https://gohugo.io/content-management/syntax-highlighting/).
|
||||
* There have been several fixes and enhancements in the Chroma highlighter. One is that it now creates Pygments compatible CSS classes, which means that you may want to re-generate the stylesheet. See the [Syntax Highlighting Doc](https://gohugo.io/content-management/syntax-highlighting/).
|
||||
|
||||
## Enhancements
|
||||
|
||||
@@ -57,5 +60,5 @@ Hugo now has:
|
||||
|
||||
## Fixes
|
||||
|
||||
* Make sure `Date` and `PublishDate` is always set to a value if one is available [6a30874f](https://github.com/gohugoio/hugo/commit/6a30874f19610a38e846e120aac03c68e12f9b7b) [@bep](https://github.com/bep) [#3854](https://github.com/gohugoio/hugo/issues/3854)
|
||||
* Make sure `Date` and `PublishDate` are always set to a value if one is available [6a30874f](https://github.com/gohugoio/hugo/commit/6a30874f19610a38e846e120aac03c68e12f9b7b) [@bep](https://github.com/bep) [#3854](https://github.com/gohugoio/hugo/issues/3854)
|
||||
* Add correct config file name to verbose server log [15ec031d](https://github.com/gohugoio/hugo/commit/15ec031d9818d239bfbff525c00cd99cc3118a96) [@mdhender](https://github.com/mdhender)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
---
|
||||
date: 2017-10-19T00:00:00+02:00
|
||||
title: "0.30.1: Two Important Bugfixes!"
|
||||
description: "Fixes `hugo -w` and validator-broken Sitemap."
|
||||
categories: ["Releases"]
|
||||
slug: 0.30.1-relnotes
|
||||
images:
|
||||
- images/blog/hugo-bug-poster.png
|
||||
---
|
||||
|
||||
|
||||
|
||||
This is a bug-fix release with two important fixes.
|
||||
|
||||
* Fix hugo -w [fa53b13c](https://github.com/gohugoio/hugo/commit/fa53b13ca0ffb1db6ed20f5353661d3f8a5fd455) [@bep](https://github.com/bep) [#3980](https://github.com/gohugoio/hugo/issues/3980)
|
||||
* Revert sitemap template change to make the Google validator happy [5109ed520](https://github.com/gohugoio/hugo/commit/5109ed520f2ddde815d50e7b31acbbfc57ce7719) [@bep](https://github.com/bep) [#3978](https://github.com/gohugoio/hugo/issues/3978)
|
||||
|
||||
|
||||
Hugo now has:
|
||||
|
||||
* 20285+ [stars](https://github.com/gohugoio/hugo/stargazers)
|
||||
* 454+ [contributors](https://github.com/gohugoio/hugo/graphs/contributors)
|
||||
* 180+ [themes](http://themes.gohugo.io/)
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
---
|
||||
date: 2017-10-19T12:00:00+02:00
|
||||
title: "0.30.2: One More Bugfix"
|
||||
description: "Fixes Fast Render mode when having sub-path in `baseURL`."
|
||||
slug: "0.30.2"
|
||||
categories: ["Releases"]
|
||||
images:
|
||||
- images/blog/hugo-bug-poster.png
|
||||
---
|
||||
This release fixes Fast Render mode with sub-path in baseURL [31641033](https://github.com/gohugoio/hugo/commit/3164103310fbca1211cfa9ce4a5eb7437854b6ad) [@bep](https://github.com/bep) [#3981](https://github.com/gohugoio/hugo/issues/3981).
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
|
||||
---
|
||||
date: 2017-11-20
|
||||
title: "Hugo 0.31: Language Multihost Edition!"
|
||||
description: "Hugo 0.31: Multihost, smart union static dirs, and more ..."
|
||||
slug: "0.31-relnotes"
|
||||
categories: ["Releases"]
|
||||
images:
|
||||
- images/blog/hugo-31-poster.png
|
||||
---
|
||||
|
||||
Hugo `0.31` is the **Language Multihost Edition!**
|
||||
|
||||
> <img src="https://esolia.com/img/eSolia-Logo-Flat-2015.svg" alt="eSolia" width="100px" align="top" style="width:100px" />The Multihost feature is sponsored by [eSolia](https://esolia.com/), [@rickcogley](https://github.com/rickcogley)'s company.
|
||||
|
||||
[Multihost](https://gohugo.io/content-management/multilingual/#configure-multilingual-multihost) means that you can have a **`baseURL` per language**, for example, `https://no.example.com` and `https://en.example.com`. This is seamlessly integrated, and the built-in web server with live reload and `navigateToChanged` etc. just works. A related enhancement in this release is the support for **as many static dirs as you need**, with intelligent language overrides, forming a big union file system. Add to that several other language related fixes and enhancements, it is safe to say that this is the version you want for multilingual Hugo sites!
|
||||
|
||||
This release represents **44 contributions by 7 contributors** to the main Hugo code base.
|
||||
[@bep](https://github.com/bep) leads the Hugo development with a significant amount of contributions, but also a big shoutout to [@kaushalmodi](https://github.com/kaushalmodi), [@natefinch](https://github.com/natefinch), and [@betaveros](https://github.com/betaveros) for their ongoing contributions.
|
||||
And as always a big thanks to [@digitalcraftsman](https://github.com/digitalcraftsman) for his relentless work on keeping the documentation and the themes site in pristine condition.
|
||||
|
||||
Many have also been busy writing and fixing the documentation in [hugoDocs](https://github.com/gohugoio/hugoDocs),
|
||||
which has received **13 contributions by 9 contributors**. A special thanks to [@oncletom](https://github.com/oncletom), [@kaushalmodi](https://github.com/kaushalmodi), [@XhmikosR](https://github.com/XhmikosR), and [@digitalcraftsman](https://github.com/digitalcraftsman) for their work on the documentation site.
|
||||
|
||||
|
||||
Hugo now has:
|
||||
|
||||
* 21105+ [stars](https://github.com/gohugoio/hugo/stargazers)
|
||||
* 455+ [contributors](https://github.com/gohugoio/hugo/graphs/contributors)
|
||||
* 184+ [themes](http://themes.gohugo.io/)
|
||||
|
||||
## Notes
|
||||
|
||||
* For mapping of translated content, Hugo now considers the full path of the content file, which makes it possible with translation of duplicate content filenames such as `index.md`. A specific translation key can be specified with the new `translationKey` front matter variable. See [#2699](https://github.com/gohugoio/hugo/issues/2699).
|
||||
|
||||
|
||||
## Enhancements
|
||||
|
||||
### Language related
|
||||
|
||||
* Support unknown language codes [23ba779f](https://github.com/gohugoio/hugo/commit/23ba779fab90ce45cddd68b4f49a2515ce6d4878) [@bep](https://github.com/bep) [#3564](https://github.com/gohugoio/hugo/issues/3564)
|
||||
* Fix `.IsTranslated` with identical filenames [b3daa1f4](https://github.com/gohugoio/hugo/commit/b3daa1f4bf1b84bcc5da028257ba609be74e3ecc) [@bep](https://github.com/bep) [#2699](https://github.com/gohugoio/hugo/issues/2699)
|
||||
* Fall back to unstranslated base template [0a81a6b4](https://github.com/gohugoio/hugo/commit/0a81a6b4bae3de53aa9c179b855c671a2d30eec7) [@bep](https://github.com/bep) [#3893](https://github.com/gohugoio/hugo/issues/3893)
|
||||
* Add support for multiple static dirs [60dfb9a6](https://github.com/gohugoio/hugo/commit/60dfb9a6e076200ab3ca3fd30e34bb3c14e0a893) [@bep](https://github.com/bep) [#36](https://github.com/gohugoio/hugo/issues/36)[#4027](https://github.com/gohugoio/hugo/issues/4027)
|
||||
* Add multilingual multihost support [2e046576](https://github.com/gohugoio/hugo/commit/2e0465764b5dacc511b977b1c9aa07324ad0ee9c) [@bep](https://github.com/bep) [#4027](https://github.com/gohugoio/hugo/issues/4027)
|
||||
|
||||
### Templates
|
||||
|
||||
* Refactor `Mod` with `cast` [76dc811c](https://github.com/gohugoio/hugo/commit/76dc811c6539b2ed8b4d3b22693e5088b9f6ecfe) [@artem-sidorenko](https://github.com/artem-sidorenko)
|
||||
* Add support for height argument to figure shortcode [488631fe](https://github.com/gohugoio/hugo/commit/488631fe0abc3667355345c7eb98ba7a2204deb5) [@kaushalmodi](https://github.com/kaushalmodi) [#4014](https://github.com/gohugoio/hugo/issues/4014)
|
||||
|
||||
### Core
|
||||
|
||||
* Use ms precision for static change logging [bb048d81](https://github.com/gohugoio/hugo/commit/bb048d811d3977adb10656335cd339cd8c945a25) [@bep](https://github.com/bep)
|
||||
* Update Chroma to get the latest SASS lexer [b32ffed6](https://github.com/gohugoio/hugo/commit/b32ffed6abc67646cad89e163846f3ffef29cec8) [@bep](https://github.com/bep) [#4069](https://github.com/gohugoio/hugo/issues/4069)
|
||||
* Bump to Go 1.9.2 [9299a16c](https://github.com/gohugoio/hugo/commit/9299a16c9952a284d3ac3f31d2662f1812f77768) [@bep](https://github.com/bep) [#4064](https://github.com/gohugoio/hugo/issues/4064)
|
||||
* Update Travis and snapcraft to Go 1.9.2 [77cbd001](https://github.com/gohugoio/hugo/commit/77cbd001ff6b2e0aaa48566ef2af49ca68e19af9) [@bep](https://github.com/bep) [#4064](https://github.com/gohugoio/hugo/issues/4064)
|
||||
* Handle Taxonomy permalinks [d9a78b61](https://github.com/gohugoio/hugo/commit/d9a78b61adefe8e1803529f4774185874af85148) [@betaveros](https://github.com/betaveros) [#1208](https://github.com/gohugoio/hugo/issues/1208)
|
||||
|
||||
|
||||
### Other
|
||||
|
||||
* Support Fast Render mode with sub-path in baseURL [31641033](https://github.com/gohugoio/hugo/commit/3164103310fbca1211cfa9ce4a5eb7437854b6ad) [@bep](https://github.com/bep) [#3981](https://github.com/gohugoio/hugo/issues/3981)
|
||||
* Simplify Site benchmarks [c3c10f2c](https://github.com/gohugoio/hugo/commit/c3c10f2c7ce4ee11186f51161943efc8b37a28c9) [@bep](https://github.com/bep)
|
||||
* Replace `make` with `mage` to build Hugo [#3969](https://github.com/gohugoio/hugo/issues/3969)
|
||||
* Convert to `dep` as dependency/vendor manager for Hugo [#3988](https://github.com/gohugoio/hugo/issues/3988)
|
||||
* Pre-allocate some slices [a9be687b](https://github.com/gohugoio/hugo/commit/a9be687b81df01c7343f78f0d3760042f467baa4) [@bep](https://github.com/bep)
|
||||
|
||||
## Fixes
|
||||
|
||||
### Templates
|
||||
|
||||
* Make sure only one instance of a cached partial is rendered [#4086](https://github.com/gohugoio/hugo/issues/4086)
|
||||
|
||||
### Other
|
||||
|
||||
* Fix broken shortcodes for `Ace` and `Amber` [503ca6de](https://github.com/gohugoio/hugo/commit/503ca6de6ceb0b4af533f9efeff917d6f3871278) [@bep](https://github.com/bep) [#4051](https://github.com/gohugoio/hugo/issues/4051)
|
||||
* Fix error handling in `mage` build [c9c19d79](https://github.com/gohugoio/hugo/commit/c9c19d794537cf76ff281788c3d6cf5f2beac54d) [@natefinch](https://github.com/natefinch)
|
||||
* Fix `hugo -w` [fa53b13c](https://github.com/gohugoio/hugo/commit/fa53b13ca0ffb1db6ed20f5353661d3f8a5fd455) [@bep](https://github.com/bep) [#3980](https://github.com/gohugoio/hugo/issues/3980)
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
---
|
||||
date: 2017-11-27
|
||||
title: "Hugo 0.31.1: One Bugfix!"
|
||||
description: "Fixes broken `--appendPort=false`."
|
||||
slug: "0.31.1"
|
||||
categories: ["Releases"]
|
||||
images:
|
||||
- images/blog/hugo-bug-poster.png
|
||||
|
||||
---
|
||||
|
||||
This is a bug-fix release with one important bug fix:
|
||||
|
||||
* Fix broken `--appendPort=false` [8afd7d9c](https://github.com/gohugoio/hugo/commit/8afd7d9ceb0d168300e3399c6e87a355a88c9a28) [@bep](https://github.com/bep) [#4111](https://github.com/gohugoio/hugo/issues/4111)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
|
||||
---
|
||||
date: 2017-12-31
|
||||
title: "0.32"
|
||||
description: "0.32"
|
||||
slug: "0.32"
|
||||
categories: ["Releases"]
|
||||
---
|
||||
|
||||
Hugo `0.32` features **Page Bundles and Image Processing** by [@bep](https://github.com/bep), which is very cool and useful on so many levels. Read about it in more detail in the [Hugo documentation](https://gohugo.io/about/new-in-032/), but some of the highlights include:
|
||||
|
||||
* Automatic bundling of a content page with its resources. Resources can be anything: Images, `JSON` files ... and also other content pages.
|
||||
* A `Resource` will have its `RelPermalink` and `Permalink` relative to the "owning page". This makes the complete article with both text and images portable (just send a ZIP file with a folder to your editor), and it can be previewed directly on GitHub.
|
||||
* Powerful and simple to use image processing with the new `.Resize`, `.Fill`, and `.Fit` methods on the new `Image` resource.
|
||||
* Full support for symbolic links inside `/content`, both for regular files and directories.
|
||||
|
||||
The built-in benchmarks in Hugo show that this is also the [fastest and most memory effective](https://gist.github.com/bep/2a9bbd221de2da5d39c8b32085c658f7) Hugo version to date. But note that the build time total reported in the console is now adjusted to be the *real total*, including the copy of static files. So, if it reports more milliseconds, it is still most likely faster ...
|
||||
|
||||
This release represents **30 contributions by 7 contributors** to the main Hugo code base.
|
||||
|
||||
[@bep](https://github.com/bep) leads the Hugo development with a significant amount of contributions, but also a big shoutout to [@betaveros](https://github.com/betaveros), [@chaseadamsio](https://github.com/chaseadamsio), and [@kropp](https://github.com/kropp). And as always big thanks to [@digitalcraftsman](https://github.com/digitalcraftsman) for his relentless work on keeping the documentation and the themes site in pristine condition.
|
||||
|
||||
Many have also been busy writing and fixing the documentation in [hugoDocs](https://github.com/gohugoio/hugoDocs),
|
||||
which has received **17 contributions by 7 contributors**. A special thanks to [@bep](https://github.com/bep), [@felicianotech](https://github.com/felicianotech), [@maiki](https://github.com/maiki), and [@carlchengli](https://github.com/carlchengli) for their work on the documentation site.
|
||||
|
||||
Hugo now has:
|
||||
|
||||
* 22061+ [stars](https://github.com/gohugoio/hugo/stargazers)
|
||||
* 454+ [contributors](https://github.com/gohugoio/hugo/graphs/contributors)
|
||||
* 193+ [themes](http://themes.gohugo.io/)
|
||||
|
||||
Today is **New Year's Eve.** It is the last day of 2017, a year that have seen a **string of pearls of Hugo releases**, making Hugo _the_ top choice for website development:
|
||||
|
||||
* 0.32, December 2017: **Page Bundles and Image Processing** edition.
|
||||
* 0.31, November 2017: The Language **Multihost Edition!** with one `baseURL` per language.
|
||||
* 0.30, October 2017: The Race Car Edition with the **Fast Render Mode**.
|
||||
* 0.29, September 2017: Added **Template Metrics**.
|
||||
* 0.28, September 2017: **Blistering fast and native syntax highlighting** from [Chroma](https://github.com/alecthomas/chroma).
|
||||
* 0.27, September 2017: Fast and flexible **Related Content.**
|
||||
* 0.26, August 2017: The **Language Style Edition** with AP Style or Chicago Style Title Case and « French Guillemets ».
|
||||
* 0.25, July 2017: The **Kinder Surprise** edition added, among other cool things, `hugo server --navigateToChanged` which navigates to the content page you start editing.
|
||||
* 0.24, June 2017: Was **The Revival of the Archetypes!** Now archetype files, i.e. the content file templates, can include template syntax with all of Hugo's functions and variables.
|
||||
* 0.23, June 2017: Hugo moved to it's own GitHub organization, **gohugoio**.
|
||||
* 0.22, June 2017: Added **nested sections**, a long sought after feature.
|
||||
* 0.21, May 2017: Full support for shortcodes per output format (think **AMP**).
|
||||
* 0.20, April 2017: Was all about **Custom Output Formats**.
|
||||
* 0.19, February 2017: Native Emacs Org-mode content support and lots of internal upgrades.
|
||||
|
||||
## Notes
|
||||
|
||||
* The build total in the console is now the ... total (i.e. it now includes both the copy of the static files and the Hugo build). So if your Hugo site seems to build slightly slower, it is in reality probably slightly faster than before this release.
|
||||
* Images and other static resources in folders with "_index.md" will have its `RelPermalink` relative to its page.
|
||||
* Images and other static resources in or below "index.md" folders will have its `RelPermalink` relative to its page (respecting permalink settings etc.)
|
||||
* Content pages in or below "index.md" will not get their own `URL`, but will be part of the `.Resources` collection of its page.
|
||||
* `.Site.Files` is deprecated.
|
||||
* Hugo no longer minfies CSS files inside `/content`. This was an undocumented "proof of concept feature". We may revisit the "assets handling" in a future release.
|
||||
* `Page.GetParam`does not lowercase your result anymore. If you really want to lowercase your params, do it with `.GetParam "myparam" | lower` or similar.
|
||||
|
||||
Previously deprecated that will now `ERROR`:
|
||||
|
||||
* `disable404`: Use `disableKinds=["404"]`
|
||||
* `disableRSS`: Use `disableKinds=["RSS"]`
|
||||
* `disableSitemap`: Use `disableKinds=["sitemap"]`
|
||||
* `disableRobotsTXT`: Use `disableKinds=["robotsTXT"]`
|
||||
|
||||
## Enhancements
|
||||
|
||||
* Add `.Title` and `.Page` to `MenuEntry` [9df3736f](https://github.com/gohugoio/hugo/commit/9df3736fec164c51d819797416dc263f2869be77) [@rmetzler](https://github.com/rmetzler) [#2784](https://github.com/gohugoio/hugo/issues/2784)
|
||||
* Add `Pandoc` support [e69da7a4](https://github.com/gohugoio/hugo/commit/e69da7a4cb725987f153707bf2fc59c135007e2a) [@betaveros](https://github.com/betaveros) [#234](https://github.com/gohugoio/hugo/issues/234)
|
||||
* Implement Page bundling and image handling [3cdf19e9](https://github.com/gohugoio/hugo/commit/3cdf19e9b7e46c57a9bb43ff02199177feb55768) [@bep](https://github.com/bep) [#3651](https://github.com/gohugoio/hugo/issues/3651)[#3158](https://github.com/gohugoio/hugo/issues/3158)[#1014](https://github.com/gohugoio/hugo/issues/1014)[#2021](https://github.com/gohugoio/hugo/issues/2021)[#1240](https://github.com/gohugoio/hugo/issues/1240)[#3757](https://github.com/gohugoio/hugo/issues/3757)
|
||||
* Make `chomp` return the type it receives [22cd89ad](https://github.com/gohugoio/hugo/commit/22cd89adc4792a3b55389d38acd4acfae3786775) [@kropp](https://github.com/kropp) [#2187](https://github.com/gohugoio/hugo/issues/2187)
|
||||
* Reuse the `BlackFriday` config instance when possible [db4b7a5c](https://github.com/gohugoio/hugo/commit/db4b7a5c6742c75f9cd9627d3b054d3a72802ec8) [@bep](https://github.com/bep)
|
||||
* Remove the goroutines from the shortcode lexer [24369410](https://github.com/gohugoio/hugo/commit/243694102a60da2fb1050020f68384539f9f9ef5) [@bep](https://github.com/bep)
|
||||
* Improve site benchmarks [051fa343](https://github.com/gohugoio/hugo/commit/051fa343d06d6c070df742f7cbd125432fcab665) [@bep](https://github.com/bep)
|
||||
* Update `Chroma` to `v0.2.0` [79892101](https://github.com/gohugoio/hugo/commit/7989210120dbde78da3741e2ef01b13f4aa78692) [@bep](https://github.com/bep) [#4087](https://github.com/gohugoio/hugo/issues/4087)
|
||||
* Update `goorgeous` to `v1.1.0` [7f2ae3ef](https://github.com/gohugoio/hugo/commit/7f2ae3ef39f27a9bd26ddb9258b073a840faf491) [@chaseadamsio](https://github.com/chaseadamsio)
|
||||
* Add test for homepage content for all rendering engines [407c2402](https://github.com/gohugoio/hugo/commit/407c24020ef2db90cf33fd07e7522b2257013722) [@bep](https://github.com/bep) [#4166](https://github.com/gohugoio/hugo/issues/4166)
|
||||
* Add output formats definition to benchmarks [a2d81ce9](https://github.com/gohugoio/hugo/commit/a2d81ce983d45b5742c93bd472503c88286f099a) [@bep](https://github.com/bep)
|
||||
|
||||
## Fixes
|
||||
|
||||
### Templates
|
||||
|
||||
* Do not unescape input to `highlight` [c067f345](https://github.com/gohugoio/hugo/commit/c067f34558b82455b63b9ce8f5983b4b4849c7cf) [@bep](https://github.com/bep) [#4179](https://github.com/gohugoio/hugo/issues/4179)
|
||||
* Properly close image file in `imageConfig` [6d79beb5](https://github.com/gohugoio/hugo/commit/6d79beb5f67dbb54d7714c3195addf9d8e3924e8) [@bep](https://github.com/bep)
|
||||
* Fix `opengraph` video range template [23f69efb](https://github.com/gohugoio/hugo/commit/23f69efb3914946b39ce673fcc0f2e3a9ed9d878) [@drlogout](https://github.com/drlogout) [#4136](https://github.com/gohugoio/hugo/issues/4136)
|
||||
* Fix `humanize` for multi-byte runes [e7652180](https://github.com/gohugoio/hugo/commit/e7652180a13ce149041c48a1c2754c471df569c8) [@bep](https://github.com/bep) [#4133](https://github.com/gohugoio/hugo/issues/4133)
|
||||
|
||||
### Other
|
||||
|
||||
* Fix broken live reload without a server port. [25114986](https://github.com/gohugoio/hugo/commit/25114986086e5877a0b4108d8cf5e4e95f377241) [@sainaen](https://github.com/sainaen) [#4141](https://github.com/gohugoio/hugo/issues/4141)
|
||||
* Make sure all language homes are always re-rendered in fast render mode [72903be5](https://github.com/gohugoio/hugo/commit/72903be587e9c4e3644f60b11e26238ec03da2db) [@bep](https://github.com/bep) [#4125](https://github.com/gohugoio/hugo/issues/4125)
|
||||
* Do not `tolower` result from Page.GetParam [1c114d53](https://github.com/gohugoio/hugo/commit/1c114d539b0755724443fe28c90b12fe2a19085a) [@bep](https://github.com/bep) [#4187](https://github.com/gohugoio/hugo/issues/4187)
|
||||
@@ -51,17 +51,15 @@
|
||||
|
||||
`extensions`
|
||||
: default: **`[]`** <br>
|
||||
Blackfriday flag: **`EXTENSION_*`** <br>
|
||||
Purpose: Enable one or more Blackfriday's Markdown extensions (if they aren't Hugo defaults). <br>
|
||||
Example: Include `hardLineBreak` in the list to enable Blackfriday's `EXTENSION_HARD_LINK_BREAK`. <br>
|
||||
*See [Blackfriday extensions](#blackfriday-extensions) section for more information.*
|
||||
Purpose: Enable one or more Blackfriday's Markdown extensions (**`EXTENSION_*`**). <br>
|
||||
Example: Include `hardLineBreak` in the list to enable Blackfriday's `EXTENSION_HARD_LINE_BREAK`. <br>
|
||||
*See [Blackfriday extensions](#blackfriday-extensions) section for information on all extensions.*
|
||||
|
||||
`extensionsmask`
|
||||
: default: **`[]`** <br>
|
||||
Blackfriday flag: **`EXTENSION_*`** <br>
|
||||
Purpose: Enable one or more of Blackfriday's Markdown extensions (if they aren't Hugo defaults). <br>
|
||||
Purpose: Disable one or more of Blackfriday's Markdown extensions (**`EXTENSION_*`**). <br>
|
||||
Example: Include `autoHeaderIds` as `false` in the list to disable Blackfriday's `EXTENSION_AUTO_HEADER_IDS`. <br>
|
||||
*See [Blackfriday extensions](#blackfriday-extensions) section for more information.*
|
||||
*See [Blackfriday extensions](#blackfriday-extensions) section for information on all extensions.*
|
||||
|
||||
## Blackfriday extensions
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
.CurrentSection
|
||||
: the page's current section. The value can be the page itself if it is a section or the homepage.
|
||||
|
||||
.InSection $anotherPage
|
||||
: whether the given page is in the current section. Note that this will always return false for pages that are not either regular, home or section pages.
|
||||
|
||||
.IsAncestor $anotherPage
|
||||
: whether the current page is an ancestor of the given page. Note that this method is not relevant for taxonomy lists and taxonomy terms pages.
|
||||
|
||||
.IsDescendant $anotherPage
|
||||
: whether the current page is a descendant of the given page. Note that this method is not relevant for taxonomy lists and taxonomy terms pages.
|
||||
|
||||
.Parent
|
||||
: a section's parent section or a page's section.
|
||||
|
||||
.Section
|
||||
: the [section](/content-management/sections/) this content belongs to. **Note:** For nested sections, this is the first path element in the directory, for example, `/blog/funny/mypost/ => blog`.
|
||||
|
||||
.Sections
|
||||
: the [sections](/content-management/sections/) below this content.
|
||||
@@ -101,7 +101,7 @@ Go templates only ship with a few basic functions but also provide a mechanism f
|
||||
=> true (i.e., since 1 is less than 2)
|
||||
```
|
||||
|
||||
Note that both examples make us of Go template's [math functions][].
|
||||
Note that both examples make use of Go template's [math functions][].
|
||||
|
||||
{{% note "Additional Boolean Operators" %}}
|
||||
There are more boolean operators than those listed in the Hugo docs in the [Golang template documentation](http://golang.org/pkg/text/template/#hdr-Functions).
|
||||
|
||||
@@ -37,8 +37,6 @@ This is the full set of built-in media types in Hugo:
|
||||
|
||||
To add or modify a media type, define it in a `mediaTypes` section in your [site configuration][config], either for all sites or for a given language.
|
||||
|
||||
Example in `config.toml`:
|
||||
|
||||
```
|
||||
[mediaTypes]
|
||||
[mediaTypes."text/enriched"]
|
||||
@@ -49,6 +47,21 @@ Example in `config.toml`:
|
||||
|
||||
The above example adds one new media type, `text/enriched`, and changes the suffix for the built-in `text/html` media type.
|
||||
|
||||
**Note:** these media types are configured for **your output formats**. If you want to redefine one of Hugo's default output formats (e.g. `HTML`), you also need to redefine the output format. So, if you want to change the suffix of the `HTML` output format from `html` (default) to `htm`:
|
||||
|
||||
```toml
|
||||
[mediaTypes]
|
||||
[mediaTypes."text/html"]
|
||||
suffix = "htm"
|
||||
|
||||
# Redefine HTML to update its media type.
|
||||
[outputFormats]
|
||||
[outputFormats.HTML]
|
||||
mediaType = "text/html"
|
||||
```
|
||||
|
||||
**Note** that for the above to work, you also need to add an`outputs` definition in your site config.
|
||||
|
||||
## Output Formats
|
||||
|
||||
Given a media type and some additional configuration, you get an `Output Format`:
|
||||
@@ -61,7 +74,7 @@ This is the full set of Hugo's built-in output formats:
|
||||
* The `MediaType` must match the `Type` of an already defined media type.
|
||||
* You can define new output formats or redefine built-in output formats; e.g., if you want to put `AMP` pages in a different path.
|
||||
|
||||
To add or modify an output format, define it in an `outputFormats` section in your site's [configuration file](/templates/configuration/), either for all sites or for a given language.
|
||||
To add or modify an output format, define it in an `outputFormats` section in your site's [configuration file](/getting-started/configuration/), either for all sites or for a given language.
|
||||
|
||||
```
|
||||
[outputFormats.MyEnrichedFormat]
|
||||
|
||||
@@ -124,7 +124,7 @@ You could then include the following as part of your shortcode templating:
|
||||
<img src="{{.Get "src" }}" alt="">
|
||||
{{ else }}
|
||||
<img src="{{.Get 0}}" alt="">
|
||||
{{ end }}.
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
See the [example Vimeo shortcode][vimeoexample] below for `.IsNamedParams` in action.
|
||||
@@ -150,7 +150,7 @@ Let's assume you would like to keep mentions of your copyright year current in y
|
||||
```
|
||||
|
||||
{{< code file="/layouts/shortcodes/year.html" >}}
|
||||
{{ .Page.Now.Year }}
|
||||
{{ now.Format "2006" }}
|
||||
{{< /code >}}
|
||||
|
||||
### Single Positional Example: `youtube`
|
||||
|
||||
@@ -78,6 +78,9 @@ A Taxonomy is a `map[string]WeightedPages`.
|
||||
.ByCount
|
||||
: Returns an OrderedTaxonomy (slice) ordered by number of entries.
|
||||
|
||||
.Reverse
|
||||
: Returns an OrderedTaxonomy (slice) in reverse order. Must be used with an OrderedTaxonomy.
|
||||
|
||||
### OrderedTaxonomy
|
||||
|
||||
Since Maps are unordered, an OrderedTaxonomy is a special structure that has a defined order.
|
||||
@@ -160,6 +163,17 @@ Taxonomies can be ordered by either alphabetical key or by the number of content
|
||||
</ul>
|
||||
```
|
||||
|
||||
### Order by Least Popular Example
|
||||
|
||||
```
|
||||
<ul>
|
||||
{{ $data := .Data }}
|
||||
{{ range $key, $value := .Data.Terms.ByCount.Reverse }}
|
||||
<li><a href="{{ $.Site.LanguagePrefix }}/{{ $data.Plural }}/{{ $value.Name | urlize }}"> {{ $value.Name }} </a> {{ $value.Count }} </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
```
|
||||
|
||||
<!-- [See Also Taxonomy Lists](/templates/list/) -->
|
||||
|
||||
## Order Content within Taxonomies
|
||||
|
||||
@@ -24,25 +24,25 @@ For information on creating shortcodes and templates that tap into Hugo's file-r
|
||||
|
||||
The `.File` object contains the following fields:
|
||||
|
||||
`.File.Path`
|
||||
.File.Path
|
||||
: the original relative path of the page (e.g., `content/posts/foo.en.md`)
|
||||
|
||||
`.File.LogicalName`
|
||||
.File.LogicalName
|
||||
: the name of the content file that represents a page (e.g., `foo.en.md`)
|
||||
|
||||
`.File.TranslationBaseName`
|
||||
.File.TranslationBaseName
|
||||
: the filename without extension or optional language identifier (e.g., `foo`)
|
||||
|
||||
`.File.BaseFileName`
|
||||
.File.BaseFileName
|
||||
: the filename without extension (e.g., `foo.en`)
|
||||
|
||||
`.File.Ext`
|
||||
.File.Ext
|
||||
: the file extension of the content file (e.g., `md`); this can also be called using `.File.Extension` as well. Note that it is *only* the extension without `.`.
|
||||
|
||||
`.File.Lang`
|
||||
.File.Lang
|
||||
: the language associated with the given file if Hugo's [Multilingual features][multilingual] are enabled (e.g., `en`)
|
||||
|
||||
`.File.Dir`
|
||||
.File.Dir
|
||||
: given the path `content/posts/dir1/dir2/`, the relative directory path of the content file will be returned (e.g., `posts/dir1/dir2/`)
|
||||
|
||||
[Multilingual]: /content-management/multilingual/
|
||||
@@ -33,22 +33,22 @@ Hugo's Git integrations should be fairly performant but *can* increase your buil
|
||||
|
||||
The `GitInfo` object contains the following fields:
|
||||
|
||||
`.AbbreviatedHash`
|
||||
.AbbreviatedHash
|
||||
: the abbreviated commit hash (e.g., `866cbcc`)
|
||||
|
||||
`.AuthorName`
|
||||
.AuthorName
|
||||
: the author's name, respecting `.mailmap`
|
||||
|
||||
`.AuthorEmail`
|
||||
.AuthorEmail
|
||||
: the author's email address, respecting `.mailmap`
|
||||
|
||||
`.AuthorDate`
|
||||
.AuthorDate
|
||||
: the author date
|
||||
|
||||
`.Hash`
|
||||
.Hash
|
||||
: the commit hash (e.g., `866cbccdab588b9908887ffd3b4f2667e94090c3`)
|
||||
|
||||
`.Subject`
|
||||
.Subject
|
||||
: commit message subject (e.g., `tpl: Add custom index function`)
|
||||
|
||||
## `.Lastmod`
|
||||
|
||||
@@ -21,16 +21,16 @@ wip: false
|
||||
|
||||
It contains the following fields:
|
||||
|
||||
`.Hugo.Generator`
|
||||
.Hugo.Generator
|
||||
: `<meta>` tag for the version of Hugo that generated the site. `.Hugo.Generator` outputs a *complete* HTML tag; e.g. `<meta name="generator" content="Hugo 0.18" />`
|
||||
|
||||
`.Hugo.Version`
|
||||
.Hugo.Version
|
||||
: the current version of the Hugo binary you are using e.g. `0.13-DEV`<br>
|
||||
|
||||
`.Hugo.CommitHash`
|
||||
.Hugo.CommitHash
|
||||
: the git commit hash of the current Hugo binary e.g. `0e8bed9ccffba0df554728b46c5bbf6d78ae5247`
|
||||
|
||||
`.Hugo.BuildDate`
|
||||
.Hugo.BuildDate
|
||||
: the compile date of the current Hugo binary formatted with RFC 3339 e.g. `2002-10-02T10:00:00-05:00`<br>
|
||||
|
||||
{{% note "Use the Hugo Generator Tag" %}}
|
||||
|
||||
@@ -20,31 +20,31 @@ toc: false
|
||||
|
||||
The [menu template][] has the following properties:
|
||||
|
||||
`.URL`
|
||||
.URL
|
||||
: string
|
||||
|
||||
`.Name`
|
||||
.Name
|
||||
: string
|
||||
|
||||
`.Menu`
|
||||
.Menu
|
||||
: string
|
||||
|
||||
`.Identifier`
|
||||
.Identifier
|
||||
: string
|
||||
|
||||
`.Pre`
|
||||
.Pre
|
||||
: template.HTML
|
||||
|
||||
`.Post`
|
||||
.Post
|
||||
: template.HTML
|
||||
|
||||
`.Weight`
|
||||
.Weight
|
||||
: int
|
||||
|
||||
`.Parent`
|
||||
.Parent
|
||||
: string
|
||||
|
||||
`.Children`
|
||||
.Children
|
||||
: Menu
|
||||
|
||||
[menu template]: /templates/menu-templates/
|
||||
@@ -26,59 +26,65 @@ See [`.Scratch`](/functions/scratch/) for page-scoped, writable variables.
|
||||
|
||||
## Page Variables
|
||||
|
||||
`.AlternativeOutputFormats`
|
||||
.AlternativeOutputFormats
|
||||
: contains all alternative formats for a given page; this variable is especially useful `link rel` list in your site's `<head>`. (See [Output Formats](/templates/output-formats/).)
|
||||
|
||||
`.Content`
|
||||
.Content
|
||||
: the content itself, defined below the front matter.
|
||||
|
||||
`.Data`
|
||||
.Data
|
||||
: the data specific to this type of page.
|
||||
|
||||
`.Date`
|
||||
.Date
|
||||
: the date associated with the page; `.Date` pulls from the `date` field in a content's front matter. See also `.ExpiryDate`, `.PublishDate`, and `.Lastmod`.
|
||||
|
||||
`.Description`
|
||||
.Description
|
||||
: the description for the page.
|
||||
|
||||
`.Draft`
|
||||
.Dir
|
||||
: the path of the folder containing this content file. The path is relative to the `content` folder.
|
||||
|
||||
.Draft
|
||||
: a boolean, `true` if the content is marked as a draft in the front matter.
|
||||
|
||||
`.ExpiryDate`
|
||||
.ExpiryDate
|
||||
: the date on which the content is scheduled to expire; `.ExpiryDate` pulls from the `expirydate` field in a content's front matter. See also `.PublishDate`, `.Date`, and `.Lastmod`.
|
||||
|
||||
`.FuzzyWordCount`
|
||||
.File
|
||||
: filesystem-related data for this content file. See also [File Variables][].
|
||||
|
||||
.FuzzyWordCount
|
||||
: the approximate number of words in the content.
|
||||
|
||||
`.Hugo`
|
||||
.Hugo
|
||||
: see [Hugo Variables](/variables/hugo/).
|
||||
|
||||
`.IsHome`
|
||||
.IsHome
|
||||
: `true` in the context of the [homepage](/templates/homepage/).
|
||||
|
||||
`.IsNode`
|
||||
.IsNode
|
||||
: always `false` for regular content pages.
|
||||
|
||||
`.IsPage`
|
||||
.IsPage
|
||||
: always `true` for regular content pages.
|
||||
|
||||
`.IsTranslated`
|
||||
.IsTranslated
|
||||
: `true` if there are translations to display.
|
||||
|
||||
`.Keywords`
|
||||
.Keywords
|
||||
: the meta keywords for the content.
|
||||
|
||||
`.Kind`
|
||||
.Kind
|
||||
: the page's *kind*. Possible return values are `page`, `home`, `section`, `taxonomy`, or `taxonomyTerm`. Note that there are also `RSS`, `sitemap`, `robotsTXT`, and `404` kinds, but these are only available during the rendering of each of these respective page's kind and therefore *not* available in any of the `Pages` collections.
|
||||
|
||||
`.Lang`
|
||||
.Lang
|
||||
: language taken from the language extension notation.
|
||||
|
||||
`.Language`
|
||||
.Language
|
||||
: a language object that points to the language's definition in the site
|
||||
`config`.
|
||||
|
||||
`.Lastmod`
|
||||
.Lastmod
|
||||
: the date the content was last modified. `.Lastmod` pulls from the `lastmod` field in a content's front matter.
|
||||
|
||||
- If `lastmod` is not set, and `.GitInfo` feature is disabled, the front matter `date` field will be used.
|
||||
@@ -86,95 +92,98 @@ See [`.Scratch`](/functions/scratch/) for page-scoped, writable variables.
|
||||
|
||||
See also `.ExpiryDate`, `.Date`, `.PublishDate`, and [`.GitInfo`][gitinfo].
|
||||
|
||||
`.LinkTitle`
|
||||
.LinkTitle
|
||||
: access when creating links to the content. If set, Hugo will use the `linktitle` from the front matter before `title`.
|
||||
|
||||
`.Next`
|
||||
.Next
|
||||
: pointer to the following content (based on the `publishdate` field in front matter).
|
||||
|
||||
`.NextInSection`
|
||||
.NextInSection
|
||||
: pointer to the following content within the same section (based on `publishdate` field in front matter).
|
||||
|
||||
`.OutputFormats`
|
||||
.OutputFormats
|
||||
: contains all formats, including the current format, for a given page. Can be combined the with [`.Get` function](/functions/get/) to grab a specific format. (See [Output Formats](/templates/output-formats/).)
|
||||
|
||||
`.Pages`
|
||||
.Pages
|
||||
: a collection of associated pages. This value will be `nil` for regular content pages. `.Pages` is an alias for `.Data.Pages`.
|
||||
|
||||
`.Permalink`
|
||||
.Permalink
|
||||
: the Permanent link for this page; see [Permalinks](/content-management/urls/)
|
||||
|
||||
`.Plain`
|
||||
.Plain
|
||||
: the Page content stripped of HTML tags and presented as a string.
|
||||
|
||||
`.PlainWords`
|
||||
.PlainWords
|
||||
: the Page content stripped of HTML as a `[]string` using Go's [`strings.Fields`](https://golang.org/pkg/strings/#Fields) to split `.Plain` into a slice.
|
||||
|
||||
`.Prev`
|
||||
.Prev
|
||||
: Pointer to the previous content (based on `publishdate` in front matter).
|
||||
|
||||
`.PrevInSection`
|
||||
.PrevInSection
|
||||
: Pointer to the previous content within the same section (based on `publishdate` in front matter). For example, `{{if .PrevInSection}}{{.PrevInSection.Permalink}}{{end}}`.
|
||||
|
||||
`.PublishDate`
|
||||
.PublishDate
|
||||
: the date on which the content was or will be published; `.Publishdate` pulls from the `publishdate` field in a content's front matter. See also `.ExpiryDate`, `.Date`, and `.Lastmod`.
|
||||
|
||||
`.RSSLink`
|
||||
.RSSLink
|
||||
: link to the taxonomies' RSS link.
|
||||
|
||||
`.RawContent`
|
||||
.RawContent
|
||||
: raw markdown content without the front matter. Useful with [remarkjs.com](
|
||||
http://remarkjs.com)
|
||||
|
||||
`.ReadingTime`
|
||||
.ReadingTime
|
||||
: the estimated time, in minutes, it takes to read the content.
|
||||
|
||||
`.Ref`
|
||||
.Ref
|
||||
: returns the permalink for a given reference (e.g., `.Ref "sample.md"`). `.Ref` does *not* handle in-page fragments correctly. See [Cross References](/content-management/cross-references/).
|
||||
|
||||
`.RelPermalink`
|
||||
.RelPermalink
|
||||
: the relative permanent link for this page.
|
||||
|
||||
`.RelRef`
|
||||
.RelRef
|
||||
: returns the relative permalink for a given reference (e.g., `RelRef
|
||||
"sample.md"`). `.RelRef` does *not* handle in-page fragments correctly. See [Cross References](/content-management/cross-references/).
|
||||
|
||||
`.Section`
|
||||
: the [section](/content-management/sections/) this content belongs to.
|
||||
|
||||
`.Site`
|
||||
.Site
|
||||
: see [Site Variables](/variables/site/).
|
||||
|
||||
`.Summary`
|
||||
.Summary
|
||||
: a generated summary of the content for easily showing a snippet in a summary view. The breakpoint can be set manually by inserting <code><!--more--></code> at the appropriate place in the content page. See [Content Summaries](/content-management/summaries/) for more details.
|
||||
|
||||
`.TableOfContents`
|
||||
.TableOfContents
|
||||
: the rendered [table of contents](/content-management/toc/) for the page.
|
||||
|
||||
`.Title`
|
||||
.Title
|
||||
: the title for this page.
|
||||
|
||||
`.Translations`
|
||||
.Translations
|
||||
: a list of translated versions of the current page. See [Multilingual Mode](/content-management/multilingual/) for more information.
|
||||
|
||||
`.Truncated`
|
||||
.Truncated
|
||||
: a boolean, `true` if the `.Summary` is truncated. Useful for showing a "Read more..." link only when necessary. See [Summaries](/content-management/summaries/) for more information.
|
||||
|
||||
`.Type`
|
||||
.Type
|
||||
: the [content type](/content-management/types/) of the content (e.g., `post`).
|
||||
|
||||
`.URL`
|
||||
.URL
|
||||
: the URL for the page relative to the web root. Note that a `url` set directly in front matter overrides the default relative URL for the rendered page.
|
||||
|
||||
`.UniqueID`
|
||||
.UniqueID
|
||||
: the MD5-checksum of the content file's path.
|
||||
|
||||
`.Weight`
|
||||
.Weight
|
||||
: assigned weight (in the front matter) to this content, used in sorting.
|
||||
|
||||
`.WordCount`
|
||||
.WordCount
|
||||
: the number of words in the content.
|
||||
|
||||
## Section Variables and Methods
|
||||
|
||||
Also see [Sections](/content-management/sections/).
|
||||
|
||||
{{< readfile file="/content/readfiles/sectionvars.md" markdown="true" >}}
|
||||
|
||||
## Page-level Params
|
||||
|
||||
Any other value defined in the front matter in a content file, including taxonomies, will be made available as part of the `.Params` variable.
|
||||
@@ -273,3 +282,4 @@ The top-level key will be preferred. Therefore, the following method, when appli
|
||||
```
|
||||
|
||||
[gitinfo]: /variables/git/
|
||||
[File Variables]: /variables/files/
|
||||
|
||||
@@ -20,13 +20,13 @@ toc: false
|
||||
|
||||
[Shortcodes][shortcodes] have access to parameters delimited in the shortcode declaration via [`.Get`][getfunction], page- and site-level variables, and also the following shortcode-specific fields:
|
||||
|
||||
`.Parent`
|
||||
.Parent
|
||||
: provides access to the parent shortcode context in nested shortcodes. This can be very useful for inheritance of common shortcode parameters from the root.
|
||||
|
||||
`.IsNamedParams`
|
||||
.IsNamedParams
|
||||
: boolean that returns `true` when the shortcode in question uses [named rather than positional parameters][shortcodes]
|
||||
|
||||
`.Inner`
|
||||
.Inner
|
||||
: represents the content between the opening and closing shortcode tags when a [closing shortcode][markdownshortcode] is used
|
||||
|
||||
[getfunction]: /functions/get/
|
||||
|
||||
@@ -22,82 +22,82 @@ The following is a list of site-level (aka "global") variables. Many of these va
|
||||
|
||||
## Site Variables List
|
||||
|
||||
`.Site.AllPages`
|
||||
.Site.AllPages
|
||||
: array of all pages, regardless of their translation.
|
||||
|
||||
`.Site.Author`
|
||||
.Site.Author
|
||||
: a map of the authors as defined in the site configuration.
|
||||
|
||||
`.Site.BaseURL`
|
||||
.Site.BaseURL
|
||||
: the base URL for the site as defined in the site configuration.
|
||||
|
||||
`.Site.BuildDrafts`
|
||||
.Site.BuildDrafts
|
||||
: a boolean (default: `false`) to indicate whether to build drafts as defined in the site configuration.
|
||||
|
||||
`.Site.Copyright`
|
||||
.Site.Copyright
|
||||
: a string representing the copyright of your website as defined in the site configuration.
|
||||
|
||||
`.Site.Data`
|
||||
.Site.Data
|
||||
: custom data, see [Data Templates](/templates/data-templates/).
|
||||
|
||||
`.Site.DisqusShortname`
|
||||
.Site.DisqusShortname
|
||||
: a string representing the shortname of the Disqus shortcode as defined in the site configuration.
|
||||
|
||||
`.Site.Files`
|
||||
.Site.Files
|
||||
: all source files for the Hugo website.
|
||||
|
||||
`.Site.GoogleAnalytics`
|
||||
.Site.GoogleAnalytics
|
||||
: a string representing your tracking code for Google Analytics as defined in the site configuration.
|
||||
|
||||
`.Site.IsMultiLingual`
|
||||
.Site.IsMultiLingual
|
||||
: whether there are more than one language in this site. See [Multilingual](/content-management/multilingual/) for more information.
|
||||
|
||||
`.Site.Language.Lang`
|
||||
.Site.Language.Lang
|
||||
: the language code of the current locale (e.g., `en`).
|
||||
|
||||
`.Site.Language.LanguageName`
|
||||
.Site.Language.LanguageName
|
||||
: the full language name (e.g. `English`).
|
||||
|
||||
`.Site.Language.Weight`
|
||||
.Site.Language.Weight
|
||||
: the weight that defines the order in the `.Site.Languages` list.
|
||||
|
||||
`.Site.Language`
|
||||
.Site.Language
|
||||
: indicates the language currently being used to render the website. This object's attributes are set in site configurations' language definition.
|
||||
|
||||
`.Site.LanguageCode`
|
||||
.Site.LanguageCode
|
||||
: a string representing the language as defined in the site configuration. This is mostly used to populate the RSS feeds with the right language code.
|
||||
|
||||
`.Site.LanguagePrefix`
|
||||
.Site.LanguagePrefix
|
||||
: this can be used to prefix URLs to point to the correct language. It will even work when only one defined language. See also the functions [absLangURL](/functions/abslangurl/) and [relLangURL](/functions/rellangurl).
|
||||
|
||||
`.Site.Languages`
|
||||
.Site.Languages
|
||||
: an ordered list (ordered by defined weight) of languages.
|
||||
|
||||
`.Site.LastChange`
|
||||
.Site.LastChange
|
||||
: a string representing the date/time of the most recent change to your site. This string is based on the [`date` variable in the front matter](/content-management/front-matter) of your content pages.
|
||||
|
||||
`.Site.Menus`
|
||||
.Site.Menus
|
||||
: all of the menus in the site.
|
||||
|
||||
`.Site.Pages`
|
||||
.Site.Pages
|
||||
: array of all content ordered by Date with the newest first. This array contains only the pages in the current language.
|
||||
|
||||
`.Site.Permalinks`
|
||||
.Site.Permalinks
|
||||
: a string to override the default [permalink](/content-management/urls/) format as defined in the site configuration.
|
||||
|
||||
`.Site.RegularPages`
|
||||
.Site.RegularPages
|
||||
: a shortcut to the *regular* page collection. `.Site.RegularPages` is equivalent to `where .Site.Pages "Kind" "page"`.
|
||||
|
||||
`.Site.RSSLink`
|
||||
.Site.RSSLink
|
||||
: the URL for the site RSS.
|
||||
|
||||
`.Site.Sections`
|
||||
.Site.Sections
|
||||
: top-level directories of the site.
|
||||
|
||||
`.Site.Taxonomies`
|
||||
.Site.Taxonomies
|
||||
: the [taxonomies](/taxonomies/usage/) for the entire site. Replaces the now-obsolete `.Site.Indexes` since v0.11. Also see section [Taxonomies elsewhere](#taxonomies-elsewhere).
|
||||
|
||||
`.Site.Title`
|
||||
.Site.Title
|
||||
: a string representing the title of the site.
|
||||
|
||||
## The `.Site.Params` Variable
|
||||
|
||||
@@ -20,13 +20,13 @@ toc: false
|
||||
|
||||
A sitemap is a `Page` and therefore has all the [page variables][pagevars] available to use sitemap templates. They also have the following sitemap-specific variables available to them:
|
||||
|
||||
`.Sitemap.ChangeFreq`
|
||||
.Sitemap.ChangeFreq
|
||||
: the page change frequency
|
||||
|
||||
`.Sitemap.Priority`
|
||||
.Sitemap.Priority
|
||||
: the priority of the page
|
||||
|
||||
`.Sitemap.Filename`
|
||||
.Sitemap.Filename
|
||||
: the sitemap filename
|
||||
|
||||
[pagevars]: /variables/page/
|
||||
@@ -24,22 +24,22 @@ toc: true
|
||||
|
||||
For example, the following fields would be available in `layouts/_defaults/terms.html`, depending on how you organize your [taxonomy templates][taxonomytemplates]:
|
||||
|
||||
`.Data.Singular`
|
||||
.Data.Singular
|
||||
: The singular name of the taxonomy (e.g., `tags => `tag`)
|
||||
|
||||
`.Data.Plural`
|
||||
.Data.Plural
|
||||
: The plural name of the taxonomy (e.g., `tags => tags`)
|
||||
|
||||
`.Data.Pages`
|
||||
.Data.Pages
|
||||
: The list of pages in the taxonomy
|
||||
|
||||
`.Data.Terms`
|
||||
.Data.Terms
|
||||
: The taxonomy itself
|
||||
|
||||
`.Data.Terms.Alphabetical`
|
||||
.Data.Terms.Alphabetical
|
||||
: The taxonomy terms alphabetized
|
||||
|
||||
`.Data.Terms.ByCount`
|
||||
.Data.Terms.ByCount
|
||||
: The Terms ordered by popularity
|
||||
|
||||
Note that `.Data.Terms.Alphabetical` and `.Data.Terms.ByCount` can also be reversed:
|
||||
|
||||
+3
-3
@@ -3,15 +3,15 @@
|
||||
command = "hugo"
|
||||
|
||||
[context.production.environment]
|
||||
HUGO_VERSION = "0.29"
|
||||
HUGO_VERSION = "0.31.1"
|
||||
HUGO_ENV = "production"
|
||||
HUGO_ENABLEGITINFO = "true"
|
||||
|
||||
[context.deploy-preview.environment]
|
||||
HUGO_VERSION = "0.29"
|
||||
HUGO_VERSION = "0.31.1"
|
||||
|
||||
[context.branch-deploy.environment]
|
||||
HUGO_VERSION = "0.29"
|
||||
HUGO_VERSION = "0.31.1"
|
||||
|
||||
[context.next.environment]
|
||||
HUGO_BASEURL = "https://next--gohugoio.netlify.com/"
|
||||
|
||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 94 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
BIN
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
+17
@@ -0,0 +1,17 @@
|
||||
[[banners]]
|
||||
name = "Forestry.io"
|
||||
link = "https://forestry.io/"
|
||||
logo = "/images/sponsors/forestry-logotype.svg"
|
||||
copy = ""
|
||||
|
||||
[[banners]]
|
||||
name = ""
|
||||
link = ""
|
||||
logo = ""
|
||||
copy = ""
|
||||
|
||||
[[banners]]
|
||||
name = ""
|
||||
link = ""
|
||||
logo = ""
|
||||
copy = ""
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user