Compare commits
224 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b096a10fe9 | |||
| 24be139cb7 | |||
| 3e0f1ad7f5 | |||
| 0bd0593a77 | |||
| c6e4aff1ce | |||
| c0f491ab6c | |||
| 67746f36dd | |||
| 7f6430d84d | |||
| 0e87b18b66 | |||
| e98f885b8a | |||
| 6498d73c08 | |||
| b5b6e81c02 | |||
| 90d3fbf1da | |||
| 5f3ad1c319 | |||
| 8cd3ea565a | |||
| 7935541087 | |||
| d6818f2381 | |||
| 592e055f12 | |||
| ab692e73de | |||
| 7cdc244a72 | |||
| b5e32eb609 | |||
| 66ec6305f6 | |||
| 1cf29200b4 | |||
| 8ccee6717c | |||
| 86a97dbd18 | |||
| 5e2e62d97f | |||
| 8ac1fcd0ce | |||
| 0ed3beec80 | |||
| 077005e514 | |||
| efc0e05c4e | |||
| 6d2ea0f7d7 | |||
| 45c7452668 | |||
| e765b43e2b | |||
| 3b67759495 | |||
| 5fad8a9d06 | |||
| 9ec00725b7 | |||
| cfd3af8e69 | |||
| 4c6fec56f1 | |||
| dac0d4a69d | |||
| 03ec2b3397 | |||
| 18f5f3c14c | |||
| 308678aa7f | |||
| e73a35dea5 | |||
| c9731b2c2a | |||
| 9ebbf1b054 | |||
| 2874fc75ce | |||
| 9e69a92e85 | |||
| 9a8b65d8d7 | |||
| 7b2e1b0be9 | |||
| e975a07fb0 | |||
| 7ad721fd78 | |||
| 5714531f34 | |||
| 3c405f5172 | |||
| 9580872459 | |||
| af99a59021 | |||
| 260b55ea56 | |||
| 8f09e5f6bc | |||
| c4a1165587 | |||
| e77bb13c20 | |||
| e6e1aca3f4 | |||
| f3b4a0e99e | |||
| 0dd6890ed5 | |||
| 6650fae7ad | |||
| b31da911b5 | |||
| 1425587193 | |||
| a883948c4f | |||
| bc36d468ab | |||
| 7da1b65968 | |||
| 868f89d5c6 | |||
| 04d80e6e87 | |||
| 0802f79e66 | |||
| 10ff2f31a6 | |||
| f8d555cca5 | |||
| c9aee467d3 | |||
| d6e8b86f66 | |||
| a098081c4a | |||
| 5d7eeeadf0 | |||
| 8b5b558bb5 | |||
| 27610ddd01 | |||
| 6b29bccfee | |||
| 28fdd71c29 | |||
| fe8462b205 | |||
| d122260de7 | |||
| a037b855dd | |||
| 7eb71ee064 | |||
| c97dae40d9 | |||
| 0aeadfd02d | |||
| 5c5efa03d2 | |||
| 73c1c7b69d | |||
| f911b107ef | |||
| 05949c9038 | |||
| d5036c3ab5 | |||
| af1f9ecf91 | |||
| 42a4f6f9cb | |||
| 79b34c2f1e | |||
| 3c6b16d5a2 | |||
| 87b3cd4655 | |||
| 5989c4d464 | |||
| af55ec7661 | |||
| f2fbf0b2ea | |||
| 4923273688 | |||
| 930a3df1b7 | |||
| e49a2b83ad | |||
| 9a0aa5fdbe | |||
| 0aaf3c56a5 | |||
| ee4a33b14f | |||
| 09c88e84d1 | |||
| 24c1770288 | |||
| b7ed67d425 | |||
| 3cd97951f1 | |||
| ee75e2999b | |||
| 15b64d51da | |||
| 148fedd227 | |||
| ec01c3a7f0 | |||
| 5761b93c96 | |||
| 87188496fb | |||
| 0c4701f0ef | |||
| d851d6b98f | |||
| 8bcc08e3b0 | |||
| dbb83f925a | |||
| 4aaed87dd9 | |||
| c7dbee2321 | |||
| 29d3778ba1 | |||
| 1b2be5e878 | |||
| baa29f6534 | |||
| c7c6b47ba8 | |||
| 08fa2b1124 | |||
| 6178238a0b | |||
| df95383914 | |||
| a49bf8707b | |||
| d76e5f36b4 | |||
| ad8cea87f3 | |||
| 4c2abe0015 | |||
| 6bf010fed4 | |||
| c8fff9501d | |||
| 3ec5fc3504 | |||
| f091fc23ed | |||
| 03122e51fa | |||
| e5200ddaa4 | |||
| a8244658f7 | |||
| 50c64415aa | |||
| 348834d017 | |||
| 254cd89c8e | |||
| 10de077164 | |||
| 3bb52bf7bf | |||
| d3d2c63dd9 | |||
| c4989c39f1 | |||
| 9262c5b32f | |||
| 2bea9d0ca1 | |||
| 1b92c8b713 | |||
| 17b21e0af1 | |||
| 7f68e3199e | |||
| 2ed75f3462 | |||
| 9d9ec1ddd9 | |||
| 9f0b02b898 | |||
| a159feffb2 | |||
| d07ff9d221 | |||
| f1b1df5058 | |||
| 559b4007f7 | |||
| 5e191ccf4c | |||
| d3cd68e656 | |||
| 68f4cd829e | |||
| 3fa7bc9c53 | |||
| 3518de1057 | |||
| 7c48ad57a9 | |||
| 0e75f6e7b1 | |||
| 6eddb3e587 | |||
| 6e03c96a20 | |||
| 4382a8a6a0 | |||
| 9dfb9c1445 | |||
| c2ffdfab63 | |||
| a99661031a | |||
| 491d406881 | |||
| d8923eb676 | |||
| d6093aba4d | |||
| 638cc806d6 | |||
| ec3dc32511 | |||
| b156ef2712 | |||
| 042f8fca03 | |||
| 431d597442 | |||
| ede452d34e | |||
| 62efcdfed4 | |||
| 4b9493cb03 | |||
| 5d0748ce51 | |||
| 63e2a46f63 | |||
| 2f2ea42c09 | |||
| 5f443bd45b | |||
| f039e3be9e | |||
| ddc8cc0082 | |||
| 0e44f75ebd | |||
| 690961ba02 | |||
| fe41bd61bb | |||
| 48120ccfd2 | |||
| 560ed6e686 | |||
| 45b9d7223a | |||
| a2a8a651f7 | |||
| 4bfa189031 | |||
| a2ec372a03 | |||
| c950699907 | |||
| 6c5ef71368 | |||
| c7b8c45d12 | |||
| e52e2a70e5 | |||
| ea165bf9e7 | |||
| 22c89dcb6c | |||
| d0e2a1fa14 | |||
| 5a94e4cfb9 | |||
| f4779b25bc | |||
| 8203fc5923 | |||
| 7acec3c639 | |||
| 74ea81b885 | |||
| 577522bd45 | |||
| 23f5b9ac4e | |||
| 1279ca201a | |||
| 9671162a22 | |||
| 3669015f56 | |||
| a0e3ff1645 | |||
| cc15864744 | |||
| b7a672fd22 | |||
| 972649c684 | |||
| afb3334ed8 | |||
| c266cd2d86 | |||
| 0b91053c9f | |||
| 396276aafa | |||
| 072cd00305 |
@@ -14,4 +14,5 @@ vendor/*/
|
||||
*.bench
|
||||
coverage*.out
|
||||
|
||||
GoBuilds
|
||||
GoBuilds
|
||||
dist
|
||||
|
||||
@@ -2,7 +2,7 @@ language: go
|
||||
sudo: required
|
||||
go:
|
||||
- 1.7.5
|
||||
- 1.8
|
||||
- 1.8.1
|
||||
- tip
|
||||
os:
|
||||
- linux
|
||||
|
||||
@@ -14,19 +14,21 @@ The Hugo community and maintainers are [very active](https://github.com/spf13/hu
|
||||
* [Submitting Patches](#submitting-patches)
|
||||
* [Code Contribution Guidelines](#code-contribution-guidelines)
|
||||
* [Git Commit Message Guidelines](#git-commit-message-guidelines)
|
||||
* [Vendored Dependencies](#vendored-dependencies)
|
||||
* [Fetching the Sources From GitHub](#fetching-the-sources-from-github)
|
||||
* [Using Git Remotes](#using-git-remotes)
|
||||
* [Build Hugo with Your Changes](#build-hugo-with-your-changes)
|
||||
* [Add Compile Information to Hugo](#add-compile-information-to-hugo)
|
||||
* [Updating the Hugo Sources](#updating-the-hugo-sources)
|
||||
|
||||
## Asking Support Questions
|
||||
|
||||
We have an active [discussion forum](http://discuss.gohugo.io) where users and developers can ask questions.
|
||||
Please don't use the Github issue tracker to ask questions.
|
||||
Please don't use the GitHub issue tracker to ask questions.
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
If you believe you have found a defect in Hugo or its documentation, use
|
||||
the Github [issue tracker](https://github.com/spf13/hugo/issues) to report the problem to the Hugo maintainers.
|
||||
the GitHub [issue tracker](https://github.com/spf13/hugo/issues) to report the problem to the Hugo maintainers.
|
||||
If you're not sure if it's a bug or not, start by asking in the [discussion forum](http://discuss.gohugo.io).
|
||||
When reporting the issue, please provide the version of Hugo in use (`hugo version`) and your operating system.
|
||||
|
||||
@@ -51,7 +53,7 @@ To make the contribution process as seamless as possible, we ask for the followi
|
||||
* Run `go fmt`.
|
||||
* Add documentation if you are adding new features or changing functionality. The docs site lives in `/docs`.
|
||||
* Squash your commits into a single commit. `git rebase -i`. It’s okay to force update your pull request with `git push -f`.
|
||||
* Make sure `go test ./...` passes, and `go build` completes. [Travis CI](https://travis-ci.org/spf13/hugo) (Linux and OS X) and [AppVeyor](https://ci.appveyor.com/project/spf13/hugo/branch/master) (Windows) will catch most things that are missing.
|
||||
* Ensure that `make check` succeeds. [Travis CI](https://travis-ci.org/spf13/hugo) (Linux and macOS) and [AppVeyor](https://ci.appveyor.com/project/spf13/hugo/branch/master) (Windows) will fail the build if `make check` fails.
|
||||
* Follow the **Git Commit Message Guidelines** below.
|
||||
|
||||
### Git Commit Message Guidelines
|
||||
@@ -82,22 +84,31 @@ new default function more useful for Hugo users.
|
||||
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.
|
||||
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
|
||||
|
||||
```
|
||||
go get github.com/kardianos/govendor
|
||||
govendor get github.com/spf13/hugo
|
||||
```
|
||||
|
||||
### Using Git Remotes
|
||||
|
||||
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. Get the latest Hugo sources:
|
||||
|
||||
```
|
||||
go get -u -t github.com/spf13/hugo/...
|
||||
```
|
||||
1. Fetch the Hugo sources as described above.
|
||||
|
||||
1. Change to the Hugo source directory:
|
||||
|
||||
```
|
||||
cd $GOPATH/src/github.com/spf13/hugo
|
||||
cd $HOME/go/src/github.com/spf13/hugo
|
||||
```
|
||||
|
||||
1. Create a new branch for your changes (the branch name is arbitrary):
|
||||
@@ -112,7 +123,7 @@ started:
|
||||
git commit -a -v
|
||||
```
|
||||
|
||||
1. Fork Hugo in Github.
|
||||
1. Fork Hugo in GitHub.
|
||||
|
||||
1. Add your fork as a new remote (the remote name, "fork" in this example, is arbitrary):
|
||||
|
||||
@@ -131,20 +142,20 @@ started:
|
||||
### Build Hugo with Your Changes
|
||||
|
||||
```bash
|
||||
cd $GOPATH/src/github.com/spf13/hugo
|
||||
go build
|
||||
mv hugo /usr/local/bin/
|
||||
cd $HOME/go/src/github.com/spf13/hugo
|
||||
make hugo
|
||||
# or to install in $HOME/go/bin:
|
||||
make install
|
||||
```
|
||||
|
||||
### Add Compile Information to Hugo
|
||||
### Updating the Hugo Sources
|
||||
|
||||
To add compile information to Hugo, replace the `go build` command with the following *(replace `/path/to/hugo` with the actual path)*:
|
||||
If you want to stay in sync with the Hugo repository, you can easily pull down
|
||||
the source changes, but you'll need to keep the vendored packages up-to-date as
|
||||
well.
|
||||
|
||||
go build -ldflags "-X /path/to/hugo/hugolib.CommitHash=`git rev-parse --short HEAD 2>/dev/null` -X github.com/spf13/hugo/hugolib.BuildDate=`date +%FT%T%z`"
|
||||
|
||||
This will result in `hugo version` output that looks similar to:
|
||||
|
||||
Hugo Static Site Generator v0.13-DEV-8042E77 buildDate: 2014-12-25T03:25:57-07:00
|
||||
|
||||
Alternatively, just run `make` — all the “magic” above is already in the `Makefile`. :wink:
|
||||
```
|
||||
git pull
|
||||
make vendor
|
||||
```
|
||||
|
||||
|
||||
@@ -76,5 +76,8 @@ test-cover-html: ## Generate test coverage report
|
||||
tail -n +2 coverage.out >> coverage-all.out;)
|
||||
go 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}'
|
||||
|
||||
@@ -11,7 +11,7 @@ A Fast and Flexible Static Site Generator built with love by [spf13](http://spf1
|
||||
[Twitter](http://twitter.com/gohugoio)
|
||||
|
||||
[](https://godoc.org/github.com/spf13/hugo)
|
||||
[](https://travis-ci.org/spf13/hugo)
|
||||
[](https://travis-ci.org/spf13/hugo)
|
||||
[](https://ci.appveyor.com/project/spf13/hugo/branch/master)
|
||||
[](https://gitter.im/spf13/hugo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://goreportcard.com/report/github.com/spf13/hugo)
|
||||
@@ -33,7 +33,7 @@ Hugo is designed to work well for any kind of website including blogs, tumbles a
|
||||
|
||||
#### Supported Architectures
|
||||
|
||||
Currently, we provide pre-built Hugo binaries for Windows, Linux, FreeBSD, NetBSD and OS X (Darwin) for x64, i386 and ARM architectures.
|
||||
Currently, we provide pre-built Hugo binaries for Windows, Linux, FreeBSD, NetBSD and macOS (Darwin) and [Android](https://gist.github.com/bep/a0d8a26cf6b4f8bc992729b8e50b480b) for x64, i386 and ARM architectures.
|
||||
|
||||
Hugo may also be compiled from source wherever the Go compiler tool chain can run, e.g. for other operating systems including DragonFly BSD, OpenBSD, Plan 9 and Solaris.
|
||||
|
||||
@@ -79,12 +79,12 @@ The Hugo community and maintainers are [very active](https://github.com/spf13/hu
|
||||
### Asking Support Questions
|
||||
|
||||
We have an active [discussion forum](http://discuss.gohugo.io) where users and developers can ask questions.
|
||||
Please don't use the Github issue tracker to ask questions.
|
||||
Please don't use the GitHub issue tracker to ask questions.
|
||||
|
||||
### Reporting Issues
|
||||
|
||||
If you believe you have found a defect in Hugo or its documentation, use
|
||||
the Github issue tracker to report the problem to the Hugo maintainers.
|
||||
the GitHub issue tracker to report the problem to the Hugo maintainers.
|
||||
If you're not sure if it's a bug or not, start by asking in the [discussion forum](http://discuss.gohugo.io).
|
||||
When reporting the issue, please provide the version of Hugo in use (`hugo version`).
|
||||
|
||||
|
||||
@@ -1,27 +1,17 @@
|
||||
image: WMF 5
|
||||
clone_folder: c:\GOPATH\src\github.com\spf13\hugo
|
||||
init:
|
||||
- cmd: >-
|
||||
set PATH=%PATH%;C:\MinGW\bin;C:\GOPATH\bin
|
||||
- copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe
|
||||
- set PATH=%PATH%;C:\MinGW\bin;%GOPATH%\bin
|
||||
- go version
|
||||
- go env
|
||||
|
||||
# clones and cd's to path
|
||||
clone_folder: C:\GOPATH\src\github.com\spf13\hugo
|
||||
|
||||
copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe
|
||||
environment:
|
||||
GOPATH: c:\GOPATH
|
||||
install:
|
||||
- cmd: >-
|
||||
gem install asciidoctor
|
||||
- gem install asciidoctor
|
||||
- pip install docutils
|
||||
|
||||
pip install docutils
|
||||
build_script:
|
||||
- cmd: make vendor
|
||||
test_script:
|
||||
- cmd: >-
|
||||
go version
|
||||
|
||||
go env
|
||||
|
||||
make hugo-race check
|
||||
|
||||
hugo -s docs/
|
||||
|
||||
hugo --renderToMemory -s docs/
|
||||
- make hugo-race check
|
||||
- hugo -s docs/
|
||||
- hugo --renderToMemory -s docs/
|
||||
|
||||
@@ -54,7 +54,10 @@ func benchmark(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
c := newCommandeer(cfg)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var memProf *os.File
|
||||
if memProfileFile != "" {
|
||||
|
||||
@@ -16,6 +16,7 @@ package commands
|
||||
import (
|
||||
"github.com/spf13/hugo/deps"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"github.com/spf13/hugo/hugofs"
|
||||
)
|
||||
|
||||
type commandeer struct {
|
||||
@@ -35,12 +36,27 @@ func (c *commandeer) Set(key string, value interface{}) {
|
||||
// be configured before it is created.
|
||||
func (c *commandeer) PathSpec() *helpers.PathSpec {
|
||||
c.configured = true
|
||||
if c.pathSpec == nil {
|
||||
c.pathSpec = helpers.NewPathSpec(c.Fs, c.Cfg)
|
||||
}
|
||||
return c.pathSpec
|
||||
}
|
||||
|
||||
func newCommandeer(cfg *deps.DepsCfg) *commandeer {
|
||||
return &commandeer{DepsCfg: cfg}
|
||||
func (c *commandeer) initFs(fs *hugofs.Fs) error {
|
||||
c.DepsCfg.Fs = fs
|
||||
ps, err := helpers.NewPathSpec(fs, c.Cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.pathSpec = ps
|
||||
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
|
||||
}
|
||||
return &commandeer{DepsCfg: cfg, pathSpec: ps}, nil
|
||||
}
|
||||
|
||||
@@ -123,14 +123,14 @@ func convertContents(mark rune) error {
|
||||
|
||||
// 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 {
|
||||
newMetadata := cast.ToStringMap(metadata)
|
||||
for k, v := range newMetadata {
|
||||
switch vv := v.(type) {
|
||||
case time.Time:
|
||||
newmetadata[k] = vv.Format(time.RFC3339)
|
||||
newMetadata[k] = vv.Format(time.RFC3339)
|
||||
}
|
||||
}
|
||||
metadata = newmetadata
|
||||
metadata = newMetadata
|
||||
}
|
||||
|
||||
page.SetDir(filepath.Join(contentDir, file.Dir()))
|
||||
|
||||
@@ -53,7 +53,9 @@ for rendering in Hugo.`,
|
||||
}
|
||||
if found, _ := helpers.Exists(gendocdir, hugofs.Os); !found {
|
||||
jww.FEEDBACK.Println("Directory", gendocdir, "does not exist, creating...")
|
||||
hugofs.Os.MkdirAll(gendocdir, 0777)
|
||||
if err := hugofs.Os.MkdirAll(gendocdir, 0777); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
now := time.Now().Format(time.RFC3339)
|
||||
prepender := func(filename string) string {
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
// Copyright 2017-present 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 (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/docshelper"
|
||||
)
|
||||
|
||||
type genDocsHelper struct {
|
||||
target string
|
||||
cmd *cobra.Command
|
||||
}
|
||||
|
||||
func createGenDocsHelper() *genDocsHelper {
|
||||
g := &genDocsHelper{
|
||||
cmd: &cobra.Command{
|
||||
Use: "docshelper",
|
||||
Short: "Generate some data files for the Hugo docs.",
|
||||
Hidden: true,
|
||||
},
|
||||
}
|
||||
|
||||
g.cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
return g.generate()
|
||||
}
|
||||
|
||||
g.cmd.PersistentFlags().StringVarP(&g.target, "dir", "", "docs/data", "Data dir")
|
||||
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *genDocsHelper) generate() error {
|
||||
fmt.Println("Generate docs data to", g.target)
|
||||
|
||||
targetFile := filepath.Join(g.target, "docs.json")
|
||||
|
||||
f, err := os.Create(targetFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
enc := json.NewEncoder(f)
|
||||
enc.SetIndent("", " ")
|
||||
|
||||
if err := enc.Encode(docshelper.DocProviders); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Done!")
|
||||
return nil
|
||||
|
||||
}
|
||||
@@ -36,14 +36,16 @@ in the "man" directory under the current directory.`,
|
||||
header := &doc.GenManHeader{
|
||||
Section: "1",
|
||||
Manual: "Hugo Manual",
|
||||
Source: fmt.Sprintf("Hugo %s", helpers.HugoVersion()),
|
||||
Source: fmt.Sprintf("Hugo %s", helpers.CurrentHugoVersion),
|
||||
}
|
||||
if !strings.HasSuffix(genmandir, helpers.FilePathSeparator) {
|
||||
genmandir += helpers.FilePathSeparator
|
||||
}
|
||||
if found, _ := helpers.Exists(genmandir, hugofs.Os); !found {
|
||||
jww.FEEDBACK.Println("Directory", genmandir, "does not exist, creating...")
|
||||
hugofs.Os.MkdirAll(genmandir, 0777)
|
||||
if err := hugofs.Os.MkdirAll(genmandir, 0777); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
cmd.Root().DisableAutoGenTag = true
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@ package commands
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
|
||||
"github.com/spf13/hugo/hugofs"
|
||||
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -28,7 +31,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/spf13/hugo/config"
|
||||
"github.com/spf13/hugo/hugofs"
|
||||
|
||||
"github.com/spf13/hugo/parser"
|
||||
flag "github.com/spf13/pflag"
|
||||
@@ -118,7 +120,10 @@ Complete documentation is available at http://gohugo.io/.`,
|
||||
return err
|
||||
}
|
||||
|
||||
c := newCommandeer(cfg)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if buildWatch {
|
||||
cfg.Cfg.Set("disableLiveReload", true)
|
||||
@@ -192,6 +197,7 @@ func AddCommands() {
|
||||
genCmd.AddCommand(genautocompleteCmd)
|
||||
genCmd.AddCommand(gendocCmd)
|
||||
genCmd.AddCommand(genmanCmd)
|
||||
genCmd.AddCommand(createGenDocsHelper().cmd)
|
||||
}
|
||||
|
||||
// initHugoBuilderFlags initializes all common flags, typically used by the
|
||||
@@ -206,7 +212,7 @@ func initRootPersistentFlags() {
|
||||
|
||||
// Set bash-completion
|
||||
validConfigFilenames := []string{"json", "js", "yaml", "yml", "toml", "tml"}
|
||||
HugoCmd.PersistentFlags().SetAnnotation("config", cobra.BashCompFilenameExt, validConfigFilenames)
|
||||
_ = HugoCmd.PersistentFlags().SetAnnotation("config", cobra.BashCompFilenameExt, validConfigFilenames)
|
||||
}
|
||||
|
||||
// initHugoBuildCommonFlags initialize common flags related to the Hugo build.
|
||||
@@ -244,10 +250,10 @@ func initHugoBuildCommonFlags(cmd *cobra.Command) {
|
||||
|
||||
// Set bash-completion.
|
||||
// Each flag must first be defined before using the SetAnnotation() call.
|
||||
cmd.Flags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{})
|
||||
cmd.Flags().SetAnnotation("cacheDir", cobra.BashCompSubdirsInDir, []string{})
|
||||
cmd.Flags().SetAnnotation("destination", cobra.BashCompSubdirsInDir, []string{})
|
||||
cmd.Flags().SetAnnotation("theme", cobra.BashCompSubdirsInDir, []string{"themes"})
|
||||
_ = cmd.Flags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{})
|
||||
_ = cmd.Flags().SetAnnotation("cacheDir", cobra.BashCompSubdirsInDir, []string{})
|
||||
_ = cmd.Flags().SetAnnotation("destination", cobra.BashCompSubdirsInDir, []string{})
|
||||
_ = cmd.Flags().SetAnnotation("theme", cobra.BashCompSubdirsInDir, []string{"themes"})
|
||||
}
|
||||
|
||||
func initBenchmarkBuildingFlags(cmd *cobra.Command) {
|
||||
@@ -269,7 +275,7 @@ func init() {
|
||||
hugoCmdV = HugoCmd
|
||||
|
||||
// Set bash-completion
|
||||
HugoCmd.PersistentFlags().SetAnnotation("logFile", cobra.BashCompFilenameExt, []string{})
|
||||
_ = HugoCmd.PersistentFlags().SetAnnotation("logFile", cobra.BashCompFilenameExt, []string{})
|
||||
}
|
||||
|
||||
// InitializeConfig initializes a config file with sensible default configuration flags.
|
||||
@@ -285,9 +291,13 @@ func InitializeConfig(subCmdVs ...*cobra.Command) (*deps.DepsCfg, error) {
|
||||
return cfg, err
|
||||
}
|
||||
|
||||
// Init file systems. This may be changed at a later point.
|
||||
cfg.Cfg = config
|
||||
|
||||
c := newCommandeer(cfg)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, cmdV := range append([]*cobra.Command{hugoCmdV}, subCmdVs...) {
|
||||
c.initializeFlags(cmdV)
|
||||
@@ -307,9 +317,6 @@ func InitializeConfig(subCmdVs ...*cobra.Command) (*deps.DepsCfg, error) {
|
||||
config.Set("logI18nWarnings", logI18nWarnings)
|
||||
|
||||
if baseURL != "" {
|
||||
if !strings.HasSuffix(baseURL, "/") {
|
||||
baseURL = baseURL + "/"
|
||||
}
|
||||
config.Set("baseURL", baseURL)
|
||||
}
|
||||
|
||||
@@ -337,13 +344,13 @@ func InitializeConfig(subCmdVs ...*cobra.Command) (*deps.DepsCfg, error) {
|
||||
}
|
||||
config.Set("workingDir", dir)
|
||||
|
||||
cfg.Fs = hugofs.NewFrom(osFs, config)
|
||||
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 {
|
||||
c.Fs.Destination = new(afero.MemMapFs)
|
||||
fs.Destination = new(afero.MemMapFs)
|
||||
// Rendering to memoryFS, publish to Root regardless of publishDir.
|
||||
c.Set("publishDir", "/")
|
||||
}
|
||||
@@ -365,14 +372,18 @@ func InitializeConfig(subCmdVs ...*cobra.Command) (*deps.DepsCfg, error) {
|
||||
if helpers.FilePathSeparator != cacheDir[len(cacheDir)-1:] {
|
||||
cacheDir = cacheDir + helpers.FilePathSeparator
|
||||
}
|
||||
isDir, err := helpers.DirExists(cacheDir, cfg.Fs.Source)
|
||||
isDir, err := helpers.DirExists(cacheDir, fs.Source)
|
||||
utils.CheckErr(cfg.Logger, err)
|
||||
if !isDir {
|
||||
mkdir(cacheDir)
|
||||
}
|
||||
config.Set("cacheDir", cacheDir)
|
||||
} else {
|
||||
config.Set("cacheDir", helpers.GetTempDir("hugo_cache", cfg.Fs.Source))
|
||||
config.Set("cacheDir", helpers.GetTempDir("hugo_cache", fs.Source))
|
||||
}
|
||||
|
||||
if err := c.initFs(fs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg.Logger.INFO.Println("Using config file:", viper.ConfigFileUsed())
|
||||
@@ -388,7 +399,7 @@ func InitializeConfig(subCmdVs ...*cobra.Command) (*deps.DepsCfg, error) {
|
||||
|
||||
if themeVersionMismatch {
|
||||
cfg.Logger.ERROR.Printf("Current theme does not support Hugo version %s. Minimum version required is %s\n",
|
||||
helpers.HugoReleaseVersion(), minVersion)
|
||||
helpers.CurrentHugoVersion.ReleaseVersion(), minVersion)
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
@@ -425,6 +436,12 @@ func createLogger(cfg config.Provider) (*jww.Notepad, error) {
|
||||
logThreshold = jww.LevelInfo
|
||||
}
|
||||
|
||||
// The global logger is used in some few cases.
|
||||
jww.SetLogOutput(logHandle)
|
||||
jww.SetLogThreshold(logThreshold)
|
||||
jww.SetStdoutThreshold(stdoutThreshold)
|
||||
helpers.InitLoggers()
|
||||
|
||||
return jww.NewNotepad(stdoutThreshold, logThreshold, outHandle, logHandle, "", log.Ldate|log.Ltime), nil
|
||||
}
|
||||
|
||||
@@ -579,8 +596,13 @@ func (c *commandeer) copyStatic() error {
|
||||
// Now that we are using a unionFs for the static directories
|
||||
// We can effectively clean the publishDir on initial sync
|
||||
syncer.Delete = c.Cfg.GetBool("cleanDestinationDir")
|
||||
|
||||
if syncer.Delete {
|
||||
c.Logger.INFO.Println("removing all files from destination that don't exist in static dirs")
|
||||
|
||||
syncer.DeleteFilter = func(f os.FileInfo) bool {
|
||||
return f.IsDir() && strings.HasPrefix(f.Name(), ".")
|
||||
}
|
||||
}
|
||||
c.Logger.INFO.Println("syncing static files to", publishDir)
|
||||
|
||||
@@ -660,17 +682,18 @@ func (c *commandeer) getDirList() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
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, c.PathSpec().AbsPathify(c.Cfg.GetString("layoutDir")), walker)
|
||||
// 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, c.PathSpec().AbsPathify(c.Cfg.GetString("layoutDir")), walker)
|
||||
|
||||
helpers.SymbolicWalk(c.Fs.Source, staticDir, walker)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, staticDir, walker)
|
||||
if c.PathSpec().ThemeSet() {
|
||||
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"), 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)
|
||||
|
||||
}
|
||||
|
||||
@@ -802,7 +825,9 @@ func (c *commandeer) newWatcher(port int) error {
|
||||
walkAdder := func(path string, f os.FileInfo, err error) error {
|
||||
if f.IsDir() {
|
||||
c.Logger.FEEDBACK.Println("adding created directory to watchlist", path)
|
||||
watcher.Add(path)
|
||||
if err := watcher.Add(path); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -811,7 +836,7 @@ func (c *commandeer) newWatcher(port int) error {
|
||||
// When mkdir -p is used, only the top directory triggers an event (at least on OSX)
|
||||
if ev.Op&fsnotify.Create == fsnotify.Create {
|
||||
if s, err := c.Fs.Source.Stat(ev.Name); err == nil && s.Mode().IsDir() {
|
||||
helpers.SymbolicWalk(c.Fs.Source, ev.Name, walkAdder)
|
||||
_ = helpers.SymbolicWalk(c.Fs.Source, ev.Name, walkAdder)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -899,7 +924,7 @@ func (c *commandeer) newWatcher(port int) error {
|
||||
// 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)
|
||||
_ = c.Fs.Destination.RemoveAll(toRemove)
|
||||
} else if err == nil {
|
||||
// If file still exists, sync it
|
||||
logger.Println("Syncing", relPath, "to", publishDir)
|
||||
@@ -1001,15 +1026,7 @@ func (c *commandeer) isThemeVsHugoVersionMismatch() (mismatch bool, requiredMinV
|
||||
config := tomlMeta.(map[string]interface{})
|
||||
|
||||
if minVersion, ok := config["min_version"]; ok {
|
||||
switch minVersion.(type) {
|
||||
case float32:
|
||||
return helpers.HugoVersionNumber < minVersion.(float32), fmt.Sprint(minVersion)
|
||||
case float64:
|
||||
return helpers.HugoVersionNumber < minVersion.(float64), fmt.Sprint(minVersion)
|
||||
default:
|
||||
return
|
||||
}
|
||||
|
||||
return helpers.CompareVersion(minVersion) > 0, fmt.Sprint(minVersion)
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
@@ -251,17 +251,13 @@ func createConfigFromJekyll(fs afero.Fs, inpath string, kind string, jekyllConfi
|
||||
}
|
||||
kind = parser.FormatSanitize(kind)
|
||||
|
||||
by, err := parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind))
|
||||
var buf bytes.Buffer
|
||||
err = parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind), &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = helpers.WriteToDisk(filepath.Join(inpath, "config."+kind), bytes.NewReader(by), fs)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
return helpers.WriteToDisk(filepath.Join(inpath, "config."+kind), &buf, fs)
|
||||
}
|
||||
|
||||
func copyFile(source string, dest string) error {
|
||||
@@ -376,7 +372,7 @@ func parseJekyllFilename(filename string) (time.Time, string, error) {
|
||||
return time.Now(), "", errors.New("filename not match")
|
||||
}
|
||||
|
||||
postDate, err := time.Parse("2006-01-02", r[0][1])
|
||||
postDate, err := time.Parse("2006-1-2", r[0][1])
|
||||
if err != nil {
|
||||
return time.Now(), "", err
|
||||
}
|
||||
@@ -522,7 +518,7 @@ func convertJekyllContent(m interface{}, content string) string {
|
||||
re *regexp.Regexp
|
||||
replace string
|
||||
}{
|
||||
{regexp.MustCompile("<!-- more -->"), "<!--more-->"},
|
||||
{regexp.MustCompile("(?i)<!-- more -->"), "<!--more-->"},
|
||||
{regexp.MustCompile(`\{%\s*raw\s*%\}\s*(.*?)\s*\{%\s*endraw\s*%\}`), "$1"},
|
||||
{regexp.MustCompile(`{%\s*highlight\s*(.*?)\s*%}`), "{{< highlight $1 >}}"},
|
||||
{regexp.MustCompile(`{%\s*endhighlight\s*%}`), "{{< / highlight >}}"},
|
||||
@@ -532,5 +528,50 @@ func convertJekyllContent(m interface{}, content string) string {
|
||||
content = replace.re.ReplaceAllString(content, replace.replace)
|
||||
}
|
||||
|
||||
replaceListFunc := []struct {
|
||||
re *regexp.Regexp
|
||||
replace func(string) string
|
||||
}{
|
||||
// Octopress image tag: http://octopress.org/docs/plugins/image-tag/
|
||||
{regexp.MustCompile(`{%\s+img\s*(.*?)\s*%}`), replaceImageTag},
|
||||
}
|
||||
|
||||
for _, replace := range replaceListFunc {
|
||||
content = replace.re.ReplaceAllStringFunc(content, replace.replace)
|
||||
}
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
func replaceImageTag(match string) string {
|
||||
r := regexp.MustCompile(`{%\s+img\s*(\p{L}*)\s+([\S]*/[\S]+)\s+(\d*)\s*(\d*)\s*(.*?)\s*%}`)
|
||||
result := bytes.NewBufferString("{{< figure ")
|
||||
parts := r.FindStringSubmatch(match)
|
||||
// Index 0 is the entire string, ignore
|
||||
replaceOptionalPart(result, "class", parts[1])
|
||||
replaceOptionalPart(result, "src", parts[2])
|
||||
replaceOptionalPart(result, "width", parts[3])
|
||||
replaceOptionalPart(result, "height", parts[4])
|
||||
// title + alt
|
||||
part := parts[5]
|
||||
if len(part) > 0 {
|
||||
splits := strings.Split(part, "'")
|
||||
lenSplits := len(splits)
|
||||
if lenSplits == 1 {
|
||||
replaceOptionalPart(result, "title", splits[0])
|
||||
} else if lenSplits == 3 {
|
||||
replaceOptionalPart(result, "title", splits[1])
|
||||
} else if lenSplits == 5 {
|
||||
replaceOptionalPart(result, "title", splits[1])
|
||||
replaceOptionalPart(result, "alt", splits[3])
|
||||
}
|
||||
}
|
||||
result.WriteString(">}}")
|
||||
return result.String()
|
||||
|
||||
}
|
||||
func replaceOptionalPart(buffer *bytes.Buffer, partName string, part string) {
|
||||
if len(part) > 0 {
|
||||
buffer.WriteString(partName + "=\"" + part + "\" ")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,8 @@ func TestConvertJekyllContent(t *testing.T) {
|
||||
}{
|
||||
{map[interface{}]interface{}{},
|
||||
`Test content\n<!-- more -->\npart2 content`, `Test content\n<!--more-->\npart2 content`},
|
||||
{map[interface{}]interface{}{},
|
||||
`Test content\n<!-- More -->\npart2 content`, `Test content\n<!--more-->\npart2 content`},
|
||||
{map[interface{}]interface{}{"excerpt_separator": "<!--sep-->"},
|
||||
`Test content\n<!--sep-->\npart2 content`, `Test content\n<!--more-->\npart2 content`},
|
||||
{map[interface{}]interface{}{}, "{% raw %}text{% endraw %}", "text"},
|
||||
@@ -95,6 +97,26 @@ func TestConvertJekyllContent(t *testing.T) {
|
||||
{map[interface{}]interface{}{},
|
||||
"{% highlight go %}\nvar s int\n{% endhighlight %}",
|
||||
"{{< highlight go >}}\nvar s int\n{{< / highlight >}}"},
|
||||
|
||||
// Octopress image tag
|
||||
{map[interface{}]interface{}{},
|
||||
"{% img http://placekitten.com/890/280 %}",
|
||||
"{{< figure src=\"http://placekitten.com/890/280\" >}}"},
|
||||
{map[interface{}]interface{}{},
|
||||
"{% img left http://placekitten.com/320/250 Place Kitten #2 %}",
|
||||
"{{< figure class=\"left\" src=\"http://placekitten.com/320/250\" title=\"Place Kitten #2\" >}}"},
|
||||
{map[interface{}]interface{}{},
|
||||
"{% img right http://placekitten.com/300/500 150 250 'Place Kitten #3' %}",
|
||||
"{{< figure class=\"right\" src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #3\" >}}"},
|
||||
{map[interface{}]interface{}{},
|
||||
"{% img right http://placekitten.com/300/500 150 250 'Place Kitten #4' 'An image of a very cute kitten' %}",
|
||||
"{{< figure class=\"right\" src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}"},
|
||||
{map[interface{}]interface{}{},
|
||||
"{% img http://placekitten.com/300/500 150 250 'Place Kitten #4' 'An image of a very cute kitten' %}",
|
||||
"{{< figure src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}"},
|
||||
{map[interface{}]interface{}{},
|
||||
"{% img right /placekitten/300/500 'Place Kitten #4' 'An image of a very cute kitten' %}",
|
||||
"{{< figure class=\"right\" src=\"/placekitten/300/500\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}"},
|
||||
}
|
||||
|
||||
for _, data := range testDataList {
|
||||
|
||||
@@ -49,7 +49,10 @@ var listDraftsCmd = &cobra.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
c := newCommandeer(cfg)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Set("buildDrafts", true)
|
||||
|
||||
@@ -87,7 +90,10 @@ posted in the future.`,
|
||||
return err
|
||||
}
|
||||
|
||||
c := newCommandeer(cfg)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Set("buildFuture", true)
|
||||
|
||||
@@ -125,7 +131,10 @@ expired.`,
|
||||
return err
|
||||
}
|
||||
|
||||
c := newCommandeer(cfg)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Set("buildExpired", true)
|
||||
|
||||
|
||||
@@ -93,7 +93,10 @@ func NewContent(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
c := newCommandeer(cfg)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if flagChanged(cmd.Flags(), "format") {
|
||||
c.Set("metaDataFormat", configFormat)
|
||||
@@ -107,11 +110,11 @@ func NewContent(cmd *cobra.Command, args []string) error {
|
||||
return newUserError("path needs to be provided")
|
||||
}
|
||||
|
||||
createpath := args[0]
|
||||
createPath := args[0]
|
||||
|
||||
var kind string
|
||||
|
||||
createpath, kind = newContentPathSection(createpath)
|
||||
createPath, kind = newContentPathSection(createPath)
|
||||
|
||||
if contentType != "" {
|
||||
kind = contentType
|
||||
@@ -123,7 +126,7 @@ func NewContent(cmd *cobra.Command, args []string) error {
|
||||
return newSystemError(err)
|
||||
}
|
||||
|
||||
return create.NewContent(s, kind, createpath)
|
||||
return create.NewContent(s, kind, createPath)
|
||||
}
|
||||
|
||||
func doNewSite(fs *hugofs.Fs, basepath string, force bool) error {
|
||||
@@ -220,7 +223,10 @@ func NewTheme(cmd *cobra.Command, args []string) error {
|
||||
return newUserError("theme name needs to be provided")
|
||||
}
|
||||
|
||||
c := newCommandeer(cfg)
|
||||
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)
|
||||
@@ -314,7 +320,7 @@ description = ""
|
||||
homepage = "http://siteforthistheme.com/"
|
||||
tags = []
|
||||
features = []
|
||||
min_version = 0.19
|
||||
min_version = "0.20"
|
||||
|
||||
[author]
|
||||
name = ""
|
||||
@@ -356,15 +362,11 @@ func createConfig(fs *hugofs.Fs, inpath string, kind string) (err error) {
|
||||
}
|
||||
kind = parser.FormatSanitize(kind)
|
||||
|
||||
by, err := parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind))
|
||||
var buf bytes.Buffer
|
||||
err = parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind), &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = helpers.WriteToDisk(filepath.Join(inpath, "config."+kind), bytes.NewReader(by), fs.Source)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
return helpers.WriteToDisk(filepath.Join(inpath, "config."+kind), &buf, fs.Source)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// +build release
|
||||
|
||||
// Copyright 2017-present 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 (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/releaser"
|
||||
)
|
||||
|
||||
func init() {
|
||||
HugoCmd.AddCommand(createReleaser().cmd)
|
||||
}
|
||||
|
||||
type releaseCommandeer struct {
|
||||
cmd *cobra.Command
|
||||
|
||||
// Will be zero for main releases.
|
||||
patchLevel int
|
||||
|
||||
skipPublish bool
|
||||
|
||||
step int
|
||||
}
|
||||
|
||||
func createReleaser() *releaseCommandeer {
|
||||
// Note: This is a command only meant for internal use and must be run
|
||||
// via "go run -tags release main.go release" on the actual code base that is in the release.
|
||||
r := &releaseCommandeer{
|
||||
cmd: &cobra.Command{
|
||||
Use: "release",
|
||||
Short: "Release a new version of Hugo.",
|
||||
Hidden: true,
|
||||
},
|
||||
}
|
||||
|
||||
r.cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
return r.release()
|
||||
}
|
||||
|
||||
r.cmd.PersistentFlags().IntVarP(&r.patchLevel, "patch", "p", 0, "Patch level, defaults to 0 for main releases")
|
||||
r.cmd.PersistentFlags().IntVarP(&r.step, "step", "s", -1, "Release step, defaults to -1 for all steps.")
|
||||
r.cmd.PersistentFlags().BoolVarP(&r.skipPublish, "skip-publish", "", false, "Skip all publishing pipes of the release")
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *releaseCommandeer) release() error {
|
||||
return releaser.New(r.patchLevel, r.step, r.skipPublish).Run()
|
||||
}
|
||||
@@ -24,8 +24,6 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"mime"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/config"
|
||||
@@ -95,9 +93,6 @@ func init() {
|
||||
|
||||
serverCmd.RunE = server
|
||||
|
||||
mime.AddExtensionType(".json", "application/json; charset=utf-8")
|
||||
mime.AddExtensionType(".css", "text/css; charset=utf-8")
|
||||
|
||||
}
|
||||
|
||||
func server(cmd *cobra.Command, args []string) error {
|
||||
@@ -106,7 +101,10 @@ func server(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
c := newCommandeer(cfg)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if flagChanged(cmd.Flags(), "disableLiveReload") {
|
||||
c.Set("disableLiveReload", disableLiveReload)
|
||||
@@ -165,6 +163,10 @@ func server(cmd *cobra.Command, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, s := range Hugo.Sites {
|
||||
s.RegisterMediaTypes()
|
||||
}
|
||||
|
||||
// Watch runs its own server as part of the routine
|
||||
if serverWatch {
|
||||
watchDirs := c.getDirList()
|
||||
|
||||
@@ -46,17 +46,17 @@ func TestUndraftContent(t *testing.T) {
|
||||
{yamlDraftFM, ""},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
for i, test := range tests {
|
||||
r := bytes.NewReader([]byte(test.fm))
|
||||
p, _ := parser.ReadFrom(r)
|
||||
res, err := undraftContent(p)
|
||||
if test.expectedErr != "" {
|
||||
if err == nil {
|
||||
t.Error("Expected error, got none")
|
||||
t.Errorf("[%d] Expected error, got none", i)
|
||||
continue
|
||||
}
|
||||
if err.Error() != test.expectedErr {
|
||||
t.Errorf("Expected %q, got %q", test.expectedErr, err)
|
||||
t.Errorf("[%d] Expected %q, got %q", i, test.expectedErr, err)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
@@ -64,19 +64,19 @@ func TestUndraftContent(t *testing.T) {
|
||||
p, _ = parser.ReadFrom(r)
|
||||
meta, err := p.Metadata()
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error %q", err)
|
||||
t.Errorf("[%d] unexpected error %q", i, err)
|
||||
continue
|
||||
}
|
||||
for k, v := range meta.(map[string]interface{}) {
|
||||
if k == "draft" {
|
||||
if v.(bool) {
|
||||
t.Errorf("Expected %q to be \"false\", got \"true\"", k)
|
||||
t.Errorf("[%d] Expected %q to be \"false\", got \"true\"", i, k)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if k == "date" {
|
||||
if !strings.HasPrefix(v.(string), time.Now().Format("2006-01-02")) {
|
||||
t.Errorf("Expected %v to start with %v", v.(string), time.Now().Format("2006-01-02"))
|
||||
t.Errorf("[%d] Expected %v to start with %v", i, v.(string), time.Now().Format("2006-01-02"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,9 +44,9 @@ func printHugoVersion() {
|
||||
formatBuildDate() // format the compile time
|
||||
}
|
||||
if hugolib.CommitHash == "" {
|
||||
jww.FEEDBACK.Printf("Hugo Static Site Generator v%s %s/%s BuildDate: %s\n", helpers.HugoVersion(), runtime.GOOS, runtime.GOARCH, hugolib.BuildDate)
|
||||
jww.FEEDBACK.Printf("Hugo Static Site Generator v%s %s/%s BuildDate: %s\n", helpers.CurrentHugoVersion, runtime.GOOS, runtime.GOARCH, hugolib.BuildDate)
|
||||
} else {
|
||||
jww.FEEDBACK.Printf("Hugo Static Site Generator v%s-%s %s/%s BuildDate: %s\n", helpers.HugoVersion(), strings.ToUpper(hugolib.CommitHash), runtime.GOOS, runtime.GOARCH, hugolib.BuildDate)
|
||||
jww.FEEDBACK.Printf("Hugo Static Site Generator v%s-%s %s/%s BuildDate: %s\n", helpers.CurrentHugoVersion, strings.ToUpper(hugolib.CommitHash), runtime.GOOS, runtime.GOARCH, hugolib.BuildDate)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,6 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package helpers implements general utility functions that work with
|
||||
// and on content. The helper functions defined here lay down the
|
||||
// foundation of how Hugo works with files and filepaths, and perform
|
||||
// string operations on content.
|
||||
package config
|
||||
|
||||
// Provider provides the configuration settings for Hugo.
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"bytes"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -72,17 +71,18 @@ func NewContent(s *hugolib.Site, kind, name string) (err error) {
|
||||
|
||||
page.SetSourceContent(psr.Content())
|
||||
|
||||
if err = page.SafeSaveSourceAs(filepath.Join(s.Cfg.GetString("contentDir"), name)); err != nil {
|
||||
contentPath := s.PathSpec.AbsPathify(filepath.Join(s.Cfg.GetString("contentDir"), name))
|
||||
|
||||
if err = page.SafeSaveSourceAs(contentPath); err != nil {
|
||||
return
|
||||
}
|
||||
jww.FEEDBACK.Println(s.PathSpec.AbsPathify(filepath.Join(s.Cfg.GetString("contentDir"), name)), "created")
|
||||
jww.FEEDBACK.Println(contentPath, "created")
|
||||
|
||||
editor := s.Cfg.GetString("newContentEditor")
|
||||
|
||||
if editor != "" {
|
||||
jww.FEEDBACK.Printf("Editing %s with %q ...\n", name, editor)
|
||||
|
||||
cmd := exec.Command(editor, s.PathSpec.AbsPathify(path.Join(s.Cfg.GetString("contentDir"), name)))
|
||||
cmd := exec.Command(editor, contentPath)
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/spf13/hugo/config"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"github.com/spf13/hugo/hugofs"
|
||||
"github.com/spf13/hugo/output"
|
||||
"github.com/spf13/hugo/tpl"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
@@ -20,7 +21,7 @@ type Deps struct {
|
||||
Log *jww.Notepad `json:"-"`
|
||||
|
||||
// The templates to use.
|
||||
Tmpl tpl.Template `json:"-"`
|
||||
Tmpl tpl.TemplateHandler `json:"-"`
|
||||
|
||||
// The file systems to use.
|
||||
Fs *hugofs.Fs `json:"-"`
|
||||
@@ -39,13 +40,16 @@ type Deps struct {
|
||||
|
||||
Language *helpers.Language
|
||||
|
||||
// All the output formats available for the current site.
|
||||
OutputFormatsConfig output.Formats
|
||||
|
||||
templateProvider ResourceProvider
|
||||
WithTemplate func(templ tpl.Template) error `json:"-"`
|
||||
WithTemplate func(templ tpl.TemplateHandler) error `json:"-"`
|
||||
|
||||
translationProvider ResourceProvider
|
||||
}
|
||||
|
||||
// Used to create and refresh, and clone resources needed.
|
||||
// ResourceProvider is used to create and refresh, and clone resources needed.
|
||||
type ResourceProvider interface {
|
||||
Update(deps *Deps) error
|
||||
Clone(deps *Deps) error
|
||||
@@ -65,7 +69,7 @@ func (d *Deps) LoadResources() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func New(cfg DepsCfg) *Deps {
|
||||
func New(cfg DepsCfg) (*Deps, error) {
|
||||
var (
|
||||
logger = cfg.Logger
|
||||
fs = cfg.Fs
|
||||
@@ -92,26 +96,37 @@ func New(cfg DepsCfg) *Deps {
|
||||
fs = hugofs.NewDefault(cfg.Language)
|
||||
}
|
||||
|
||||
ps, err := helpers.NewPathSpec(fs, cfg.Language)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d := &Deps{
|
||||
Fs: fs,
|
||||
Log: logger,
|
||||
templateProvider: cfg.TemplateProvider,
|
||||
translationProvider: cfg.TranslationProvider,
|
||||
WithTemplate: cfg.WithTemplate,
|
||||
PathSpec: helpers.NewPathSpec(fs, cfg.Language),
|
||||
PathSpec: ps,
|
||||
ContentSpec: helpers.NewContentSpec(cfg.Language),
|
||||
Cfg: cfg.Language,
|
||||
Language: cfg.Language,
|
||||
}
|
||||
|
||||
return d
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// ForLanguage creates a copy of the Deps with the language dependent
|
||||
// parts switched out.
|
||||
func (d Deps) ForLanguage(l *helpers.Language) (*Deps, error) {
|
||||
var err error
|
||||
|
||||
d.PathSpec, err = helpers.NewPathSpec(d.Fs, l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d.PathSpec = helpers.NewPathSpec(d.Fs, l)
|
||||
d.ContentSpec = helpers.NewContentSpec(l)
|
||||
d.Cfg = l
|
||||
d.Language = l
|
||||
@@ -147,7 +162,7 @@ type DepsCfg struct {
|
||||
|
||||
// Template handling.
|
||||
TemplateProvider ResourceProvider
|
||||
WithTemplate func(templ tpl.Template) error
|
||||
WithTemplate func(templ tpl.TemplateHandler) error
|
||||
|
||||
// i18n handling.
|
||||
TranslationProvider ResourceProvider
|
||||
|
||||
@@ -2,7 +2,6 @@ title = "Hugo: A Fast and Flexible Website Generator"
|
||||
baseurl = "http://gohugo.io/"
|
||||
MetaDataFormat = "yaml"
|
||||
pluralizeListTitles = false
|
||||
enableGitInfo = true
|
||||
|
||||
[blackfriday]
|
||||
plainIDAnchors = true
|
||||
@@ -10,7 +9,7 @@ enableGitInfo = true
|
||||
[params]
|
||||
description = "Documentation of Hugo, a fast and flexible static site generator built with love by spf13, bep and friends in Go"
|
||||
author = "Steve Francia (spf13) and friends"
|
||||
release = "0.19"
|
||||
release = "0.21-DEV"
|
||||
|
||||
[taxonomies]
|
||||
tag = "tags"
|
||||
@@ -46,6 +45,11 @@ enableGitInfo = true
|
||||
identifier = "about"
|
||||
pre = "<i class='fa fa-heart'></i>"
|
||||
weight = -110
|
||||
[[menu.main]]
|
||||
name = "Release Notes"
|
||||
url = "/release-notes/"
|
||||
pre = "<i class='fa fa-newspaper-o'></i>"
|
||||
weight = -111
|
||||
[[menu.main]]
|
||||
name = "Getting Started"
|
||||
identifier = "getting started"
|
||||
|
||||
@@ -13,7 +13,7 @@ title: Contributing to Hugo
|
||||
weight: 30
|
||||
---
|
||||
|
||||
All contributions to Hugo are welcome. Whether you want to scratch an itch or simply contribute to the project, feel free to pick something from the [roadmap]({{< relref "meta/roadmap.md" >}}) or contact [spf13](http://spf13.com/) about what may make sense to do next.
|
||||
All contributions to Hugo are welcome. Whether you want to scratch an itch or simply contribute to the project, feel free to pick something from the [roadmap]({{< relref "meta/roadmap.md" >}}) or contact the dev team via the [Forums](https://discuss.gohugo.io/) or [Gitter](https://gitter.im/spf13/hugo) about what may make sense to do next.
|
||||
|
||||
You should fork the project and make your changes. *We encourage pull requests to discuss code changes.*
|
||||
|
||||
@@ -23,45 +23,44 @@ When you're ready to create a pull request, be sure to:
|
||||
* Have test cases for the new code. If you have questions about how to do it, please ask in your pull request.
|
||||
* Run `go fmt`.
|
||||
* Squash your commits into a single commit. `git rebase -i`. It's okay to force update your pull request.
|
||||
* Make sure `go test ./...` passes, and `go build` completes. Our [Travis CI loop](https://travis-ci.org/spf13/hugo) will catch most things that are missing. The exception: Windows. We run on Windows from time to time, but if you have access, please check on a Windows machine too.
|
||||
* Run `make check` and ensure it succeeds. [Travis CI](https://travis-ci.org/spf13/hugo) and [Appveyor](https://ci.appveyor.com/project/spf13/hugo) will runs these checks and fail the build if `make check` fails.
|
||||
|
||||
## Contribution Overview
|
||||
|
||||
We wrote a [detailed guide]({{< relref "tutorials/how-to-contribute-to-hugo.md" >}}) for newcomers that guides you step by step to your first contribution. If you are more experienced, follow the guide below.
|
||||
|
||||
|
||||
# Building from source
|
||||
|
||||
## Clone locally (for contributors):
|
||||
## Vendored Dependencies
|
||||
|
||||
git clone https://github.com/spf13/hugo
|
||||
cd hugo
|
||||
go get
|
||||
Hugo uses [govendor][] 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 Hugo's dependencies.
|
||||
|
||||
Because Go expects all of your libraries to be found in either
|
||||
`$GOROOT` or `$GOPATH`, it's helpful to symlink the project to one
|
||||
of the following paths:
|
||||
## Fetch the Sources
|
||||
|
||||
* `ln -s /path/to/your/hugo $GOPATH/src/github.com/spf13/hugo`
|
||||
* `ln -s /path/to/your/hugo $GOROOT/src/pkg/github.com/spf13/hugo`
|
||||
go get github.com/kardianos/govendor
|
||||
govendor get github.com/spf13/hugo
|
||||
|
||||
## Running Hugo
|
||||
|
||||
cd /path/to/hugo
|
||||
go install github.com/spf13/hugo/hugo
|
||||
cd $HOME/go/src/github.com/spf13/hugo
|
||||
go run main.go
|
||||
|
||||
## Building Hugo
|
||||
|
||||
cd /path/to/hugo
|
||||
go build -o hugo main.go
|
||||
mv hugo /usr/local/bin/
|
||||
cd $HOME/go/src/github.com/spf13/hugo
|
||||
make build
|
||||
# or to install to $HOME/go/bin:
|
||||
make install
|
||||
|
||||
|
||||
# Showcase additions
|
||||
|
||||
You got your new website running and it's powered by Hugo? Great. You can add your website with a few steps to the [showcase](/showcase/).
|
||||
|
||||
First, make sure that you created a [fork](https://help.github.com/articles/fork-a-repo/) of Hugo on Github and cloned your fork on your local computer. Next, create a separate branch for your additions:
|
||||
First, make sure that you created a [fork](https://help.github.com/articles/fork-a-repo/) of Hugo on GitHub and cloned your fork on your local computer. Next, create a separate branch for your additions:
|
||||
|
||||
```
|
||||
# You can choose a different descriptive branch name if you like
|
||||
@@ -108,3 +107,5 @@ If everything looks fine, we are ready to commit your additions. For the sake of
|
||||
Last but not least, we're ready to create a [pull request](https://github.com/spf13/hugo/compare).
|
||||
|
||||
Don't forget to accept the contributor license agreement. Click on the yellow badge in the automatically added comment in the pull request.
|
||||
|
||||
[govendor]: https://github.com/kardianos/govendor
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
lastmod: 2017-02-05
|
||||
lastmod: 2017-03-02
|
||||
date: 2014-03-24T20:00:00Z
|
||||
linktitle: Press
|
||||
notoc: true
|
||||
@@ -18,122 +18,123 @@ Hugo has been featured in the following Blog Posts, Press and Media.
|
||||
|
||||
| Title | Author | Date |
|
||||
| ------ | ------ | -----: |
|
||||
| [Build a Hugo site using Cloud9 IDE and host on App Engine](https://loyall.ch/lab/2017/01/build-a-static-website-with-cloud9-hugo-and-app-engine/) | Pascal Aubort | 5 Feb 2017 |
|
||||
| [How to use Firebase to host a Hugo site](https://www.m0d3rnc0ad.com/post/static-site-firebase/) | Andrew Cuga | 4 Feb 2017 |
|
||||
| [A publishing workflow for teams using static site generators](https://www.keybits.net/post/publishing-workflow-for-teams-using-static-site-generators/) | Tom Atkins | 2 Jan 2017 |
|
||||
| [How to deploy a Hugo site to DigitalOcean automatically with Wercker](https://gettingthingstech.com/how-to-deploy-a-hugo-site-to-digitalocean-automatically-with-wercker/) | Jacob Long | 24 Dec 2016 |
|
||||
| [How To Dynamically Use Google Fonts In A Hugo Website](https://stoned.io/web-development/hugo/How-To-Dynamically-Use-Google-Fonts-In-A-Hugo-Website/) | Hash Borgir | 27 Oct 2016 |
|
||||
| [Embedding Facebook In A Hugo Template](https://stoned.io/web-development/hugo/Embedding-Facebook-In-A-Hugo-Template/) | Hash Borgir | 22 Oct 2016 |
|
||||
| [通过 Gitlab-cl 将 Hugo blog 自动部署至 GitHub](https://zetaoyang.github.io/post/2016/10/17/gitlab-cl.html) <small>(Chinese, Continious integration)</small> | Zetao Yang | 17 Oct 2016 |
|
||||
| [A Step-by-Step Guide: Hugo on Netlify](https://www.netlify.com/blog/2016/09/21/a-step-by-step-guide-hugo-on-netlify/) | Eli Williamson | 21 Sep 2016 |
|
||||
| [Building our site: From Django & Wordpress to a static generator (Part I)](https://tryolabs.com/blog/2016/09/20/building-our-site-django-wordpress-to-static-part-i/) | Alan Descoins | 20 Sep 2016 |
|
||||
| [Webseitenmaschine - Statische Websites mit Hugo erzeugen](http://www.heise.de/ct/ausgabe/2016-12-Statische-Websites-mit-Hugo-erzeugen-3211704.html) <small>(German, $)</small> | Christian Helmbold | 27 May 2016 |
|
||||
| [Cómo hacer sitios web estáticos con Hugo y Go - Platzi](https://www.youtube.com/watch?v=qaXXpdiCHXE) <small>(Video tutorial)</small> | Verónica López | 6 Apr 2016 |
|
||||
| [CDNOverview: A CDN comparison site made with Hugo](https://www.cloakfusion.com/cdnoverview-cdn-comparison-site-made-hugo/) | Thijs de Zoete | 23 Feb 2016 |
|
||||
| [Hugo: A Modern WebSite Engine That Just Works](https://github.com/shekhargulati/52-technologies-in-2016/blob/master/07-hugo/README.md) | Shekhar Gulati | 14 Feb 2016 |
|
||||
| [Minify Hugo Generated HTML](http://ratson.name/blog/minify-hugo-generated-html/) | Ratson | 2 Feb 2016 |
|
||||
| [Static site generators: el futuro de las webs estáticas<br>(Hugo, Jekyll, Flask y otros)](http://sitelabs.es/static-site-generators-futuro-las-webs-estaticas/) | Eneko Sarasola | 9 Jan 2016 |
|
||||
| [Writing a Lambda Function for Hugo](https://blog.jolexa.net/post/writing-a-lambda-function-for-hugo/) | Jeremy Olexa | 1 Jan 2016 |
|
||||
| [Ein Blog mit Hugo erstellen - Tutorial](http://privat.albicker.org/tags/hugo.html) <small>(Deutsch/German)</small> | Bernhard Albicker | 30 Dec 2015 |
|
||||
| [How to host Hugo static website generator on AWS Lambda](http://bezdelev.com/post/hugo-aws-lambda-static-website/) | Ilya Bezdelev | 15 Dec 2015 |
|
||||
| [Migrating from Pelican to Hugo](http://www.softinio.com/post/migrating-from-pelican-to-hugo/) | Salar Rahmanian | 29 Nov 2015 |
|
||||
| [Hugo + Uberspace + Git = Hubergit — eine Anleitung (German)](https://harms-ensink.name/post/hubergit/) | Christoph Harms-Ensink | 24 Nov 2015 |
|
||||
| [Static Website Generators Reviewed: Jekyll, Middleman, Roots, Hugo](http://www.smashingmagazine.com/2015/11/static-website-generators-jekyll-middleman-roots-hugo-review/) | <div style="line-height: 100%">Mathias Biilmann Christensen</div> | 16 Nov 2015 |
|
||||
| [How To Deploy a Hugo Site to Production with Git Hooks on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-hugo-site-to-production-with-git-hooks-on-ubuntu-14-04) | Justin Ellingwood | 12 Nov 2015 |
|
||||
| [How To Install and Use Hugo, a Static Site Generator, on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-hugo-a-static-site-generator-on-ubuntu-14-04) | Justin Ellingwood | 9 Nov 2015 |
|
||||
| [Switching from Wordpress to Hugo](http://justinfx.com/2015/11/08/switching-from-wordpress-to-hugo/) | Justin Israel | 8 Nov 2015 |
|
||||
| [Hands-on Experience with Hugo as a Static Site Generator](http://usersnap.com/blog/hands-on-experience-with-hugo-static-site-generator/) | Thomas Peham | 15 Oct 2015 |
|
||||
| [Statische Webseites mit Hugo erstellen/Vortrag mit Foliensatz (deutsch)](http://sfd.koelnerlinuxtreffen.de/2015/HaraldWeidner/) | Harald Weidner | 19 Sep 2015 |
|
||||
| [Moving from WordPress to Hugo](http://abhipandey.com/2015/09/moving-to-hugo/) | Abhishek Pandey | 15 Sep 2015 |
|
||||
| [<span lang="zh-CN">通过webhook将Hugo自动部署至GitHub Pages和GitCafe Pages</span> <small>(Automated deployment)</small>](http://blog.coderzh.com/2015/09/13/use-webhook-automated-deploy-hugo/) | CoderZh | 13 Sep 2015 |
|
||||
| [<span lang="zh-CN">使用hugo搭建个人博客站点</span> <small>(Using Hugo to build a personal blog site)</small>](http://blog.coderzh.com/2015/08/29/hugo/) | CoderZh | 29 Aug 2015 |
|
||||
| [Good-Bye Wordpress, Hello Hugo!](http://blog.arminhanisch.de/2015/08/blog-migration-zu-hugo/) <small>(German)</small> | Armin Hanisch | 18 Aug 2015 |
|
||||
| [Static Site E-Commerce: Integrating Snipcart with Hugo](https://snipcart.com/blog/snipcart-hugo-integration) | Francis Tremblay | 13 Aug 2015 |
|
||||
| [Générer votre site web statique avec Hugo <small>(Generate your static site with Hugo)<small>](http://www.linux-pratique.com/?p=191) | Benoît Benedetti | 26 June 2015 |
|
||||
| [<span lang="ja">Hugo向けの新しいテーマを作った</span> <small>(I created a new theme for Hugo)<small>](http://yet.unresolved.xyz/blog/2015/06/20/making-new-theme-robust-for-hugo/) | Daisuke Tsuji | 20 June 2015 |
|
||||
| [Hugo - Gerando um site com conteúdo estático. (Portuguese Brazil)](http://blog.ffrizzo.com/posts/hugo/) | Fabiano Frizzo | 2 Jun 2015 |
|
||||
| [An Introduction to Static Site Generators](http://davidwalsh.name/introduction-static-site-generators) | Eduardo Bouças | 20 May 2015 |
|
||||
| [Hugo Still Rules](http://cheekycoder.com/2015/05/hugo-still-rules/) | Cheeky Coder | 18 May 2015 |
|
||||
| [hugo - Static Site Generator](http://gscacco.github.io/post/hugo/) | G Scaccoio | 4 May 2015 |
|
||||
| [<span lang="ja">WindowsでHugoを使う</span>](http://ureta.net/2015/05/hugo-on-windows/) | <span lang="ja">うれ太郎</span> | 1 May 2015 |
|
||||
| [<span lang="ja">Hugoのshortcodesを用いてサイトにスライドなどを埋め込む</span>](http://blog.yucchiy.com/2015/04/29/hugo-shortcode/) | Yucchiy | 29 Apr 2015 |
|
||||
| [<span lang="ja">HugoとCircleCIでGitHub PagesにBlogを公開してみたら超簡単だった</span>](http://hori-ryota.github.io/blog/create-blog-with-hugo-and-circleci/) | Hori Ryota | 17 Apr 2015 |
|
||||
| [How to build a mobile friendly website Part 2 - Ok to Go](http://jbrodriguez.io/mobile-friendly-website-2/) | Juan B. Rodriguez | 13 Apr 2015 |
|
||||
| [10 Best Static Site Generators](http://beebom.com/2015/04/best-static-site-generators) | Aniruddha Mysore | 6 Apr 2015 |
|
||||
| [Goodbye WordPress; Hello Hugo](http://willwarren.com/2015/04/05/goodbye-wordpress-hello-hugo/) | Will Warren | 5 Apr 2015 |
|
||||
| [Static Websites with Hugo on Google Cloud Storage](http://www.moxie.io/post/static-websites-with-hugo-on-google-cloud-storage/) | Moxie Input/Output | 2 Apr 2015 |
|
||||
| [De nuevo iniciando un blog](http://alvarolizama.net/blog/denuevo-iniciando-un-blog/) | Alvaro Lizama | 29 Mar 2015 |
|
||||
| [We moved our blog from Posthaven to Hugo after only three posts. Why?](http://blog.hypriot.com/post/moved-from-posthaven-to-hugo/) | Hypriot | 27 Mar 2015 |
|
||||
| [Hugo is cool](http://tnt.wicast.tk/2015/03/23/hugo-is-cool/) <small>(<span lang="zh-CN">中文</span> Chinese)</small> | wicast | 23 Mar 2015 |
|
||||
| [Top Static Site Generators in 2015](http://superdevresources.com/static-site-generators-2015/) | Kanishk Kunal | 12 Mar 2015 |
|
||||
| [Moving to Hugo](http://abiosoft.com/moving-to-hugo/) | Abiola Ibrahim | 8 Mar 2015 |
|
||||
| [<span lang="ja">Hugoで試行錯誤する</span> - log](http://deprode.net/log/logs/first/) | Deprode | 28 Feb 2015 |
|
||||
| [Migrating a blog (yes, this one!) from Wordpress to Hugo](http://justindunham.net/migrating-from-wordpress-to-hugo/) | Justin Dunham | 13 Feb 2015 |
|
||||
| [<span lang="ja">blogをoctopressからHugoに乗り換えたメモ</span>](http://blog.jigyakkuma.org/2015/02/11/hugo/) | jigyakkuma | 11 Feb 2015 |
|
||||
| [<span lang="ja">Hugoでブログをつくった</span>](http://porgy13.github.io/post/new-hugo-blog/) | porgy13 | 7 Feb 2015 |
|
||||
| [<span lang="ja">Hugoにブログを移行した</span>](http://keichi.net/post/first/) | Keichi Takahashi | 4 Feb 2015 |
|
||||
| [<span lang="zh-CN">Hugo静态网站生成器中文教程</span>](http://nanshu.wang/post/2015-01-31/) | Nanshu Wang | 31 Jan 2015 |
|
||||
| [<span lang="ja">Hugo + Github Pages + Wercker CI = ¥0(無料)<br>でコマンド 1 発(自動化)でサイト<br>・ブログを公開・運営・分析・収益化</span>](http://qiita.com/yoheimuta/items/8a619cac356bed89a4c9) | Yohei Yoshimuta | 31 Jan 2015 |
|
||||
| [Running Hugo websites on anynines](http://blog.anynines.com/running-hugo-websites-on-anynines/) | Julian Weber | 30 Jan 2015 |
|
||||
| [MiddlemanからHugoへ移行した](http://re-dzine.net/2015/01/hugo/) | Haruki Konishi | 21 Jan 2015 |
|
||||
| [WordPress から Hugo に乗り換えました](http://rakuishi.com/archives/wordpress-to-hugo/) | rakuishi | 20 Jan 2015 |
|
||||
| [HUGOを使ってサイトを立ち上げる方法](http://qiita.com/syui/items/869538099551f24acbbf) | Syui | 17 Jan 2015 |
|
||||
| [<span lang="ja">Jekyllが許されるのは小学生までだよね</span>](http://t32k.me/mol/log/hugo/) | Ishimoto Koji | 16 Jan 2015 |
|
||||
| [Getting started with Hugo](http://anthonyfok.org/post/getting-started-with-hugo/) | Anthony Fok | 12 Jan 2015 |
|
||||
| [<span lang="zh-CN">把这个博客静态化了</span> <small>(Migrate to Hugo)</small>](http://lich-eng.com/2015/01/03/migrate-to-hugo/) | Li Cheng | 3 Jan 2015 |
|
||||
| [My Hugo Experiment](http://tilde.club/~jbaty/2014/12/2014-12-31-my-hugo-experiment/) | Jack Baty | 31 Dec 2014 |
|
||||
| [Porting my blog with Hugo](http://blog.srackham.com/posts/porting-my-blog-with-hugo/) | Stuart Rackham | 30 Dec 2014 |
|
||||
| [Hugoを使ってみたときのメモ](http://machortz.github.io/posts/usinghugo/) | Machortz | 29 Dec 2014 |
|
||||
| [OctopressからHugoへ移行した](http://deeeet.com/writing/2014/12/25/hugo/) | Taichi Nakashima | 25 Dec 2014 |
|
||||
| [Hugo로 Github에 블로그 호스팅하기](http://cdpython.github.io/post/go/hugo/hugo-github/) | CD Python | 25 Dec 2014 |
|
||||
| [Migrating to Hugo From Octopress](http://nathanleclaire.com/blog/2014/12/22/migrating-to-hugo-from-octopress/) | Nathan LeClaire | 22 Dec 2014 |
|
||||
| [Dynamic Pages with GoHugo.io](http://cyrillschumacher.com/2014/12/21/dynamic-pages-with-gohugo.io/) | Cyrill Schumacher | 21 Dec 2014 |
|
||||
| [6 Static Blog Generators That Aren’t Jekyll](http://www.sitepoint.com/6-static-blog-generators-arent-jekyll/) | David Turnbull | 8 Dec 2014 |
|
||||
| [Travel Blogging Setup](http://www.stou.dk/2014/11/travel-blogging-setup/) | Rasmus Stougaard | 23 Nov 2014 |
|
||||
| [Hosting A Hugo Website Behind Nginx](http://www.bigbeeconsultants.co.uk/blog/hosting-hugo-website-behind-nginx) | Rick Beton | 20 Nov 2014 |
|
||||
| [<span lang="zh-CN">使用Hugo搭建免费个人Blog</span> <small>(How to use Hugo)</small>](http://ulricqin.com/post/how-to-use-hugo/) | Ulric Qin <span lang="zh-CN">秦晓辉</span> | 11 Nov 2014 |
|
||||
| [Built in Speed and Built for Speed by Hugo](http://cheekycoder.com/2014/10/built-for-speed-by-hugo/) | Cheeky Coder | 30 Oct 2014 |
|
||||
| [hugo, syncthing](http://fredix.ovh/2014/10/hugo-syncthing/) | Frédéric Logier | 13 Oct 2014 |
|
||||
| [Hugo para crear sitios web estáticos](http://www.webbizarro.com/noticias/1076/hugo-para-crear-sitios-web-estaticos/) | Web Bizarro | 19 Aug 2014 |
|
||||
| [Going with hugo](http://www.markuseliasson.se/article/going-with-hugo/) | Markus Eliasson | 18 Aug 2014 |
|
||||
| [Benchmarking Jekyll, Hugo and Wintersmith](http://fredrikloch.me/post/2014-08-12-Jekyll-and-its-alternatives-from-a-site-generation-point-of-view/) | Fredrik Loch | 12 Aug 2014 |
|
||||
| [Goodbye Octopress, Hello Hugo!](http://andreimihu.com/blog/2014/08/11/goodbye-octopress-hello-hugo/) | Andrei Mihu | 11 Aug 2014 |
|
||||
| [Beautiful sites for Open Source projects](http://beautifulopen.com/2014/08/09/hugo/) | Beautiful Open | 9 Aug 2014 |
|
||||
| [Hugo: Beyond the Defaults](http://npf.io/2014/08/hugo-beyond-the-defaults/) | Nate Finch | 8 Aug 2014 |
|
||||
| [First Impressions of Hugo](https://peteraba.com/blog/first-impressions-of-hugo/) | Peter Aba | 6 Aug 2014 |
|
||||
| [New Site Workflow](http://vurt.co.uk/post/new_website/) | Giles Paterson | 5 Aug 2014 |
|
||||
| [How I Learned to Stop Worrying and Love the (Static) Web](http://cognition.ca/post/about-hugo/) | Joshua McKenty | 4 Aug 2014 |
|
||||
| [Hugo - Static Site Generator](http://kenwoo.io/blog/hugo---static-site-generator/) | Kenny Woo | 3 Aug 2014 |
|
||||
| [Hugo Is Friggin' Awesome](http://npf.io/2014/08/hugo-is-awesome/) | Nate Finch | 1 Aug 2014 |
|
||||
| [<span lang="zh-CN">再次搬家</span> <small>(Move from WordPress to Hugo)</small>](http://www.chingli.com/misc/move-from-wordpress-to-hugo/) | <span lang="zh-CN">青砾</span> (chingli) | 12 July 2014 |
|
||||
| [Embedding Gists in Hugo](http://danmux.com/posts/embedded_gists/) | Dan Mull | 5 July 2014 |
|
||||
| [An Introduction To Hugo](http://www.cirrushosting.com/web-hosting-blog/an-introduction-to-hugo/) | Dan Silber | 1 July 2014 |
|
||||
| [Moving to Hugo](http://danmux.com/posts/hugo_based_blog/) | Dan Mull | 29 May 2014 |
|
||||
| [<span lang="zh-CN">开源之静态站点生成器排行榜</span><br><small>(Leaderboard of open-source static website generators)</small>](http://code.csdn.net/news/2819909) | CSDN.net | 23 May 2014 |
|
||||
| [How I deploy this site using Fabric](http://carlorat.me/quote/fabric/) | Carlo Ratam | 21 May 2014 |
|
||||
| [Finally, a satisfying and effective blog setup](http://michaelwhatcott.com/now-powered-by-hugo/) | Michael Whatcott | 20 May 2014 |
|
||||
| [Hugo from scratch](http://zackofalltrades.com/notes/2014/05/hugo-from-scratch/) | Zack Williams | 18 May 2014 |
|
||||
| [Why I switched away from Jekyll](http://www.jakejanuzelli.com/why-I-switched-away-from-jekyll/) | Jake Januzelli | 10 May 2014 |
|
||||
| [Welcome our new blog](http://blog.ninya.io/posts/welcome-our-new-blog/) | Ninya.io | 11 Apr 2014 |
|
||||
| [Mission Not Accomplished](http://johnsto.co.uk/blog/mission-not-accomplished/) | Dave Johnston | 3 Apr 2014 |
|
||||
| [Hugo - A Static Site Builder in Go](http://deepfriedcode.com/post/hugo/) | Deep Fried Code | 30 Mar 2014 |
|
||||
| [Adventures in Angular Podcast](http://devchat.tv/adventures-in-angular/003-aia-gdes) | Matias Niemela | 28 Mar 2014 |
|
||||
| [Hugo](http://bra.am/post/hugo/) | bra.am | 23 Mar 2014 |
|
||||
| [Converting Blogger To Markdown](http://trishagee.github.io/project/atom-to-hugo/) | Trisha Gee | 20 Mar 2014 |
|
||||
| [Moving to Hugo Static Web Pages](http://tepid.org/tech/hugo-web/) | Tobias Weingartner | 16 Mar 2014 |
|
||||
| [Hugo and GitHub Pages](http://spencerlyon.com/blog/2014/creating-the-site/) | Spencer Lyon | 15 Mar 2014 |
|
||||
| [New Blog Engine: Hugo](https://blog.afoolishmanifesto.com/posts/hugo/) | fREW Schmidt | 15 Mar 2014 |
|
||||
| [Hugo + gulp.js = Huggle](http://ktmud.github.io/huggle/en/intro/) ([English](http://ktmud.github.io/huggle/en/intro/), [<span lang="zh-CN">中文</span>](http://ktmud.github.io/huggle/zh/intro/)) | Jesse Yang <span lang="zh-CN">杨建超</span> | 8 Mar 2014 |
|
||||
| [Powered by Hugo](http://kieranhealy.org/blog/archives/2014/02/24/powered-by-hugo/) | Kieran Healy | 24 Feb 2014 |
|
||||
| [<span lang="ja">静的サイトを素早く構築するために<br>GoLangで作られたジェネレータHugo</span>](http://hamasyou.com/blog/2014/02/21/hugo/) | <div lang="ja" style="line-height: 1.1;">Shogo Hamada<br>濱田章吾</div> | 21 Feb 2014 |
|
||||
| [Latest Roundup of Useful Tools For Developers](http://codegeekz.com/latest-roundup-of-useful-tools-for-developers/) | CodeGeekz | 13 Feb 2014 |
|
||||
| [Hugo: Static Site Generator written in Go](http://www.braveterry.com/2014/02/06/hugo-static-site-generator-written-in-go/) | Brave Terry | 6 Feb 2014 |
|
||||
| [10 Useful HTML5 Tools for Web Designers and Developers](http://designdizzy.com/10-useful-html5-tools-for-web-designers-and-developers/) | Design Dizzy | 4 Feb 2014 |
|
||||
| [Hugo – Fast, Flexible Static Site Generator](http://cube3x.com/hugo-fast-flexible-static-site-generator/) | Joby Joseph | 18 Jan 2014 |
|
||||
| [Hugo: A new way to build static website](http://www.w3update.com/opensource/hugo-a-new-way-to-build-static-website.html) | w3update | 17 Jan 2014 |
|
||||
| [Xaprb now uses Hugo](http://xaprb.com/blog/2014/01/15/using-hugo/) | Baron Schwartz | 15 Jan 2014 |
|
||||
| [New jQuery Plugins And Resources That Web Designers Need](http://www.designyourway.net/blog/resources/new-jquery-plugins-and-resources-that-web-designers-need/) | Design Your Way | 2014 |
|
||||
| [On Blog Construction](http://alexla.sh/post/on-blog-construction/) | Alexander Lash | 27 Dec 2013 |
|
||||
| [Hugo](http://onethingwell.org/post/69070926608/hugo) | One Thing Well | 5 Dec 2013 |
|
||||
| [In Praise Of Hugo](http://sound-guru.com/blog/post/hello-world/) | sound-guru.com | 19 Oct 2013 |
|
||||
| [Hosting a blog on S3 and Cloudfront](http://www.danesparza.net/2013/07/hosting-a-blog-on-s3-and-cloudfront/) | Dan Esparza | 24 July 2013 |
|
||||
| [Hugo Easy Gallery - Automagical PhotoSwipe image gallery with a one-line shortcode](https://www.liwen.id.au/heg/)| Li-Wen Yip | 2017-03-25 |
|
||||
| [Hugo Tutorial: How to Build & Host a (Very Fast) Static E-Commerce Site](https://snipcart.com/blog/hugo-tutorial-static-site-ecommerce) | Snipcart | 2017-03-12 |
|
||||
| [Automagical image gallery in Hugo with PhotoSwipe and jQuery](https://www.liwen.id.au/photoswipe/)| Li-Wen Yip | 2017-03-04 |
|
||||
| [Adding Isso Comments to Hugo](https://stiobhart.net/2017-02-24-isso-comments/) | Stíobhart Matulevicz | 2017-02-24 |
|
||||
| [Zero to HTTP/2 with AWS and Hugo](https://habd.as/zero-to-http-2-aws-hugo/) | Josh Habdas | 2017-02-16 |
|
||||
| [How to Password Protect a Hugo Site](https://www.aerobatic.com/blog/password-protect-a-hugo-site/) | Aerobatic | 2017-02-19 |
|
||||
| [Switching from Wordpress to Hugo](http://schnuddelhuddel.de/switching-from-wordpress-to-hugo/) | Mario Martelli | 2017-02-19 | ]
|
||||
| [Deploy a Hugo site to Aerobatic with CircleCI ](https://www.aerobatic.com/blog/hugo-github-circleci/) | Aerobatic | 2017-02-14 |
|
||||
| [NPM scripts for building and deploying Hugo site](https://www.aerobatic.com/blog/hugo-npm-buildtool-setup/) | Aerobatic | 2017-02-12 |
|
||||
| [Getting started with Hugo and the plain-blog theme, on NearlyFreeSpeech.Net](https://www.penwatch.net/cms/get_started_plain_blog/) | Li-aung “Lewis” Yip | 2017-02-12 |
|
||||
| [Build a Hugo site using Cloud9 IDE and host on App Engine](https://loyall.ch/lab/2017/01/build-a-static-website-with-cloud9-hugo-and-app-engine/)| Pascal Aubort | 2017-02-05 |
|
||||
| [Hugo Continuous Deployment with Bitbucket Pipelines and Aerobatic](https://www.aerobatic.com/blog/hugo-bitbucket-pipelines/) | Aerobatic | 2017-02-04 |
|
||||
| [How to use Firebase to host a Hugo site](https://www.m0d3rnc0ad.com/post/static-site-firebase/) | Andrew Cuga | 2017-02-04 |
|
||||
| [A publishing workflow for teams using static site generators](https://www.keybits.net/post/publishing-workflow-for-teams-using-static-site-generators/) | Tom Atkins | 2017-01-02 |
|
||||
| [How To Dynamically Use Google Fonts In A Hugo Website](https://stoned.io/web-development/hugo/How-To-Dynamically-Use-Google-Fonts-In-A-Hugo-Website/) | Hash Borgir | 2016-10-27 |
|
||||
| [Embedding Facebook In A Hugo Template](https://stoned.io/web-development/hugo/Embedding-Facebook-In-A-Hugo-Template/) | Hash Borgir | 2016-10-22 |
|
||||
| [通过 Gitlab-cl 将 Hugo blog 自动部署至 GitHub](https://zetaoyang.github.io/post/2016/10/17/gitlab-cl.html) <small>(Chinese, Continious integration)</small> | Zetao Yang | 2016-10-17 |
|
||||
| [A Step-by-Step Guide: Hugo on Netlify](https://www.netlify.com/blog/2016/09/21/a-step-by-step-guide-hugo-on-netlify/) | Eli Williamson | 2016-09-21 |
|
||||
| [Building our site: From Django & Wordpress to a static generator (Part I)](https://tryolabs.com/blog/2016/09/20/building-our-site-django-wordpress-to-static-part-i/) | Alan Descoins | 2016-09-20 |
|
||||
| [Webseitenmaschine - Statische Websites mit Hugo erzeugen](http://www.heise.de/ct/ausgabe/2016-12-Statische-Websites-mit-Hugo-erzeugen-3211704.html) <small>(German, $)</small> | Christian Helmbold | 2016-05-27 |
|
||||
| [Cómo hacer sitios web estáticos con Hugo y Go - Platzi](https://www.youtube.com/watch?v=qaXXpdiCHXE) <small>(Video tutorial)</small> | Verónica López | 2016-04-06 |
|
||||
| [CDNOverview: A CDN comparison site made with Hugo](https://www.cloakfusion.com/cdnoverview-cdn-comparison-site-made-hugo/) | Thijs de Zoete | 2016-02-23 |
|
||||
| [Hugo: A Modern WebSite Engine That Just Works](https://github.com/shekhargulati/52-technologies-in-2016/blob/master/07-hugo/README.md) | Shekhar Gulati | 2016-02-14 |
|
||||
| [Minify Hugo Generated HTML](http://ratson.name/blog/minify-hugo-generated-html/) | Ratson | 2016-02-02 |
|
||||
| [<span lang="ja">HugoのデプロイをWerckerからCircle CIに変更した</span> - log](http://log.deprode.net/logs/2016-01-17/) | Deprode | 2016-01-17 |
|
||||
| [Static site generators: el futuro de las webs estáticas<br>(Hugo, Jekyll, Flask y otros)](http://sitelabs.es/static-site-generators-futuro-las-webs-estaticas/) | Eneko Sarasola | 2016-01-09 |
|
||||
| [Writing a Lambda Function for Hugo](https://blog.jolexa.net/post/writing-a-lambda-function-for-hugo/) | Jeremy Olexa | 2016-01-01 |
|
||||
| [Ein Blog mit Hugo erstellen - Tutorial](http://privat.albicker.org/tags/hugo.html) <small>(Deutsch/German)</small> | Bernhard Albicker | 2015-12-30 |
|
||||
| [How to host Hugo static website generator on AWS Lambda](http://bezdelev.com/post/hugo-aws-lambda-static-website/) | Ilya Bezdelev | 2015-12-15 |
|
||||
| [Migrating from Pelican to Hugo](http://www.softinio.com/post/migrating-from-pelican-to-hugo/) | Salar Rahmanian | 2015-11-29 |
|
||||
| [Static Website Generators Reviewed: Jekyll, Middleman, Roots, Hugo](http://www.smashingmagazine.com/2015/11/static-website-generators-jekyll-middleman-roots-hugo-review/) | Mathias Biilmann Christensen | 2015-11-16 |
|
||||
| [How To Deploy a Hugo Site to Production with Git Hooks on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-hugo-site-to-production-with-git-hooks-on-ubuntu-14-04) | Justin Ellingwood | 2015-11-12 |
|
||||
| [How To Install and Use Hugo, a Static Site Generator, on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-hugo-a-static-site-generator-on-ubuntu-14-04) | Justin Ellingwood | 2015-11-09 |
|
||||
| [Switching from Wordpress to Hugo](http://justinfx.com/2015/11/08/switching-from-wordpress-to-hugo/) | Justin Israel | 2015-11-08 |
|
||||
| [Hands-on Experience with Hugo as a Static Site Generator](http://usersnap.com/blog/hands-on-experience-with-hugo-static-site-generator/) | Thomas Peham | 2015 -10-15 |
|
||||
| [Statische Webseites mit Hugo erstellen/Vortrag mit Foliensatz (deutsch)](http://sfd.koelnerlinuxtreffen.de/2015/HaraldWeidner/) | Harald Weidner | 2015-09-19 |
|
||||
| [Moving from WordPress to Hugo](http://abhipandey.com/2015/09/moving-to-hugo/) | Abhishek Pandey | 2015-09-15 |
|
||||
| [<span lang="zh-CN">通过webhook将Hugo自动部署至GitHub Pages和GitCafe Pages</span> <small>(Automated deployment)</small>](http://blog.coderzh.com/2015/09/13/use-webhook-automated-deploy-hugo/) | CoderZh | 2015-09-13 |
|
||||
| [<span lang="zh-CN">使用hugo搭建个人博客站点</span> <small>(Using Hugo to build a personal blog site)</small>](http://blog.coderzh.com/2015/08/29/hugo/) | CoderZh | 2015-08-29 |
|
||||
| [Good-Bye Wordpress, Hello Hugo!](http://blog.arminhanisch.de/2015/08/blog-migration-zu-hugo/) <small>(German)</small> | Armin Hanisch | 2015-08-18 |
|
||||
| [Générer votre site web statique avec Hugo <small>(Generate your static site with Hugo)<small>](http://www.linux-pratique.com/?p=191) | Benoît Benedetti | 2015-06-26 |
|
||||
| [<span lang="ja">Hugo向けの新しいテーマを作った</span> <small>(I created a new theme for Hugo)<small>](https://yet.unresolved.xyz/blog/2016/10/03/how-to-make-of-hugo-theme/) | Daisuke Tsuji | 2015-06-20 |
|
||||
| [Hugo - Gerando um site com conteúdo estático. (Portuguese Brazil)](http://blog.ffrizzo.com/posts/hugo/) | Fabiano Frizzo | 2015-06-02 |
|
||||
| [An Introduction to Static Site Generators](http://davidwalsh.name/introduction-static-site-generators) | Eduardo Bouças | 2015-05-20 |
|
||||
| [Hugo Still Rules](http://cheekycoder.com/2015/05/hugo-still-rules/) | Cheeky Coder | 2015-05-18 |
|
||||
| [hugo - Static Site Generator](http://gscacco.github.io/post/hugo/) | G Scaccoio | 2015-05-04 |
|
||||
| [<span lang="ja">WindowsでHugoを使う</span>](http://ureta.net/2015/05/hugo-on-windows/) | <span lang="ja">うれ太郎</span> | 2015-05-01 |
|
||||
| [<span lang="ja">Hugoのshortcodesを用いてサイトにスライドなどを埋め込む</span>](http://blog.yucchiy.com/2015/04/29/hugo-shortcode/) | Yucchiy | 2015-04-29 |
|
||||
| [<span lang="ja">HugoとCircleCIでGitHub PagesにBlogを公開してみたら超簡単だった</span>](http://hori-ryota.github.io/blog/create-blog-with-hugo-and-circleci/) | Hori Ryota | 2015-04-17 |
|
||||
| [10 Best Static Site Generators](http://beebom.com/2015/04/best-static-site-generators) | Aniruddha Mysore | 2015-04-06 |
|
||||
| [Goodbye WordPress; Hello Hugo](http://willwarren.com/2015/04/05/goodbye-wordpress-hello-hugo/) | Will Warren | 2015-04-05 |
|
||||
| [Static Websites with Hugo on Google Cloud Storage](http://www.moxie.io/post/static-websites-with-hugo-on-google-cloud-storage/) | Moxie Input/Output | 2015-04-02 |
|
||||
| [De nuevo iniciando un blog](https://alvarolizama.net/) | Alvaro Lizama | 2015-03-29 |
|
||||
| [We moved our blog from Posthaven to Hugo after only three posts. Why?](http://blog.hypriot.com/post/moved-from-posthaven-to-hugo/) | Hypriot | 2015-03-27 |
|
||||
| [Top Static Site Generators in 2015](http://superdevresources.com/static-site-generators-2015/) | Kanishk Kunal | 2015-03-12 |
|
||||
| [Moving to Hugo](http://abiosoft.com/moving-to-hugo/) | Abiola Ibrahim | 2015-03-08 |
|
||||
| [Migrating a blog (yes, this one!) from Wordpress to Hugo](http://justindunham.net/migrating-from-wordpress-to-hugo/) | Justin Dunham | 2015-02-13 |
|
||||
| [<span lang="ja">blogをoctopressからHugoに乗り換えたメモ</span>](http://blog.jigyakkuma.org/2015/02/11/hugo/) | jigyakkuma | 2015-02-11 |
|
||||
| [<span lang="ja">Hugoでブログをつくった</span>](http://porgy13.github.io/post/new-hugo-blog/) | porgy13 | 2015-02-07 |
|
||||
| [<span lang="ja">Hugoにブログを移行した</span>](http://keichi.net/post/first/) | Keichi Takahashi | 2015-02-04 |
|
||||
| [<span lang="zh-CN">Hugo静态网站生成器中文教程</span>](http://nanshu.wang/post/2015-01-31/) | Nanshu Wang | 2015-01-31 |
|
||||
| [<span lang="ja">Hugo + GitHub Pages + Wercker CI = ¥0(無料)<br>でコマンド 1 発(自動化)でサイト<br>・ブログを公開・運営・分析・収益化</span>](http://qiita.com/yoheimuta/items/8a619cac356bed89a4c9) | Yohei Yoshimuta | 2015-01-31 |
|
||||
| [Running Hugo websites on anynines](http://blog.anynines.com/running-hugo-websites-on-anynines/) | Julian Weber | 2015-01-30 |
|
||||
| [MiddlemanからHugoへ移行した](http://re-dzine.net/2015/01/hugo/) | Haruki Konishi | 2015-01-21 |
|
||||
| [WordPress から Hugo に乗り換えました](http://rakuishi.com/archives/wordpress-to-hugo/) | rakuishi | 2015-01-20 |
|
||||
| [HUGOを使ってサイトを立ち上げる方法](http://qiita.com/syui/items/869538099551f24acbbf) | Syui | 2015-01-17 |
|
||||
| [<span lang="ja">Jekyllが許されるのは小学生までだよね</span>](http://t32k.me/mol/log/hugo/) | Ishimoto Koji | 2015-01-16 |
|
||||
| [Getting started with Hugo](http://anthonyfok.org/post/getting-started-with-hugo/) | Anthony Fok | 2015-01-12 |
|
||||
| [<span lang="zh-CN">把这个博客静态化了</span> <small>(Migrate to Hugo)</small>](http://lich-eng.com/2015/01/03/migrate-to-hugo/)| Li Cheng | 2015-01-03 |
|
||||
| [Porting my blog with Hugo](http://blog.srackham.com/posts/porting-my-blog-with-hugo/) | Stuart Rackham | 2014-12-30 |
|
||||
| [Hugoを使ってみたときのメモ](http://machortz.github.io/posts/usinghugo/) | Machortz | 2014-12-29 |
|
||||
| [OctopressからHugoへ移行した](http://deeeet.com/writing/2014/12/25/hugo/) | Taichi Nakashima | 2014-12-25 |
|
||||
| [Migrating to Hugo From Octopress](http://nathanleclaire.com/blog/2014/12/22/migrating-to-hugo-from-octopress/) | Nathan LeClaire | 2014-12-22 |
|
||||
| [Dynamic Pages with GoHugo.io](http://cyrillschumacher.com/2014/12/21/dynamic-pages-with-gohugo.io/) | Cyrill Schumacher | 2014-12-21 |
|
||||
| [6 Static Blog Generators That Aren’t Jekyll](http://www.sitepoint.com/6-static-blog-generators-arent-jekyll/) | David Turnbull | 2014-12-08 |
|
||||
| [Travel Blogging Setup](http://www.stou.dk/2014/11/travel-blogging-setup/) | Rasmus Stougaard | 2014-11-23 |
|
||||
| [Hosting A Hugo Website Behind Nginx](http://www.bigbeeconsultants.co.uk/blog/hosting-hugo-website-behind-nginx) | Rick Beton | 2014-11-20 |
|
||||
| [<span lang="zh-CN">使用Hugo搭建免费个人Blog</span> <small>(How to use Hugo)</small>](http://ulricqin.com/post/how-to-use-hugo/) | Ulric Qin <span lang="zh-CN">秦晓辉</span> | 2014-11-11 |
|
||||
| [Built in Speed and Built for Speed by Hugo](http://cheekycoder.com/2014/10/built-for-speed-by-hugo/) | Cheeky Coder | 2014-10-30 |
|
||||
| [Hugo para crear sitios web estáticos](http://www.webbizarro.com/noticias/1076/hugo-para-crear-sitios-web-estaticos/) | Web Bizarro | 2014-08-19 |
|
||||
| [Going with hugo](http://www.markuseliasson.se/article/going-with-hugo/) | Markus Eliasson | 2014-08-18 |
|
||||
| [Benchmarking Jekyll, Hugo and Wintersmith](http://fredrikloch.me/post/2014-08-12-Jekyll-and-its-alternatives-from-a-site-generation-point-of-view/) | Fredrik Loch | 2014-08-12 |
|
||||
| [Goodbye Octopress, Hello Hugo!](http://andreimihu.com/blog/2014/08/11/goodbye-octopress-hello-hugo/) | Andrei Mihu | 2014-08-11 |
|
||||
| [Beautiful sites for Open Source projects](http://beautifulopen.com/2014/08/09/hugo/) | Beautiful Open | 2014-08-09 |
|
||||
| [Hugo: Beyond the Defaults](http://npf.io/2014/08/hugo-beyond-the-defaults/) | Nate Finch | 2014-08-08 |
|
||||
| [First Impressions of Hugo](https://peteraba.com/blog/first-impressions-of-hugo/) | Peter Aba | 2014-06-06 |
|
||||
| [New Site Workflow](http://vurt.co.uk/post/new_website/) | Giles Paterson | 2014-08-05 |
|
||||
| [How I Learned to Stop Worrying and Love the (Static) Web](http://cognition.ca/post/about-hugo/) | Joshua McKenty | 2014-08-04 |
|
||||
| [Hugo - Static Site Generator](http://kenwoo.io/blog/hugo---static-site-generator/) | Kenny Woo | 2014-08-03 |
|
||||
| [Hugo Is Friggin' Awesome](http://npf.io/2014/08/hugo-is-awesome/) | Nate Finch | 2014-08-01 |
|
||||
| [<span lang="zh-CN">再次搬家</span> <small>(Move from WordPress to Hugo)</small>](http://www.chingli.com/misc/move-from-wordpress-to-hugo/) | <span lang="zh-CN">青砾</span> (chingli) | 2014-07-12 |
|
||||
| [Embedding Gists in Hugo](http://danmux.com/posts/embedded_gists/) | Dan Mull | 2014-07-05 |
|
||||
| [An Introduction To Hugo](http://www.cirrushosting.com/web-hosting-blog/an-introduction-to-hugo/) | Dan Silber | 2014-07-01 |
|
||||
| [Moving to Hugo](http://danmux.com/posts/hugo_based_blog/) | Dan Mull | 2014-05-29 |
|
||||
| [<span lang="zh-CN">开源之静态站点生成器排行榜</span><br><small>(Leaderboard of open-source static website generators)</small>](http://code.csdn.net/news/2819909) | CSDN.net | 2014-05-23 |
|
||||
| [Finally, a satisfying and effective blog setup](http://michaelwhatcott.com/now-powered-by-hugo/) | Michael Whatcott | 2014-05-20 |
|
||||
| [Hugo from scratch](http://zackofalltrades.com/notes/2014/05/hugo-from-scratch/) | Zack Williams | 2014-05-18 |
|
||||
| [Why I switched away from Jekyll](http://www.jakejanuzelli.com/why-I-switched-away-from-jekyll/) | Jake Januzelli | 2014-05-10 |
|
||||
| [Welcome our new blog](http://blog.ninya.io/posts/welcome-our-new-blog/) | Ninya.io | 2014-04-11 |
|
||||
| [Mission Not Accomplished](http://johnsto.co.uk/blog/mission-not-accomplished/) | Dave Johnston | 2014-04-03 |
|
||||
| [Hugo - A Static Site Builder in Go](http://deepfriedcode.com/post/hugo/) | Deep Fried Code | 2014-03-30 |
|
||||
| [Adventures in Angular Podcast](http://devchat.tv/adventures-in-angular/003-aia-gdes) | Matias Niemela | 2014-03-28 |
|
||||
| [Hugo](http://bra.am/post/hugo/) | bra.am | 2014-03-23 |
|
||||
| [Converting Blogger To Markdown](http://trishagee.github.io/project/atom-to-hugo/) | Trisha Gee | 2014-03-20 |
|
||||
| [Moving to Hugo Static Web Pages](http://tepid.org/tech/hugo-web/) | Tobias Weingartner | 2014-03-16 |
|
||||
| [New Blog Engine: Hugo](https://blog.afoolishmanifesto.com/posts/hugo/) | fREW Schmidt | 2014-03-15 |
|
||||
| [Hugo + gulp.js = Huggle](http://ktmud.github.io/huggle/en/intro/) ([English](http://ktmud.github.io/huggle/en/intro/), [<span lang="zh-CN">中文</span>](http://ktmud.github.io/huggle/zh/intro/)) | Jesse Yang <span lang="zh-CN">杨建超</span> | 2014-03-08 |
|
||||
| [Powered by Hugo](http://kieranhealy.org/blog/archives/2014/02/24/powered-by-hugo/) | Kieran Healy | 2014-02-24 |
|
||||
| [<span lang="ja">静的サイトを素早く構築するために<br>GoLangで作られたジェネレータHugo</span>](http://hamasyou.com/blog/2014/02/21/hugo/)| <div lang="ja" style="line-height: 1.1;">Shogo Hamada<br>濱田章吾</div> | 2014-02-21 |
|
||||
| [Latest Roundup of Useful Tools For Developers](http://codegeekz.com/latest-roundup-of-useful-tools-for-developers/) | CodeGeekz | 2014-02-13 |
|
||||
| [Hugo: Static Site Generator written in Go](http://www.braveterry.com/2014/02/06/hugo-static-site-generator-written-in-go/) | Brave Terry | 2014-02-06 |
|
||||
| [10 Useful HTML5 Tools for Web Designers and Developers](http://designdizzy.com/10-useful-html5-tools-for-web-designers-and-developers/) | Design Dizzy | 2014-02-04 |
|
||||
| [Hugo – Fast, Flexible Static Site Generator](http://cube3x.com/hugo-fast-flexible-static-site-generator/) | Joby Joseph | 2014-01-18 |
|
||||
| [Hugo: A new way to build static website](http://www.w3update.com/opensource/hugo-a-new-way-to-build-static-website.html) | w3update | 2014-01-17 |
|
||||
| [Xaprb now uses Hugo](http://xaprb.com/blog/2014/01/15/using-hugo/) | Baron Schwartz | 2014-01-15 |
|
||||
| [New jQuery Plugins And Resources That Web Designers Need](http://www.designyourway.net/blog/resources/new-jquery-plugins-and-resources-that-web-designers-need/) | Design Your Way | 2014-01-01 |
|
||||
| [On Blog Construction](http://alexla.sh/post/on-blog-construction/) | Alexander Lash | 2013-12-27 |
|
||||
| [Hugo](http://onethingwell.org/post/69070926608/hugo) | One Thing Well | 2013-12-05 |
|
||||
| [In Praise Of Hugo](http://sound-guru.com/blog/post/hello-world/) | sound-guru.com | 2013-10-19 |
|
||||
| [Hosting a blog on S3 and Cloudfront](http://www.danesparza.net/2013/07/hosting-a-blog-on-s3-and-cloudfront/) | Dan Esparza | 2013-07-24 |
|
||||
|
||||
@@ -21,7 +21,7 @@ Supported formats:
|
||||
|
||||
* **[TOML][]**, identified by '`+++`'.
|
||||
* **[YAML][]**, identified by '`---`'.
|
||||
* **[JSON][]**, a single JSON object which is surrounded by '`{`' and '`}`', each on their own line.
|
||||
* **[JSON][]**, a single JSON object which is surrounded by '`{`' and '`}`', followed by a newline.
|
||||
|
||||
[TOML]: https://github.com/toml-lang/toml "Tom's Obvious, Minimal Language"
|
||||
[YAML]: http://www.yaml.org/ "YAML Ain't Markup Language"
|
||||
|
||||
@@ -118,9 +118,9 @@ The above also uses the `i18n` func, see [Translation of strings](#translation-o
|
||||
|
||||
### Translation of strings
|
||||
|
||||
Hugo uses [go-i18n](https://github.com/nicksnyder/go-i18n) to support string translations. Follow the link to find tools to manage your translation workflows.
|
||||
Hugo uses [go-i18n](https://github.com/nicksnyder/go-i18n) to support string translations. Follow the link to find tools to manage your translation workflows.
|
||||
|
||||
Translations are collected from the `themes/[name]/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.yaml`, `fr.yaml`, etc.
|
||||
Translations are collected from the `themes/[name]/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.
|
||||
|
||||
From within your templates, use the `i18n` function like this:
|
||||
|
||||
@@ -128,11 +128,11 @@ From within your templates, use the `i18n` function like this:
|
||||
{{ i18n "home" }}
|
||||
```
|
||||
|
||||
This uses a definition like this one in `i18n/en-US.yaml`:
|
||||
This uses a definition like this one in `i18n/en-US.toml`:
|
||||
|
||||
```
|
||||
- id: home
|
||||
translation: "Home"
|
||||
[home]
|
||||
other = "Home"
|
||||
```
|
||||
|
||||
Often you will want to use to the page variables in the translations strings. To do that, pass on the "." context when calling `i18n`:
|
||||
@@ -141,19 +141,18 @@ Often you will want to use to the page variables in the translations strings. To
|
||||
{{ i18n "wordCount" . }}
|
||||
```
|
||||
|
||||
This uses a definition like this one in `i18n/en-US.yaml`:
|
||||
This uses a definition like this one in `i18n/en-US.toml`:
|
||||
|
||||
```
|
||||
- id: wordCount
|
||||
translation: "This article has {{ .WordCount }} words."
|
||||
[wordCount]
|
||||
other = "This article has {{ .WordCount }} words."
|
||||
```
|
||||
An example of singular and plural form:
|
||||
|
||||
```
|
||||
- id: readingTime
|
||||
translation:
|
||||
one: "One minute read"
|
||||
other: "{{.Count}} minutes read"
|
||||
[readingTime]
|
||||
one = "One minute read"
|
||||
other = "{{.Count}} minutes read"
|
||||
```
|
||||
And then in the template:
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ If this is confusing or you are unfamiliar with Hugo's template hierarchy, visit
|
||||
Now that you've got a handle on templates lets recap some Hugo basics to understand how to use an \_index.md file with a List page.
|
||||
|
||||
1. Sections and Taxonomies are 'List' pages, NOT single pages.
|
||||
2. List pages are rendered using the template heirarchy found in the [Content - List Template](http://localhost:1313/templates/list/) docs.
|
||||
2. List pages are rendered using the template heirarchy found in the [Content - List Template](/templates/list/) docs.
|
||||
3. The Home page, though technically a List page, can have [it's own template](/templates/homepage/) at layouts/index.html rather than \_default/list.html. Many themes exploit this behaviour so you are likely to encounter this specific use case.
|
||||
4. Taxonomy terms pages are 'lists of metadata' not lists of content, so [have their own templates](/templates/terms/).
|
||||
|
||||
|
||||
@@ -72,9 +72,10 @@ Now, reference the partial template from your page template:
|
||||
|
||||
A few alternatives exist to [Disqus](https://disqus.com/):
|
||||
|
||||
* [txtpen](https://txtpen.com)
|
||||
* [Discourse](http://www.discourse.org)
|
||||
* [IntenseDebate](http://intensedebate.com/)
|
||||
* [Livefyre](http://livefyre.com/)
|
||||
* [Livefyre](http://www.adobe.com/marketing-cloud/enterprise-content-management/ugc-content-platform.html)
|
||||
* [Muut](http://muut.com/)
|
||||
* [多说](http://duoshuo.com/) ([Duoshuo](http://duoshuo.com/), popular in China)
|
||||
* [isso](http://posativ.org/isso/) (Self-hosted, Python)
|
||||
@@ -88,6 +89,10 @@ Written using Go, Socket.io and MongoDB, it is very fast and easy to deploy.
|
||||
|
||||
It is in early development but shows promise. If you have interest, please help by contributing whether via a pull request, an issue or even just a tweet. Everything helps.
|
||||
|
||||
## txtpen
|
||||
|
||||
[txtpen](https://txtpen.com) adds highlighting an in-line commenting similar to Medium to your Hugo blog.
|
||||
|
||||
## Discourse
|
||||
|
||||
Additionally, you may recognize [Discourse](http://www.discourse.org) as the system that powers the [Hugo Discussion Forum](http://discuss.gohugo.io).
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/output-formats/
|
||||
- /doc/custom-output/
|
||||
date: 2017-03-22T08:20:13+01:00
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
title: Output Formats
|
||||
weight: 5
|
||||
toc: true
|
||||
---
|
||||
|
||||
Hugo `0.20` introduced the powerful feature **Custom Output Formats**; Hugo isn't just that "static HTML with an added RSS feed" anymore. _Say hello_ to calendars, e-book formats, Google AMP, and JSON search indexes, to name a few.
|
||||
|
||||
This page describes how to properly configure your site with the media types and output formats you need.
|
||||
|
||||
## Media Types
|
||||
|
||||
A [media type](https://en.wikipedia.org/wiki/Media_type) (also known as MIME type and content type) is a two-part identifier for file formats and format contents transmitted on the Internet.
|
||||
|
||||
This is the full set of built-in media types in Hugo:
|
||||
|
||||
{{< datatable "media" "types" "Type" "Suffix" >}}
|
||||
|
||||
**Note:**
|
||||
|
||||
* It is possible to add custom media types or change the defaults (if you, say, want to change the suffix to `asp` for `text/html`).
|
||||
* The `Suffix` is the value that will be used for URLs and filenames for that media type in Hugo.
|
||||
* The `Type` is the identifier that must be used when defining new `Output Formats` (see below).
|
||||
* The full set of media types will be registered in Hugo's built-in development server to make sure they are recognized by the browser.
|
||||
|
||||
To add or modify a media type, define it in a `mediaTypes` section in your site config (either for all sites or for a given language).
|
||||
|
||||
Example in `config.toml`:
|
||||
|
||||
```toml
|
||||
[mediaTypes]
|
||||
[mediaTypes."text/enriched"]
|
||||
suffix = "enr"
|
||||
[mediaTypes."text/html"]
|
||||
suffix = "asp"
|
||||
```
|
||||
|
||||
The above example adds one new media type, `text/enriched`, and changes the suffix for the built-in `text/html` media type.
|
||||
|
||||
## Output Formats
|
||||
Given a media type and some additional configuration, you get an `Output Format`.
|
||||
|
||||
This is the full set of built-in output formats in Hugo:
|
||||
|
||||
{{< datatable "output" "formats" "Name" "MediaType" "Path" "BaseName" "Rel" "Protocol" "IsPlainText" "IsHTML" "NoUgly" "NotAlternative">}}
|
||||
|
||||
**Note:**
|
||||
|
||||
* A page can be output in as many output formats as you want, and you can have an infinite amount of output formats defined, as long as _they resolve to a unique path on the file system_. In the table above, the best example of this is `AMP` vs. `HTML`: We have given `AMP` a value for `Path` so it doesn't overwrite the `HTML` version, i.e. we can now have both `/index.html` and `/amp/index.html`.
|
||||
* The `MediaType` must match the `Type` of an already defined media type (see above).
|
||||
* You can define new or redefine built-in output formats (if you, as an example, want to put `AMP` pages in a different path).
|
||||
|
||||
To add or modify a media type, define it in a `outputFormats` section in your site config (either for all sites or for a given language).
|
||||
|
||||
Example in `config.toml`:
|
||||
|
||||
```toml
|
||||
[outputFormats.MyEnrichedFormat]
|
||||
mediaType = "text/enriched"
|
||||
baseName = "myindex"
|
||||
isPlainText = true
|
||||
protocol = "bep://"
|
||||
```
|
||||
|
||||
The above example is fictional, but if used for the home page on a site with `baseURL` `http://example.org`, it will produce a plain text home page with the URL `bep://example.org/myindex.enr`.
|
||||
|
||||
All the available configuration options for output formats and their default values:
|
||||
|
||||
Field | Description
|
||||
--- | ---
|
||||
**Name** | The output format identifier. This is used to define what output format(s) you want for your pages.
|
||||
**MediaType**|This must match the `Type` of a defined media type. |
|
||||
**Path** | Sub path to save the output files.
|
||||
**BaseName** | The base filename for the list filenames (home page etc.). **Default:** _index_.
|
||||
**Rel** | Can be used to create `rel` values in `link` tags. **Default:** _alternate_.
|
||||
**Protocol** | Will replace the "http://" or "https://" in your `baseURL` for this output format.
|
||||
**IsPlainText** | Use Go's plain text templates parser for the templates. **Default:** _false_.
|
||||
**IsHTML** | Used in situations only relevant for `HTML` type of formats, page aliases being one example.|
|
||||
**NoUgly** | If `uglyURLs` is enabled globally, this can be used to turn it off for a given output format. **Default:** _false_.
|
||||
**NotAlternative** | Enable if it doesn't make sense to include this format in an the `.AlternativeOutputFormats` format listing on `Page`, `CSS` being one good example. Note that we use the term "alternative" and not "alternate" here, as it does not necessarily replace the other format, it is an alternative representation. **Default:** _false_.
|
||||
|
||||
|
||||
## Output Formats for your pages
|
||||
|
||||
A `Page` in Hugo can be rendered to multiple representations on the file system: In its default configuration all will get an `HTML` page and some of them will get an `RSS` page (home page, sections etc.).
|
||||
|
||||
This can be changed by defining an `outputs` list of output formats in either the `Page` front matter or in the site configuration (either for all sites or per language).
|
||||
|
||||
Example from site config in `config.toml`:
|
||||
|
||||
```toml
|
||||
[outputs]
|
||||
home = [ "HTML", "AMP", "RSS"]
|
||||
page = [ "HTML"]
|
||||
```
|
||||
Note:
|
||||
|
||||
* The output definition is per `Page` `Kind`(`page`, `home`, `section`, `taxonomy`, `taxonomyTerm`).
|
||||
* The names used must match the `Name` of a defined `Output Format`.
|
||||
* Any `Kind` without a definition will get `HTML`.
|
||||
* These can be overriden per `Page` in front matter (see below).
|
||||
|
||||
A `Page` with `YAML` front matter defining some output formats for that `Page`:
|
||||
|
||||
```yaml
|
||||
---
|
||||
date: "2016-03-19"
|
||||
outputs:
|
||||
- html
|
||||
- amp
|
||||
- json
|
||||
---
|
||||
```
|
||||
Note that the names used for the output formats are case insensitive.
|
||||
|
||||
## Link to Output Formats
|
||||
|
||||
`Page` has both `.OutputFormats` (all formats including the current) and `.AlternativeOutputFormats`, the latter useful for creating a `link rel` list in your `head` section:
|
||||
|
||||
```
|
||||
{{ range .AlternativeOutputFormats -}}
|
||||
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
|
||||
{{ end -}}
|
||||
```
|
||||
|
||||
Note that `.Permalink` on `RelPermalink` on `Page` will return the first output format defined for that page (usually `HTML` if nothing else is defined).
|
||||
|
||||
This is how you link to a given output format:
|
||||
|
||||
```
|
||||
{{ with .OutputFormats.Get "json" -}}
|
||||
<a href="{{ .Permalink }}">{{ .Name }}</a>
|
||||
{{- end }}
|
||||
```
|
||||
From content files, you can use the `ref` or `relref` shortcodes:
|
||||
|
||||
```
|
||||
[Neat]({{</* ref "blog/neat.md" "amp" */>}})
|
||||
[Who]({{</* relref "about.md#who" "amp" */>}})
|
||||
```
|
||||
|
||||
## Templates for your Output Formats
|
||||
|
||||
Of course, for a new Output Format to render anything useful, we need a template for it.
|
||||
|
||||
**The fundamental thing to understand about this is that we in `Hugo 0.20` now also look at Output Format´s `Name` and MediaType´s `Suffix` when we choose the templates to use to render a given `Page`.**
|
||||
|
||||
And with so many possible variations, this is best explained with some examples:
|
||||
|
||||
|
||||
{{< datatable "output" "layouts" "Example" "OutputFormat" "Suffix" "Template Lookup Order" >}}
|
||||
|
||||
**Note:**
|
||||
|
||||
* All of the above examples can use a base template, see [Blocks]({{< relref "templates/blocks.md" >}}).
|
||||
* All of the above examples can also include partials.
|
||||
|
||||
Hugo will now also detect the media type and output format of partials, if possible, and use that information to decide if the partial should be parsed as a plain text template or not.
|
||||
|
||||
Hugo will look for the name given, so you can name it whatever you want. But if you want it treated as plain text, you should use the file suffix and, if needed, the name of the Output Format (`[partial name].[OutputFormat].[suffix])`.
|
||||
|
||||
The partial below is a plain text template (Outpuf Format is `CSV`, and since this is the only output format with the suffix `csv`, we don't need to include the Output Format's `Name`):
|
||||
|
||||
```
|
||||
{{ partial "mytextpartial.csv" . }}
|
||||
```
|
||||
|
||||
Also note that plain text partials can currently only be included in plain text templates, and vice versa. See [this issue](https://github.com/spf13/hugo/issues/3273) for some background.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -157,6 +157,11 @@ Read more on [cross-references]({{% ref "extras/crossreferences.md" %}}).
|
||||
|
||||
[Neat]({{</* ref "blog/neat.md" */>}})
|
||||
[Who]({{</* relref "about.md#who" */>}})
|
||||
|
||||
If the page exists in multiple [output formats]({{< relref "extras/output-formats.md" >}}), `ref` or `relref` can be used with a output format name:
|
||||
|
||||
[Neat]({{</* ref "blog/neat.md" "amp" */>}})
|
||||
|
||||
|
||||
#### Example Output
|
||||
|
||||
|
||||
@@ -134,8 +134,6 @@ along with their current, default values:
|
||||
disable404: false
|
||||
# Do not inject generator meta tag on homepage
|
||||
disableHugoGeneratorInject: false
|
||||
# edit new content with this editor, if provided
|
||||
editor: ""
|
||||
# Enable Emoji emoticons support for page content.
|
||||
# See www.emoji-cheat-sheet.com
|
||||
enableEmoji: false
|
||||
@@ -153,6 +151,7 @@ along with their current, default values:
|
||||
logFile: ""
|
||||
# "yaml", "toml", "json"
|
||||
metaDataFormat: "toml"
|
||||
# Edit new content with this editor, if provided
|
||||
newContentEditor: ""
|
||||
# Don't sync permission mode of files
|
||||
noChmod: false
|
||||
|
||||
@@ -36,12 +36,12 @@ where you don't have a privileged account.
|
||||
Ideally, you should install it somewhere in your `PATH` for easy use.
|
||||
`/usr/local/bin` is the most probable location.
|
||||
|
||||
On OS X, if you have [Homebrew](http://brew.sh/), installation is even
|
||||
On macOS, if you have [Homebrew](http://brew.sh/), installation is even
|
||||
easier: just run `brew update && brew install hugo`.
|
||||
|
||||
For a more detailed explanation follow the corresponding installation guides:
|
||||
|
||||
- [Installation on OS X]({{< relref "tutorials/installing-on-mac.md" >}})
|
||||
- [Installation on macOS]({{< relref "tutorials/installing-on-mac.md" >}})
|
||||
- [Installation on Windows]({{< relref "tutorials/installing-on-windows.md" >}})
|
||||
|
||||
### Installing Pygments (optional)
|
||||
@@ -56,35 +56,83 @@ you need to install the Python-based Pygments program. The procedure is outlined
|
||||
Upgrading Hugo is as easy as downloading and replacing the executable you’ve
|
||||
placed in your `PATH`.
|
||||
|
||||
## Installing from snap
|
||||
## Installing Hugo on Linux from native packages
|
||||
|
||||
### Arch Linux
|
||||
|
||||
You can install Hugo from the [Arch user repository](https://aur.archlinux.org/) on Arch Linux or derivatives such as Manjaro.
|
||||
|
||||
sudo pacman -S yaourt
|
||||
yaourt -S hugo
|
||||
|
||||
Be aware that Hugo is built from source. This means that additional tools like [Git](https://git-scm.com/) and [Go](https://golang.org/doc/install) will be installed as well.
|
||||
|
||||
### Debian and Ubuntu
|
||||
|
||||
Hugo has been included in Debian and Ubuntu since 2016, and thus installing Hugo is as simple as:
|
||||
|
||||
sudo apt install hugo
|
||||
|
||||
Pros:
|
||||
|
||||
* Native Debian/Ubuntu package maintained by Debian Developers
|
||||
* Pre-installed bash completion script and man pages for best interactive experience
|
||||
|
||||
Cons:
|
||||
|
||||
* 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, as described below.
|
||||
|
||||
### Fedora 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.19)
|
||||
|
||||
See also [this discussion](https://discuss.gohugo.io/t/solved-fedora-copr-repository-out-of-service/2491).
|
||||
|
||||
### Snap package for Hugo
|
||||
|
||||
In any of the [Linux distributions that support snaps](http://snapcraft.io/docs/core/install):
|
||||
|
||||
$ snap install hugo
|
||||
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/spf13/hugo/issues/3143).
|
||||
|
||||
## Installing from source
|
||||
|
||||
### Prerequisite tools for downloading and building source code
|
||||
|
||||
* [Git](http://git-scm.com/)
|
||||
* [Go][] 1.5+
|
||||
* [Go][] 1.8+
|
||||
* [govendor][]
|
||||
|
||||
### Get directly from GitHub
|
||||
### Vendored Dependencies
|
||||
|
||||
$ export GOPATH=$HOME/go
|
||||
$ go get -v github.com/spf13/hugo
|
||||
Hugo uses [govendor][] 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 Hugo's dependencies.
|
||||
|
||||
`go get` will then fetch Hugo and all its dependent libraries to your
|
||||
`$GOPATH/src` directory, and compile everything into the final `hugo`
|
||||
(or `hugo.exe`) executable, which you will find sitting in the
|
||||
`$GOPATH/bin/` directory, all ready to go!
|
||||
### Fetch from GitHub
|
||||
|
||||
You may run `go get` with the `-u` option to update Hugo's dependencies:
|
||||
go get github.com/kardianos/govendor
|
||||
govendor get github.com/spf13/hugo
|
||||
|
||||
$ go get -u -v github.com/spf13/hugo
|
||||
`govendor get` will fetch Hugo and all its dependent libraries to
|
||||
`$HOME/go/src/github.com/spf13/hugo`, and compile everything into a final `hugo`
|
||||
(or `hugo.exe`) executable, which you will find sitting inside
|
||||
`$HOME/go/bin/`, all ready to go!
|
||||
|
||||
*Windows users: where you see the `$HOME` environment variable above, replace it with `%USERPROFILE%`.*
|
||||
|
||||
|
||||
*Note: For syntax highlighting using the [highlight shortcode](/extras/highlighting/),
|
||||
you need to install the Python-based [Pygments](http://pygments.org/) program.*
|
||||
|
||||
## Contributing
|
||||
|
||||
Please see the [contributing guide](/doc/contributing/).
|
||||
Please see the [contributing guide](/doc/contributing/) if you are interested in
|
||||
working with the Hugo source or contributing to the project in any way.
|
||||
|
||||
[Go]: http://golang.org/
|
||||
[govendor]: https://github.com/kardianos/govendor
|
||||
|
||||
@@ -99,7 +99,7 @@ Hugo boasts the following features:
|
||||
### General
|
||||
|
||||
* Extremely fast build times (~1 ms per page)
|
||||
* Completely cross platform: Runs on <i class="fa fa-apple"></i> Mac OS X, <i class="fa fa-linux"></i> Linux, <i class="fa fa-windows"></i> Windows, and more!
|
||||
* Completely cross platform: Runs on <i class="fa fa-apple"></i> macOS, <i class="fa fa-linux"></i> Linux, <i class="fa fa-windows"></i> Windows, and more!
|
||||
* Easy [installation](/overview/installing/)
|
||||
* Render changes [on the fly](/overview/usage/) with [LiveReload](/extras/livereload/) as you develop
|
||||
* Complete theme support
|
||||
|
||||
@@ -78,12 +78,13 @@ $ tree -a
|
||||
|-- content
|
||||
|-- data
|
||||
|-- layouts
|
||||
`-- static
|
||||
|-- static
|
||||
`-- themes
|
||||
|
||||
5 directories, 1 file
|
||||
6 directories, 1 file
|
||||
```
|
||||
|
||||
As mentioned in the command output, `bookshelf` directory has 5 sub-directories and 1 file. Let's look at each of them one by one.
|
||||
As mentioned in the command output, `bookshelf` directory has 6 sub-directories and 1 file. Let's look at each of them one by one.
|
||||
|
||||
* **archetypes**: You can create new content files in Hugo using the `hugo new` command. When you run that command, it adds few configuration properties to the post like date and title. [Archetype]({{< relref "content/archetypes.md" >}}) allows you to define your own configuration properties that will be added to the post front matter whenever `hugo new` command is used.
|
||||
|
||||
@@ -99,6 +100,8 @@ You can write these files in YAML, JSON, or TOML format.
|
||||
|
||||
* **static**: This directory is used to store all the static content that your website will need like images, CSS, JavaScript or other static content.
|
||||
|
||||
* **themes**: This is where you will create a theme for your site to use. Themes provide the layout and templates that renders content. There's a wide variety of open-source themes available to download and use but you can also create your own if you prefer.
|
||||
|
||||
## Step 3. Add content
|
||||
|
||||
Let's now add a post to our `bookshelf`. We will use the `hugo new` command to add a post. In January, I read [Good To Great](http://www.amazon.com/Good-Great-Some-Companies-Others/dp/0066620996/) book so we will start with creating a post for it. **Make sure you are inside the `bookshelf` directory.**
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
---
|
||||
date: 2017-04-24
|
||||
title: 0.20.3
|
||||
---
|
||||
|
||||
|
||||
|
||||
This is a bug-fix relase with one important fix. But it also adds some harness around [GoReleaser](https://github.com/goreleaser/goreleaser) to automate the Hugo release process. Big thanks to [@caarlos0](https://github.com/caarlos0) for great and super-fast support fixing issues along the way.
|
||||
|
||||
Hugo now has:
|
||||
|
||||
* 16619+ [stars](https://github.com/spf13/hugo/stargazers)
|
||||
* 458+ [contributors](https://github.com/spf13/hugo/graphs/contributors)
|
||||
* 156+ [themes](http://themes.gohugo.io/)
|
||||
|
||||
## Enhancement
|
||||
|
||||
* Automate the Hugo release process [550eba64](https://github.com/spf13/hugo/commit/550eba64705725eb54fdb1042e0fb4dbf6f29fd0) [@bep](https://github.com/bep) [#3358](https://github.com/spf13/hugo/issues/3358)
|
||||
|
||||
## Fix
|
||||
|
||||
* Fix handling of zero-length files [9bf5c381](https://github.com/spf13/hugo/commit/9bf5c381b6b3e69d4d8dbfd7a40074ac44792bbf) [@bep](https://github.com/bep) [#3355](https://github.com/spf13/hugo/issues/3355)
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
---
|
||||
date: 2017-04-24
|
||||
title: 0.20.4
|
||||
---
|
||||
|
||||
|
||||
|
||||
This is the second bug-fix relase of the day, fixing a couple of issues related to the new release scripts.
|
||||
|
||||
|
||||
Hugo now has:
|
||||
|
||||
* 16626+ [stars](https://github.com/spf13/hugo/stargazers)
|
||||
* 457+ [contributors](https://github.com/spf13/hugo/graphs/contributors)
|
||||
* 156+ [themes](http://themes.gohugo.io/)
|
||||
|
||||
|
||||
* Fix statically linked binaries [275bcf56](https://github.com/spf13/hugo/commit/275bcf566c7cb72367d4423cf4810319311ff680) [@munnerz](https://github.com/munnerz) [#3382](https://github.com/spf13/hugo/issues/3382)
|
||||
* Filename change in Hugo 0.20.3 binaries [\](https://github.com/spf13/hugo/issues/3385)
|
||||
* Fix version calculation [cb3c6b6f](https://github.com/spf13/hugo/commit/cb3c6b6f7670f85189a4a3637e7132901d1ed6e9) [@bep](https://github.com/bep)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
date: 2017-04-17
|
||||
aliases:
|
||||
- /doc/release-notes/
|
||||
- /meta/release-notes/
|
||||
title: Release Notes
|
||||
weight: 10
|
||||
---
|
||||
@@ -2,13 +2,127 @@
|
||||
aliases:
|
||||
- /doc/release-notes/
|
||||
- /meta/release-notes/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: about
|
||||
title: Release Notes
|
||||
weight: 10
|
||||
date: 2017-04-16
|
||||
title: Older Release Notes
|
||||
---
|
||||
# **0.20.2** April 16th 2017
|
||||
|
||||
Hugo `0.20.2` adds support for plain text partials included into `HTML` templates. This was a side-effect of the big new [Custom Output Format](https://gohugo.io/extras/output-formats/) feature in `0.20`, and while the change was intentional and there was an ongoing discussion about fixing it in {{< gh 3273 >}}, it did break some themes. There were valid workarounds for these themes, but we might as well get it right.
|
||||
|
||||
The most obvious use case for this is inline `CSS` styles, which you now can do without having to name your partials with a `html` suffix.
|
||||
|
||||
A simple example:
|
||||
|
||||
In `layouts/partials/mystyles.css`:
|
||||
|
||||
```css
|
||||
body {
|
||||
background-color: {{ .Param "colors.main" }}
|
||||
}
|
||||
```
|
||||
|
||||
Then in `config.toml` (note that by using the `.Param` lookup func, we can override the color in a page's front matter if we want):
|
||||
|
||||
```toml
|
||||
[params]
|
||||
[params.colors]
|
||||
main = "green"
|
||||
text = "blue"
|
||||
```
|
||||
|
||||
And then in `layouts/partials/head.html` (or the partial used to include the head section into your layout):
|
||||
|
||||
```html
|
||||
<head>
|
||||
<style type="text/css">
|
||||
{{ partial "mystyles.css" . | safeCSS }}
|
||||
</style>
|
||||
</head>
|
||||
```
|
||||
|
||||
Of course, `0.20` also made it super-easy to create external `CSS` stylesheets based on your site and page configuration. A simple example:
|
||||
|
||||
Add "CSS" to your home page's `outputs` list, create the template `/layouts/index.css` using Go template syntax for the dynamic parts, and then include it into your `HTML` template with:
|
||||
|
||||
```html
|
||||
{{ with .OutputFormats.Get "css" }}
|
||||
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
|
||||
{{ end }}`
|
||||
```
|
||||
|
||||
|
||||
# **0.20.1** April 13th 2017
|
||||
Hugo `0.20.1` is a bug fix release, fixing some important regressions introduced in `0.20` a couple of days ago:
|
||||
|
||||
* Fix logic for base template in work dir vs in the theme {{< gh 3323 >}}
|
||||
* camelCased templates (partials, shortcodes etc.) not found {{< gh 3333 >}}
|
||||
* Live-reload fails with `_index.md` with paginator {{< gh 3315 >}}
|
||||
* `rssURI` WARNING always shown {{< gh 3319 >}}
|
||||
|
||||
See the [full list](https://github.com/spf13/hugo/milestone/16?closed=1).
|
||||
|
||||
# **0.20** April 10th 2017
|
||||
|
||||
Hugo `0.20` introduces the powerful and long sought after feature [Custom Output Formats]({{< ref "extras/output-formats.md" >}}); Hugo isn't just that "static HTML with an added RSS feed" anymore. *Say hello* to calendars, e-book formats, Google AMP, and JSON search indexes, to name a few ({{< gh 2828 >}}).
|
||||
|
||||
This release represents **over 180 contributions by over 30 contributors** to the main Hugo code base. Since last release Hugo has **gained 1100 stars, 20 new contributors and 5 additional themes.**
|
||||
|
||||
Hugo now has:
|
||||
|
||||
- 16300+ stars
|
||||
- 495+ contributors
|
||||
- 156+ themes
|
||||
|
||||
{{< gh "@bep" >}} still leads the Hugo development with his witty Norwegian humor, and once again contributed a significant amount of additions. Also a big shoutout to {{< gh "@digitalcraftsman" >}} for his relentless work on keeping the documentation and the themes site in pristine condition, and {{< gh "@moorereason" >}} and {{< gh "@bogem" >}} for their ongoing contributions.
|
||||
|
||||
## Other Highlights
|
||||
|
||||
{{< gh "@bogem" >}} has also contributed TOML as an alternative and much simpler format for language/i18n files ({{< gh 3200 >}}). A feature you will appreciate when you start to work on larger translations.
|
||||
|
||||
Also, there have been some important updates in the Emacs Org-mode handling: {{< gh "@chaseadamsio" >}} has fixed the newline-handling ({{< gh 3126 >}}) and {{< gh "@clockoon" >}} has added basic footnote support.
|
||||
|
||||
Worth mentioning is also the ongoing work that {{< gh "@rdwatters" >}} and {{< gh "@budparr" >}} is doing to re-do the [gohugo.io](https://gohugo.io/) site, including a total restructuring and partial rewrite of the documentation. It is getting close to finished, and it looks fantastic!
|
||||
|
||||
## Notes
|
||||
* `RSS` description in the built-in template is changed from full `.Content` to `.Summary`. This is a somewhat breaking change, but is what most people expect from their RSS feeds. If you want full content, please provide your own RSS template.
|
||||
* The deprecated `.RSSlink` is now removed. Use `.RSSLink`.
|
||||
* `RSSUri` is deprecated and will be removed in a future Hugo version, replace it with an output format definition.
|
||||
* The deprecated `.Site.GetParam` is now removed, use `.Site.Param`.
|
||||
* Hugo does no longer append missing trailing slash to `baseURL` set as a command line parameter, making it consistent with how it behaves from site config. {{< gh 3262 >}}
|
||||
|
||||
## Enhancements
|
||||
|
||||
* Hugo `0.20` is built with Go 1.8.1.
|
||||
* Add `.Site.Params.mainSections` that defaults to the section with the most pages. Plan is to get themes to use this instead of the hardcoded `blog` in `where` clauses. {{< gh 3206 >}}
|
||||
* File extension is now configurable. {{< gh 320 >}}
|
||||
* Impove `markdownify` template function performance. {{< gh 3292 >}}
|
||||
* Add taxonomy terms' pages to `.Data.Pages` {{< gh 2826 >}}
|
||||
* Change `RSS` description from full `.Content` to `.Summary`.
|
||||
* Ignore "." dirs in `hugo --cleanDestinationDir` {{< gh 3202 >}}
|
||||
* Allow `jekyll import` to accept both `2006-01-02` and `2006-1-2` date format {{< gh 2738 >}}
|
||||
* Raise the default `rssLimit` {{< gh 3145 >}}
|
||||
* Unify section list vs single template lookup order {{< gh 3116 >}}
|
||||
* Allow `apply` to be used with the built-in Go template funcs `print`, `printf` and `println`. {{< gh 3139 >}}
|
||||
|
||||
## Fixes
|
||||
* Fix deadlock in `getJSON` {{< gh 3211 >}}
|
||||
* Make sure empty terms pages are created. {{< gh 2977 >}}
|
||||
* Fix base template lookup order for sections {{< gh 2995 >}}
|
||||
* `URL` fixes:
|
||||
* Fix pagination URLs with `baseURL` with sub-root and `canonifyUrls=false` {{< gh 1252 >}}
|
||||
* Fix pagination URL for resources with "." in name {{< gh 2110 >}} {{< gh 2374 >}} {{< gh 1885 >}}
|
||||
* Handle taxonomy names with period {{< gh 3169 >}}
|
||||
* Handle `uglyURLs` ambiguity in `Permalink` {{< gh 3102 >}}
|
||||
* Fix `Permalink` for language-roots wrong when `uglyURLs` is `true` {{< gh 3179 >}}
|
||||
* Fix misc case issues for `URLs` {{< gh 1641 >}}
|
||||
* Fix for taxonomies URLs when `uglyUrls=true` {{< gh 1989 >}}
|
||||
* Fix empty `RSSLink` for list pages with content page. {{< gh 3131 >}}
|
||||
* Correctly identify regular pages on the form "my_index_page.md" {{< gh 3234 >}}
|
||||
* `Exit -1` on `ERROR` in global logger {{< gh 3239 >}}
|
||||
* Document hugo `help command` {{< gh 2349 >}}
|
||||
* Fix internal `Hugo` version handling for bug fix releases. {{< gh 3025 >}}
|
||||
* Only return `RSSLink` for pages that actually have a RSS feed. {{< gh 1302 >}}
|
||||
|
||||
|
||||
# **0.19** February 27th 2017
|
||||
|
||||
@@ -24,7 +138,7 @@ Hugo now has:
|
||||
|
||||
Furthermore, Hugo has its own Twitter account ([@gohugoio](https://twitter.com/gohugoio)) where we share bite-sized news and themes from the Hugo community.
|
||||
|
||||
{{< gh "@bep" >}} leads the Hugo development and once again contributed a significant amount of additions. Also a big shoutout to {{< gh "@chaseadamsio" >}} for the Emacs Org-mode support, {{< gh "@digitalcraftsman" >}} for his relentless work on keeping the documentation and the themes site in pristine condition, {{< gh "@fj" >}}for his work on revising the `params` handling in Hugo, and {{< gh "@moorereason" >}} and {{< gh "@bogem" >}} for their ongoing contributions.
|
||||
{{< gh "@bep" >}} leads the Hugo development and once again contributed a significant amount of additions. Also a big shoutout to {{< gh "@chaseadamsio" >}} for the Emacs Org-mode support, {{< gh "@digitalcraftsman" >}} for his relentless work on keeping the documentation and the themes site in pristine condition, {{< gh "@fj" >}}for his work on revising the `params` handling in Hugo, and {{< gh "@moorereason" >}} and {{< gh "@bogem" >}} for their ongoing contributions.
|
||||
|
||||
## Highlights
|
||||
Hugo `0.19` brings native Emacs Org-mode content support ({{<gh 1483>}}), big thanks to {{< gh "@chaseadamsio" >}}.
|
||||
@@ -42,7 +156,7 @@ disableKinds = ["page", "home", "section", "taxonomy", "taxonomyTerm", "RSS", "s
|
||||
|
||||
* Add ability to sort pages by frontmatter parameters, enabling easy custom "top 10" page lists. {{<gh 3022 >}}
|
||||
* Add `truncate` template function {{<gh 2882 >}}
|
||||
* Add `now` function, which replaces the now deprecated `.Now` {{<gh 2882 >}}
|
||||
* Add `now` function, which replaces the now deprecated `.Now` {{<gh 2859 >}}
|
||||
* Make RSS item limit configurable {{<gh 3035 >}}
|
||||
|
||||
## Enhancements
|
||||
@@ -70,10 +184,10 @@ disableKinds = ["page", "home", "section", "taxonomy", "taxonomyTerm", "RSS", "s
|
||||
* Fix `.Site.Pages` handling on live reloads {{<gh 2869 >}}
|
||||
* `UniqueID` now correctly uses the fill file path from the content root to calculate the hash, and is finally ... unique!
|
||||
* Discard current language based on `.Lang()`, go get translations correct for paginated pages. {{<gh 2972 >}}
|
||||
* Fix infinite loop in template AST handling for recursive templates {{<gh 2927 >}}
|
||||
* Fix issue with watching when config loading fails {{<gh 2603 >}}
|
||||
* Correctly flush the imageConfig on live-reload {{<gh 3016 >}}
|
||||
* Fix parsing of TOML arrays in frontmatter {{<gh 2752 >}}
|
||||
* Fix infinite loop in template AST handling for recursive templates {{<gh 2927 >}}
|
||||
* Fix issue with watching when config loading fails {{<gh 2603 >}}
|
||||
* Correctly flush the imageConfig on live-reload {{<gh 3016 >}}
|
||||
* Fix parsing of TOML arrays in frontmatter {{<gh 2752 >}}
|
||||
|
||||
## Docs
|
||||
* Add tutorial "How to use Google Firebase to host a Hugo site" {{<gh 3007 >}}
|
||||
@@ -326,7 +440,7 @@ times decreased anywhere from 10% to 99%.
|
||||
* Add `themesDir` option to configuration {{<gh 1556>}}
|
||||
* Add support for Go 1.6 `block` keyword in templates {{<gh 1832>}}
|
||||
* Partial static sync {{<gh 1644>}}
|
||||
* Source file based relative linking (a la Github) {{<gh 0x0f6b334b6715253b030c4e783b88e911b6e53e56>}}
|
||||
* Source file based relative linking (a la GitHub) {{<gh 0x0f6b334b6715253b030c4e783b88e911b6e53e56>}}
|
||||
* Add `ByLastmod` sort function to pages. {{<gh 0xeb627ca16de6fb5e8646279edd295a8bf0f72bf1 >}}
|
||||
* New templates functions:
|
||||
* `readFile` {{<gh 1551 >}}
|
||||
@@ -7,6 +7,6 @@ sitelink: http://balaramadurai.net
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
thumbnail: /img/balaramadurai-net-tn.png
|
||||
thumbnail: /img/balaramadurai-net-tn.jpg
|
||||
title: Dr. Bala Ramadurai | Professor & Consultant in Innovation, Design Thinking and Tech Forecasting
|
||||
---
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
date: 2017-03-15T07:32:00Z
|
||||
description: "Bharath M. Palavalli"
|
||||
license: ""
|
||||
licenseLink: ""
|
||||
sitelink: http://bharathpalavalli.com
|
||||
sourceLink: https://github.com/bmp/bharathmp-hugo/tree/gh-pages
|
||||
tags:
|
||||
- personal
|
||||
- website
|
||||
thumbnail: /img/bharathpalavalli-tn.png
|
||||
title: bharathpalavalli.com
|
||||
---
|
||||
|
||||
@@ -9,6 +9,6 @@ sourceLink: https://github.com/christianmendoza/christianmendoza.me
|
||||
tags:
|
||||
- personal
|
||||
- profile
|
||||
thumbnail: /img/christianmendoza-tn.png
|
||||
thumbnail: /img/christianmendoza-tn.jpg
|
||||
title: christianmendoza.me
|
||||
---
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
date: 2017-03-07T07:32:00Z
|
||||
description: "Indian Recipes Blog"
|
||||
license: ""
|
||||
licenseLink: ""
|
||||
sitelink: https://enjoyable.recipes/
|
||||
sourceLink: https://github.com/shubhojyoti/enjoyablerecipes-hugo
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
- recipes
|
||||
- zurb-foundation
|
||||
thumbnail: /img/enjoyablerecipes-tn.png
|
||||
title: Enjoyable Recipes
|
||||
---
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
date: 2017-04-02T07:32:00Z
|
||||
description: "Personal blog of Enrique Saez Gil - esaezgil"
|
||||
license: ""
|
||||
licenseLink: ""
|
||||
sitelink: https://esaezgil.com
|
||||
sourceLink: https://github.com/esaezgil/esaezgil.github.io
|
||||
tags:
|
||||
- personal
|
||||
- technical blog
|
||||
- software
|
||||
- open source
|
||||
thumbnail: /img/esaezgil_com-tn.png
|
||||
title: esaezgil.com
|
||||
---
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
date: 2017-03-31T22:36:12+03:00
|
||||
description: "Multilingual website. Size 20GB, build time 25 mins. Cloudflare, s3, bootstrap 4"
|
||||
license: ""
|
||||
licenseLink: ""
|
||||
sitelink: https://firstname.club
|
||||
sourceLink:
|
||||
tags:
|
||||
- data
|
||||
- website
|
||||
thumbnail: /img/firstnameclub.png
|
||||
title: firstname club
|
||||
---
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
date: 2017-03-12T13:14:14+08:00
|
||||
description: "Personal blog of Rosen Lu"
|
||||
license: ""
|
||||
licenseLink: ""
|
||||
sitelink: http://lucumt.info/posts
|
||||
sourceLink: https://github.com/lucumt/ghblog
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
thumbnail: /img/lucumt.info.png
|
||||
title: 飞狐的部落格
|
||||
---
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
date: 2017-03-08T07:32:00Z
|
||||
description: "All the songs that get stuck in my head"
|
||||
license: ""
|
||||
licenseLink: ""
|
||||
sitelink: https://myearworms.com/
|
||||
sourceLink: https://github.com/jaydreyer/myearworms
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
- music
|
||||
thumbnail: /img/myearworms-tn.jpg
|
||||
title: My Earworms
|
||||
---
|
||||
@@ -9,6 +9,6 @@ tags:
|
||||
- personal
|
||||
- travel
|
||||
- blog
|
||||
thumbnail: /img/neavey-tn.png
|
||||
thumbnail: /img/neavey-tn.jpg
|
||||
title: neavey.net
|
||||
---
|
||||
|
||||
@@ -9,7 +9,7 @@ sourceLink: https://github.com/robertbasic/robertbasic.com-hugo
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
thumbnail: /img/robertbasic-tn.jpg
|
||||
thumbnail: /img/robertbasic-tn.png
|
||||
title: Robert Basic's blog
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
date: 2017-04-13T07:32:00Z
|
||||
description: ""
|
||||
license: ""
|
||||
licenseLink: ""
|
||||
sitelink: https://sanjay-saxena.github.io
|
||||
sourceLink: https://github.com/sanjay-saxena/sanjay-saxena-hugo
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
thumbnail: /img/sanjay-saxena-tn.png
|
||||
title: sanjay-saxena.github.io
|
||||
---
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
date: 2017-08-01T08:12:00Z
|
||||
description: "All-in-One Intelligent Bot for Business"
|
||||
license: ""
|
||||
licenseLink: ""
|
||||
sitelink: http://siba.ai/
|
||||
tags:
|
||||
- corporate
|
||||
- saas
|
||||
- software
|
||||
- chatbot
|
||||
- blog
|
||||
thumbnail: /img/siba-tn.png
|
||||
title: Siba Chatbot
|
||||
---
|
||||
|
||||
@@ -8,7 +8,7 @@ sourceLink: https://github.com/Draga/go-web
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
thumbnail: /img/stefano.chiodino-tn.png
|
||||
thumbnail: /img/stefano.chiodino-tn.jpg
|
||||
title: stefano.chiodino.uk
|
||||
---
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ sitelink: http://thecodeking.co.uk
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
thumbnail: /img/thecodeking-tn.png
|
||||
thumbnail: /img/thecodeking-tn.jpg
|
||||
title: thecodeking
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
date: 2017-03-18T11:30:00Z
|
||||
description: "Blog of programmer Tibo Beijen"
|
||||
license: ""
|
||||
licenseLink: ""
|
||||
sitelink: https://www.tibobeijen.nl/
|
||||
sourceLink: https://github.com/TBeijen/tbnl-hugo
|
||||
tags:
|
||||
- personal
|
||||
- programming
|
||||
- blog
|
||||
thumbnail: /img/tibobeijen-nl-tn.png
|
||||
title: tibobeijen.nl
|
||||
---
|
||||
|
||||
@@ -9,6 +9,6 @@ sourceLink: https://bitbucket.org/lynxiayel/yulinling_source_public
|
||||
tags:
|
||||
- blog
|
||||
- documentation
|
||||
thumbnail: /img/yulinling-tn.png
|
||||
thumbnail: /img/yulinling-tn.jpg
|
||||
title: <span lang="zh-CN">语林灵</span> (Yulinling)
|
||||
---
|
||||
|
||||
@@ -9,29 +9,45 @@ title: Block Templates
|
||||
weight: 80
|
||||
---
|
||||
|
||||
Go 1.6 includes a powerful new keyword, `block`. This construct allows you to define the outer shell of your pages one or more master template(s), filling in or overriding portions as necessary.
|
||||
The `block` keyword in Go templates allows you to define the outer shell of your pages one or more master template(s), filling in or overriding portions as necessary.
|
||||
|
||||
## Base template lookup
|
||||
This is the order Hugo searches for a base template:
|
||||
|
||||
1. /layouts/_current-path_/_template-name_-baseof.html, e.g. list-baseof.html.
|
||||
2. /layouts/_current-path_/baseof.html
|
||||
3. /layouts/_default/_template-name_-baseof.html e.g. list-baseof.html.
|
||||
4. /layouts/_default/baseof.html
|
||||
In version `0.20` Hugo introduced custom [Output Formats]({{< relref "extras/output-formats.md" >}}), all of which can have their own templates that also can use a base template if needed.
|
||||
|
||||
This introduced two new terms relevant in the lookup of the templates, the media type's `Suffix` and the output format's `Name`.
|
||||
|
||||
Given the above, Hugo tries to use the most specific base tamplate it finds:
|
||||
|
||||
1. /layouts/_current-path_/_template-name_-baseof.[output-format].[suffix], e.g. list-baseof.amp.html.
|
||||
1. /layouts/_current-path_/_template-name_-baseof.[suffix], e.g. list-baseof.html.
|
||||
2. /layouts/_current-path_/baseof.[output-format].[suffix], e.g baseof.amp.html
|
||||
2. /layouts/_current-path_/baseof.[suffix], e.g baseof.html
|
||||
3. /layouts/_default/_template-name_-baseof.[output-format].[suffix] e.g. list-baseof.amp.html.
|
||||
3. /layouts/_default/_template-name_-baseof.[suffix], e.g. list-baseof.html.
|
||||
4. /layouts/_default/baseof.[output-format].[suffix]
|
||||
4. /layouts/_default/baseof.[suffix]
|
||||
|
||||
For each of the steps above, it will first look in the project, then, if theme is set, in the theme's layouts folder. Hugo picks the first base template found.
|
||||
|
||||
As an example, with a site using the theme `exampletheme`, when rendering the section list for the section `post`. Hugo picks the `section/post.html` as the template and this template has a `define` section that indicates it needs a base template. This is then the lookup order:
|
||||
|
||||
1. `/layouts/section/post-baseof.html`
|
||||
2. `/themes/exampletheme/layouts/section/post-baseof.html`
|
||||
3. `/layouts/section/baseof.html`
|
||||
4. `/themes/exampletheme/layouts/section/baseof.html`
|
||||
5. `/layouts/_default/post-baseof.html`
|
||||
6. `/themes/exampletheme/layouts/_default/post-baseof.html`
|
||||
7. `/layouts/_default/baseof.html`
|
||||
8. `/themes/exampletheme/layouts/_default/baseof.html`
|
||||
As an example, with a site using the theme `exampletheme`, when rendering the section list for the section `post` for the output format `Calendar`. Hugo picks the `section/post.calendar.ics` as the template and this template has a `define` section that indicates it needs a base template. This is then the lookup order:
|
||||
|
||||
1. `/layouts/section/post-baseof.calendar.ics`
|
||||
1. `/layouts/section/post-baseof.ics`
|
||||
2. `/themes/exampletheme/layouts/section/post-baseof.calendar.ics`
|
||||
2. `/themes/exampletheme/layouts/section/post-baseof.ics`
|
||||
3. `/layouts/section/baseof.calendar.ics`
|
||||
3. `/layouts/section/baseof.ics`
|
||||
4. `/themes/exampletheme/layouts/section/baseof.calendar.ics`
|
||||
4. `/themes/exampletheme/layouts/section/baseof.ics`
|
||||
5. `/layouts/_default/post-baseof.calendar.ics`
|
||||
5. `/layouts/_default/post-baseof.ics`
|
||||
6. `/themes/exampletheme/layouts/_default/post-baseof.calendar.ics`
|
||||
6. `/themes/exampletheme/layouts/_default/post-baseof.ics`
|
||||
7. `/layouts/_default/baseof.calendar.ics`
|
||||
7. `/layouts/_default/baseof.ics`
|
||||
8. `/themes/exampletheme/layouts/_default/baseof.calendar.ics`
|
||||
8. `/themes/exampletheme/layouts/_default/baseof.ics`
|
||||
|
||||
|
||||
## Define the base template
|
||||
|
||||
@@ -214,6 +214,23 @@ e.g.
|
||||
</ul>
|
||||
|
||||
|
||||
### union
|
||||
Given two arrays (or slices) A and B, this function will return a new array that contains the elements or objects that belong to either A or to B or to both. The elements supported are strings, integers and floats (only float64).
|
||||
|
||||
```
|
||||
{{ union (slice 1 2 3) (slice 3 4 5) }}
|
||||
<!-- returns [1 2 3 4 5] -->
|
||||
|
||||
{{ union (slice 1 2 3) nil }}
|
||||
<!-- returns [1 2 3] -->
|
||||
|
||||
{{ union nil (slice 1 2 3) }}
|
||||
<!-- returns [1 2 3] -->
|
||||
|
||||
{{ union nil nil }}
|
||||
<!-- returns an error because both arrays/slices have to be of the same type -->
|
||||
```
|
||||
|
||||
### isset
|
||||
Returns true if the parameter is set.
|
||||
Takes either a slice, array or channel and an index or a map and a key as input.
|
||||
@@ -536,7 +553,7 @@ Pluralize the given word with a set of common English pluralization rules.
|
||||
e.g. `{{ "cat" | pluralize }}` → "cats"
|
||||
|
||||
### findRE
|
||||
Returns a list of strings that match the regular expression. By default all matches will be included. The number of matches can be limitted with an optional third parameter.
|
||||
Returns a list of strings that match the regular expression. By default all matches will be included. The number of matches can be limited with an optional third parameter.
|
||||
|
||||
The example below returns a list of all second level headers (`<h2>`) in the content:
|
||||
|
||||
|
||||
@@ -40,9 +40,11 @@ the list will be needed.
|
||||
A Section will be rendered at /`SECTION`/ (e.g. http://spf13.com/project/)
|
||||
|
||||
* /layouts/section/`SECTION`.html
|
||||
* /layouts/`SECTION`/list.html
|
||||
* /layouts/\_default/section.html
|
||||
* /layouts/\_default/list.html
|
||||
* /themes/`THEME`/layouts/section/`SECTION`.html
|
||||
* /themes/layouts/`SECTION`/list.html
|
||||
* /themes/`THEME`/layouts/\_default/section.html
|
||||
* /themes/`THEME`/layouts/\_default/list.html
|
||||
|
||||
@@ -253,7 +255,7 @@ The below example sorts a list of posts by their rating.
|
||||
If the frontmatter field of interest is nested beneath another field, you can
|
||||
also get it:
|
||||
|
||||
{{ range (.Date.Pages.ByParam "author.last_name") }}
|
||||
{{ range (.Data.Pages.ByParam "author.last_name") }}
|
||||
<!-- ... -->
|
||||
{{ end }}
|
||||
|
||||
|
||||
@@ -48,6 +48,14 @@ Hugo will use the following prioritized list. If a file isn’t present, then th
|
||||
* /themes/`THEME`/layouts/\_default/rss.xml
|
||||
* [Embedded rss.xml](#the-embedded-rss-xml:eceb479b7b3b2077408a2878a29e1320)
|
||||
|
||||
### Taxonomy Terms RSS
|
||||
|
||||
* /layouts/taxonomy/`SINGULAR`.terms.rss.xml
|
||||
* /layouts/\_default/rss.xml
|
||||
* /themes/`THEME`/layouts/taxonomy/`SINGULAR`.terms.rss.xml
|
||||
* /themes/`THEME`/layouts/\_default/rss.xml
|
||||
* [Embedded rss.xml](#the-embedded-rss-xml:eceb479b7b3b2077408a2878a29e1320)
|
||||
|
||||
|
||||
## Configuring RSS
|
||||
|
||||
|
||||
@@ -31,16 +31,29 @@ one.
|
||||
|
||||
## Hugo’s sitemap.xml
|
||||
|
||||
This template respects the version 0.9 of the [Sitemap
|
||||
Protocol](http://www.sitemaps.org/protocol.html).
|
||||
This template uses the version 0.9 of the [Sitemap
|
||||
Protocol](http://www.sitemaps.org/protocol.html) with Google's [hreflang
|
||||
attributes](https://support.google.com/webmasters/answer/2620865?hl=en&topic=2370587&ctx=topic)
|
||||
for linking to translated content.
|
||||
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
|
||||
xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
||||
{{ range .Data.Pages }}
|
||||
<url>
|
||||
<loc>{{ .Permalink }}</loc>{{ if not .Lastmod.IsZero }}
|
||||
<lastmod>{{ safeHTML ( .Lastmod.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod>{{ end }}{{ with .Sitemap.ChangeFreq }}
|
||||
<changefreq>{{ . }}</changefreq>{{ end }}{{ if ge .Sitemap.Priority 0.0 }}
|
||||
<priority>{{ .Sitemap.Priority }}</priority>{{ end }}
|
||||
<priority>{{ .Sitemap.Priority }}</priority>{{ end }}{{ if .IsTranslated }}{{ range .Translations }}
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="{{ .Lang }}"
|
||||
href="{{ .Permalink }}"
|
||||
/>{{ end }}
|
||||
<xhtml:link
|
||||
rel="alternate"
|
||||
hreflang="{{ .Lang }}"
|
||||
href="{{ .Permalink }}"
|
||||
/>{{ end }}
|
||||
</url>
|
||||
{{ end }}
|
||||
</urlset>
|
||||
|
||||
@@ -57,6 +57,7 @@ Taxonomy Terms pages will additionally have:
|
||||
|
||||
* **.Data.Singular** The singular name of the taxonomy
|
||||
* **.Data.Plural** The plural name of the taxonomy
|
||||
* **.Data.Pages** (or as **.Pages**) The taxonomy Terms index pages
|
||||
* **.Data.Terms** The taxonomy itself
|
||||
* **.Data.Terms.Alphabetical** The Terms alphabetized
|
||||
* **.Data.Terms.ByCount** The Terms ordered by popularity
|
||||
@@ -121,7 +122,7 @@ Another example listing the content for each term (ordered by Date):
|
||||
|
||||
## Ordering
|
||||
|
||||
Hugo can order the meta data in two different ways. It can be ordered:
|
||||
Hugo can order the term meta data in two different ways. It can be ordered:
|
||||
|
||||
* by the number of contents assigned to that key, or
|
||||
* alphabetically.
|
||||
@@ -162,3 +163,14 @@ Hugo can order the meta data in two different ways. It can be ordered:
|
||||
</section>
|
||||
|
||||
{{ partial "footer.html" . }}
|
||||
|
||||
Hugo can also order and paginate the term index pages in all the normal ways.
|
||||
|
||||
### Example terms.html snippet (paginated and ordered by date)
|
||||
|
||||
<h1 id="title">{{ .Title }}</h1>
|
||||
<ul>
|
||||
{{ range .Paginator.Pages.ByDate.Reverse }}
|
||||
<li><a href="{{ .Permalink }}">{{ .Title }}</a> {{ $.Data.Terms.Count .Data.Term }}</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
|
||||
@@ -180,7 +180,7 @@ Also available is `.Site` which has the following:
|
||||
**.Site.BaseURL** The base URL for the site as defined in the site configuration file.<br>
|
||||
**.Site.RSSLink** The URL for the site RSS.<br>
|
||||
**.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).<br>
|
||||
**.Site.Pages** Array of all content ordered by Date, newest first. Replaces the now-deprecated `.Site.Recent` starting v0.13. This array contains only the pages in the current language.<br>
|
||||
**.Site.Pages** Array of all content ordered by Date, newest first. `.Site.Pages` replaced `.Site.Recent`, which is no longer supported. This array contains only the pages in the current language.<br>
|
||||
**.Site.AllPages** Array of all pages regardless of their translation.<br>
|
||||
**.Site.Params** A container holding the values from the `params` section of your site configuration file. For example, a TOML config file might look like this:
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ If you don't want to use [Wercker for automated deployments]({{< relref "tutoria
|
||||
- [hugo-lambda](https://github.com/ryansb/hugo-lambda) - A wrapper around the Hugo static site generator to have it run in AWS Lambda whenever new (Markdown or other) content is uploaded.
|
||||
- [hugodeploy](https://github.com/mindok/hugodeploy) - Simple SFTP deployment tool for static websites (e.g. created by Hugo) with optional minification.
|
||||
- [webhook](https://github.com/adnanh/webhook) - Run build and deployment scripts (e.g. hugo) on incoming webhooks
|
||||
- [Hugo SFTP Upload](https://github.com/thomasmey/HugoSftpUpload) - Sync the local build of your Hugo website with your remote webserver via SFTP.
|
||||
|
||||
----
|
||||
|
||||
@@ -98,6 +99,7 @@ If you still want to use an editor, look at these plugins to automate your workf
|
||||
|
||||
### Emacs
|
||||
|
||||
- [easy-hugo](https://github.com/masasam/emacs-easy-hugo) - Major mode & tools for Hugo.
|
||||
- [hugo.el](https://github.com/yewton/hugo.el) - Some helper functions for creating a Website with Hugo.
|
||||
|
||||
### Vim
|
||||
@@ -125,10 +127,10 @@ A static site with a dynamic search function? Yes. Alternatively to embeddable s
|
||||
- [Algolia](https://www.algolia.com/)'s Search API makes it easy to deliver a great search experience in your apps & websites. Algolia Search provides hosted full-text, numerical, faceted and geolocalized search.
|
||||
|
||||
- [Appernetic.io](https://appernetic.io) is a Hugo Static Site Generator as a Service that is easy to use for non-technical users.
|
||||
Features: inline PageDown editor, visual tree view, image upload and digital asset management with Cloudinary, site preview, continuous integration with GitHub, atomic deploy and hosting, Git and Hugo integration, autosave, custom domain, project syncing, theme cloning and management. Developers have complete control over the source code and can manage it with GitHub’s deceptively simple workflow.
|
||||
Features: inline PageDown editor, visual tree view, image upload and digital asset management with Cloudinary, site preview, continuous integration with GitHub, atomic deploy and hosting, Git and Hugo integration, autosave, custom domain, project syncing, theme cloning and management. Developers have complete control over the source code and can manage it with GitHub's deceptively simple workflow.
|
||||
|
||||
- [Netlify.com](https://www.netlify.com), builds, deploy & hosts your static site or app (Hugo, Jekyll etc). Build, deploy and host your static site or app with a drag and drop interface and automatic deploys from GitHub or Bitbucket.
|
||||
Features: global CDN, atomic deploys, ultra fast DNS, instant cache invalidation, high availability, automated hosting, Git integration, form submission hooks, authentication providers, custom domain. Developers have complete control over the source code and can manage it with GitHub’s or Bitbuckets deceptively simple workflow.
|
||||
Features: global CDN, atomic deploys, ultra fast DNS, instant cache invalidation, high availability, automated hosting, Git integration, form submission hooks, authentication providers, custom domain. Developers have complete control over the source code and can manage it with GitHub's or Bitbuckets deceptively simple workflow.
|
||||
|
||||
- [Forestry.io](https://forestry.io/) - A simple CMS for Jekyll and Hugo sites with support for GitHub, GitLab and Bitbucket. Every time an update is made via the CMS, Forestry will commit changes back to your repo and will compile/deploy your site (S3, GitHub Pages, FTP, etc).
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
authors:
|
||||
- Arjen Schwarz
|
||||
- Samuel Debruyn
|
||||
lastmod: 2015-11-01
|
||||
lastmod: 2017-02-26
|
||||
date: 2015-01-12
|
||||
linktitle: Automated deployments
|
||||
toc: true
|
||||
@@ -137,7 +137,7 @@ After you are registered, you will need to link your GitHub and/or Bitbucket acc
|
||||
|
||||
## Add your project
|
||||
|
||||
Now that we've got all the preliminaries out of the way, it's time to set up our application. For this we click on the **+ Create** button next to Applications, and then we'll choose to use GitHub as our provider.
|
||||
Now that we've got all the preliminaries out of the way, it's time to set up our application. For this we click on the **+ Create** button next to Applications. Create a new application, and choose to use GitHub.
|
||||
|
||||
![][6]
|
||||
|
||||
@@ -151,71 +151,65 @@ Clicking this will make Wercker show you all the repositories you have on GitHub
|
||||
|
||||
[7]: /img/tutorials/automated-deployments/wercker-select-repository.png
|
||||
|
||||
## Select the repository owner
|
||||
## Configure access
|
||||
|
||||
In the next step, Wercker asks you to select the repository owner. Just select your own GitHub account and continue.
|
||||
As Wercker doesn't access to check out your private projects by default, it will ask you what you want to do. When your project is public, as needs to be the case if you wish to use GitHub Pages, the top choice is recommended. When you use this it will simply check out the code in the same way anybody visiting the project on GitHub can do.
|
||||
|
||||
![][8]
|
||||
|
||||
[8]: /img/tutorials/automated-deployments/wercker-select-owner.png
|
||||
[8]: /img/tutorials/automated-deployments/wercker-access.png
|
||||
|
||||
## Configure access
|
||||
## Public or not
|
||||
|
||||
This step can be slightly tricky. As Wercker doesn't access to check out your private projects by default it will ask you what you want to do. When your project is public, as needs to be the case if you wish to use GitHub Pages, the top choice is recommended. When you use this it will simply check out the code in the same way anybody visiting the project on GitHub can do.
|
||||
This is a personal choice; you can make an app public so that everyone can see more details about it. This doesn't give you any real benefits either way in general, although as part of the tutorial I have of course made this app public so you can see it in action [yourself](https://app.wercker.com/#applications/5586dcbdaf7de9c51b02b0d5).
|
||||
|
||||
![][9]
|
||||
|
||||
[9]: /img/tutorials/automated-deployments/wercker-access.png
|
||||
[9]: /img/tutorials/automated-deployments/public-or-not.png
|
||||
|
||||
## Wercker.yml
|
||||
|
||||
Wercker will now attempt to create an initial *wercker.yml* file for you. Or rather, it will create the code you can copy into it yourself. Because there is nothing special about our project according to Wercker, we will simply get the `debian` box. So what we do now is create a *wercker.yml* file in the root of our project that contains the provided configuration, and after we finish setting up the app we will expand this file to make it actually do something.
|
||||
Choose Default for your programming language. Wercker will now attempt to create an initial *wercker.yml* file for you. Or rather, it will create the code you can copy into it yourself. Because there is nothing special about our project according to Wercker, we will simply get the `debian` box. So what we do now is create a *wercker.yml* file in the local root of our project that contains the provided configuration, and after we finish setting up the app we will expand this file to make it actually do something.
|
||||
|
||||
![][10]
|
||||
|
||||
[10]: /img/tutorials/automated-deployments/werckeryml.png
|
||||
|
||||
## Public or not
|
||||
## And we've got an app
|
||||
|
||||
This is a personal choice, you can make an app public so that everyone can see more details about it. This doesn't give you any real benefits either way in general, although as part of the tutorial I have of course made this app public so you can see it in action [yourself](https://app.wercker.com/#applications/5586dcbdaf7de9c51b02b0d5).
|
||||
The application is added now, and Wercker will be offering you the chance to trigger a build. As we haven't pushed up the **wercker.yml** file however, we will politely decline this option. Wercker has automatically added a build pipeline to your application.
|
||||
|
||||
## Adding build step
|
||||
|
||||
And now we're going to add the build step to the build pipeline. First, we go to the "Registry" action in the top menu and then search for "hugo build". Find the **Hugo-Build** task by Arjen and select it.
|
||||
|
||||
![][11]
|
||||
|
||||
[11]: /img/tutorials/automated-deployments/public-or-not.png
|
||||
|
||||
## And we've got an app
|
||||
|
||||
The application is added now, and Wercker will be offering you the chance to trigger a build. As we haven't pushed up the **wercker.yml** file however, we will politely decline this option.
|
||||
|
||||
![][12]
|
||||
|
||||
[12]: /img/tutorials/automated-deployments/and-we-ve-got-an-app.png
|
||||
|
||||
## Adding steps
|
||||
|
||||
And now we're going to add the steps themselves. First, we go to the "Registry" action in the top menu and then search for "hugo build". The first result is the **Hugo-Build** task, which we select.
|
||||
|
||||
![][13]
|
||||
|
||||
[13]: /img/tutorials/automated-deployments/wercker-search.png
|
||||
[11]: /img/tutorials/automated-deployments/wercker-search.png
|
||||
|
||||
## Using Hugo-Build
|
||||
|
||||
Inside the details of this step you will see how to use it. At the top is a summary for the very basic usage, but when scrolling down you go through the README of the step which will usually contain more details about the advanced options available and a full example of using the step.
|
||||
Inside the details of this step you will see how to use it. At the top is a summary for very basic usage, but when scrolling down you go through the README of the step which will usually contain more details about the advanced options available and a full example of using the step.
|
||||
|
||||
We're not going to use any of the advanced features in this tutorial, so we'll return to our project and add the details we need to our wercker.yml file so that it looks like the below. Wercker also has a [page](http://devcenter.wercker.com/articles/werckeryml/validate.html) for validating wercker.yml files, and it's usually a good idea to do so before committing changes as minor typos might cause it to fail.
|
||||
We're not going to use any of the advanced features in this tutorial, so we'll return to our project and add the details we need to our wercker.yml file so that it looks like below:
|
||||
|
||||
```yaml
|
||||
box: debian
|
||||
build:
|
||||
steps:
|
||||
- install-packages:
|
||||
packages: git
|
||||
- script:
|
||||
name: download theme
|
||||
code: |
|
||||
$(git clone https://github.com/spf13/herring-cove ./themes/herring-cove)
|
||||
- arjen/hugo-build:
|
||||
version: "0.14"
|
||||
theme: herring-cove
|
||||
flags: --buildDrafts=true
|
||||
```
|
||||
|
||||
This concludes the first step, so we'll test that it all works as it should by pushing up our wercker.yml file and seeing the magic at work.
|
||||
As you can see, we have two steps in the build pipeline. The first step downloads the theme, and the second step runs arjen's hugo-build step. To use a different theme, you can replace the link to the herring-cove source with another theme's repository - just make sure the name of the folder you download the theme to (./themes/your-theme-name) matches the theme name you tell arjen/hugo-build to use (theme: your-theme-name). Now we'll test that it all works as it should by pushing up our wercker.yml file to GitHub and seeing the magic at work.
|
||||
|
||||
```bash
|
||||
git commit -a -m "Add wercker.yml"
|
||||
@@ -224,13 +218,25 @@ git push origin master
|
||||
|
||||
Once completed a nice tick should have appeared in front of your first build, and if you want you can look at the details by clicking on it. However, we're not done yet as we still need to deploy it to GitHub Pages.
|
||||
|
||||
![][14]
|
||||
![][12]
|
||||
|
||||
[14]: /img/tutorials/automated-deployments/using-hugo-build.png
|
||||
[12]: /img/tutorials/automated-deployments/using-hugo-build.png
|
||||
|
||||
## Adding a GitHub Pages step
|
||||
## Adding a deploy pipeline
|
||||
|
||||
In order to deploy to GitHub Pages we need to add a deploy step. Once again searching through the Steps repository we find that the most popular step is the **lukevevier/gh-pages** step so we add the configuration for that to our wercker.yml file. Additionally we need to ensure that the box we run on has git and ssh installed. We can do this using the **install-packages** command, which then turns the wercker.yml file into this:
|
||||
In order to deploy to GitHub Pages we need to add a deploy pipeline.
|
||||
|
||||
1. First, go to your Wercker application's page. Go to the "Workflows" tab and click on "Add new pipeline." Name it whatever you want; "deploy-production" or "deploy" works fine. For your YML Pipeline name, type in "deploy" without quotes. Leave the hook type as "Default" and hit the Create button.
|
||||
|
||||
2. Now you need to link the deploy pipeline to your build pipeline. In the workflow editor, click on the + next to your build pipeline and add the deploy pipeline you've just made. Now the deploy pipeline will be run automatically whenever the build pipeline is completed successfully.
|
||||
|
||||
![][13]
|
||||
|
||||
[13]: /img/tutorials/automated-deployments/adding-a-deploy-pipeline.png
|
||||
|
||||
## Adding a deploy step
|
||||
|
||||
Next, we need to add a step to our deploy pipeline that will deploy the Hugo-built website to your GitHub pages repository. Once again searching through the Steps registry, we find that the most popular step is the **lukevevier/gh-pages** step so we add the configuration for that to our wercker.yml file. Additionally, we need to ensure that the box we run on has git and ssh installed. We can do this using the **install-packages** command, which then turns the wercker.yml file into this:
|
||||
|
||||
```yaml
|
||||
box: debian
|
||||
@@ -254,19 +260,13 @@ How does the GitHub Pages configuration work? We've selected a couple of things,
|
||||
|
||||
Secondly we've configured the basedir to **public**, this is the directory that will be used as the website on GitHub Pages.
|
||||
|
||||
And lastly, you can see here that this has a **$GIT_TOKEN** variable. This is used for pushing our changes up to GitHub and we will need to configure this before we can do that. We do this by going to our app's settings and clicking on **Deploy targets**. Now, we **Add deploy target** and select **Custom deploy**.
|
||||
And lastly, you can see here that this has a **$GIT_TOKEN** variable. This is used for pushing our changes up to GitHub and we will need to configure this before we can do that. To do this, go to your application page and click on the "Environment" tab. Under Application Environment Variables, put **$GIT_TOKEN** for the Key. Now you'll need to create an access token in GitHub. How to do that is described on a [GitHub help page](https://help.github.com/articles/creating-an-access-token-for-command-line-use/). Copy and paste the access token you generated from GitHub into the Value box. **Make sure you check Protected** and then hit Add.
|
||||
|
||||
![][15]
|
||||
![][14]
|
||||
|
||||
[15]: /img/tutorials/automated-deployments/adding-a-github-pages-step.png
|
||||
[14]: /img/tutorials/automated-deployments/adding-a-deploy-step.png
|
||||
|
||||
## Configure the deploy step
|
||||
|
||||
Simply fill in the name, and make sure you enable **auto deploy** from the **master** branch. Next you add a variable for the **GIT_TOKEN**, for this you'll need to create an access token in GitHub. How to do that is described on a [GitHub help page](https://help.github.com/articles/creating-an-access-token-for-command-line-use/). With the deploy step configured in Wercker, we can push the updated wercker.yml file to GitHub and it will create the GitHub pages site for us. The example site we used here is accessible under hugo-wercker.ig.nore.me
|
||||
|
||||
![][16]
|
||||
|
||||
[16]: /img/tutorials/automated-deployments/configure-the-deploy-step.png
|
||||
With the deploy step configured in Wercker, we can push the updated wercker.yml file to GitHub and it will create the GitHub pages site for us. The example site we used here is accessible under hugo-wercker.ig.nore.me
|
||||
|
||||
## Conclusion
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ refer to the [GitHub Pages docs](https://help.github.com/articles/user-organizat
|
||||
[As described](https://help.github.com/articles/configuring-a-publishing-source-for-github-pages/#publishing-your-github-pages-site-from-a-docs-folder-on-your-master-branch) in the GitHub Pages docs, you can deploy from a folder called _docs_ on your master branch.
|
||||
This requires to change the Hugo publish directory in the site config (e.g. _config.toml_):
|
||||
|
||||
publishDir: "docs"
|
||||
publishDir = "docs"
|
||||
|
||||
After running `hugo`, push your master branch to the remote repo and choose the _docs_ folder as the website source of your repo
|
||||
(in your GitHub project, go to "Settings " -> "GitHub Pages" -> "Source" -> Select "master branch /docs folder").
|
||||
|
||||
@@ -14,7 +14,7 @@ weight: 10
|
||||
|
||||
Hugo is an open source project and lives by the work of its [contributors](https://github.com/spf13/hugo/graphs/contributors). Help to make Hugo even more awesome. There are plenty of [open issues](https://github.com/spf13/hugo/issues) on GitHub and we need your help.
|
||||
|
||||
This tutorial is intended for people who are new to Git, GitHub or open source projects in general. It should help to overcome most of the barriers that newcomers encounter. It describes step by step what you need to do.
|
||||
This tutorial is intended for people who are new to Git, GitHub or open source projects in general. It should help to overcome most of the barriers that newcomers encounter. It describes step by step what you need to do.
|
||||
|
||||
For any kind of questions please take a look at our [forum](https://discuss.gohugo.io/).
|
||||
|
||||
@@ -24,7 +24,7 @@ The installation of Go should take only a few minutes. [Download](https://golang
|
||||
|
||||
Let's confirm the correct installation of Go. Open a terminal (or command line under Windows). Execute `go version` and you should see the version number of your Go installation. Next, make sure that you setup the `GOPATH` as described in the installation guide.
|
||||
|
||||
You can print the `GOPATH` with `echo $GOPATH`. You should see a non-empty string containing a valid path to your Go workspace.
|
||||
You can print the `GOPATH` with `echo $GOPATH`. You should see a non-empty string containing a valid path to your Go workspace.
|
||||
|
||||
### GVM as alternative
|
||||
|
||||
@@ -42,7 +42,7 @@ If you're going to contribute code, you'll need to have an account on GitHub. Go
|
||||
|
||||
You will need to install Git. This tutorial assumes basic knowledge about Git. Refer to this excellent [Git book](https://git-scm.com/) if you are not sure where to begin. The used terminology will be explained with annotations.
|
||||
|
||||
Git is a [version control system](https://en.wikipedia.org/wiki/Version_control) to track the changes of source code. Hugo depends on smaller third-party packages that are used to extend the functionality. We use them because we don't want to reinvent the wheel.
|
||||
Git is a [version control system](https://en.wikipedia.org/wiki/Version_control) to track the changes of source code. Hugo depends on smaller third-party packages that are used to extend the functionality. We use them because we don't want to reinvent the wheel.
|
||||
|
||||
Go ships with a sub-command called `get` that will download these packages for us when we setup our working environment. The source code of the packages is tracked with Git. `get` will interact with the Git servers of the package hosters in order to fetch all dependencies.
|
||||
|
||||
@@ -82,7 +82,17 @@ hub version 2.2.2
|
||||
|
||||
The working copy is set up locally on your computer. It's what you'll edit, compile, and end up pushing back to GitHub. The main steps are cloning the repository and creating your fork as a remote.
|
||||
|
||||
### Clone the repository
|
||||
### 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.
|
||||
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.
|
||||
|
||||
```sh
|
||||
go get -v -u github.com/kardianos/govendor
|
||||
```
|
||||
|
||||
### Fetch the Sources from GitHub
|
||||
|
||||
We assume that you've set up your `GOPATH` (see the section above if you're unsure about this). You should now copy the Hugo repository down to your computer. You'll hear this called "clone the repo". GitHub's [help pages](https://help.github.com/articles/cloning-a-repository/) give us a short explanation:
|
||||
|
||||
@@ -90,10 +100,10 @@ We assume that you've set up your `GOPATH` (see the section above if you're unsu
|
||||
|
||||
We're going to clone the [master Hugo repository](https://github.com/spf13/hugo). That seems counter-intuitive, since you won't have commit rights on it. But it's required for the Go workflow. You'll work on a copy of the master and push your changes to your own repository on GitHub.
|
||||
|
||||
So, let's clone that master repository:
|
||||
So, let's clone that master repository with govendor:
|
||||
|
||||
```sh
|
||||
go get -v -u github.com/spf13/hugo
|
||||
govendor get -v github.com/spf13/hugo
|
||||
```
|
||||
|
||||
### Fork the repository
|
||||
@@ -104,7 +114,7 @@ If you're not fimiliar with this term, GitHub's [help pages](https://help.github
|
||||
|
||||
#### Fork by hand
|
||||
|
||||
Open the [Hugo repository](https://github.com/spf13/hugo) on Github and click on the "Fork" button in the top right.
|
||||
Open the [Hugo repository](https://github.com/spf13/hugo) on GitHub and click on the "Fork" button in the top right.
|
||||
|
||||

|
||||
|
||||
@@ -116,7 +126,7 @@ Switch back to the terminal and move into the directory of the cloned master rep
|
||||
|
||||
```sh
|
||||
cd $GOPATH/src/github.com/spf13/hugo
|
||||
```
|
||||
```
|
||||
|
||||
Now Git needs to know that our fork exists by adding the copied remote url:
|
||||
|
||||
@@ -128,11 +138,11 @@ git remote add <YOUR-GITHUB-USERNAME> <COPIED REMOTE-URL>
|
||||
|
||||
Alternatively, you can use the Git wrapper Hub. Hub makes forking a repository easy:
|
||||
|
||||
```sh
|
||||
```sh
|
||||
git fork
|
||||
```
|
||||
|
||||
That command will log in to GitHub using your account, create a fork of the repository that you're currently working in, and add it as a remote to your working copy.
|
||||
That command will log in to GitHub using your account, create a fork of the repository that you're currently working in, and add it as a remote to your working copy.
|
||||
|
||||
#### Trust, but verify
|
||||
|
||||
@@ -175,7 +185,7 @@ You can check on which branch your are with `git branch`. You should see a list
|
||||
|
||||
### Contributing to the documentation
|
||||
|
||||
Perhaps you want to start contributing to the docs. Then you can ignore most of the following steps. You can find the documentation within the cloned repository in the subfolder `docs`. Change the directory with `cd docs`. Install the [latest release]({{< relref "overview/installing.md" >}}). Or read on and build Hugo from source.
|
||||
Perhaps you want to start contributing to the docs. Then you can ignore most of the following steps. You can find the documentation within the cloned repository in the subfolder `docs`. Change the directory with `cd docs`. Install the [latest release]({{< relref "overview/installing.md" >}}). Or read on and build Hugo from source.
|
||||
|
||||
You can start Hugo's built-in server via `hugo server`. Browse the documentation by entering [http://localhost:1313](http://localhost:1313) in the address bar of your browser. The server automatically updates the page if you change its content.
|
||||
|
||||
@@ -184,21 +194,23 @@ You can start Hugo's built-in server via `hugo server`. Browse the documentation
|
||||
While making changes in the codebase it's a good idea to build the binary to test them:
|
||||
|
||||
```sh
|
||||
go build -o hugo main.go
|
||||
make hugo
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
Sometimes changes on the codebase can cause unintended side effects. Or they don't work as expected. Most functions have their own test cases. You can find them in files ending with `_test.go`.
|
||||
|
||||
Make sure the commands `go test ./...` passes, and `go build` completes.
|
||||
```sh
|
||||
make check
|
||||
```
|
||||
|
||||
### Formatting
|
||||
|
||||
The Go code styleguide maybe is opiniated but it ensures that the codebase looks the same, regardless who wrote the code. Go comes with its own formatting tool. Let's apply the styleguide to our addtions:
|
||||
The Go code styleguide maybe is opiniated but it ensures that the codebase looks the same, regardless who wrote the code. Go comes with its own formatting tool. Let's apply the styleguide to our additions:
|
||||
|
||||
```sh
|
||||
go fmt ./...
|
||||
govendor fmt +local
|
||||
```
|
||||
|
||||
Once you made your additions commit your changes. Make sure that you follow our [code contribution guidelines](https://github.com/spf13/hugo/blob/master/CONTRIBUTING.md):
|
||||
@@ -213,7 +225,7 @@ The commit message should describe what the commit does (e.g. add feature XYZ),
|
||||
|
||||
### Modify commits
|
||||
|
||||
You noticed some commit messages don't fulfill the code contribution guidelines or you just forget something to add some files? No problem. Git provides the necessary tools to fix such problems. The next two methods cover all common cases.
|
||||
You noticed some commit messages don't fulfill the code contribution guidelines or you just forget something to add some files? No problem. Git provides the necessary tools to fix such problems. The next two methods cover all common cases.
|
||||
|
||||
If you are unsure what a command does leave the commit as it is. We can fix your commits later in the pull request.
|
||||
|
||||
@@ -274,7 +286,7 @@ squash 3502f2e Refactoring and typo fixes
|
||||
|
||||
We also want to rewrite the commits message of the third last commit. We forgot "docs:" as prefix according to the code contribution guidelines. The operation to rewrite a commit is called `reword` (or `r` as shortcut).
|
||||
|
||||
You should end up with a similar setup:
|
||||
You should end up with a similar setup:
|
||||
|
||||
```sh
|
||||
pick 80d02a1 tpl: Add hasPrefix to the template funcs' "smoke test"
|
||||
@@ -303,7 +315,7 @@ To push our commits to the fork on GitHub we need to speficy a destination. A de
|
||||
git push --set-upstream <YOUR-GITHUB-USERNAME> <BRANCHNAME>
|
||||
```
|
||||
|
||||
Now Git knows the destination. Next time when you to push commits you just need to enter `git push`.
|
||||
Now Git knows the destination. Next time when you to push commits you just need to enter `git push`.
|
||||
|
||||
If you modified your commit history in the last step GitHub will reject your try to push. This is a safety-feature because the commit history isn't the same and new commits can't be appended as usual. You can enforce this push explicitly with `git push --force`.
|
||||
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
{
|
||||
"media": {
|
||||
"types": [
|
||||
{
|
||||
"Type": "application/javascript",
|
||||
"String": "application/javascript+js",
|
||||
"MainType": "application",
|
||||
"SubType": "javascript",
|
||||
"Suffix": "js"
|
||||
},
|
||||
{
|
||||
"Type": "application/json",
|
||||
"String": "application/json+json",
|
||||
"MainType": "application",
|
||||
"SubType": "json",
|
||||
"Suffix": "json"
|
||||
},
|
||||
{
|
||||
"Type": "application/rss",
|
||||
"String": "application/rss+xml",
|
||||
"MainType": "application",
|
||||
"SubType": "rss",
|
||||
"Suffix": "xml"
|
||||
},
|
||||
{
|
||||
"Type": "application/xml",
|
||||
"String": "application/xml+xml",
|
||||
"MainType": "application",
|
||||
"SubType": "xml",
|
||||
"Suffix": "xml"
|
||||
},
|
||||
{
|
||||
"Type": "text/calendar",
|
||||
"String": "text/calendar+ics",
|
||||
"MainType": "text",
|
||||
"SubType": "calendar",
|
||||
"Suffix": "ics"
|
||||
},
|
||||
{
|
||||
"Type": "text/css",
|
||||
"String": "text/css+css",
|
||||
"MainType": "text",
|
||||
"SubType": "css",
|
||||
"Suffix": "css"
|
||||
},
|
||||
{
|
||||
"Type": "text/csv",
|
||||
"String": "text/csv+csv",
|
||||
"MainType": "text",
|
||||
"SubType": "csv",
|
||||
"Suffix": "csv"
|
||||
},
|
||||
{
|
||||
"Type": "text/html",
|
||||
"String": "text/html+html",
|
||||
"MainType": "text",
|
||||
"SubType": "html",
|
||||
"Suffix": "html"
|
||||
},
|
||||
{
|
||||
"Type": "text/plain",
|
||||
"String": "text/plain+txt",
|
||||
"MainType": "text",
|
||||
"SubType": "plain",
|
||||
"Suffix": "txt"
|
||||
}
|
||||
]
|
||||
},
|
||||
"output": {
|
||||
"formats": [
|
||||
{
|
||||
"MediaType": "text/html+html",
|
||||
"Name": "AMP",
|
||||
"Path": "amp",
|
||||
"BaseName": "index",
|
||||
"Rel": "amphtml",
|
||||
"Protocol": "",
|
||||
"IsPlainText": false,
|
||||
"IsHTML": true,
|
||||
"NoUgly": false,
|
||||
"NotAlternative": false
|
||||
},
|
||||
{
|
||||
"MediaType": "text/css+css",
|
||||
"Name": "CSS",
|
||||
"Path": "",
|
||||
"BaseName": "styles",
|
||||
"Rel": "stylesheet",
|
||||
"Protocol": "",
|
||||
"IsPlainText": true,
|
||||
"IsHTML": false,
|
||||
"NoUgly": false,
|
||||
"NotAlternative": true
|
||||
},
|
||||
{
|
||||
"MediaType": "text/csv+csv",
|
||||
"Name": "CSV",
|
||||
"Path": "",
|
||||
"BaseName": "index",
|
||||
"Rel": "alternate",
|
||||
"Protocol": "",
|
||||
"IsPlainText": true,
|
||||
"IsHTML": false,
|
||||
"NoUgly": false,
|
||||
"NotAlternative": false
|
||||
},
|
||||
{
|
||||
"MediaType": "text/calendar+ics",
|
||||
"Name": "Calendar",
|
||||
"Path": "",
|
||||
"BaseName": "index",
|
||||
"Rel": "alternate",
|
||||
"Protocol": "webcal://",
|
||||
"IsPlainText": true,
|
||||
"IsHTML": false,
|
||||
"NoUgly": false,
|
||||
"NotAlternative": false
|
||||
},
|
||||
{
|
||||
"MediaType": "text/html+html",
|
||||
"Name": "HTML",
|
||||
"Path": "",
|
||||
"BaseName": "index",
|
||||
"Rel": "canonical",
|
||||
"Protocol": "",
|
||||
"IsPlainText": false,
|
||||
"IsHTML": true,
|
||||
"NoUgly": false,
|
||||
"NotAlternative": false
|
||||
},
|
||||
{
|
||||
"MediaType": "application/json+json",
|
||||
"Name": "JSON",
|
||||
"Path": "",
|
||||
"BaseName": "index",
|
||||
"Rel": "alternate",
|
||||
"Protocol": "",
|
||||
"IsPlainText": true,
|
||||
"IsHTML": false,
|
||||
"NoUgly": false,
|
||||
"NotAlternative": false
|
||||
},
|
||||
{
|
||||
"MediaType": "application/rss+xml",
|
||||
"Name": "RSS",
|
||||
"Path": "",
|
||||
"BaseName": "index",
|
||||
"Rel": "alternate",
|
||||
"Protocol": "",
|
||||
"IsPlainText": false,
|
||||
"IsHTML": false,
|
||||
"NoUgly": true,
|
||||
"NotAlternative": false
|
||||
}
|
||||
],
|
||||
"layouts": [
|
||||
{
|
||||
"Example": "AMP home, with theme \"demoTheme\".",
|
||||
"OutputFormat": "AMP",
|
||||
"Suffix": "html",
|
||||
"Template Lookup Order": [
|
||||
"layouts/index.amp.html",
|
||||
"layouts/index.html",
|
||||
"layouts/_default/list.amp.html",
|
||||
"layouts/_default/list.html",
|
||||
"demoTheme/layouts/index.amp.html",
|
||||
"demoTheme/layouts/index.html",
|
||||
"demoTheme/layouts/_default/list.amp.html",
|
||||
"demoTheme/layouts/_default/list.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Example": "JSON home, no theme.",
|
||||
"OutputFormat": "JSON",
|
||||
"Suffix": "json",
|
||||
"Template Lookup Order": [
|
||||
"layouts/index.json.json",
|
||||
"layouts/index.json",
|
||||
"layouts/_default/list.json.json",
|
||||
"layouts/_default/list.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Example": "CSV regular, \"layout: demolayout\" in front matter.",
|
||||
"OutputFormat": "CSV",
|
||||
"Suffix": "csv",
|
||||
"Template Lookup Order": [
|
||||
"layouts/_default/demolayout.csv.csv",
|
||||
"layouts/_default/demolayout.csv"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Example": "JSON regular, \"type: demotype\" in front matter.",
|
||||
"OutputFormat": "CSV",
|
||||
"Suffix": "csv",
|
||||
"Template Lookup Order": [
|
||||
"layouts/demotype/single.csv.csv",
|
||||
"layouts/demotype/single.csv",
|
||||
"layouts/_default/single.csv.csv",
|
||||
"layouts/_default/single.csv"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Example": "HTML regular.",
|
||||
"OutputFormat": "HTML",
|
||||
"Suffix": "html",
|
||||
"Template Lookup Order": [
|
||||
"layouts/_default/single.html.html",
|
||||
"layouts/_default/single.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Example": "AMP regular.",
|
||||
"OutputFormat": "AMP",
|
||||
"Suffix": "html",
|
||||
"Template Lookup Order": [
|
||||
"layouts/_default/single.amp.html",
|
||||
"layouts/_default/single.html"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Example": "Calendar blog section.",
|
||||
"OutputFormat": "Calendar",
|
||||
"Suffix": "ics",
|
||||
"Template Lookup Order": [
|
||||
"layouts/section/blog.calendar.ics",
|
||||
"layouts/section/blog.ics",
|
||||
"layouts/blog/list.calendar.ics",
|
||||
"layouts/blog/list.ics",
|
||||
"layouts/_default/section.calendar.ics",
|
||||
"layouts/_default/section.ics",
|
||||
"layouts/_default/list.calendar.ics",
|
||||
"layouts/_default/list.ics"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Example": "Calendar taxonomy list.",
|
||||
"OutputFormat": "Calendar",
|
||||
"Suffix": "ics",
|
||||
"Template Lookup Order": [
|
||||
"layouts/taxonomy/tag.calendar.ics",
|
||||
"layouts/taxonomy/tag.ics",
|
||||
"layouts/_default/taxonomy.calendar.ics",
|
||||
"layouts/_default/taxonomy.ics",
|
||||
"layouts/_default/list.calendar.ics",
|
||||
"layouts/_default/list.ics"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Example": "Calendar taxonomy term.",
|
||||
"OutputFormat": "Calendar",
|
||||
"Suffix": "ics",
|
||||
"Template Lookup Order": [
|
||||
"layouts/taxonomy/tag.terms.calendar.ics",
|
||||
"layouts/taxonomy/tag.terms.ics",
|
||||
"layouts/_default/terms.calendar.ics",
|
||||
"layouts/_default/terms.ics"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,26 @@
|
||||
|
||||
[[quotes]]
|
||||
name = "Execute"
|
||||
twitter_handle = "@executerun"
|
||||
quote = "Hah, #gohugo. I was working with #gohugo on #linux but now I realised how easy is to set-up it on #windows. Just need to add binary to #path!"
|
||||
link = "https://twitter.com/executerun/status/809753145270272005"
|
||||
date = 2016-12-16T00:00:00Z
|
||||
|
||||
|
||||
[[quotes]]
|
||||
name = "Janez Čadež"
|
||||
twitter_handle = "@jamziSLO"
|
||||
quote = "Building @garazaFRI website in #hugo. This static site generator is soooo damn fast!"
|
||||
link = "https://twitter.com/jamziSLO/status/817720283977183234"
|
||||
date = 2017-01-07T00:00:00Z
|
||||
|
||||
[[quotes]]
|
||||
name = "Hans Beck"
|
||||
twitter_handle = "@EnrichedGamesHB"
|
||||
quote = "Diving deeper into @GoHugoIO . A lot of docs there, top work! But I've the impressed that #gohugo is far easier than its feels from the docs!"
|
||||
link = "https://twitter.com/EnrichedGamesHB/status/836854762440130560"
|
||||
date = 2017-03-01T00:00:00Z
|
||||
|
||||
[[quotes]]
|
||||
name = "Alan Richardson"
|
||||
twitter_handle = "@eviltester"
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
<p>Last revision: {{ .Lastmod.Format "January 2, 2006" }}{{ if .IsPage }}{{ with .GitInfo }} | <a href="https://github.com/spf13/hugo/commit/{{ .Hash }}">{{ .Subject }} ({{ .AbbreviatedHash }})</a>{{end }}{{ end }}
|
||||
<span style="float: right;">Hugo v{{ .Site.Params.release }} documentation</span>
|
||||
</p>
|
||||
{{ with getenv "REPOSITORY_URL" -}}
|
||||
<a href="https://www.netlify.com" style="float: right; padding-right: 20px;">
|
||||
<img src="https://www.netlify.com/img/global/badges/netlify-color-bg.svg"/>
|
||||
</a>
|
||||
{{- end }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -40,9 +40,9 @@
|
||||
<div class="top-nav notification-row">
|
||||
<!-- notification dropdown end-->
|
||||
<div class="hidden-xs nav-github pull-right">
|
||||
<span rel="show-github" data-user="spf13" data-repo="hugo" data-type="follow"></span>
|
||||
<span rel="show-github" data-user="bep" data-type="follow"></span>
|
||||
<span rel="show-github" data-user="spf13" data-type="follow"></span>
|
||||
<span rel="show-github" data-user="spf13" data-repo="hugo"></span>
|
||||
<span rel="show-github" data-user="spf13" data-repo="hugo" data-type="fork"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
{{ partial "header.html" . }}
|
||||
<h1>Hugo Commands</h1>
|
||||
<p>This is an autogenerated and up-to-date (thanks to <a href="https://github.com/spf13/cobra">Cobra</a>) documentation for all the CLI commands in Hugo.</p>
|
||||
<p>Hugo’s CLI (command line interface) commands are listed here.
|
||||
This autogenerated list is always up to date (thanks to
|
||||
<a href="https://github.com/spf13/cobra">Cobra</a>).
|
||||
</p>
|
||||
<ul>
|
||||
{{ range .Data.Pages }}
|
||||
<li><a href="{{ .URL }}">{{ .Title }}</a></li>
|
||||
{{ end }}
|
||||
{{- range .Data.Pages }}
|
||||
<li><a href="{{ .URL }}">{{ .Title }}</a></li>
|
||||
{{- end }}
|
||||
</ul>
|
||||
{{ partial "footer.html" . }}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{{ define "main" }}
|
||||
{{ range .Pages }}
|
||||
<h1>{{ .Title }} {{ .Date.Format "Jan 2, 2006" }}</h1>
|
||||
{{ .Content }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
@@ -0,0 +1,26 @@
|
||||
{{ $package := (index .Params 0) }}
|
||||
{{ $listname := (index .Params 1) }}
|
||||
{{ $list := (index (index .Site.Data.docs $package) $listname) }}
|
||||
{{ $fields := after 2 .Params }}
|
||||
<table class="table table-bordered">
|
||||
{{ range $list }}
|
||||
{{ range $k, $v := . }}
|
||||
{{ $.Scratch.Set $k $v }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ range $i, $_ := $fields }}
|
||||
<tr>
|
||||
{{ $.Scratch.Set "i" $i }}
|
||||
|
||||
{{ $field := (index $fields ($.Scratch.Get "i") ) }}
|
||||
<th>{{ $field }}</th>
|
||||
{{ range $list }}
|
||||
<td>
|
||||
{{ index . $field }}
|
||||
</td>
|
||||
{{ end }}
|
||||
|
||||
</tr>
|
||||
{{ end }}
|
||||
</table>
|
||||
@@ -0,0 +1,23 @@
|
||||
{{ $package := (index .Params 0) }}
|
||||
{{ $listname := (index .Params 1) }}
|
||||
{{ $list := (index (index .Site.Data.docs $package) $listname) }}
|
||||
{{ $fields := after 2 .Params }}
|
||||
|
||||
<table class="table table-bordered">
|
||||
<tr>
|
||||
{{ range $fields }}
|
||||
<th>{{ . }}</th>
|
||||
{{ end }}
|
||||
</tr>
|
||||
{{ range $list }}
|
||||
<tr>
|
||||
{{ range $k, $v := . }}
|
||||
{{ $.Scratch.Set $k $v }}
|
||||
{{ end }}
|
||||
{{ range $fields }}
|
||||
<td>{{ $.Scratch.Get . }}</td>
|
||||
{{ end }}
|
||||
</tr>
|
||||
{{ end }}
|
||||
</table>
|
||||
|
||||
|
After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 259 KiB |
|
After Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 217 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 46 KiB |
|
After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 99 KiB |
|
Before Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 242 KiB |
|
After Width: | Height: | Size: 70 KiB |