mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-30 18:22:37 +00:00
Compare commits
285 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0283db6c60 | |||
| 58188807aa | |||
| 51d5c5421e | |||
| a9a5b1e094 | |||
| cf5c2df81c | |||
| 158e1151cd | |||
| 337d0c5f51 | |||
| f0c0ece44d | |||
| a34213f0b5 | |||
| fe40823de0 | |||
| ae742cb1bd | |||
| feeed073c3 | |||
| 94e736c5e1 | |||
| 1707dae8d3 | |||
| 2fa70c9344 | |||
| b6f3f087aa | |||
| adfd4370b6 | |||
| 25d691daff | |||
| df20b05463 | |||
| 863a812e07 | |||
| f08ea02d24 | |||
| 016398ffe2 | |||
| 3752348ef1 | |||
| 4eb2fec67c | |||
| 83c761b71a | |||
| ed4a00e46f | |||
| 7b472e4608 | |||
| 96e3fbcf23 | |||
| a91aba1c15 | |||
| 6413559f75 | |||
| 322c567220 | |||
| 91bb774ae4 | |||
| 3f0379adb7 | |||
| ae5a45be6f | |||
| 4d912e2aad | |||
| 1e27d05891 | |||
| d418c2c2ea | |||
| b2fcbb1f97 | |||
| 3446fe9b89 | |||
| 4a7c2b3695 | |||
| 912147ab89 | |||
| 517b6b6238 | |||
| a19563910e | |||
| 0432c64dd2 | |||
| 5a0819b9b5 | |||
| 78c863305f | |||
| 22ad1ebdbb | |||
| ebdd8cba3f | |||
| 8125b4b03d | |||
| 87217d1d0a | |||
| ffd7dc396e | |||
| 2228d3e289 | |||
| 5903a9ce10 | |||
| 4d644c9d68 | |||
| 34a216fe67 | |||
| adee04f4b4 | |||
| 9421380168 | |||
| 5d03086981 | |||
| 07700aab0d | |||
| 4d5e4f379a | |||
| cd77968284 | |||
| c7b9347be0 | |||
| c6b9037294 | |||
| 09a934b321 | |||
| e6cc2a6551 | |||
| a39ae4bb07 | |||
| b3eeb97642 | |||
| 3cf4300097 | |||
| 9409bc0f79 | |||
| 4eb1650bec | |||
| 20c9b6ec81 | |||
| f8a119b606 | |||
| ecaf14514e | |||
| d4f8f88e67 | |||
| 4e524ffcff | |||
| 64f0e9d1c1 | |||
| 13d53b31f1 | |||
| 51dd462c39 | |||
| b6ea6d07d0 | |||
| 4dac1781e3 | |||
| 8a409894bd | |||
| 46db900dab | |||
| 60c9f3b1c3 | |||
| 57e10f174e | |||
| db85e83403 | |||
| 1046e9363f | |||
| d5803da1be | |||
| 27c77e1ab9 | |||
| 218773a82b | |||
| a97ef61bad | |||
| 4aaf27dc55 | |||
| f7d0b05f93 | |||
| f82428d2e0 | |||
| 50fb49c3d9 | |||
| 5235a5bf5e | |||
| 1921a70ab1 | |||
| f0eecc6a4f | |||
| 768ec5df9f | |||
| 238e7f7fbe | |||
| 0aaa38544d | |||
| fdec5e3084 | |||
| 71abb53fff | |||
| db5d79862b | |||
| 2d3189b227 | |||
| 4b04db0f08 | |||
| 97c1866e32 | |||
| 8969331f5b | |||
| 6feb138785 | |||
| 059e8458d6 | |||
| ab82a27d05 | |||
| f25d8a9e17 | |||
| 54a89cde69 | |||
| 2cd962233f | |||
| 865877cd05 | |||
| 1ff80a8bbe | |||
| 956ef40978 | |||
| 196da49c9d | |||
| 2aa4c009ee | |||
| eb738cd35c | |||
| 3dd8c1c026 | |||
| fd301c3c05 | |||
| 54ef60b03a | |||
| 14a758ff24 | |||
| e64eb5ec2b | |||
| d36d71edd3 | |||
| a54fd7df21 | |||
| 16e1d99c6d | |||
| bf8a61fde5 | |||
| 72158ab2e8 | |||
| cb359a75c1 | |||
| 82db039436 | |||
| 2d2289c79b | |||
| 6894f121b7 | |||
| 245212a5b7 | |||
| f3cd083961 | |||
| 407c24020e | |||
| c067f34558 | |||
| 72903be587 | |||
| 1c114d539b | |||
| e141294619 | |||
| 612dcc1944 | |||
| e50a8c7a14 | |||
| 7e76a6fd3b | |||
| 1b0780dbeb | |||
| 3cdf19e9b7 | |||
| 02f2735f68 | |||
| 22cd89adc4 | |||
| db4b7a5c67 | |||
| 2511498608 | |||
| 9df3736fec | |||
| 243694102a | |||
| 3153526161 | |||
| fdbef2a81c | |||
| 426ac9c18e | |||
| 84805a68ca | |||
| a2d81ce983 | |||
| 051fa343d0 | |||
| 23f69efb39 | |||
| e69da7a4cb | |||
| e7652180a1 | |||
| 7989210120 | |||
| 7f2ae3ef39 | |||
| 8a8ba63c7e | |||
| c1c04d74a0 | |||
| aa68205d16 | |||
| 94115888e3 | |||
| bf8aa4ac5a | |||
| 6d79beb5f6 | |||
| 8afd7d9ceb | |||
| 42fbf15fb7 | |||
| 288723a049 | |||
| f4b416bbef | |||
| 058f25146c | |||
| 3dd7e8b7a7 | |||
| 30c0d485ea | |||
| 14786c4d8f | |||
| 089fe49309 | |||
| 118b83d74b | |||
| adbd5bc47f | |||
| c1d325934e | |||
| d99db71ab5 | |||
| 503ca6de6c | |||
| b3daa1f4bf | |||
| df1677a6e8 | |||
| 05e42bc643 | |||
| 0a81a6b4ba | |||
| 60dfb9a6e0 | |||
| 2e0465764b | |||
| 6233ddf9d1 | |||
| e66d813bcb | |||
| f5ed04bd4a | |||
| 7730d683e8 | |||
| bb048d811d | |||
| 9299a16c99 | |||
| a9be687b81 | |||
| b32ffed6ab | |||
| 77cbd001ff | |||
| 764f1304e1 | |||
| d9a78b61ad | |||
| 23ba779fab | |||
| 550cec0b1f | |||
| b88a105a7c | |||
| b3443b3d0c | |||
| c97216e4f0 | |||
| bb04010cbf | |||
| 76dc811c65 | |||
| 488631fe0a | |||
| fdd62eb4c3 | |||
| b6f2e3b438 | |||
| c61998d3ac | |||
| 45ad8ac381 | |||
| 133cfd1710 | |||
| db1a5af15d | |||
| 9ccc958ce7 | |||
| 30e471b8c6 | |||
| f711b170e4 | |||
| 9536f7cd05 | |||
| 1ac47cd88a | |||
| ba0b22ef44 | |||
| c9c19d7945 | |||
| 1d52bfbb47 | |||
| 142ebba2c5 | |||
| bf633ea2f2 | |||
| 6faf47e8dd | |||
| 7954bc0f0f | |||
| c4bf03a558 | |||
| 3164103310 | |||
| 6a5170116c | |||
| 325009c3fd | |||
| bc53cd7b15 | |||
| 4e07b4144f | |||
| 89a3f47a21 | |||
| 35be07f7c8 | |||
| 6f84570d8f | |||
| 8964162573 | |||
| e939aaed8b | |||
| d2b3f00df7 | |||
| fa53b13ca0 | |||
| c3c10f2c7c | |||
| ad5ef43838 | |||
| 5109ed520f | |||
| 45e0908b86 | |||
| 41180c51e1 | |||
| 811f381e23 | |||
| 7d783a1c0e | |||
| 49d5e7da42 | |||
| 190508ae1e | |||
| 04bdb596ad | |||
| fe71cb6f5f | |||
| 68ace43431 | |||
| ecf5e081b5 | |||
| 5c31e0c341 | |||
| 7c30e2cbb0 | |||
| 60bd332c1f | |||
| 6a30874f19 | |||
| 15ec031d98 | |||
| 01e54609e7 | |||
| 5800a20a25 | |||
| e2e8bcbec3 | |||
| 66a169a249 | |||
| 2cc4765670 | |||
| 856fc445da | |||
| a6ed645a34 | |||
| 23488f874c | |||
| 8d2580f07c | |||
| 06e5633400 | |||
| dae5a7c61c | |||
| a58741a172 | |||
| d32fd8e328 | |||
| 0859d9dfe6 | |||
| 384a6ac4bd | |||
| 4fc67fe44a | |||
| 47fdfd5196 | |||
| d45e358a05 | |||
| 24fab99841 | |||
| 6a986b7c07 | |||
| 8cf55aff00 | |||
| 8717a60cc0 | |||
| 2818878994 | |||
| b6a30283f0 | |||
| 9d68f695e7 | |||
| 57adc539fc | |||
| b277cb33e4 | |||
| a354d130dc | |||
| f806e951fd |
@@ -1,7 +1,7 @@
|
||||
defaults: &defaults
|
||||
working_directory: /go/src/github.com/gohugoio
|
||||
docker:
|
||||
- image: bepsays/ci-goreleaser:0.30.5-2
|
||||
- image: bepsays/ci-goreleaser:0.34.2-7
|
||||
|
||||
version: 2
|
||||
jobs:
|
||||
@@ -12,10 +12,11 @@ jobs:
|
||||
path: hugo
|
||||
- run:
|
||||
command: |
|
||||
go get -d github.com/magefile/mage/...
|
||||
git clone git@github.com:gohugoio/hugoDocs.git
|
||||
cd hugo
|
||||
make vendor
|
||||
make check
|
||||
mage vendor
|
||||
mage check
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths: .
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 90
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 14
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- Keep
|
||||
- Security
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: Stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. The resources of the Hugo team are limited, and so we are asking for your help.
|
||||
|
||||
If this is a **bug** and you can still reproduce this error on the <code>master</code> branch, please reply with all of the information you have about it in order to keep the issue open.
|
||||
|
||||
If this is a **feature request**, and you feel that it is still relevant and valuable, please tell us why.
|
||||
|
||||
This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions.
|
||||
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
+6
-4
@@ -2,8 +2,8 @@ language: go
|
||||
sudo: required
|
||||
dist: precise
|
||||
go:
|
||||
- 1.8.3
|
||||
- 1.9
|
||||
- 1.8.6
|
||||
- 1.9.3
|
||||
- tip
|
||||
os:
|
||||
- linux
|
||||
@@ -13,9 +13,11 @@ matrix:
|
||||
- go: tip
|
||||
fast_finish: true
|
||||
install:
|
||||
- make vendor
|
||||
- go get github.com/magefile/mage
|
||||
- mage vendor
|
||||
script:
|
||||
- make hugo-race check
|
||||
- mage hugoRace
|
||||
- mage -v check
|
||||
- ./hugo -s docs/
|
||||
- ./hugo --renderToMemory -s docs/
|
||||
before_install:
|
||||
|
||||
+69
-28
@@ -36,6 +36,23 @@ the GitHub [issue tracker](https://github.com/gohugoio/hugo/issues) to report th
|
||||
If you're not sure if it's a bug or not, start by asking in the [discussion forum](https://discourse.gohugo.io).
|
||||
When reporting the issue, please provide the version of Hugo in use (`hugo version`) and your operating system.
|
||||
|
||||
## Code Contribution
|
||||
|
||||
Hugo has become a fully featured static site generator, so any new functionality must meet these criterias:
|
||||
|
||||
* It must be useful to many.
|
||||
* It must fit natural into _what Hugo does best._
|
||||
* It must strive not to break existing sites.
|
||||
* It must close ur update an open [Hugo issue](https://github.com/gohugoio/hugo/issues)
|
||||
* If it is of some complexity, the contributor is expected to maintain and support the new future (answer questions on the forum, fix any bugs etc.).
|
||||
|
||||
So, to avoid doing unneeded work, it is recommended to open up a discussion on the [Hugo Forum](https://discourse.gohugo.io/) to get some acceptance that this is a good idea. Also, if this is a complex feature, create a small design proposal on the [Hugo issue tracker](https://github.com/gohugoio/hugo/issues) before you start coding.
|
||||
|
||||
|
||||
**Bug fixes are, of course, always welcome.**
|
||||
|
||||
|
||||
|
||||
## Submitting Patches
|
||||
|
||||
The Hugo project welcomes all contributors and contributions regardless of skill or experience level.
|
||||
@@ -57,7 +74,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`.
|
||||
* Ensure that `make check` succeeds. [Travis CI](https://travis-ci.org/gohugoio/hugo) (Linux and macOS) and [AppVeyor](https://ci.appveyor.com/project/gohugoio/hugo/branch/master) (Windows) will fail the build if `make check` fails.
|
||||
* Ensure that `mage check` succeeds. [Travis CI](https://travis-ci.org/gohugoio/hugo) (Linux and macOS) and [AppVeyor](https://ci.appveyor.com/project/gohugoio/hugo/branch/master) (Windows) will fail the build if `mage check` fails.
|
||||
* Follow the **Git Commit Message Guidelines** below.
|
||||
|
||||
### Git Commit Message Guidelines
|
||||
@@ -88,42 +105,42 @@ 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 -u github.com/kardianos/govendor
|
||||
govendor get github.com/gohugoio/hugo
|
||||
```
|
||||
|
||||
### Using Git Remotes
|
||||
### Fetching the Sources From GitHub
|
||||
|
||||
Due to the way Go handles package imports, the best approach for working on a
|
||||
Hugo fork is to use Git Remotes. Here's a simple walk-through for getting
|
||||
started:
|
||||
|
||||
1. Fetch the Hugo sources as described above.
|
||||
|
||||
1. Change to the Hugo source directory:
|
||||
1. Get the Hugo source:
|
||||
|
||||
```bash
|
||||
go get -u -v -d github.com/gohugoio/hugo
|
||||
```
|
||||
|
||||
1. Install Mage:
|
||||
|
||||
```bash
|
||||
go get github.com/magefile/mage
|
||||
```
|
||||
|
||||
1. Change to the Hugo source directory and fetch the dependencies:
|
||||
|
||||
```bash
|
||||
cd $HOME/go/src/github.com/gohugoio/hugo
|
||||
mage vendor
|
||||
```
|
||||
|
||||
Note that Hugo uses [Go Dep](https://github.com/golang/dep) to vendor dependencies, rather than a a simple `go get`. We don't commit the vendored packages themselves to the Hugo git repository. The call to `mage vendor` takes care of all this for you.
|
||||
|
||||
1. Create a new branch for your changes (the branch name is arbitrary):
|
||||
|
||||
```
|
||||
```bash
|
||||
git checkout -b iss1234
|
||||
```
|
||||
|
||||
1. After making your changes, commit them to your new branch:
|
||||
|
||||
```
|
||||
```bash
|
||||
git commit -a -v
|
||||
```
|
||||
|
||||
@@ -131,25 +148,49 @@ started:
|
||||
|
||||
1. Add your fork as a new remote (the remote name, "fork" in this example, is arbitrary):
|
||||
|
||||
```
|
||||
```bash
|
||||
git remote add fork git://github.com/USERNAME/hugo.git
|
||||
```
|
||||
|
||||
1. Push the changes to your new remote:
|
||||
|
||||
```
|
||||
```bash
|
||||
git push --set-upstream fork iss1234
|
||||
```
|
||||
|
||||
1. You're now ready to submit a PR based upon the new branch in your forked repository.
|
||||
|
||||
### Build Hugo with Your Changes
|
||||
### Building Hugo with Your Changes
|
||||
|
||||
Hugo uses [mage](https://github.com/magefile/mage) to sync vendor dependencies, build Hugo, run the test suite and other things. You must run mage from the Hugo directory.
|
||||
|
||||
```bash
|
||||
cd $HOME/go/src/github.com/gohugoio/hugo
|
||||
make hugo
|
||||
# or to install in $HOME/go/bin:
|
||||
make install
|
||||
```
|
||||
|
||||
To build Hugo:
|
||||
|
||||
```bash
|
||||
mage hugo
|
||||
```
|
||||
|
||||
To install hugo in `$HOME/go/bin`:
|
||||
|
||||
```bash
|
||||
mage install
|
||||
```
|
||||
|
||||
To run the tests:
|
||||
|
||||
```bash
|
||||
mage hugoRace
|
||||
mage -v check
|
||||
```
|
||||
|
||||
To list all available commands along with descriptions:
|
||||
|
||||
```bash
|
||||
mage -l
|
||||
```
|
||||
|
||||
### Updating the Hugo Sources
|
||||
@@ -158,8 +199,8 @@ 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.
|
||||
|
||||
```
|
||||
```bash
|
||||
git pull
|
||||
make vendor
|
||||
mage vendor
|
||||
```
|
||||
|
||||
|
||||
+2
-3
@@ -1,12 +1,11 @@
|
||||
FROM golang:1.9.0-alpine3.6 AS build
|
||||
|
||||
RUN apk add --no-cache --virtual git musl-dev
|
||||
RUN go get github.com/kardianos/govendor
|
||||
RUN go get github.com/golang/dep/cmd/dep
|
||||
|
||||
ADD vendor/vendor.json /go/src/github.com/gohugoio/hugo/vendor/vendor.json
|
||||
WORKDIR /go/src/github.com/gohugoio/hugo
|
||||
RUN govendor sync
|
||||
ADD . /go/src/github.com/gohugoio/hugo/
|
||||
RUN dep ensure
|
||||
RUN go install -ldflags '-s -w'
|
||||
|
||||
FROM alpine:3.6
|
||||
|
||||
Generated
+386
@@ -0,0 +1,386 @@
|
||||
# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
|
||||
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/BurntSushi/toml"
|
||||
packages = ["."]
|
||||
revision = "a368813c5e648fee92e5f6c30e3944ff9d5e8895"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/PuerkitoBio/purell"
|
||||
packages = ["."]
|
||||
revision = "0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/PuerkitoBio/urlesc"
|
||||
packages = ["."]
|
||||
revision = "de5bf2ad457846296e2031421a34e2568e304e35"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/alecthomas/chroma"
|
||||
packages = [
|
||||
".",
|
||||
"formatters",
|
||||
"formatters/html",
|
||||
"lexers",
|
||||
"styles"
|
||||
]
|
||||
revision = "e0f32fbcb59bc99c521910291b7ba8ecdb17ca34"
|
||||
version = "v0.2.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/bep/gitmap"
|
||||
packages = ["."]
|
||||
revision = "de8030ebafb76c6e84d50ee6d143382637c00598"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/chaseadamsio/goorgeous"
|
||||
packages = ["."]
|
||||
revision = "dcf1ef873b8987bf12596fe6951c48347986eb2f"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/cpuguy83/go-md2man"
|
||||
packages = ["md2man"]
|
||||
revision = "1d903dcb749992f3741d744c0f8376b4bd7eb3e1"
|
||||
version = "v1.0.7"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/danwakefield/fnmatch"
|
||||
packages = ["."]
|
||||
revision = "cbb64ac3d964b81592e64f957ad53df015803288"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/davecgh/go-spew"
|
||||
packages = ["spew"]
|
||||
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/disintegration/imaging"
|
||||
packages = ["."]
|
||||
revision = "dd50a3ee9985ccd313a2f03c398fcaedc96dc707"
|
||||
version = "v1.2.4"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/dlclark/regexp2"
|
||||
packages = [
|
||||
".",
|
||||
"syntax"
|
||||
]
|
||||
revision = "487489b64fb796de2e55f4e8a4ad1e145f80e957"
|
||||
version = "v1.1.6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/eknkc/amber"
|
||||
packages = [
|
||||
".",
|
||||
"parser"
|
||||
]
|
||||
revision = "cdade1c073850f4ffc70a829e31235ea6892853b"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/fortytw2/leaktest"
|
||||
packages = ["."]
|
||||
revision = "7dad53304f9614c1c365755c1176a8e876fee3e8"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/fsnotify/fsnotify"
|
||||
packages = ["."]
|
||||
revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9"
|
||||
version = "v1.4.7"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gobwas/glob"
|
||||
packages = [
|
||||
".",
|
||||
"compiler",
|
||||
"match",
|
||||
"syntax",
|
||||
"syntax/ast",
|
||||
"syntax/lexer",
|
||||
"util/runes",
|
||||
"util/strings"
|
||||
]
|
||||
revision = "bea32b9cd2d6f55753d94a28e959b13f0244797a"
|
||||
version = "v0.2.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/websocket"
|
||||
packages = ["."]
|
||||
revision = "ea4d1f681babbce9545c9c5f3d5194a789c89f5b"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/go-immutable-radix"
|
||||
packages = ["."]
|
||||
revision = "8aac2701530899b64bdea735a1de8da899815220"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/golang-lru"
|
||||
packages = ["simplelru"]
|
||||
revision = "0a025b7e63adc15a622f29b0b2c4c3848243bbf6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/hcl"
|
||||
packages = [
|
||||
".",
|
||||
"hcl/ast",
|
||||
"hcl/parser",
|
||||
"hcl/scanner",
|
||||
"hcl/strconv",
|
||||
"hcl/token",
|
||||
"json/parser",
|
||||
"json/scanner",
|
||||
"json/token"
|
||||
]
|
||||
revision = "23c074d0eceb2b8a5bfdbb271ab780cde70f05a8"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/inconshreveable/mousetrap"
|
||||
packages = ["."]
|
||||
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
|
||||
version = "v1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/jdkato/prose"
|
||||
packages = [
|
||||
"internal/util",
|
||||
"transform"
|
||||
]
|
||||
revision = "20d3663d4bc9dd10d75abcde9d92e04b4861c674"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/kyokomi/emoji"
|
||||
packages = ["."]
|
||||
revision = "7e06b236c489543f53868841f188a294e3383eab"
|
||||
version = "v1.5"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/magefile/mage"
|
||||
packages = [
|
||||
"mg",
|
||||
"sh"
|
||||
]
|
||||
revision = "2f974307b636f59c13b88704cf350a4772fef271"
|
||||
version = "v1.0.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/magiconair/properties"
|
||||
packages = ["."]
|
||||
revision = "d419a98cdbed11a922bf76f257b7c4be79b50e73"
|
||||
version = "v1.7.4"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/markbates/inflect"
|
||||
packages = ["."]
|
||||
revision = "a12c3aec81a6a938bf584a4bac567afed9256586"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/mattn/go-runewidth"
|
||||
packages = ["."]
|
||||
revision = "9e777a8366cce605130a531d2cd6363d07ad7317"
|
||||
version = "v0.0.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/miekg/mmark"
|
||||
packages = ["."]
|
||||
revision = "fd2f6c1403b37925bd7fe13af05853b8ae58ee5f"
|
||||
version = "v1.3.6"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/mitchellh/mapstructure"
|
||||
packages = ["."]
|
||||
revision = "b4575eea38cca1123ec2dc90c26529b5c5acfcff"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/nicksnyder/go-i18n"
|
||||
packages = [
|
||||
"i18n/bundle",
|
||||
"i18n/language",
|
||||
"i18n/translation"
|
||||
]
|
||||
revision = "0dc1626d56435e9d605a29875701721c54bc9bbd"
|
||||
version = "v1.10.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/olekukonko/tablewriter"
|
||||
packages = ["."]
|
||||
revision = "96aac992fc8b1a4c83841a6c3e7178d20d989625"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pelletier/go-toml"
|
||||
packages = ["."]
|
||||
revision = "16398bac157da96aa88f98a2df640c7f32af1da2"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/pmezard/go-difflib"
|
||||
packages = ["difflib"]
|
||||
revision = "792786c7400a136282c1664665ae0a8db921c6c2"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/russross/blackfriday"
|
||||
packages = ["."]
|
||||
revision = "4048872b16cc0fc2c5fd9eacf0ed2c2fedaa0c8c"
|
||||
version = "v1.5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/shurcooL/sanitized_anchor_name"
|
||||
packages = ["."]
|
||||
revision = "86672fcb3f950f35f2e675df2240550f2a50762f"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/afero"
|
||||
packages = [
|
||||
".",
|
||||
"mem"
|
||||
]
|
||||
revision = "bb8f1927f2a9d3ab41c9340aa034f6b803f4359c"
|
||||
version = "v1.0.2"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/cast"
|
||||
packages = ["."]
|
||||
revision = "acbeb36b902d72a7a4c18e8f3241075e7ab763e4"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/cobra"
|
||||
packages = [
|
||||
".",
|
||||
"doc"
|
||||
]
|
||||
revision = "b95ab734e27d33e0d8fbabf71ca990568d4e2020"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/fsync"
|
||||
packages = ["."]
|
||||
revision = "12a01e648f05a938100a26858d2d59a120307a18"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/jwalterweatherman"
|
||||
packages = ["."]
|
||||
revision = "7c0cea34c8ece3fbeb2b27ab9b59511d360fb394"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/nitro"
|
||||
packages = ["."]
|
||||
revision = "24d7ef30a12da0bdc5e2eb370a79c659ddccf0e8"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/pflag"
|
||||
packages = ["."]
|
||||
revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/spf13/viper"
|
||||
packages = ["."]
|
||||
revision = "25b30aa063fc18e48662b86996252eabdcf2f0c7"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/stretchr/testify"
|
||||
packages = [
|
||||
"assert",
|
||||
"require"
|
||||
]
|
||||
revision = "b91bfb9ebec76498946beb6af7c0230c7cc7ba6c"
|
||||
version = "v1.2.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/yosssi/ace"
|
||||
packages = ["."]
|
||||
revision = "ea038f4770b6746c3f8f84f14fa60d9fe1205b56"
|
||||
version = "v0.0.5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/image"
|
||||
packages = [
|
||||
"bmp",
|
||||
"riff",
|
||||
"tiff",
|
||||
"tiff/lzw",
|
||||
"vp8",
|
||||
"vp8l",
|
||||
"webp"
|
||||
]
|
||||
revision = "12117c17ca67ffa1ce22e9409f3b0b0a93ac08c7"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/net"
|
||||
packages = [
|
||||
"context",
|
||||
"idna"
|
||||
]
|
||||
revision = "5ccada7d0a7ba9aeb5d3aca8d3501b4c2a509fec"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sync"
|
||||
packages = ["errgroup"]
|
||||
revision = "fd80eb99c8f653c847d294a001bdf2a3a6f768f5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
revision = "810d7000345868fc619eb81f46307107118f4ae1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/text"
|
||||
packages = [
|
||||
"collate",
|
||||
"collate/build",
|
||||
"internal/colltab",
|
||||
"internal/gen",
|
||||
"internal/tag",
|
||||
"internal/triegen",
|
||||
"internal/ucd",
|
||||
"language",
|
||||
"secure/bidirule",
|
||||
"transform",
|
||||
"unicode/bidi",
|
||||
"unicode/cldr",
|
||||
"unicode/norm",
|
||||
"unicode/rangetable",
|
||||
"width"
|
||||
]
|
||||
revision = "e19ae1496984b1c655b8044a65c0300a3c878dd3"
|
||||
|
||||
[[projects]]
|
||||
branch = "v2"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
revision = "d670f9405373e636a5a2765eea47fac0c9bc91a4"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "c80ffe69d34005d8d72a87cc491ce1d9c91272e4b7f8fbd22d4fda8973fa8556"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/BurntSushi/toml"
|
||||
branch = "master"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/PuerkitoBio/purell"
|
||||
version = "1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/alecthomas/chroma"
|
||||
version = "^0.2.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/bep/gitmap"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/chaseadamsio/goorgeous"
|
||||
version = "^1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/disintegration/imaging"
|
||||
version = "~v1.2.4"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/magefile/mage"
|
||||
version = "v1"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/eknkc/amber"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/fortytw2/leaktest"
|
||||
version = "1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/fsnotify/fsnotify"
|
||||
version = "^1.4.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gorilla/websocket"
|
||||
version = "1.2.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/hashicorp/go-immutable-radix"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/jdkato/prose"
|
||||
version = "1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/kyokomi/emoji"
|
||||
version = "1.5.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/markbates/inflect"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/miekg/mmark"
|
||||
version = "^1.3.6"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/mitchellh/mapstructure"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/nicksnyder/go-i18n"
|
||||
version = "^1.10.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/russross/blackfriday"
|
||||
version = "^1.5.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/afero"
|
||||
version = "^1.0.1"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/cast"
|
||||
version = "^1.1.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/cobra"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/fsync"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/jwalterweatherman"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/spf13/nitro"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/pflag"
|
||||
version = "1.0.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/viper"
|
||||
version = "1.0.0"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/stretchr/testify"
|
||||
version = "1.1.4"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/olekukonko/tablewriter"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/yosssi/ace"
|
||||
version = "^0.0.5"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/image"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/text"
|
||||
|
||||
[[constraint]]
|
||||
branch = "v2"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/gobwas/glob"
|
||||
version = "0.2.2"
|
||||
@@ -1,86 +0,0 @@
|
||||
# A Self-Documenting Makefile: http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
|
||||
|
||||
PACKAGE = github.com/gohugoio/hugo
|
||||
COMMIT_HASH = `git rev-parse --short HEAD 2>/dev/null`
|
||||
BUILD_DATE = `date +%FT%T%z`
|
||||
LDFLAGS = -ldflags "-X ${PACKAGE}/hugolib.CommitHash=${COMMIT_HASH} -X ${PACKAGE}/hugolib.BuildDate=${BUILD_DATE}"
|
||||
NOGI_LDFLAGS = -ldflags "-X ${PACKAGE}/hugolib.BuildDate=${BUILD_DATE}"
|
||||
|
||||
# allow user to override go executable by running as GOEXE=xxx make ... on unix-like systems
|
||||
GOEXE ?= go
|
||||
|
||||
.PHONY: vendor docker check fmt lint test test-race vet test-cover-html help
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
vendor: ## Install govendor and sync Hugo's vendored dependencies
|
||||
${GOEXE} get github.com/kardianos/govendor
|
||||
govendor sync ${PACKAGE}
|
||||
|
||||
hugo: vendor ## Build hugo binary
|
||||
${GOEXE} build ${LDFLAGS} ${PACKAGE}
|
||||
|
||||
hugo-race: vendor ## Build hugo binary with race detector enabled
|
||||
${GOEXE} build -race ${LDFLAGS} ${PACKAGE}
|
||||
|
||||
install: vendor ## Install hugo binary
|
||||
${GOEXE} install ${LDFLAGS} ${PACKAGE}
|
||||
|
||||
hugo-no-gitinfo: LDFLAGS = ${NOGI_LDFLAGS}
|
||||
hugo-no-gitinfo: vendor hugo ## Build hugo without git info
|
||||
|
||||
docker: ## Build hugo Docker container
|
||||
docker build -t hugo .
|
||||
docker rm -f hugo-build || true
|
||||
docker run --name hugo-build hugo ls /go/bin
|
||||
docker cp hugo-build:/go/bin/hugo .
|
||||
docker rm hugo-build
|
||||
|
||||
govendor: vendor # Deprecated: use "vendor" target
|
||||
get: vendor # Deprecated: use "vendor"
|
||||
gitinfo: hugo # Deprecated: use "hugo" target
|
||||
install-gitinfo: install # Deprecated: use "install" target
|
||||
no-git-info: hugo-no-gitinfo # Deprecated: use "hugo-no-gitinfo" target
|
||||
|
||||
check: test-race test386 fmt vet ## Run tests and linters
|
||||
|
||||
test386: ## Run tests in 32-bit mode
|
||||
GOARCH=386 govendor test +local
|
||||
|
||||
test: ## Run tests
|
||||
govendor test +local
|
||||
|
||||
test-race: ## Run tests with race detector
|
||||
govendor test -race +local
|
||||
|
||||
fmt: ## Run gofmt linter
|
||||
@for d in `govendor list -no-status +local | sed 's/github.com.gohugoio.hugo/./'` ; do \
|
||||
if [ "`gofmt -l $$d/*.go | tee /dev/stderr`" ]; then \
|
||||
echo "^ improperly formatted go files" && echo && exit 1; \
|
||||
fi \
|
||||
done
|
||||
|
||||
lint: ## Run golint linter
|
||||
@for d in `govendor list -no-status +local | sed 's/github.com.gohugoio.hugo/./'` ; do \
|
||||
if [ "`golint $$d | tee /dev/stderr`" ]; then \
|
||||
echo "^ golint errors!" && echo && exit 1; \
|
||||
fi \
|
||||
done
|
||||
|
||||
vet: ## Run go vet linter
|
||||
@if [ "`govendor vet +local | tee /dev/stderr`" ]; then \
|
||||
echo "^ go vet errors!" && echo && exit 1; \
|
||||
fi
|
||||
|
||||
test-cover-html: PACKAGES = $(shell govendor list -no-status +local | sed 's/github.com.gohugoio.hugo/./')
|
||||
test-cover-html: ## Generate test coverage report
|
||||
echo "mode: count" > coverage-all.out
|
||||
$(foreach pkg,$(PACKAGES),\
|
||||
govendor test -coverprofile=coverage.out -covermode=count $(pkg);\
|
||||
tail -n +2 coverage.out >> coverage-all.out;)
|
||||
${GOEXE} tool cover -html=coverage-all.out
|
||||
|
||||
check-vendor: ## Verify that vendored packages match git HEAD
|
||||
@git diff-index --quiet HEAD vendor/ || (echo "check-vendor target failed: vendored packages out of sync" && echo && git diff vendor/ && exit 1)
|
||||
|
||||
help:
|
||||
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||
@@ -1,6 +1,6 @@
|
||||

|
||||
|
||||
A Fast and Flexible Static Site Generator built with love by [spf13](http://spf13.com/) and [friends](https://github.com/gohugoio/hugo/graphs/contributors) in [Go][].
|
||||
A Fast and Flexible Static Site Generator built with love by [bep](https://github.com/bep), [spf13](http://spf13.com/) and [friends](https://github.com/gohugoio/hugo/graphs/contributors) in [Go][].
|
||||
|
||||
[Website](https://gohugo.io) |
|
||||
[Forum](https://discourse.gohugo.io) |
|
||||
@@ -19,23 +19,22 @@ A Fast and Flexible Static Site Generator built with love by [spf13](http://spf1
|
||||
## Overview
|
||||
|
||||
Hugo is a static HTML and CSS website generator written in [Go][].
|
||||
It is optimized for speed, easy use and configurability.
|
||||
It is optimized for speed, ease of use, and configurability.
|
||||
Hugo takes a directory with content and templates and renders them into a full HTML website.
|
||||
|
||||
Hugo relies on Markdown files with front matter for meta data.
|
||||
And you can run Hugo from any directory.
|
||||
Hugo relies on Markdown files with front matter for metadata, and you can run Hugo from any directory.
|
||||
This works well for shared hosts and other systems where you don’t have a privileged account.
|
||||
|
||||
Hugo renders a typical website of moderate size in a fraction of a second.
|
||||
A good rule of thumb is that each piece of content renders in around 1 millisecond.
|
||||
|
||||
Hugo is designed to work well for any kind of website including blogs, tumbles and docs.
|
||||
Hugo is designed to work well for any kind of website including blogs, tumbles, and docs.
|
||||
|
||||
#### Supported 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.
|
||||
Currently, we provide pre-built Hugo binaries for Windows, Linux, FreeBSD, NetBSD, 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.
|
||||
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.
|
||||
|
||||
**Complete documentation is available at [Hugo Documentation][].**
|
||||
|
||||
@@ -100,6 +99,7 @@ When reporting the issue, please provide the version of Hugo in use (`hugo versi
|
||||
The Hugo project welcomes all contributors and contributions regardless of skill or experience level.
|
||||
If you are interested in helping with the project, we will help you with your contribution.
|
||||
Hugo is a very active project with many contributions happening daily.
|
||||
|
||||
Because we want to create the best possible product for our users and the best contribution experience for our developers,
|
||||
we have a set of guidelines which ensure that all contributions are acceptable.
|
||||
The guidelines are not intended as a filter or barrier to participation.
|
||||
|
||||
+3
-2
@@ -1,5 +1,4 @@
|
||||
init:
|
||||
- copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe
|
||||
- set PATH=%PATH%;C:\MinGW\bin;%GOPATH%\bin
|
||||
- go version
|
||||
- go env
|
||||
@@ -10,8 +9,10 @@ clone_folder: C:\GOPATH\src\github.com\gohugoio\hugo
|
||||
install:
|
||||
- gem install asciidoctor
|
||||
- pip install docutils
|
||||
- go get github.com/magefile/mage
|
||||
|
||||
build_script:
|
||||
- make hugo-race check
|
||||
- mage vendor hugoRace
|
||||
- mage -v check
|
||||
- hugo -s docs/
|
||||
- hugo --renderToMemory -s docs/
|
||||
|
||||
+1
-1
@@ -9,4 +9,4 @@ GOEXE="${GOEXE-go}"
|
||||
|
||||
echo "Running with BenchmarkSiteBuilding/${1}"
|
||||
|
||||
"${GOEXE}" test -run="NONE" -bench="BenchmarkSiteBuilding/${1}$" -test.benchmem=true ./hugolib -memprofile mem.prof -cpuprofile cpu.prof
|
||||
"${GOEXE}" test -run="NONE" -bench="BenchmarkSiteBuilding/${1}" -test.benchmem=true ./hugolib -memprofile mem.prof -count 3 -cpuprofile cpu.prof
|
||||
|
||||
@@ -48,12 +48,11 @@ func init() {
|
||||
}
|
||||
|
||||
func benchmark(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig(benchmarkCmd)
|
||||
if err != nil {
|
||||
return err
|
||||
cfgInit := func(c *commandeer) error {
|
||||
c.Set("renderToMemory", renderToMemory)
|
||||
return nil
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
c, err := InitializeConfig(false, cfgInit, benchmarkCmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -84,7 +83,7 @@ func benchmark(cmd *cobra.Command, args []string) error {
|
||||
|
||||
t := time.Now()
|
||||
for i := 0; i < benchmarkTimes; i++ {
|
||||
if err = c.resetAndBuildSites(false); err != nil {
|
||||
if err = c.resetAndBuildSites(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
+28
-10
@@ -14,14 +14,23 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/gohugoio/hugo/common/types"
|
||||
"github.com/gohugoio/hugo/deps"
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/gohugoio/hugo/hugofs"
|
||||
src "github.com/gohugoio/hugo/source"
|
||||
)
|
||||
|
||||
type commandeer struct {
|
||||
*deps.DepsCfg
|
||||
pathSpec *helpers.PathSpec
|
||||
pathSpec *helpers.PathSpec
|
||||
visitedURLs *types.EvictingStringQueue
|
||||
|
||||
staticDirsConfig []*src.Dirs
|
||||
|
||||
serverPorts []int
|
||||
languages helpers.Languages
|
||||
|
||||
configured bool
|
||||
}
|
||||
|
||||
@@ -46,17 +55,26 @@ func (c *commandeer) initFs(fs *hugofs.Fs) error {
|
||||
return err
|
||||
}
|
||||
c.pathSpec = ps
|
||||
|
||||
dirsConfig, err := c.createStaticDirsConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.staticDirsConfig = dirsConfig
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func newCommandeer(cfg *deps.DepsCfg) (*commandeer, error) {
|
||||
l := cfg.Language
|
||||
if l == nil {
|
||||
l = helpers.NewDefaultLanguage(cfg.Cfg)
|
||||
func newCommandeer(cfg *deps.DepsCfg, running bool) (*commandeer, error) {
|
||||
cfg.Running = running
|
||||
|
||||
var languages helpers.Languages
|
||||
|
||||
if l, ok := cfg.Cfg.Get("languagesSorted").(helpers.Languages); ok {
|
||||
languages = l
|
||||
}
|
||||
ps, err := helpers.NewPathSpec(cfg.Fs, l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &commandeer{DepsCfg: cfg, pathSpec: ps}, nil
|
||||
|
||||
c := &commandeer{DepsCfg: cfg, languages: languages, visitedURLs: types.NewEvictingStringQueue(10)}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
+90
-65
@@ -14,12 +14,15 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
src "github.com/gohugoio/hugo/source"
|
||||
|
||||
"github.com/gohugoio/hugo/hugolib"
|
||||
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gohugoio/hugo/parser"
|
||||
"github.com/spf13/cast"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -78,81 +81,103 @@ func init() {
|
||||
}
|
||||
|
||||
func convertContents(mark rune) error {
|
||||
cfg, err := InitializeConfig()
|
||||
if outputDir == "" && !unsafe {
|
||||
return newUserError("Unsafe operation not allowed, use --unsafe or set a different output path")
|
||||
}
|
||||
|
||||
c, err := InitializeConfig(false, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h, err := hugolib.NewHugoSites(*cfg)
|
||||
h, err := hugolib.NewHugoSites(*c.DepsCfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := h.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
site := h.Sites[0]
|
||||
|
||||
if err = site.Initialise(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if site.Source == nil {
|
||||
panic("site.Source not set")
|
||||
}
|
||||
if len(site.Source.Files()) < 1 {
|
||||
return errors.New("No source files found")
|
||||
}
|
||||
|
||||
contentDir := site.PathSpec.AbsPathify(site.Cfg.GetString("contentDir"))
|
||||
site.Log.FEEDBACK.Println("processing", len(site.Source.Files()), "content files")
|
||||
for _, file := range site.Source.Files() {
|
||||
site.Log.INFO.Println("Attempting to convert", file.LogicalName())
|
||||
page, err := site.NewPage(file.LogicalName())
|
||||
if err != nil {
|
||||
site.Log.FEEDBACK.Println("processing", len(site.AllPages), "content files")
|
||||
for _, p := range site.AllPages {
|
||||
if err := convertAndSavePage(p, site, mark); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
psr, err := parser.ReadFrom(file.Contents)
|
||||
if err != nil {
|
||||
site.Log.ERROR.Println("Error processing file:", file.Path())
|
||||
return err
|
||||
}
|
||||
metadata, err := psr.Metadata()
|
||||
if err != nil {
|
||||
site.Log.ERROR.Println("Error processing file:", file.Path())
|
||||
return err
|
||||
}
|
||||
|
||||
// better handling of dates in formats that don't have support for them
|
||||
if mark == parser.FormatToLeadRune("json") || mark == parser.FormatToLeadRune("yaml") || mark == parser.FormatToLeadRune("toml") {
|
||||
newMetadata := cast.ToStringMap(metadata)
|
||||
for k, v := range newMetadata {
|
||||
switch vv := v.(type) {
|
||||
case time.Time:
|
||||
newMetadata[k] = vv.Format(time.RFC3339)
|
||||
}
|
||||
}
|
||||
metadata = newMetadata
|
||||
}
|
||||
|
||||
page.SetDir(filepath.Join(contentDir, file.Dir()))
|
||||
page.SetSourceContent(psr.Content())
|
||||
if err = page.SetSourceMetaData(metadata, mark); err != nil {
|
||||
site.Log.ERROR.Printf("Failed to set source metadata for file %q: %s. For more info see For more info see https://github.com/gohugoio/hugo/issues/2458", page.FullFilePath(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
if outputDir != "" {
|
||||
if err = page.SaveSourceAs(filepath.Join(outputDir, page.FullFilePath())); err != nil {
|
||||
return fmt.Errorf("Failed to save file %q: %s", page.FullFilePath(), err)
|
||||
}
|
||||
} else {
|
||||
if unsafe {
|
||||
if err = page.SaveSource(); err != nil {
|
||||
return fmt.Errorf("Failed to save file %q: %s", page.FullFilePath(), err)
|
||||
}
|
||||
} else {
|
||||
site.Log.FEEDBACK.Println("Unsafe operation not allowed, use --unsafe or set a different output path")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convertAndSavePage(p *hugolib.Page, site *hugolib.Site, mark rune) error {
|
||||
// The resources are not in .Site.AllPages.
|
||||
for _, r := range p.Resources.ByType("page") {
|
||||
if err := convertAndSavePage(r.(*hugolib.Page), site, mark); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if p.Filename() == "" {
|
||||
// No content file.
|
||||
return nil
|
||||
}
|
||||
|
||||
site.Log.INFO.Println("Attempting to convert", p.LogicalName())
|
||||
newPage, err := site.NewPage(p.LogicalName())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
f, _ := p.File.(src.ReadableFile)
|
||||
file, err := f.Open()
|
||||
if err != nil {
|
||||
site.Log.ERROR.Println("Error reading file:", p.Path())
|
||||
file.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
psr, err := parser.ReadFrom(file)
|
||||
if err != nil {
|
||||
site.Log.ERROR.Println("Error processing file:", p.Path())
|
||||
file.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
file.Close()
|
||||
|
||||
metadata, err := psr.Metadata()
|
||||
if err != nil {
|
||||
site.Log.ERROR.Println("Error processing file:", p.Path())
|
||||
return err
|
||||
}
|
||||
|
||||
// better handling of dates in formats that don't have support for them
|
||||
if mark == parser.FormatToLeadRune("json") || mark == parser.FormatToLeadRune("yaml") || mark == parser.FormatToLeadRune("toml") {
|
||||
newMetadata := cast.ToStringMap(metadata)
|
||||
for k, v := range newMetadata {
|
||||
switch vv := v.(type) {
|
||||
case time.Time:
|
||||
newMetadata[k] = vv.Format(time.RFC3339)
|
||||
}
|
||||
}
|
||||
metadata = newMetadata
|
||||
}
|
||||
|
||||
newPage.SetSourceContent(psr.Content())
|
||||
if err = newPage.SetSourceMetaData(metadata, mark); err != nil {
|
||||
site.Log.ERROR.Printf("Failed to set source metadata for file %q: %s. For more info see For more info see https://github.com/gohugoio/hugo/issues/2458", newPage.FullFilePath(), err)
|
||||
return nil
|
||||
}
|
||||
|
||||
newFilename := p.Filename()
|
||||
if outputDir != "" {
|
||||
newFilename = filepath.Join(outputDir, p.Dir(), newPage.LogicalName())
|
||||
}
|
||||
|
||||
if err = newPage.SaveSourceAs(newFilename); err != nil {
|
||||
return fmt.Errorf("Failed to save file %q: %s", newFilename, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+474
-321
File diff suppressed because it is too large
Load Diff
@@ -144,11 +144,6 @@ func importFromJekyll(cmd *cobra.Command, args []string) error {
|
||||
"$ git clone https://github.com/spf13/herring-cove.git " + args[1] + "/themes/herring-cove")
|
||||
jww.FEEDBACK.Println("$ cd " + args[1] + "\n$ hugo server --theme=herring-cove")
|
||||
|
||||
jww.FEEDBACK.Println("Congratulations!", fileCount, "post(s) imported!")
|
||||
jww.FEEDBACK.Println("Now, start Hugo by yourself:\n" +
|
||||
"$ git clone https://github.com/spf13/herring-cove.git " + args[1] + "/themes/herring-cove")
|
||||
jww.FEEDBACK.Println("$ cd " + args[1] + "\n$ hugo server --theme=herring-cove")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -255,7 +250,7 @@ func loadJekyllConfig(fs afero.Fs, jekyllRoot string) map[string]interface{} {
|
||||
return nil
|
||||
}
|
||||
|
||||
return c.(map[string]interface{})
|
||||
return c
|
||||
}
|
||||
|
||||
func createConfigFromJekyll(fs afero.Fs, inpath string, kind string, jekyllConfig map[string]interface{}) (err error) {
|
||||
@@ -468,7 +463,6 @@ func convertJekyllPost(s *hugolib.Site, path, relPath, targetDir string, draft b
|
||||
return err
|
||||
}
|
||||
|
||||
page.SetDir(targetParentDir)
|
||||
page.SetSourceContent([]byte(content))
|
||||
page.SetSourceMetaData(newmetadata, parser.FormatToLeadRune("yaml"))
|
||||
page.SaveSourceAs(targetFile)
|
||||
@@ -479,8 +473,6 @@ func convertJekyllPost(s *hugolib.Site, path, relPath, targetDir string, draft b
|
||||
}
|
||||
|
||||
func convertJekyllMetaData(m interface{}, postName string, postDate time.Time, draft bool) (interface{}, error) {
|
||||
url := postDate.Format("/2006/01/02/") + postName + "/"
|
||||
|
||||
metadata, err := cast.ToStringMapE(m)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -498,7 +490,7 @@ func convertJekyllMetaData(m interface{}, postName string, postDate time.Time, d
|
||||
delete(metadata, key)
|
||||
case "permalink":
|
||||
if str, ok := value.(string); ok {
|
||||
url = str
|
||||
metadata["url"] = str
|
||||
}
|
||||
delete(metadata, key)
|
||||
case "category":
|
||||
@@ -527,7 +519,6 @@ func convertJekyllMetaData(m interface{}, postName string, postDate time.Time, d
|
||||
|
||||
}
|
||||
|
||||
metadata["url"] = url
|
||||
metadata["date"] = postDate.Format(time.RFC3339)
|
||||
|
||||
return metadata, nil
|
||||
|
||||
@@ -51,9 +51,9 @@ func TestConvertJekyllMetadata(t *testing.T) {
|
||||
expect string
|
||||
}{
|
||||
{map[interface{}]interface{}{}, "testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
|
||||
`{"date":"2015-10-01T00:00:00Z","url":"/2015/10/01/testPost/"}`},
|
||||
`{"date":"2015-10-01T00:00:00Z"}`},
|
||||
{map[interface{}]interface{}{}, "testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), true,
|
||||
`{"date":"2015-10-01T00:00:00Z","draft":true,"url":"/2015/10/01/testPost/"}`},
|
||||
`{"date":"2015-10-01T00:00:00Z","draft":true}`},
|
||||
{map[interface{}]interface{}{"Permalink": "/permalink.html", "layout": "post"},
|
||||
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
|
||||
`{"date":"2015-10-01T00:00:00Z","url":"/permalink.html"}`},
|
||||
@@ -62,13 +62,13 @@ func TestConvertJekyllMetadata(t *testing.T) {
|
||||
`{"date":"2015-10-01T00:00:00Z","url":"/permalink.html"}`},
|
||||
{map[interface{}]interface{}{"category": nil, "permalink": 123},
|
||||
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
|
||||
`{"date":"2015-10-01T00:00:00Z","url":"/2015/10/01/testPost/"}`},
|
||||
`{"date":"2015-10-01T00:00:00Z"}`},
|
||||
{map[interface{}]interface{}{"Excerpt_Separator": "sep"},
|
||||
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
|
||||
`{"date":"2015-10-01T00:00:00Z","excerpt_separator":"sep","url":"/2015/10/01/testPost/"}`},
|
||||
`{"date":"2015-10-01T00:00:00Z","excerpt_separator":"sep"}`},
|
||||
{map[interface{}]interface{}{"category": "book", "layout": "post", "Others": "Goods", "Date": "2015-10-01 12:13:11"},
|
||||
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
|
||||
`{"Others":"Goods","categories":["book"],"date":"2015-10-01T12:13:11Z","url":"/2015/10/01/testPost/"}`},
|
||||
`{"Others":"Goods","categories":["book"],"date":"2015-10-01T12:13:11Z"}`},
|
||||
}
|
||||
|
||||
for _, data := range testDataList {
|
||||
|
||||
+18
-30
@@ -43,20 +43,16 @@ var listDraftsCmd = &cobra.Command{
|
||||
Short: "List all drafts",
|
||||
Long: `List all of the drafts in your content directory.`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
cfg, err := InitializeConfig()
|
||||
cfgInit := func(c *commandeer) error {
|
||||
c.Set("buildDrafts", true)
|
||||
return nil
|
||||
}
|
||||
c, err := InitializeConfig(false, cfgInit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Set("buildDrafts", true)
|
||||
|
||||
sites, err := hugolib.NewHugoSites(*cfg)
|
||||
sites, err := hugolib.NewHugoSites(*c.DepsCfg)
|
||||
|
||||
if err != nil {
|
||||
return newSystemError("Error creating sites", err)
|
||||
@@ -84,20 +80,16 @@ var listFutureCmd = &cobra.Command{
|
||||
Long: `List all of the posts in your content directory which will be
|
||||
posted in the future.`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
cfg, err := InitializeConfig()
|
||||
cfgInit := func(c *commandeer) error {
|
||||
c.Set("buildFuture", true)
|
||||
return nil
|
||||
}
|
||||
c, err := InitializeConfig(false, cfgInit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Set("buildFuture", true)
|
||||
|
||||
sites, err := hugolib.NewHugoSites(*cfg)
|
||||
sites, err := hugolib.NewHugoSites(*c.DepsCfg)
|
||||
|
||||
if err != nil {
|
||||
return newSystemError("Error creating sites", err)
|
||||
@@ -125,20 +117,16 @@ var listExpiredCmd = &cobra.Command{
|
||||
Long: `List all of the posts in your content directory which has already
|
||||
expired.`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
cfg, err := InitializeConfig()
|
||||
cfgInit := func(c *commandeer) error {
|
||||
c.Set("buildExpired", true)
|
||||
return nil
|
||||
}
|
||||
c, err := InitializeConfig(false, cfgInit)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c.Set("buildExpired", true)
|
||||
|
||||
sites, err := hugolib.NewHugoSites(*cfg)
|
||||
sites, err := hugolib.NewHugoSites(*c.DepsCfg)
|
||||
|
||||
if err != nil {
|
||||
return newSystemError("Error creating sites", err)
|
||||
|
||||
@@ -33,7 +33,7 @@ func init() {
|
||||
}
|
||||
|
||||
func printConfig(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig(configCmd)
|
||||
cfg, err := InitializeConfig(false, nil, configCmd)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
+20
-19
@@ -86,21 +86,19 @@ as you see fit.`,
|
||||
|
||||
// NewContent adds new content to a Hugo site.
|
||||
func NewContent(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig()
|
||||
cfgInit := func(c *commandeer) error {
|
||||
if cmd.Flags().Changed("editor") {
|
||||
c.Set("newContentEditor", contentEditor)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
c, err := InitializeConfig(false, cfgInit)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("editor") {
|
||||
c.Set("newContentEditor", contentEditor)
|
||||
}
|
||||
|
||||
if len(args) < 1 {
|
||||
return newUserError("path needs to be provided")
|
||||
}
|
||||
@@ -115,6 +113,8 @@ func NewContent(cmd *cobra.Command, args []string) error {
|
||||
kind = contentType
|
||||
}
|
||||
|
||||
cfg := c.DepsCfg
|
||||
|
||||
ps, err := helpers.NewPathSpec(cfg.Fs, cfg.Cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -130,7 +130,7 @@ func NewContent(cmd *cobra.Command, args []string) error {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := Hugo.Build(hugolib.BuildCfg{SkipRender: true, PrintStats: false}); err != nil {
|
||||
if err := Hugo.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ func NewSite(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// NewTheme creates a new Hugo theme.
|
||||
func NewTheme(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig()
|
||||
c, err := InitializeConfig(false, nil)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -250,14 +250,11 @@ func NewTheme(cmd *cobra.Command, args []string) error {
|
||||
return newUserError("theme name needs to be provided")
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
createpath := c.PathSpec().AbsPathify(filepath.Join(c.Cfg.GetString("themesDir"), args[0]))
|
||||
jww.INFO.Println("creating theme at", createpath)
|
||||
|
||||
cfg := c.DepsCfg
|
||||
|
||||
if x, _ := helpers.Exists(createpath, cfg.Fs.Source); x {
|
||||
return newUserError(createpath, "already exists")
|
||||
}
|
||||
@@ -347,7 +344,7 @@ description = ""
|
||||
homepage = "http://example.com/"
|
||||
tags = []
|
||||
features = []
|
||||
min_version = "0.29"
|
||||
min_version = "0.35"
|
||||
|
||||
[author]
|
||||
name = ""
|
||||
@@ -375,7 +372,11 @@ func newContentPathSection(path string) (string, string) {
|
||||
var section string
|
||||
// assume the first directory is the section (kind)
|
||||
if strings.Contains(createpath[1:], helpers.FilePathSeparator) {
|
||||
section = helpers.GuessSection(createpath)
|
||||
parts := strings.Split(strings.TrimPrefix(createpath, helpers.FilePathSeparator), helpers.FilePathSeparator)
|
||||
if len(parts) > 0 {
|
||||
section = parts[0]
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return createpath, section
|
||||
|
||||
+232
-97
@@ -19,12 +19,18 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/gohugoio/hugo/livereload"
|
||||
|
||||
"github.com/gohugoio/hugo/config"
|
||||
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -41,6 +47,8 @@ var (
|
||||
liveReloadPort int
|
||||
serverWatch bool
|
||||
noHTTPCache bool
|
||||
|
||||
disableFastRender bool
|
||||
)
|
||||
|
||||
var serverCmd = &cobra.Command{
|
||||
@@ -94,6 +102,8 @@ func init() {
|
||||
serverCmd.Flags().BoolVar(&disableLiveReload, "disableLiveReload", false, "watch without enabling live browser reload on rebuild")
|
||||
serverCmd.Flags().BoolVar(&navigateToChanged, "navigateToChanged", false, "navigate to changed content file on live browser reload")
|
||||
serverCmd.Flags().BoolVar(&renderToDisk, "renderToDisk", false, "render to Destination path (default is render to memory & serve from there)")
|
||||
serverCmd.Flags().BoolVar(&disableFastRender, "disableFastRender", false, "enables full re-renders on changes")
|
||||
|
||||
serverCmd.Flags().String("memstats", "", "log memory usage to this file")
|
||||
serverCmd.Flags().String("meminterval", "100ms", "interval to poll memory usage (requires --memstats), valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".")
|
||||
|
||||
@@ -102,79 +112,102 @@ func init() {
|
||||
}
|
||||
|
||||
func server(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig(serverCmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("disableLiveReload") {
|
||||
c.Set("disableLiveReload", disableLiveReload)
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("navigateToChanged") {
|
||||
c.Set("navigateToChanged", navigateToChanged)
|
||||
}
|
||||
|
||||
if serverWatch {
|
||||
c.Set("watch", true)
|
||||
}
|
||||
|
||||
if c.Cfg.GetBool("watch") {
|
||||
serverWatch = true
|
||||
c.watchConfig()
|
||||
}
|
||||
|
||||
l, err := net.Listen("tcp", net.JoinHostPort(serverInterface, strconv.Itoa(serverPort)))
|
||||
if err == nil {
|
||||
l.Close()
|
||||
} else {
|
||||
if serverCmd.Flags().Changed("port") {
|
||||
// port set explicitly by user -- he/she probably meant it!
|
||||
return newSystemErrorF("Server startup failed: %s", err)
|
||||
}
|
||||
jww.ERROR.Println("port", serverPort, "already in use, attempting to use an available port")
|
||||
sp, err := helpers.FindAvailablePort()
|
||||
if err != nil {
|
||||
return newSystemError("Unable to find alternative port to use:", err)
|
||||
}
|
||||
serverPort = sp.Port
|
||||
}
|
||||
|
||||
c.Set("port", serverPort)
|
||||
if liveReloadPort != -1 {
|
||||
c.Set("liveReloadPort", liveReloadPort)
|
||||
} else {
|
||||
c.Set("liveReloadPort", serverPort)
|
||||
}
|
||||
|
||||
baseURL, err = fixURL(c.Cfg, baseURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Set("baseURL", baseURL)
|
||||
|
||||
if err := memStats(); err != nil {
|
||||
jww.ERROR.Println("memstats error:", err)
|
||||
}
|
||||
|
||||
// If a Destination is provided via flag write to disk
|
||||
if destination != "" {
|
||||
renderToDisk = true
|
||||
}
|
||||
|
||||
// Hugo writes the output to memory instead of the disk
|
||||
if !renderToDisk {
|
||||
cfg.Fs.Destination = new(afero.MemMapFs)
|
||||
// Rendering to memoryFS, publish to Root regardless of publishDir.
|
||||
c.Set("publishDir", "/")
|
||||
cfgInit := func(c *commandeer) error {
|
||||
c.Set("renderToMemory", !renderToDisk)
|
||||
if cmd.Flags().Changed("navigateToChanged") {
|
||||
c.Set("navigateToChanged", navigateToChanged)
|
||||
}
|
||||
if cmd.Flags().Changed("disableLiveReload") {
|
||||
c.Set("disableLiveReload", disableLiveReload)
|
||||
}
|
||||
if cmd.Flags().Changed("disableFastRender") {
|
||||
c.Set("disableFastRender", disableFastRender)
|
||||
}
|
||||
if serverWatch {
|
||||
c.Set("watch", true)
|
||||
}
|
||||
|
||||
serverPorts := make([]int, 1)
|
||||
|
||||
if c.languages.IsMultihost() {
|
||||
if !serverAppend {
|
||||
return newSystemError("--appendPort=false not supported when in multihost mode")
|
||||
}
|
||||
serverPorts = make([]int, len(c.languages))
|
||||
}
|
||||
|
||||
currentServerPort := serverPort
|
||||
|
||||
for i := 0; i < len(serverPorts); i++ {
|
||||
l, err := net.Listen("tcp", net.JoinHostPort(serverInterface, strconv.Itoa(currentServerPort)))
|
||||
if err == nil {
|
||||
l.Close()
|
||||
serverPorts[i] = currentServerPort
|
||||
} else {
|
||||
if i == 0 && serverCmd.Flags().Changed("port") {
|
||||
// port set explicitly by user -- he/she probably meant it!
|
||||
return newSystemErrorF("Server startup failed: %s", err)
|
||||
}
|
||||
jww.ERROR.Println("port", serverPort, "already in use, attempting to use an available port")
|
||||
sp, err := helpers.FindAvailablePort()
|
||||
if err != nil {
|
||||
return newSystemError("Unable to find alternative port to use:", err)
|
||||
}
|
||||
serverPorts[i] = sp.Port
|
||||
}
|
||||
|
||||
currentServerPort = serverPorts[i] + 1
|
||||
}
|
||||
|
||||
c.serverPorts = serverPorts
|
||||
|
||||
c.Set("port", serverPort)
|
||||
if liveReloadPort != -1 {
|
||||
c.Set("liveReloadPort", liveReloadPort)
|
||||
} else {
|
||||
c.Set("liveReloadPort", serverPorts[0])
|
||||
}
|
||||
|
||||
isMultiHost := c.languages.IsMultihost()
|
||||
for i, language := range c.languages {
|
||||
var serverPort int
|
||||
if isMultiHost {
|
||||
serverPort = serverPorts[i]
|
||||
} else {
|
||||
serverPort = serverPorts[0]
|
||||
}
|
||||
|
||||
baseURL, err := fixURL(language, baseURL, serverPort)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if isMultiHost {
|
||||
language.Set("baseURL", baseURL)
|
||||
}
|
||||
if i == 0 {
|
||||
c.Set("baseURL", baseURL)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
}
|
||||
|
||||
if err := c.build(serverWatch); err != nil {
|
||||
if err := memStats(); err != nil {
|
||||
jww.ERROR.Println("memstats error:", err)
|
||||
}
|
||||
|
||||
c, err := InitializeConfig(true, cfgInit, serverCmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := c.serverBuild(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -182,75 +215,177 @@ func server(cmd *cobra.Command, args []string) error {
|
||||
s.RegisterMediaTypes()
|
||||
}
|
||||
|
||||
if serverWatch {
|
||||
c.watchConfig()
|
||||
}
|
||||
|
||||
// Watch runs its own server as part of the routine
|
||||
if serverWatch {
|
||||
watchDirs := c.getDirList()
|
||||
baseWatchDir := c.Cfg.GetString("workingDir")
|
||||
for i, dir := range watchDirs {
|
||||
watchDirs[i], _ = helpers.GetRelativePath(dir, baseWatchDir)
|
||||
|
||||
watchDirs, err := c.getDirList()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rootWatchDirs := strings.Join(helpers.UniqueStrings(helpers.ExtractRootPaths(watchDirs)), ",")
|
||||
baseWatchDir := c.Cfg.GetString("workingDir")
|
||||
relWatchDirs := make([]string, len(watchDirs))
|
||||
for i, dir := range watchDirs {
|
||||
relWatchDirs[i], _ = helpers.GetRelativePath(dir, baseWatchDir)
|
||||
}
|
||||
|
||||
rootWatchDirs := strings.Join(helpers.UniqueStrings(helpers.ExtractRootPaths(relWatchDirs)), ",")
|
||||
|
||||
jww.FEEDBACK.Printf("Watching for changes in %s%s{%s}\n", baseWatchDir, helpers.FilePathSeparator, rootWatchDirs)
|
||||
err := c.newWatcher(serverPort)
|
||||
watcher, err := c.newWatcher(watchDirs...)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer watcher.Close()
|
||||
|
||||
}
|
||||
|
||||
c.serve(serverPort)
|
||||
return c.serve()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *commandeer) serve(port int) {
|
||||
if renderToDisk {
|
||||
jww.FEEDBACK.Println("Serving pages from " + c.PathSpec().AbsPathify(c.Cfg.GetString("publishDir")))
|
||||
} else {
|
||||
jww.FEEDBACK.Println("Serving pages from memory")
|
||||
type fileServer struct {
|
||||
baseURLs []string
|
||||
roots []string
|
||||
c *commandeer
|
||||
}
|
||||
|
||||
func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, error) {
|
||||
baseURL := f.baseURLs[i]
|
||||
root := f.roots[i]
|
||||
port := f.c.serverPorts[i]
|
||||
|
||||
publishDir := f.c.Cfg.GetString("publishDir")
|
||||
|
||||
if root != "" {
|
||||
publishDir = filepath.Join(publishDir, root)
|
||||
}
|
||||
|
||||
absPublishDir := f.c.PathSpec().AbsPathify(publishDir)
|
||||
|
||||
if i == 0 {
|
||||
if renderToDisk {
|
||||
jww.FEEDBACK.Println("Serving pages from " + absPublishDir)
|
||||
} else {
|
||||
jww.FEEDBACK.Println("Serving pages from memory")
|
||||
}
|
||||
}
|
||||
|
||||
httpFs := afero.NewHttpFs(f.c.Fs.Destination)
|
||||
fs := filesOnlyFs{httpFs.Dir(absPublishDir)}
|
||||
|
||||
doLiveReload := !buildWatch && !f.c.Cfg.GetBool("disableLiveReload")
|
||||
fastRenderMode := doLiveReload && !f.c.Cfg.GetBool("disableFastRender")
|
||||
|
||||
if i == 0 && fastRenderMode {
|
||||
jww.FEEDBACK.Println("Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender")
|
||||
}
|
||||
|
||||
// We're only interested in the path
|
||||
u, err := url.Parse(baseURL)
|
||||
if err != nil {
|
||||
return nil, "", "", fmt.Errorf("Invalid baseURL: %s", err)
|
||||
}
|
||||
|
||||
httpFs := afero.NewHttpFs(c.Fs.Destination)
|
||||
fs := filesOnlyFs{httpFs.Dir(c.PathSpec().AbsPathify(c.Cfg.GetString("publishDir")))}
|
||||
decorate := func(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if noHTTPCache {
|
||||
w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0")
|
||||
w.Header().Set("Pragma", "no-cache")
|
||||
}
|
||||
|
||||
if fastRenderMode {
|
||||
p := r.RequestURI
|
||||
if strings.HasSuffix(p, "/") || strings.HasSuffix(p, "html") || strings.HasSuffix(p, "htm") {
|
||||
f.c.visitedURLs.Add(p)
|
||||
}
|
||||
}
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
fileserver := decorate(http.FileServer(fs))
|
||||
mu := http.NewServeMux()
|
||||
|
||||
// We're only interested in the path
|
||||
u, err := url.Parse(c.Cfg.GetString("baseURL"))
|
||||
if err != nil {
|
||||
jww.ERROR.Fatalf("Invalid baseURL: %s", err)
|
||||
}
|
||||
if u.Path == "" || u.Path == "/" {
|
||||
http.Handle("/", fileserver)
|
||||
mu.Handle("/", fileserver)
|
||||
} else {
|
||||
http.Handle(u.Path, http.StripPrefix(u.Path, fileserver))
|
||||
mu.Handle(u.Path, http.StripPrefix(u.Path, fileserver))
|
||||
}
|
||||
|
||||
jww.FEEDBACK.Printf("Web Server is available at %s (bind address %s)\n", u.String(), serverInterface)
|
||||
jww.FEEDBACK.Println("Press Ctrl+C to stop")
|
||||
|
||||
endpoint := net.JoinHostPort(serverInterface, strconv.Itoa(port))
|
||||
err = http.ListenAndServe(endpoint, nil)
|
||||
if err != nil {
|
||||
jww.ERROR.Printf("Error: %s\n", err.Error())
|
||||
os.Exit(1)
|
||||
|
||||
return mu, u.String(), endpoint, nil
|
||||
}
|
||||
|
||||
func (c *commandeer) serve() error {
|
||||
|
||||
isMultiHost := Hugo.IsMultihost()
|
||||
|
||||
var (
|
||||
baseURLs []string
|
||||
roots []string
|
||||
)
|
||||
|
||||
if isMultiHost {
|
||||
for _, s := range Hugo.Sites {
|
||||
baseURLs = append(baseURLs, s.BaseURL.String())
|
||||
roots = append(roots, s.Language.Lang)
|
||||
}
|
||||
} else {
|
||||
s := Hugo.Sites[0]
|
||||
baseURLs = []string{s.BaseURL.String()}
|
||||
roots = []string{""}
|
||||
}
|
||||
|
||||
srv := &fileServer{
|
||||
baseURLs: baseURLs,
|
||||
roots: roots,
|
||||
c: c,
|
||||
}
|
||||
|
||||
doLiveReload := !c.Cfg.GetBool("disableLiveReload")
|
||||
|
||||
if doLiveReload {
|
||||
livereload.Initialize()
|
||||
}
|
||||
|
||||
var sigs = make(chan os.Signal)
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||
|
||||
for i, _ := range baseURLs {
|
||||
mu, serverURL, endpoint, err := srv.createEndpoint(i)
|
||||
|
||||
if doLiveReload {
|
||||
mu.HandleFunc("/livereload.js", livereload.ServeJS)
|
||||
mu.HandleFunc("/livereload", livereload.Handler)
|
||||
}
|
||||
jww.FEEDBACK.Printf("Web Server is available at %s (bind address %s)\n", serverURL, serverInterface)
|
||||
go func() {
|
||||
err = http.ListenAndServe(endpoint, mu)
|
||||
if err != nil {
|
||||
jww.ERROR.Printf("Error: %s\n", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
jww.FEEDBACK.Println("Press Ctrl+C to stop")
|
||||
|
||||
<-sigs
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// fixURL massages the baseURL into a form needed for serving
|
||||
// all pages correctly.
|
||||
func fixURL(cfg config.Provider, s string) (string, error) {
|
||||
func fixURL(cfg config.Provider, s string, port int) (string, error) {
|
||||
useLocalhost := false
|
||||
if s == "" {
|
||||
s = cfg.GetString("baseURL")
|
||||
@@ -292,7 +427,7 @@ func fixURL(cfg config.Provider, s string) (string, error) {
|
||||
return "", fmt.Errorf("Failed to split baseURL hostpost: %s", err)
|
||||
}
|
||||
}
|
||||
u.Host += fmt.Sprintf(":%d", serverPort)
|
||||
u.Host += fmt.Sprintf(":%d", port)
|
||||
}
|
||||
|
||||
return u.String(), nil
|
||||
|
||||
@@ -47,7 +47,7 @@ func TestFixURL(t *testing.T) {
|
||||
v.Set("baseURL", test.CfgBaseURL)
|
||||
serverAppend = test.AppendPort
|
||||
serverPort = test.Port
|
||||
result, err := fixURL(v, baseURL)
|
||||
result, err := fixURL(v, baseURL, serverPort)
|
||||
if err != nil {
|
||||
t.Errorf("Test #%d %s: unexpected error %s", i, test.TestName, err)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
// Copyright 2017 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/fsnotify/fsnotify"
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
src "github.com/gohugoio/hugo/source"
|
||||
"github.com/spf13/fsync"
|
||||
)
|
||||
|
||||
type staticSyncer struct {
|
||||
c *commandeer
|
||||
d *src.Dirs
|
||||
}
|
||||
|
||||
func newStaticSyncer(c *commandeer) (*staticSyncer, error) {
|
||||
dirs, err := src.NewDirs(c.Fs, c.Cfg, c.DepsCfg.Logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &staticSyncer{c: c, d: dirs}, nil
|
||||
}
|
||||
|
||||
func (s *staticSyncer) isStatic(path string) bool {
|
||||
return s.d.IsStatic(path)
|
||||
}
|
||||
|
||||
func (s *staticSyncer) syncsStaticEvents(staticEvents []fsnotify.Event) error {
|
||||
c := s.c
|
||||
|
||||
syncFn := func(dirs *src.Dirs, publishDir string) (uint64, error) {
|
||||
staticSourceFs, err := dirs.CreateStaticFs()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if dirs.Language != nil {
|
||||
// Multihost setup
|
||||
publishDir = filepath.Join(publishDir, dirs.Language.Lang)
|
||||
}
|
||||
|
||||
if staticSourceFs == nil {
|
||||
c.Logger.WARN.Println("No static directories found to sync")
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
syncer := fsync.NewSyncer()
|
||||
syncer.NoTimes = c.Cfg.GetBool("noTimes")
|
||||
syncer.NoChmod = c.Cfg.GetBool("noChmod")
|
||||
syncer.SrcFs = staticSourceFs
|
||||
syncer.DestFs = c.Fs.Destination
|
||||
|
||||
// prevent spamming the log on changes
|
||||
logger := helpers.NewDistinctFeedbackLogger()
|
||||
|
||||
for _, ev := range staticEvents {
|
||||
// Due to our approach of layering both directories and the content's rendered output
|
||||
// into one we can't accurately remove a file not in one of the source directories.
|
||||
// If a file is in the local static dir and also in the theme static dir and we remove
|
||||
// it from one of those locations we expect it to still exist in the destination
|
||||
//
|
||||
// If Hugo generates a file (from the content dir) over a static file
|
||||
// the content generated file should take precedence.
|
||||
//
|
||||
// Because we are now watching and handling individual events it is possible that a static
|
||||
// event that occupies the same path as a content generated file will take precedence
|
||||
// until a regeneration of the content takes places.
|
||||
//
|
||||
// Hugo assumes that these cases are very rare and will permit this bad behavior
|
||||
// The alternative is to track every single file and which pipeline rendered it
|
||||
// and then to handle conflict resolution on every event.
|
||||
|
||||
fromPath := ev.Name
|
||||
|
||||
// If we are here we already know the event took place in a static dir
|
||||
relPath := dirs.MakeStaticPathRelative(fromPath)
|
||||
if relPath == "" {
|
||||
// Not member of this virtual host.
|
||||
continue
|
||||
}
|
||||
|
||||
// Remove || rename is harder and will require an assumption.
|
||||
// Hugo takes the following approach:
|
||||
// If the static file exists in any of the static source directories after this event
|
||||
// Hugo will re-sync it.
|
||||
// If it does not exist in all of the static directories Hugo will remove it.
|
||||
//
|
||||
// This assumes that Hugo has not generated content on top of a static file and then removed
|
||||
// the source of that static file. In this case Hugo will incorrectly remove that file
|
||||
// from the published directory.
|
||||
if ev.Op&fsnotify.Rename == fsnotify.Rename || ev.Op&fsnotify.Remove == fsnotify.Remove {
|
||||
if _, err := staticSourceFs.Stat(relPath); os.IsNotExist(err) {
|
||||
// If file doesn't exist in any static dir, remove it
|
||||
toRemove := filepath.Join(publishDir, relPath)
|
||||
|
||||
logger.Println("File no longer exists in static dir, removing", toRemove)
|
||||
_ = c.Fs.Destination.RemoveAll(toRemove)
|
||||
} else if err == nil {
|
||||
// If file still exists, sync it
|
||||
logger.Println("Syncing", relPath, "to", publishDir)
|
||||
|
||||
if err := syncer.Sync(filepath.Join(publishDir, relPath), relPath); err != nil {
|
||||
c.Logger.ERROR.Println(err)
|
||||
}
|
||||
} else {
|
||||
c.Logger.ERROR.Println(err)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// For all other event operations Hugo will sync static.
|
||||
logger.Println("Syncing", relPath, "to", publishDir)
|
||||
if err := syncer.Sync(filepath.Join(publishDir, relPath), relPath); err != nil {
|
||||
c.Logger.ERROR.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
_, err := c.doWithPublishDirs(syncFn)
|
||||
return err
|
||||
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
// Copyright 2015 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 (
|
||||
"bytes"
|
||||
"errors"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/gohugoio/hugo/parser"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var undraftCmd = &cobra.Command{
|
||||
Use: "undraft path/to/content",
|
||||
Short: "Undraft resets the content's draft status",
|
||||
Long: `Undraft resets the content's draft status
|
||||
and updates the date to the current date and time.
|
||||
If the content's draft status is 'False', nothing is done.`,
|
||||
RunE: Undraft,
|
||||
}
|
||||
|
||||
// Undraft publishes the specified content by setting its draft status
|
||||
// to false and setting its publish date to now. If the specified content is
|
||||
// not a draft, it will log an error.
|
||||
func Undraft(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(args) < 1 {
|
||||
return newUserError("a piece of content needs to be specified")
|
||||
}
|
||||
|
||||
location := args[0]
|
||||
// open the file
|
||||
f, err := cfg.Fs.Source.Open(location)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// get the page from file
|
||||
p, err := parser.ReadFrom(f)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w, err := undraftContent(p)
|
||||
if err != nil {
|
||||
return newSystemErrorF("an error occurred while undrafting %q: %s", location, err)
|
||||
}
|
||||
|
||||
f, err = cfg.Fs.Source.OpenFile(location, os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
return newSystemErrorF("%q not be undrafted due to error opening file to save changes: %q\n", location, err)
|
||||
}
|
||||
defer f.Close()
|
||||
_, err = w.WriteTo(f)
|
||||
if err != nil {
|
||||
return newSystemErrorF("%q not be undrafted due to save error: %q\n", location, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// undraftContent: if the content is a draft, change its draft status to
|
||||
// 'false' and set the date to time.Now(). If the draft status is already
|
||||
// 'false', don't do anything.
|
||||
func undraftContent(p parser.Page) (bytes.Buffer, error) {
|
||||
var buff bytes.Buffer
|
||||
// get the metadata; easiest way to see if it's a draft
|
||||
meta, err := p.Metadata()
|
||||
if err != nil {
|
||||
return buff, err
|
||||
}
|
||||
// since the metadata was obtainable, we can also get the key/value separator for
|
||||
// Front Matter
|
||||
fm := p.FrontMatter()
|
||||
if fm == nil {
|
||||
return buff, errors.New("Front Matter was found, nothing was finalized")
|
||||
}
|
||||
|
||||
var isDraft, gotDate bool
|
||||
var date string
|
||||
L:
|
||||
for k, v := range meta.(map[string]interface{}) {
|
||||
switch k {
|
||||
case "draft":
|
||||
if !v.(bool) {
|
||||
return buff, errors.New("not a Draft: nothing was done")
|
||||
}
|
||||
isDraft = true
|
||||
if gotDate {
|
||||
break L
|
||||
}
|
||||
case "date":
|
||||
date = v.(string) // capture the value to make replacement easier
|
||||
gotDate = true
|
||||
if isDraft {
|
||||
break L
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if draft wasn't found in FrontMatter, it isn't a draft.
|
||||
if !isDraft {
|
||||
return buff, errors.New("not a Draft: nothing was done")
|
||||
}
|
||||
|
||||
// get the front matter as bytes and split it into lines
|
||||
var lineEnding []byte
|
||||
fmLines := bytes.Split(fm, []byte("\n"))
|
||||
if len(fmLines) == 1 { // if the result is only 1 element, try to split on dos line endings
|
||||
fmLines = bytes.Split(fm, []byte("\r\n"))
|
||||
if len(fmLines) == 1 {
|
||||
return buff, errors.New("unable to split FrontMatter into lines")
|
||||
}
|
||||
lineEnding = append(lineEnding, []byte("\r\n")...)
|
||||
} else {
|
||||
lineEnding = append(lineEnding, []byte("\n")...)
|
||||
}
|
||||
|
||||
// Write the front matter lines to the buffer, replacing as necessary
|
||||
for _, v := range fmLines {
|
||||
pos := bytes.Index(v, []byte("draft"))
|
||||
if pos != -1 {
|
||||
continue
|
||||
}
|
||||
pos = bytes.Index(v, []byte("date"))
|
||||
if pos != -1 { // if date field wasn't found, add it
|
||||
v = bytes.Replace(v, []byte(date), []byte(time.Now().Format(time.RFC3339)), 1)
|
||||
}
|
||||
buff.Write(v)
|
||||
buff.Write(lineEnding)
|
||||
}
|
||||
|
||||
// append the actual content
|
||||
buff.Write(p.Content())
|
||||
|
||||
return buff, nil
|
||||
}
|
||||
@@ -1,87 +0,0 @@
|
||||
// Copyright 2015 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
|
||||
|
||||
// TODO Support Mac Encoding (\r)
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/gohugoio/hugo/parser"
|
||||
)
|
||||
|
||||
var (
|
||||
jsonFM = "{\n \"date\": \"12-04-06\",\n \"title\": \"test json\"\n}"
|
||||
jsonDraftFM = "{\n \"draft\": true,\n \"date\": \"12-04-06\",\n \"title\":\"test json\"\n}"
|
||||
tomlFM = "+++\n date= \"12-04-06\"\n title= \"test toml\"\n+++"
|
||||
tomlDraftFM = "+++\n draft= true\n date= \"12-04-06\"\n title=\"test toml\"\n+++"
|
||||
yamlFM = "---\n date: \"12-04-06\"\n title: \"test yaml\"\n---"
|
||||
yamlDraftFM = "---\n draft: true\n date: \"12-04-06\"\n title: \"test yaml\"\n---"
|
||||
yamlYesDraftFM = "---\n draft: yes\n date: \"12-04-06\"\n title: \"test yaml\"\n---"
|
||||
)
|
||||
|
||||
func TestUndraftContent(t *testing.T) {
|
||||
tests := []struct {
|
||||
fm string
|
||||
expectedErr string
|
||||
}{
|
||||
{jsonFM, "not a Draft: nothing was done"},
|
||||
{jsonDraftFM, ""},
|
||||
{tomlFM, "not a Draft: nothing was done"},
|
||||
{tomlDraftFM, ""},
|
||||
{yamlFM, "not a Draft: nothing was done"},
|
||||
{yamlDraftFM, ""},
|
||||
{yamlYesDraftFM, ""},
|
||||
}
|
||||
|
||||
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.Errorf("[%d] Expected error, got none", i)
|
||||
continue
|
||||
}
|
||||
if err.Error() != test.expectedErr {
|
||||
t.Errorf("[%d] Expected %q, got %q", i, test.expectedErr, err)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
r = bytes.NewReader(res.Bytes())
|
||||
p, _ = parser.ReadFrom(r)
|
||||
meta, err := p.Metadata()
|
||||
if err != nil {
|
||||
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("[%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("[%d] Expected %v to start with %v", i, v.(string), time.Now().Format("2006-01-02"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,15 +14,11 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gohugoio/hugo/helpers"
|
||||
"github.com/gohugoio/hugo/hugolib"
|
||||
"github.com/kardianos/osext"
|
||||
"github.com/spf13/cobra"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
@@ -38,43 +34,9 @@ var versionCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
func printHugoVersion() {
|
||||
if hugolib.BuildDate == "" {
|
||||
setBuildDate() // set the build date from executable's mdate
|
||||
} else {
|
||||
formatBuildDate() // format the compile time
|
||||
}
|
||||
if hugolib.CommitHash == "" {
|
||||
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.CurrentHugoVersion, strings.ToUpper(hugolib.CommitHash), runtime.GOOS, runtime.GOARCH, hugolib.BuildDate)
|
||||
}
|
||||
}
|
||||
|
||||
// setBuildDate checks the ModTime of the Hugo executable and returns it as a
|
||||
// formatted string. This assumes that the executable name is Hugo, if it does
|
||||
// not exist, an empty string will be returned. This is only called if the
|
||||
// hugolib.BuildDate wasn't set during compile time.
|
||||
//
|
||||
// osext is used for cross-platform.
|
||||
func setBuildDate() {
|
||||
fname, _ := osext.Executable()
|
||||
dir, err := filepath.Abs(filepath.Dir(fname))
|
||||
if err != nil {
|
||||
jww.ERROR.Println(err)
|
||||
return
|
||||
}
|
||||
fi, err := os.Lstat(filepath.Join(dir, filepath.Base(fname)))
|
||||
if err != nil {
|
||||
jww.ERROR.Println(err)
|
||||
return
|
||||
}
|
||||
t := fi.ModTime()
|
||||
hugolib.BuildDate = t.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
// formatBuildDate formats the hugolib.BuildDate according to the value in
|
||||
// .Params.DateFormat, if it's set.
|
||||
func formatBuildDate() {
|
||||
t, _ := time.Parse("2006-01-02T15:04:05-0700", hugolib.BuildDate)
|
||||
hugolib.BuildDate = t.Format(time.RFC3339)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
// 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 types contains types shared between packages in Hugo.
|
||||
package types
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// EvictingStringQueue is a queue which automatically evicts elements from the head of
|
||||
// the queue when attempting to add new elements onto the queue and it is full.
|
||||
// This queue orders elements LIFO (last-in-first-out). It throws away duplicates.
|
||||
// Note: This queue currently does not contain any remove (poll etc.) methods.
|
||||
type EvictingStringQueue struct {
|
||||
size int
|
||||
vals []string
|
||||
set map[string]bool
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
// NewEvictingStringQueue creates a new queue with the given size.
|
||||
func NewEvictingStringQueue(size int) *EvictingStringQueue {
|
||||
return &EvictingStringQueue{size: size, set: make(map[string]bool)}
|
||||
}
|
||||
|
||||
// Add adds a new string to the tail of the queue if it's not already there.
|
||||
func (q *EvictingStringQueue) Add(v string) {
|
||||
q.mu.Lock()
|
||||
if q.set[v] {
|
||||
q.mu.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
if len(q.set) == q.size {
|
||||
// Full
|
||||
delete(q.set, q.vals[0])
|
||||
q.vals = append(q.vals[:0], q.vals[1:]...)
|
||||
}
|
||||
q.set[v] = true
|
||||
q.vals = append(q.vals, v)
|
||||
q.mu.Unlock()
|
||||
}
|
||||
|
||||
// Peek looks at the last element added to the queue.
|
||||
func (q *EvictingStringQueue) Peek() string {
|
||||
q.mu.Lock()
|
||||
l := len(q.vals)
|
||||
if l == 0 {
|
||||
q.mu.Unlock()
|
||||
return ""
|
||||
}
|
||||
elem := q.vals[l-1]
|
||||
q.mu.Unlock()
|
||||
return elem
|
||||
}
|
||||
|
||||
// PeekAll looks at all the elements in the queue, with the newest first.
|
||||
func (q *EvictingStringQueue) PeekAll() []string {
|
||||
q.mu.Lock()
|
||||
vals := make([]string, len(q.vals))
|
||||
copy(vals, q.vals)
|
||||
q.mu.Unlock()
|
||||
for i, j := 0, len(vals)-1; i < j; i, j = i+1, j-1 {
|
||||
vals[i], vals[j] = vals[j], vals[i]
|
||||
}
|
||||
return vals
|
||||
}
|
||||
|
||||
// PeekAllSet returns PeekAll as a set.
|
||||
func (q *EvictingStringQueue) PeekAllSet() map[string]bool {
|
||||
all := q.PeekAll()
|
||||
set := make(map[string]bool)
|
||||
for _, v := range all {
|
||||
set[v] = true
|
||||
}
|
||||
|
||||
return set
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
// 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 types
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestEvictingStringQueue(t *testing.T) {
|
||||
assert := require.New(t)
|
||||
|
||||
queue := NewEvictingStringQueue(3)
|
||||
|
||||
assert.Equal("", queue.Peek())
|
||||
queue.Add("a")
|
||||
queue.Add("b")
|
||||
queue.Add("a")
|
||||
assert.Equal("b", queue.Peek())
|
||||
queue.Add("b")
|
||||
assert.Equal("b", queue.Peek())
|
||||
|
||||
queue.Add("a")
|
||||
queue.Add("b")
|
||||
|
||||
assert.Equal([]string{"b", "a"}, queue.PeekAll())
|
||||
assert.Equal("b", queue.Peek())
|
||||
queue.Add("c")
|
||||
queue.Add("d")
|
||||
// Overflowed, a should now be removed.
|
||||
assert.Equal([]string{"d", "c", "b"}, queue.PeekAll())
|
||||
assert.Len(queue.PeekAllSet(), 3)
|
||||
assert.True(queue.PeekAllSet()["c"])
|
||||
}
|
||||
|
||||
func TestEvictingStringQueueConcurrent(t *testing.T) {
|
||||
var wg sync.WaitGroup
|
||||
val := "someval"
|
||||
|
||||
queue := NewEvictingStringQueue(3)
|
||||
|
||||
for j := 0; j < 100; j++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
queue.Add(val)
|
||||
v := queue.Peek()
|
||||
if v != val {
|
||||
t.Error("wrong val")
|
||||
}
|
||||
vals := queue.PeekAll()
|
||||
if len(vals) != 1 || vals[0] != val {
|
||||
t.Error("wrong val")
|
||||
}
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
@@ -20,6 +20,7 @@ type Provider interface {
|
||||
GetBool(key string) bool
|
||||
GetStringMap(key string) map[string]interface{}
|
||||
GetStringMapString(key string) map[string]string
|
||||
GetStringSlice(key string) []string
|
||||
Get(key string) interface{}
|
||||
Set(key string, value interface{})
|
||||
IsSet(key string) bool
|
||||
|
||||
@@ -16,6 +16,7 @@ package create
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -43,15 +44,21 @@ type ArchetypeFileData struct {
|
||||
// on the presence of language code in the filename.
|
||||
Site *hugolib.Site
|
||||
|
||||
// Name will in most cases be the same as TranslationBaseName, e.g. "my-post".
|
||||
// But if that value is "index" (bundles), the Name is instead the owning folder.
|
||||
// This is the value you in most cases would want to use to construct the title in your
|
||||
// archetype template.
|
||||
Name string
|
||||
|
||||
// The target content file. Note that the .Content will be empty, as that
|
||||
// has not been created yet.
|
||||
*source.File
|
||||
source.File
|
||||
}
|
||||
|
||||
const (
|
||||
// ArchetypeTemplateTemplate is used as initial template when adding an archetype template.
|
||||
ArchetypeTemplateTemplate = `---
|
||||
title: "{{ replace .TranslationBaseName "-" " " | title }}"
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
draft: true
|
||||
---
|
||||
@@ -82,11 +89,19 @@ func executeArcheTypeAsTemplate(s *hugolib.Site, kind, targetPath, archetypeFile
|
||||
)
|
||||
|
||||
sp := source.NewSourceSpec(s.Deps.Cfg, s.Deps.Fs)
|
||||
f := sp.NewFile(targetPath)
|
||||
f := sp.NewFileInfo("", targetPath, false, nil)
|
||||
|
||||
name := f.TranslationBaseName()
|
||||
if name == "index" || name == "_index" {
|
||||
// Page bundles; the directory name will hopefully have a better name.
|
||||
dir := strings.TrimSuffix(f.Dir(), helpers.FilePathSeparator)
|
||||
_, name = filepath.Split(dir)
|
||||
}
|
||||
|
||||
data := ArchetypeFileData{
|
||||
Type: kind,
|
||||
Date: time.Now().Format(time.RFC3339),
|
||||
Name: name,
|
||||
File: f,
|
||||
Site: s,
|
||||
}
|
||||
|
||||
Vendored
+11
-1
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/gohugoio/hugo/hugofs"
|
||||
"github.com/gohugoio/hugo/metrics"
|
||||
"github.com/gohugoio/hugo/output"
|
||||
"github.com/gohugoio/hugo/source"
|
||||
"github.com/gohugoio/hugo/tpl"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
@@ -33,6 +34,9 @@ type Deps struct {
|
||||
// The ContentSpec to use
|
||||
*helpers.ContentSpec `json:"-"`
|
||||
|
||||
// The SourceSpec to use
|
||||
SourceSpec *source.SourceSpec `json:"-"`
|
||||
|
||||
// The configuration to use
|
||||
Cfg config.Provider `json:"-"`
|
||||
|
||||
@@ -122,6 +126,8 @@ func New(cfg DepsCfg) (*Deps, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sp := source.NewSourceSpec(cfg.Language, fs)
|
||||
|
||||
d := &Deps{
|
||||
Fs: fs,
|
||||
Log: logger,
|
||||
@@ -130,12 +136,13 @@ func New(cfg DepsCfg) (*Deps, error) {
|
||||
WithTemplate: cfg.WithTemplate,
|
||||
PathSpec: ps,
|
||||
ContentSpec: contentSpec,
|
||||
SourceSpec: sp,
|
||||
Cfg: cfg.Language,
|
||||
Language: cfg.Language,
|
||||
}
|
||||
|
||||
if cfg.Cfg.GetBool("templateMetrics") {
|
||||
d.Metrics = metrics.NewProvider()
|
||||
d.Metrics = metrics.NewProvider(cfg.Cfg.GetBool("templateMetricsHints"))
|
||||
}
|
||||
|
||||
return d, nil
|
||||
@@ -194,4 +201,7 @@ type DepsCfg struct {
|
||||
|
||||
// i18n handling.
|
||||
TranslationProvider ResourceProvider
|
||||
|
||||
// Whether we are in running (server) mode
|
||||
Running bool
|
||||
}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
/.idea
|
||||
/public
|
||||
nohup.out
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
---
|
||||
title: "{{ replace .TranslationBaseName "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
linktitle: ""
|
||||
description: ""
|
||||
godocref: ""
|
||||
publishdate: ""
|
||||
lastmod: ""
|
||||
categories: []
|
||||
keywords: []
|
||||
tags: []
|
||||
weight: 00
|
||||
slug: ""
|
||||
aliases: []
|
||||
toc: false
|
||||
draft: true
|
||||
---
|
||||
---
|
||||
+3
-2
@@ -71,7 +71,7 @@ twitter = "GoHugoIO"
|
||||
[params]
|
||||
description = "The world’s fastest framework for building websites"
|
||||
## Used for views in rendered HTML (i.e., rather than using the .Hugo variable)
|
||||
release = "0.29"
|
||||
release = "0.35"
|
||||
## Setting this to true will add a "noindex" to *EVERY* page on the site
|
||||
removefromexternalsearch = false
|
||||
## Gh repo for site footer (include trailing slash)
|
||||
@@ -98,7 +98,8 @@ twitter = "GoHugoIO"
|
||||
## Configuration for BlackFriday markdown parser: https://github.com/russross/blackfriday
|
||||
[blackfriday]
|
||||
plainIDAnchors = true
|
||||
hrefTargetBlank = true
|
||||
# See https://github.com/gohugoio/hugo/issues/2424
|
||||
hrefTargetBlank = false
|
||||
angledQuotes = false
|
||||
latexDashes = true
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ toc: true
|
||||
* Support for [Go][], [Amber], and [Ace][] HTML templates
|
||||
* [Syntax highlighting][] powered by [Pygments][]
|
||||
|
||||
See what's coming next in the [Hugo roadmap][].
|
||||
|
||||
[Ace]: /templates/alternatives/
|
||||
[aliases]: /content-management/urls/#aliases
|
||||
@@ -71,7 +70,6 @@ See what's coming next in the [Hugo roadmap][].
|
||||
[Google Analytics]: https://google-analytics.com/
|
||||
[homepage]: /templates/homepage/
|
||||
[hostanywhere]: /hosting-and-deployment/
|
||||
[Hugo roadmap]: /about/roadmap
|
||||
[install]: /getting-started/installing/
|
||||
[LiveReload]: /getting-started/usage/
|
||||
[organization for your projects]: /getting-started/directory-structure/
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
---
|
||||
title: Hugo 0.32 HOWTO
|
||||
description: About page bundles, image processing and more.
|
||||
date: 2017-12-28
|
||||
keywords: [ssg,static,performance,security]
|
||||
menu:
|
||||
docs:
|
||||
parent: "about"
|
||||
weight: 10
|
||||
weight: 10
|
||||
sections_weight: 10
|
||||
draft: false
|
||||
aliases: []
|
||||
toc: true
|
||||
images:
|
||||
- images/blog/sunset.jpg
|
||||
---
|
||||
|
||||
|
||||
{{% note %}}
|
||||
This documentation belongs in other places in this documentation site, but is put here first ... to get something up and running fast.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
Also see this demo project from [bep](https://github.com/bep/), the clever Norwegian behind these new features:
|
||||
|
||||
* http://hugotest.bep.is/
|
||||
* https://github.com/bep/hugotest (source)
|
||||
|
||||
## Page Resources
|
||||
|
||||
### Organize Your Content
|
||||
|
||||
{{< figure src="/images/hugo-content-bundles.png" title="Pages with image resources" >}}
|
||||
|
||||
The content folder above shows a mix of content pages (`md` (i.e. markdown) files) and image resources.
|
||||
|
||||
{{% note %}}
|
||||
You can use any file type as a content resource as long as it is a MIME type recognized by Hugo (`json` files will, as one example, work fine). If you want to get exotic, you can define your [own media type](/templates/output-formats/#media-types).
|
||||
{{% /note %}}
|
||||
|
||||
The 3 page bundles marked in red explained from top to bottom:
|
||||
|
||||
1. The home page with one image resource (`1-logo.png`)
|
||||
2. The blog section with two images resources and two pages resources (`content1.md`, `content2.md`). Note that the `_index.md` represents the URL for this section.
|
||||
3. An article (`hugo-is-cool`) with a folder with some images and one content resource (`cats-info.md`). Note that the `index.md` represents the URL for this article.
|
||||
|
||||
The content files below `blog/posts` are just regular standalone pages.
|
||||
|
||||
{{% note %}}
|
||||
Note that changes to any resource inside the `content` folder will trigger a reload when running in watch (aka server or live reload mode), it will even work with `--navigateToChanged`.
|
||||
{{% /note %}}
|
||||
|
||||
#### Sort Order
|
||||
|
||||
* Pages are sorted according to standard Hugo page sorting rules.
|
||||
* Images and other resources are sorted in lexicographical order.
|
||||
|
||||
### Handle Page Resources in Templates
|
||||
|
||||
|
||||
#### List all Resources
|
||||
|
||||
```html
|
||||
{{ range .Resources }}
|
||||
<li><a href="{{ .RelPermalink }}">{{ .ResourceType | title }}</a></li>
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
For an absolute URL, use `.Permalink`.
|
||||
|
||||
**Note:** The permalink will be relative to the content page, respecting permalink settings. Also, included page resources will not have a value for `RelPermalink`.
|
||||
|
||||
#### List All Resources by Type
|
||||
|
||||
```html
|
||||
{{ with .Resources.ByType "image" }}
|
||||
{{ end }}
|
||||
|
||||
```
|
||||
|
||||
Type here is `page` for pages, else the main type in the MIME type, so `image`, `json` etc.
|
||||
|
||||
#### Get a Specific Resource
|
||||
|
||||
```html
|
||||
{{ $logo := .Resources.GetByPrefix "logo" }}
|
||||
{{ with $logo }}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
#### Include Page Resource Content
|
||||
|
||||
```html
|
||||
{{ with .Resources.ByType "page" }}
|
||||
{{ range . }}
|
||||
<h3>{{ .Title }}</h3>
|
||||
{{ .Content }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Image Processing
|
||||
|
||||
The `image` resource implements the methods `Resize`, `Fit` and `Fill`:
|
||||
|
||||
Resize
|
||||
: Resize to the given dimension, `{{ $logo.Resize "200x" }}` will resize to 200 pixels wide and preserve the aspect ratio. Use `{{ $logo.Resize "200x100" }}` to control both height and width.
|
||||
|
||||
Fit
|
||||
: Scale down the image to fit the given dimensions, e.g. `{{ $logo.Fit "200x100" }}` will fit the image inside a box that is 200 pixels wide and 100 pixels high.
|
||||
|
||||
Fill
|
||||
: Resize and crop the image given dimensions, e.g. `{{ $logo.Fill "200x100" }}` will resize and crop to width 200 and height 100
|
||||
|
||||
|
||||
{{% note %}}
|
||||
Image operations in Hugo currently **do not preserve EXIF data** as this is not supported by Go's [image package](https://github.com/golang/go/search?q=exif&type=Issues&utf8=%E2%9C%93). This will be improved on in the future.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
### Image Processing Examples
|
||||
|
||||
_The photo of the sunset used in the examples below is Copyright [Bjørn Erik Pedersen](https://commons.wikimedia.org/wiki/User:Bep) (Creative Commons Attribution-Share Alike 4.0 International license)_
|
||||
|
||||
|
||||
{{< imgproc sunset Resize "300x" />}}
|
||||
|
||||
{{< imgproc sunset Fill "90x120 left" />}}
|
||||
|
||||
{{< imgproc sunset Fill "90x120 right" />}}
|
||||
|
||||
{{< imgproc sunset Fit "90x90" />}}
|
||||
|
||||
{{< imgproc sunset Resize "300x q10" />}}
|
||||
|
||||
|
||||
This is the shortcode used in the examples above:
|
||||
|
||||
|
||||
{{< code file="layouts/shortcodes/imgproc.html" >}}
|
||||
{{< readfile file="layouts/shortcodes/imgproc.html" >}}
|
||||
{{< /code >}}
|
||||
|
||||
And it is used like this:
|
||||
|
||||
```html
|
||||
{{</* imgproc sunset Resize "300x" */>}}
|
||||
```
|
||||
|
||||
### Image Processing Options
|
||||
|
||||
In addition to the dimensions (e.g. `200x100`) where either height or width can be omitted, Hugo supports a set of additional image options:
|
||||
|
||||
Anchor
|
||||
: Only relevant for `Fill`. This is useful for thumbnail generation where the main motive is located in, say, the left corner. Valid are `Center`, `TopLeft`, `Top`, `TopRight`, `Left`, `Right`, `BottomLeft`, `Bottom`, `BottomRight`. Example: `{{ $logo.Fill "200x100 BottomLeft" }}`
|
||||
|
||||
JPEG Quality
|
||||
: Only relevant for JPEG images, values 1 to 100 inclusive, higher is better. Default is 75. `{{ $logo.Resize "200x q50" }}`
|
||||
|
||||
Rotate
|
||||
: Rotates an image by the given angle counter-clockwise. The rotation will be performed first to get the dimensions correct. `{{ $logo.Resize "200x r90" }}`. The main use of this is to be able to manually correct for [EXIF orientation](https://github.com/golang/go/issues/4341) of JPEG images.
|
||||
|
||||
Resample Filter
|
||||
: Filter used in resizing. Default is `Box`, a simple and fast resampling filter appropriate for downscaling. See https://github.com/disintegration/imaging for more. If you want to trade quality for faster processing, this may be a option to test.
|
||||
|
||||
|
||||
|
||||
### Performance
|
||||
|
||||
Processed images are stored below `<project-dir>/resources` (can be set with `resourceDir` config setting). This folder is deliberately placed in the project, as it is recommended to check these into source control as part of the project. These images are not "Hugo fast" to generate, but once generated they can be reused.
|
||||
|
||||
If you change your image settings (e.g. size), remove or rename images etc., you will end up with unused images taking up space and cluttering your project.
|
||||
|
||||
To clean up, run:
|
||||
|
||||
```bash
|
||||
hugo --gc
|
||||
```
|
||||
|
||||
|
||||
{{% note %}}
|
||||
**GC** is short for **Garbage Collection**.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
### Default Image Processing Config
|
||||
|
||||
You can configure an `imaging` section in `config.toml` with default image processing options:
|
||||
|
||||
```toml
|
||||
[imaging]
|
||||
# Default resample filter used for resizing. Default is Box,
|
||||
# a simple and fast averaging filter appropriate for downscaling.
|
||||
# See https://github.com/disintegration/imaging
|
||||
resampleFilter = "box"
|
||||
|
||||
# Defatult JPEG quality setting. Default is 75.
|
||||
quality = 68
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 88 KiB |
@@ -1,51 +0,0 @@
|
||||
---
|
||||
title: Roadmap
|
||||
linktitle: Roadmap
|
||||
description: Take a look at what's in the pipeline for future versions of the Hugo project.
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
lastmod: 2017-02-01
|
||||
categories: [about hugo]
|
||||
keywords: [about,contribute,roadmap]
|
||||
menu:
|
||||
docs:
|
||||
parent: "about"
|
||||
weight: 50
|
||||
weight: 50
|
||||
sections_weight: 50
|
||||
draft: false
|
||||
aliases: [/meta/roadmap]
|
||||
toc: false
|
||||
---
|
||||
|
||||
To track Hugo's progress, see our [GitHub Milestones][milestones].
|
||||
|
||||
In no particular order, here are some other features currently being worked on:
|
||||
|
||||
* Even easier deployment to S3, SSH, GitHub, rsync. Give the [hosting and deployment][] section a shot.
|
||||
* Import from other website systems. There are already [existing migration tools][migrate], but they don’t cover all major platforms.
|
||||
* An interactive web-based editor (See the [related forum thread][])
|
||||
* Additional [themes][], which are always ongoing and [contributions are welcome][themescontrib]!
|
||||
* Dynamic image resizing via shortcodes ({{< gh 1014 >}})
|
||||
* Native support for additional content formats (AsciiDoc {{< gh 1435>}}, reST {{< gh 1436 >}})
|
||||
* And, last but not least, [***your*** best ideas!][]
|
||||
|
||||
## Contributions Welcome
|
||||
|
||||
Feel free to [contribute to Hugo's development][devcontribute], [improve Hugo's documentation][doccontribute], or [open a new issue][newissue] if you have an idea for a new feature.
|
||||
|
||||
[#98]: https://github.com/gohugoio/hugo/issues/98
|
||||
[#1014]: https://github.com/gohugoio/hugo/issues/1014
|
||||
[#1435]: https://github.com/gohugoio/hugo/issues/1435
|
||||
[#1436]: https://github.com/gohugoio/hugo/issues/1436
|
||||
[devcontribute]: /contribute/development/
|
||||
[doccontribute]: /contribute/documentation/
|
||||
[hosting and deployment]: /hosting-and-deployment/
|
||||
[migrate]: /tools/migrations/
|
||||
[milestones]: https://github.com/gohugoio/hugo/milestones/
|
||||
[newissue]: https://github.com/gohugoio/hugo/issues/
|
||||
[related forum thread]: https://discourse.gohugo.io/t/web-based-editor/155
|
||||
[themes]: /themes/
|
||||
[themescontrib]: /contribute/themes/
|
||||
[tutorials]: /tutorials
|
||||
[***your*** best ideas!]: /contribute/
|
||||
@@ -19,7 +19,7 @@ toc: true
|
||||
|
||||
Hugo is a general-purpose website framework. Technically speaking, Hugo is a [static site generator][]. Unlike systems that dynamically build a page with each visitor request, Hugo builds pages when you create or update your content. Since websites are viewed far more often than they are edited, Hugo is designed to provide an optimal viewing experience for your website's end users and an ideal writing experience for website authors.
|
||||
|
||||
Websites built with Hugo are extremely fast and secure. Hugo sites can be hosted anywhere, including [Netlify][], [Heroku][], [GoDaddy][], [DreamHost][], [GitHub Pages][], [Surge][], [Aerobatic][], [Firebase][], [Google Cloud Storage][], [Amazon S3][], [Rackspace][], [Azure][], and [CloudFront][] and work well with CDNs. Hugo sites run without the need for a database or dependencies on expensive runtimes like Ruby, Python, or PHP.
|
||||
Websites built with Hugo are extremely fast and secure. Hugo sites can be hosted anywhere, including [Netlify][], [Heroku][], [GoDaddy][], [DreamHost][], [GitHub Pages][], [GitLab Pages][], [Surge][], [Aerobatic][], [Firebase][], [Google Cloud Storage][], [Amazon S3][], [Rackspace][], [Azure][], and [CloudFront][] and work well with CDNs. Hugo sites run without the need for a database or dependencies on expensive runtimes like Ruby, Python, or PHP.
|
||||
|
||||
We think of Hugo as the ideal website creation tool with nearly instant build times, able to rebuild whenever a change is made.
|
||||
|
||||
@@ -50,7 +50,7 @@ Hugo is for people building a blog, a company site, a portfolio site, documentat
|
||||
[DreamHost]: http://www.dreamhost.com/
|
||||
[Firebase]: https://firebase.google.com/docs/hosting/ "Firebase static hosting"
|
||||
[GitHub Pages]: https://pages.github.com/
|
||||
[GitLab]: https://about.gitlab.com
|
||||
[GitLab Pages]: https://about.gitlab.com/features/pages/
|
||||
[Go language]: https://golang.org/
|
||||
[GoDaddy]: https://www.godaddy.com/ "Godaddy.com Hosting"
|
||||
[Google Cloud Storage]: http://cloud.google.com/storage/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo"
|
||||
slug: hugo
|
||||
url: /commands/hugo/
|
||||
@@ -10,7 +10,6 @@ hugo builds your site
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
hugo is the main command, used to build your Hugo site.
|
||||
|
||||
Hugo is a Fast and Flexible Static Site Generator
|
||||
@@ -30,18 +29,16 @@ hugo [flags]
|
||||
-E, --buildExpired include expired content
|
||||
-F, --buildFuture include content with publishdate in the future
|
||||
--cacheDir string filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--canonifyURLs (deprecated) if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir remove files from destination not found in static directories
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
--debug debug output
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 do not render 404 page
|
||||
--disableKinds stringSlice disable different kind of pages (home, RSS etc.)
|
||||
--disableRSS do not build RSS files
|
||||
--disableSitemap do not build Sitemap file
|
||||
--enableGitInfo add Git revision, date and author info to the pages
|
||||
--forceSyncStatic copy all files when static is changed.
|
||||
--gc enable to run some cleanup tasks (remove unused cache files) after the build
|
||||
-h, --help help for hugo
|
||||
--i18n-warnings print missing translations
|
||||
--ignoreCache ignores the cache directory
|
||||
@@ -50,21 +47,24 @@ hugo [flags]
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--noChmod don't sync permission mode of files
|
||||
--noTimes don't sync modification time of files
|
||||
--pluralizeListTitles pluralize titles in lists using inflect (default true)
|
||||
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--pluralizeListTitles (deprecated) pluralize titles in lists using inflect (default true)
|
||||
--preserveTaxonomyNames (deprecated) preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--quiet build in quiet mode
|
||||
--renderToMemory render to memory (only useful for benchmark testing)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
--templateMetrics display metrics about template executions
|
||||
--templateMetricsHints calculate some improvement hints when combined with --templateMetrics
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--themesDir string filesystem path to themes directory
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
--uglyURLs (deprecated) if true, use /filename.html instead of /filename/
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
-w, --watch watch filesystem for changes and recreate as needed
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo benchmark](/commands/hugo_benchmark/) - Benchmark Hugo by building a site a number of times.
|
||||
* [hugo check](/commands/hugo_check/) - Contains some verification checks
|
||||
* [hugo config](/commands/hugo_config/) - Print the site configuration
|
||||
@@ -75,7 +75,6 @@ hugo [flags]
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
* [hugo new](/commands/hugo_new/) - Create new content for your site
|
||||
* [hugo server](/commands/hugo_server/) - A high performance webserver
|
||||
* [hugo undraft](/commands/hugo_undraft/) - Undraft resets the content's draft status
|
||||
* [hugo version](/commands/hugo_version/) - Print the version number of Hugo
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo benchmark"
|
||||
slug: hugo_benchmark
|
||||
url: /commands/hugo_benchmark/
|
||||
@@ -10,7 +10,6 @@ Benchmark Hugo by building a site a number of times.
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Hugo can build a site many times over and analyze the running process
|
||||
creating a benchmark.
|
||||
|
||||
@@ -26,18 +25,16 @@ hugo benchmark [flags]
|
||||
-E, --buildExpired include expired content
|
||||
-F, --buildFuture include content with publishdate in the future
|
||||
--cacheDir string filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--canonifyURLs (deprecated) if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir remove files from destination not found in static directories
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
-n, --count int number of times to build the site (default 13)
|
||||
--cpuprofile string path/filename for the CPU profile file
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 do not render 404 page
|
||||
--disableKinds stringSlice disable different kind of pages (home, RSS etc.)
|
||||
--disableRSS do not build RSS files
|
||||
--disableSitemap do not build Sitemap file
|
||||
--enableGitInfo add Git revision, date and author info to the pages
|
||||
--forceSyncStatic copy all files when static is changed.
|
||||
--gc enable to run some cleanup tasks (remove unused cache files) after the build
|
||||
-h, --help help for benchmark
|
||||
--i18n-warnings print missing translations
|
||||
--ignoreCache ignores the cache directory
|
||||
@@ -45,14 +42,16 @@ hugo benchmark [flags]
|
||||
--memprofile string path/filename for the memory profile file
|
||||
--noChmod don't sync permission mode of files
|
||||
--noTimes don't sync modification time of files
|
||||
--pluralizeListTitles pluralize titles in lists using inflect (default true)
|
||||
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--pluralizeListTitles (deprecated) pluralize titles in lists using inflect (default true)
|
||||
--preserveTaxonomyNames (deprecated) preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--renderToMemory render to memory (only useful for benchmark testing)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
--templateMetrics display metrics about template executions
|
||||
--templateMetricsHints calculate some improvement hints when combined with --templateMetrics
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--themesDir string filesystem path to themes directory
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
--uglyURLs (deprecated) if true, use /filename.html instead of /filename/
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
@@ -68,6 +67,7 @@ hugo benchmark [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo check"
|
||||
slug: hugo_check
|
||||
url: /commands/hugo_check/
|
||||
@@ -10,7 +10,6 @@ Contains some verification checks
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Contains some verification checks
|
||||
|
||||
### Options
|
||||
@@ -32,7 +31,8 @@ Contains some verification checks
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo check ulimit](/commands/hugo_check_ulimit/) - Check system ulimit settings
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo check ulimit"
|
||||
slug: hugo_check_ulimit
|
||||
url: /commands/hugo_check_ulimit/
|
||||
@@ -10,7 +10,6 @@ Check system ulimit settings
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Hugo will inspect the current ulimit settings on the system.
|
||||
This is primarily to ensure that Hugo can watch enough files on some OSs
|
||||
|
||||
@@ -37,6 +36,7 @@ hugo check ulimit [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo check](/commands/hugo_check/) - Contains some verification checks
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo config"
|
||||
slug: hugo_config
|
||||
url: /commands/hugo_config/
|
||||
@@ -10,7 +10,6 @@ Print the site configuration
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Print the site configuration, both default and custom settings.
|
||||
|
||||
```
|
||||
@@ -36,6 +35,7 @@ hugo config [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo convert"
|
||||
slug: hugo_convert
|
||||
url: /commands/hugo_convert/
|
||||
@@ -10,7 +10,6 @@ Convert your content to different formats
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Convert your content (e.g. front matter) to different formats.
|
||||
|
||||
See convert's subcommands toJSON, toTOML and toYAML for more information.
|
||||
@@ -37,9 +36,10 @@ See convert's subcommands toJSON, toTOML and toYAML for more information.
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo convert toJSON](/commands/hugo_convert_tojson/) - Convert front matter to JSON
|
||||
* [hugo convert toTOML](/commands/hugo_convert_totoml/) - Convert front matter to TOML
|
||||
* [hugo convert toYAML](/commands/hugo_convert_toyaml/) - Convert front matter to YAML
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo convert toJSON"
|
||||
slug: hugo_convert_toJSON
|
||||
url: /commands/hugo_convert_tojson/
|
||||
@@ -10,7 +10,6 @@ Convert front matter to JSON
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
toJSON converts all front matter in the content directory
|
||||
to use JSON for the front matter.
|
||||
|
||||
@@ -40,6 +39,7 @@ hugo convert toJSON [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo convert toTOML"
|
||||
slug: hugo_convert_toTOML
|
||||
url: /commands/hugo_convert_totoml/
|
||||
@@ -10,7 +10,6 @@ Convert front matter to TOML
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
toTOML converts all front matter in the content directory
|
||||
to use TOML for the front matter.
|
||||
|
||||
@@ -40,6 +39,7 @@ hugo convert toTOML [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo convert toYAML"
|
||||
slug: hugo_convert_toYAML
|
||||
url: /commands/hugo_convert_toyaml/
|
||||
@@ -10,7 +10,6 @@ Convert front matter to YAML
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
toYAML converts all front matter in the content directory
|
||||
to use YAML for the front matter.
|
||||
|
||||
@@ -40,6 +39,7 @@ hugo convert toYAML [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo env"
|
||||
slug: hugo_env
|
||||
url: /commands/hugo_env/
|
||||
@@ -10,7 +10,6 @@ Print Hugo version and environment info
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Print Hugo version and environment info. This is useful in Hugo bug reports.
|
||||
|
||||
```
|
||||
@@ -36,6 +35,7 @@ hugo env [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo gen"
|
||||
slug: hugo_gen
|
||||
url: /commands/hugo_gen/
|
||||
@@ -10,7 +10,6 @@ A collection of several useful generators.
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
A collection of several useful generators.
|
||||
|
||||
### Options
|
||||
@@ -32,10 +31,11 @@ A collection of several useful generators.
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo gen autocomplete](/commands/hugo_gen_autocomplete/) - Generate shell autocompletion script for Hugo
|
||||
* [hugo gen chromastyles](/commands/hugo_gen_chromastyles/) - Generate CSS stylesheet for the Chroma code highlighter
|
||||
* [hugo gen doc](/commands/hugo_gen_doc/) - Generate Markdown documentation for the Hugo CLI.
|
||||
* [hugo gen man](/commands/hugo_gen_man/) - Generate man pages for the Hugo CLI
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo gen autocomplete"
|
||||
slug: hugo_gen_autocomplete
|
||||
url: /commands/hugo_gen_autocomplete/
|
||||
@@ -10,7 +10,6 @@ Generate shell autocompletion script for Hugo
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Generates a shell autocompletion script for Hugo.
|
||||
|
||||
NOTE: The current version supports Bash only.
|
||||
@@ -54,6 +53,7 @@ hugo gen autocomplete [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo gen chromastyles"
|
||||
slug: hugo_gen_chromastyles
|
||||
url: /commands/hugo_gen_chromastyles/
|
||||
@@ -10,7 +10,6 @@ Generate CSS stylesheet for the Chroma code highlighter
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Generate CSS stylesheet for the Chroma code highlighter for a given style. This stylesheet is needed if pygmentsUseClasses is enabled in config.
|
||||
|
||||
See https://help.farbox.com/pygments.html for preview of available styles
|
||||
@@ -41,6 +40,7 @@ hugo gen chromastyles [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo gen doc"
|
||||
slug: hugo_gen_doc
|
||||
url: /commands/hugo_gen_doc/
|
||||
@@ -10,7 +10,6 @@ Generate Markdown documentation for the Hugo CLI.
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Generate Markdown documentation for the Hugo CLI.
|
||||
|
||||
This command is, mostly, used to create up-to-date documentation
|
||||
@@ -43,6 +42,7 @@ hugo gen doc [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo gen man"
|
||||
slug: hugo_gen_man
|
||||
url: /commands/hugo_gen_man/
|
||||
@@ -10,7 +10,6 @@ Generate man pages for the Hugo CLI
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
This command automatically generates up-to-date man pages of Hugo's
|
||||
command-line interface. By default, it creates the man page files
|
||||
in the "man" directory under the current directory.
|
||||
@@ -39,6 +38,7 @@ hugo gen man [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo import"
|
||||
slug: hugo_import
|
||||
url: /commands/hugo_import/
|
||||
@@ -10,7 +10,6 @@ Import your site from others.
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Import your site from other web site generators like Jekyll.
|
||||
|
||||
Import requires a subcommand, e.g. `hugo import jekyll jekyll_root_path target_path`.
|
||||
@@ -34,7 +33,8 @@ Import requires a subcommand, e.g. `hugo import jekyll jekyll_root_path target_p
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo import jekyll](/commands/hugo_import_jekyll/) - hugo import from Jekyll
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo import jekyll"
|
||||
slug: hugo_import_jekyll
|
||||
url: /commands/hugo_import_jekyll/
|
||||
@@ -10,7 +10,6 @@ hugo import from Jekyll
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
hugo import from Jekyll.
|
||||
|
||||
Import from Jekyll requires two paths, e.g. `hugo import jekyll jekyll_root_path target_path`.
|
||||
@@ -39,6 +38,7 @@ hugo import jekyll [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo import](/commands/hugo_import/) - Import your site from others.
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo list"
|
||||
slug: hugo_list
|
||||
url: /commands/hugo_list/
|
||||
@@ -10,7 +10,6 @@ Listing out various types of content
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Listing out various types of content.
|
||||
|
||||
List requires a subcommand, e.g. `hugo list drafts`.
|
||||
@@ -35,9 +34,10 @@ List requires a subcommand, e.g. `hugo list drafts`.
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo list drafts](/commands/hugo_list_drafts/) - List all drafts
|
||||
* [hugo list expired](/commands/hugo_list_expired/) - List all posts already expired
|
||||
* [hugo list future](/commands/hugo_list_future/) - List all posts dated in the future
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo list drafts"
|
||||
slug: hugo_list_drafts
|
||||
url: /commands/hugo_list_drafts/
|
||||
@@ -10,7 +10,6 @@ List all drafts
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
List all of the drafts in your content directory.
|
||||
|
||||
```
|
||||
@@ -37,6 +36,7 @@ hugo list drafts [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo list expired"
|
||||
slug: hugo_list_expired
|
||||
url: /commands/hugo_list_expired/
|
||||
@@ -10,7 +10,6 @@ List all posts already expired
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
List all of the posts in your content directory which has already
|
||||
expired.
|
||||
|
||||
@@ -38,6 +37,7 @@ hugo list expired [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo list future"
|
||||
slug: hugo_list_future
|
||||
url: /commands/hugo_list_future/
|
||||
@@ -10,7 +10,6 @@ List all posts dated in the future
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
List all of the posts in your content directory which will be
|
||||
posted in the future.
|
||||
|
||||
@@ -38,6 +37,7 @@ hugo list future [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo new"
|
||||
slug: hugo_new
|
||||
url: /commands/hugo_new/
|
||||
@@ -10,7 +10,6 @@ Create new content for your site
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Create a new content file and automatically set the date and title.
|
||||
It will guess which kind of file to create based on the path provided.
|
||||
|
||||
@@ -44,8 +43,9 @@ hugo new [path] [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo new site](/commands/hugo_new_site/) - Create a new site (skeleton)
|
||||
* [hugo new theme](/commands/hugo_new_theme/) - Create a new theme
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo new site"
|
||||
slug: hugo_new_site
|
||||
url: /commands/hugo_new_site/
|
||||
@@ -10,7 +10,6 @@ Create a new site (skeleton)
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Create a new site in the provided directory.
|
||||
The new site will have the correct structure, but no content or theme yet.
|
||||
Use `hugo new [contentPath]` to create new content.
|
||||
@@ -41,6 +40,7 @@ hugo new site [path] [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo new](/commands/hugo_new/) - Create new content for your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo new theme"
|
||||
slug: hugo_new_theme
|
||||
url: /commands/hugo_new_theme/
|
||||
@@ -10,7 +10,6 @@ Create a new theme
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Create a new theme (skeleton) called [name] in the current directory.
|
||||
New theme is a skeleton. Please add content to the touched files. Add your
|
||||
name to the copyright line in the license and adjust the theme.toml file
|
||||
@@ -40,6 +39,7 @@ hugo new theme [name] [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo new](/commands/hugo_new/) - Create new content for your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo server"
|
||||
slug: hugo_server
|
||||
url: /commands/hugo_server/
|
||||
@@ -10,7 +10,6 @@ A high performance webserver
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Hugo provides its own webserver which builds and serves the site.
|
||||
While hugo server is high performance, it is a webserver with limited options.
|
||||
Many run it in production, but the standard behavior is for people to use it
|
||||
@@ -38,17 +37,16 @@ hugo server [flags]
|
||||
-E, --buildExpired include expired content
|
||||
-F, --buildFuture include content with publishdate in the future
|
||||
--cacheDir string filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--canonifyURLs (deprecated) if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir remove files from destination not found in static directories
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 do not render 404 page
|
||||
--disableFastRender enables full re-renders on changes
|
||||
--disableKinds stringSlice disable different kind of pages (home, RSS etc.)
|
||||
--disableLiveReload watch without enabling live browser reload on rebuild
|
||||
--disableRSS do not build RSS files
|
||||
--disableSitemap do not build Sitemap file
|
||||
--enableGitInfo add Git revision, date and author info to the pages
|
||||
--forceSyncStatic copy all files when static is changed.
|
||||
--gc enable to run some cleanup tasks (remove unused cache files) after the build
|
||||
-h, --help help for server
|
||||
--i18n-warnings print missing translations
|
||||
--ignoreCache ignores the cache directory
|
||||
@@ -58,17 +56,19 @@ hugo server [flags]
|
||||
--memstats string log memory usage to this file
|
||||
--navigateToChanged navigate to changed content file on live browser reload
|
||||
--noChmod don't sync permission mode of files
|
||||
--noHTTPCache prevent HTTP caching (default true)
|
||||
--noHTTPCache prevent HTTP caching
|
||||
--noTimes don't sync modification time of files
|
||||
--pluralizeListTitles pluralize titles in lists using inflect (default true)
|
||||
--pluralizeListTitles (deprecated) pluralize titles in lists using inflect (default true)
|
||||
-p, --port int port on which the server will listen (default 1313)
|
||||
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--preserveTaxonomyNames (deprecated) preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--renderToDisk render to Destination path (default is render to memory & serve from there)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
--templateMetrics display metrics about template executions
|
||||
--templateMetricsHints calculate some improvement hints when combined with --templateMetrics
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--themesDir string filesystem path to themes directory
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
--uglyURLs (deprecated) if true, use /filename.html instead of /filename/
|
||||
-w, --watch watch filesystem for changes and recreate as needed (default true)
|
||||
```
|
||||
|
||||
@@ -85,6 +85,7 @@ hugo server [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
title: "hugo undraft"
|
||||
slug: hugo_undraft
|
||||
url: /commands/hugo_undraft/
|
||||
---
|
||||
## hugo undraft
|
||||
|
||||
Undraft resets the content's draft status
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Undraft resets the content's draft status
|
||||
and updates the date to the current date and time.
|
||||
If the content's draft status is 'False', nothing is done.
|
||||
|
||||
```
|
||||
hugo undraft path/to/content [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for undraft
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--debug debug output
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2017-09-25T08:30:15+02:00
|
||||
date: 2018-01-31T11:40:21+01:00
|
||||
title: "hugo version"
|
||||
slug: hugo_version
|
||||
url: /commands/hugo_version/
|
||||
@@ -10,7 +10,6 @@ Print the version number of Hugo
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
All software has versions. This is Hugo's.
|
||||
|
||||
```
|
||||
@@ -36,6 +35,7 @@ hugo version [flags]
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 25-Sep-2017
|
||||
###### Auto generated by spf13/cobra on 31-Jan-2018
|
||||
|
||||
@@ -173,7 +173,7 @@ title = "post from custom archetype"
|
||||
As an example of archetypes in practice, the following is the `functions` archetype from the Hugo docs:
|
||||
|
||||
{{< code file="archetypes/functions.md" >}}
|
||||
{{< readfile file="/themes/gohugoioTheme/archetypes/functions.md" >}}
|
||||
{{< readfile file="/archetypes/functions.md" >}}
|
||||
{{< /code >}}
|
||||
|
||||
{{% note %}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: Cross References
|
||||
title: Links and Cross References
|
||||
description: Hugo makes it easy to link documents together.
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
@@ -21,12 +21,12 @@ toc: true
|
||||
## Use `ref` and `relref`
|
||||
|
||||
```
|
||||
{{</* ref "document" */>}}
|
||||
{{</* ref "document.md" */>}}
|
||||
{{</* ref "#anchor" */>}}
|
||||
{{</* ref "document#anchor" */>}}
|
||||
{{</* relref "document" */>}}
|
||||
{{</* ref "document.md#anchor" */>}}
|
||||
{{</* relref "document.md" */>}}
|
||||
{{</* relref "#anchor" */>}}
|
||||
{{</* relref "document#anchor" */>}}
|
||||
{{</* relref "document.md#anchor" */>}}
|
||||
```
|
||||
|
||||
The single parameter to `ref` is a string with a content `documentname` (e.g., `about.md`) with or without an appended in-document `anchor` (`#who`) without spaces.
|
||||
@@ -120,4 +120,4 @@ Ensuring heading uniqueness across the site is accomplished with a unique identi
|
||||
[built-in Hugo shortcodes]: /content-management/shortcodes/#using-the-built-in-shortcodes
|
||||
[lists]: /templates/lists/
|
||||
[output formats]: /templates/output-formats/
|
||||
[shortcode]: /content-management/shortcodes/
|
||||
[shortcode]: /content-management/shortcodes/
|
||||
|
||||
@@ -6,7 +6,7 @@ date: 2017-01-10
|
||||
publishdate: 2017-01-10
|
||||
lastmod: 2017-04-06
|
||||
categories: [content management]
|
||||
keywords: [markdown,asciidoc,mmark,content format]
|
||||
keywords: [markdown,asciidoc,mmark,pandoc,content format]
|
||||
menu:
|
||||
docs:
|
||||
parent: "content-management"
|
||||
@@ -195,12 +195,19 @@ With this setup, everything is in place for a natural usage of MathJax on pages
|
||||
|
||||
## Additional Formats Through External Helpers
|
||||
|
||||
Hugo has new concept called _external helpers_. It means that you can write your content using [Asciidoc][ascii], [reStructuredText][rest]. If you have files with associated extensions, Hugo will call external commands to generate the content. ([See the Hugo source code for external helpers][helperssource].)
|
||||
Hugo has a new concept called _external helpers_. It means that you can write your content using [Asciidoc][ascii], [reStructuredText][rest], or [pandoc]. If you have files with associated extensions, Hugo will call external commands to generate the content. ([See the Hugo source code for external helpers][helperssource].)
|
||||
|
||||
For example, for Asciidoc files, Hugo will try to call the `asciidoctor` or `asciidoc` command. This means that you will have to install the associated tool on your machine to be able to use these formats. ([See the Asciidoctor docs for installation instructions](http://asciidoctor.org/docs/install-toolchain/)).
|
||||
|
||||
To use these formats, just use the standard extension and the front matter exactly as you would do with natively supported `.md` files.
|
||||
|
||||
Hugo passes reasonable default arguments to these external helpers by default:
|
||||
|
||||
- `asciidoc`: `--no-header-footer --safe -`
|
||||
- `asciidoctor`: `--no-header-footer --safe --trace -`
|
||||
- `rst2html`: `--leave-comments --initial-header-level=2`
|
||||
- `pandoc`: `--mathjax`
|
||||
|
||||
{{% warning "Performance of External Helpers" %}}
|
||||
Because additional formats are external commands generation performance will rely heavily on the performance of the external tool you are using. As this feature is still in its infancy, feedback is welcome.
|
||||
{{% /warning %}}
|
||||
@@ -235,6 +242,7 @@ Markdown syntax is simple enough to learn in a single sitting. The following are
|
||||
[mmark]: https://github.com/miekg/mmark
|
||||
[mmarkgh]: https://github.com/miekg/mmark/wiki/Syntax
|
||||
[org]: http://orgmode.org/
|
||||
[pandoc]: http://www.pandoc.org/
|
||||
[Pygments]: http://pygments.org/
|
||||
[rest]: http://docutils.sourceforge.net/rst.html
|
||||
[sc]: /content-management/shortcodes/
|
||||
|
||||
@@ -103,6 +103,9 @@ There are a few predefined variables that Hugo is aware of. See [Page Variables]
|
||||
`expiryDate`
|
||||
: the datetime at which the content should no longer be published by Hugo; expired content will not be rendered unless the `--buildExpired` flag is passed to the `hugo` command.
|
||||
|
||||
`headless`
|
||||
: if `true`, sets a leaf bundle to be [headless][headless-bundle].
|
||||
|
||||
`isCJKLanguage`
|
||||
: if `true`, Hugo will explicitly treat the content as a CJK language; both `.Summary` and `.WordCount` work properly in CJK languages.
|
||||
|
||||
@@ -127,6 +130,9 @@ There are a few predefined variables that Hugo is aware of. See [Page Variables]
|
||||
`publishDate`
|
||||
: if in the future, content will not be rendered unless the `--buildFuture` flag is passed to `hugo`.
|
||||
|
||||
`resources`
|
||||
: used for configuring page bundle resources. See [Page Resources][page-resources].
|
||||
|
||||
`slug`
|
||||
: appears as the tail of the output URL. A value specified in front matter will override the segment of the URL based on the filename.
|
||||
|
||||
@@ -186,11 +192,13 @@ It's possible to set some options for Markdown rendering in a content's front ma
|
||||
[content type]: /content-management/types/
|
||||
[contentorg]: /content-management/organization/
|
||||
[definetype]: /content-management/types/#defining-a-content-type "Learn how to specify a type and a layout in a content's front matter"
|
||||
[headless-bundle]: /content-management/page-bundles/#headless-bundle
|
||||
[json]: https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf "Specification for JSON, JavaScript Object Notation"
|
||||
[lists]: /templates/lists/#ordering-content "See how to order content in list pages; for example, templates that look to specific _index.md for content and front matter."
|
||||
[lookup]: /templates/lookup-order/ "Hugo traverses your templates in a specific order when rendering content to allow for DRYer templating."
|
||||
[ordering]: /templates/lists/ "Hugo provides multiple ways to sort and order your content in list templates"
|
||||
[outputs]: /templates/output-formats/ "With the release of v22, you can output your content to any text format using Hugo's familiar templating"
|
||||
[page-resources]: /content-management/page-resources/
|
||||
[pagevars]: /variables/page/
|
||||
[section]: /content-management/sections/
|
||||
[taxweight]: /content-management/taxonomies/
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
---
|
||||
title: "Image Processing"
|
||||
description: "Image Page resources can be resized and cropped."
|
||||
date: 2018-01-24T13:10:00-05:00
|
||||
lastmod: 2018-01-26T15:59:07-05:00
|
||||
linktitle: "Image Processing"
|
||||
categories: ["content management"]
|
||||
keywords: [bundle,content,resources,images]
|
||||
weight: 4004
|
||||
draft: false
|
||||
toc: true
|
||||
menu:
|
||||
docs:
|
||||
parent: "content-management"
|
||||
weight: 32
|
||||
---
|
||||
|
||||
## The Image Page Resource
|
||||
|
||||
The `image` is a [Page Resource]({{< relref "content-management/page-resources" >}}), and the processing methods listed below does not work on images inside your `/static` folder.
|
||||
|
||||
|
||||
To get all images in a [Page Bundle]({{< relref "content-management/organization#page-bundles" >}}):
|
||||
|
||||
|
||||
```html
|
||||
{{ with .Resources.ByType "image" }}
|
||||
{{ end }}
|
||||
|
||||
```
|
||||
|
||||
## Image Processing Methods
|
||||
|
||||
|
||||
The `image` resource implements the methods `Resize`, `Fit` and `Fill`, each returning the transformed image using the specified dimensions and processing options.
|
||||
|
||||
Resize
|
||||
: Resizes the image to the specified width and height.
|
||||
|
||||
```go
|
||||
// Resize to a width of 600px and preserve ratio
|
||||
{{ $image := $resource.Resize "600x" }}
|
||||
|
||||
// Resize to a height of 400px and preserve ratio
|
||||
{{ $image := $resource.Resize "x400" }}
|
||||
|
||||
// Resize to a width 600px and a height of 400px
|
||||
{{ $image := $resource.Resize "600x400" }}
|
||||
```
|
||||
|
||||
Fit
|
||||
: Scale down the image to fit the given dimensions while maintaining aspect ratio. Both height and width are required.
|
||||
|
||||
```go
|
||||
{{ $image := $resource.Fit "600x400" }}
|
||||
```
|
||||
|
||||
Fill
|
||||
: Resize and crop the image to match the given dimensions. Both height and width are required.
|
||||
|
||||
```go
|
||||
{{ $image := $resource.Fill "600x400" }}
|
||||
```
|
||||
|
||||
|
||||
{{% note %}}
|
||||
Image operations in Hugo currently **do not preserve EXIF data** as this is not supported by Go's [image package](https://github.com/golang/go/search?q=exif&type=Issues&utf8=%E2%9C%93). This will be improved on in the future.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
## Image Processing Options
|
||||
|
||||
In addition to the dimensions (e.g. `600x400`), Hugo supports a set of additional image options.
|
||||
|
||||
|
||||
JPEG Quality
|
||||
: Only relevant for JPEG images, values 1 to 100 inclusive, higher is better. Default is 75.
|
||||
|
||||
```go
|
||||
{{ $image.Resize "600x q50" }}
|
||||
```
|
||||
|
||||
Rotate
|
||||
: Rotates an image by the given angle counter-clockwise. The rotation will be performed first to get the dimensions correct. The main use of this is to be able to manually correct for [EXIF orientation](https://github.com/golang/go/issues/4341) of JPEG images.
|
||||
|
||||
```go
|
||||
{{ $image.Resize "600x r90" }}
|
||||
```
|
||||
|
||||
Anchor
|
||||
: Only relevant for the `Fill` method. This is useful for thumbnail generation where the main motive is located in, say, the left corner.
|
||||
Valid are `Center`, `TopLeft`, `Top`, `TopRight`, `Left`, `Right`, `BottomLeft`, `Bottom`, `BottomRight`.
|
||||
|
||||
```go
|
||||
{{ $image.Fill "300x200 BottomLeft" }}
|
||||
```
|
||||
|
||||
Resample Filter
|
||||
: Filter used in resizing. Default is `Box`, a simple and fast resampling filter appropriate for downscaling.
|
||||
|
||||
Examples are: `Box`, `NearestNeighbor`, `Linear`, `Gaussian`.
|
||||
|
||||
See https://github.com/disintegration/imaging for more. If you want to trade quality for faster processing, this may be a option to test.
|
||||
|
||||
```go
|
||||
{{ $image.Resize "600x400 Gaussian" }}
|
||||
```
|
||||
|
||||
### Image Processing Examples
|
||||
|
||||
_The photo of the sunset used in the examples below is Copyright [Bjørn Erik Pedersen](https://commons.wikimedia.org/wiki/User:Bep) (Creative Commons Attribution-Share Alike 4.0 International license)_
|
||||
|
||||
|
||||
{{< imgproc sunset Resize "300x" />}}
|
||||
|
||||
{{< imgproc sunset Fill "90x120 left" />}}
|
||||
|
||||
{{< imgproc sunset Fill "90x120 right" />}}
|
||||
|
||||
{{< imgproc sunset Fit "90x90" />}}
|
||||
|
||||
{{< imgproc sunset Resize "300x q10" />}}
|
||||
|
||||
|
||||
This is the shortcode used in the examples above:
|
||||
|
||||
|
||||
{{< code file="layouts/shortcodes/imgproc.html" >}}
|
||||
{{< readfile file="layouts/shortcodes/imgproc.html" >}}
|
||||
{{< /code >}}
|
||||
|
||||
And it is used like this:
|
||||
|
||||
```html
|
||||
{{</* imgproc sunset Resize "300x" /*/>}}
|
||||
```
|
||||
|
||||
|
||||
{{% note %}}
|
||||
**Tip:** Note the self-closing shortcode syntax above. The `imgproc` shortcode can be called both with and without **inner content**.
|
||||
{{% /note %}}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 88 KiB |
@@ -18,7 +18,7 @@ toc: true
|
||||
---
|
||||
|
||||
{{% note "Lazy Blogger"%}}
|
||||
If all you want is a simple menu for your sections, see the ["Section Menu for Lazy Bloggers" in Menu Templates](/templates/menu-templates/#section-menu-for-lazy-blogger).
|
||||
If all you want is a simple menu for your sections, see the ["Section Menu for Lazy Bloggers" in Menu Templates](/templates/menu-templates/#section-menu-for-lazy-bloggers).
|
||||
{{% /note %}}
|
||||
|
||||
You can do this:
|
||||
|
||||
@@ -13,11 +13,11 @@ menu:
|
||||
weight: 150
|
||||
weight: 150 #rem
|
||||
draft: false
|
||||
aliases: [/content/multilingual/,/content-management/multilingual/]
|
||||
aliases: [/content/multilingual/,/content-management/multilingual/,/tutorials/create-a-multilingual-site/]
|
||||
toc: true
|
||||
---
|
||||
|
||||
You should define the available languages in a `Languages` section in your site configuration.
|
||||
You should define the available languages in a `languages` section in your site configuration.
|
||||
|
||||
## Configure Languages
|
||||
|
||||
@@ -30,24 +30,24 @@ copyright = "Everything is mine"
|
||||
[params.navigation]
|
||||
help = "Help"
|
||||
|
||||
[Languages]
|
||||
[Languages.en]
|
||||
[languages]
|
||||
[languages.en]
|
||||
title = "My blog"
|
||||
weight = 1
|
||||
[Languages.en.params]
|
||||
linkedin = "english-link"
|
||||
|
||||
[Languages.fr]
|
||||
[languages.fr]
|
||||
copyright = "Tout est à moi"
|
||||
title = "Mon blog"
|
||||
weight = 2
|
||||
[Languages.fr.params]
|
||||
linkedin = "lien-francais"
|
||||
[Languages.fr.navigation]
|
||||
|
||||
# skip params key for front matter
|
||||
[languages.fr.navigation]
|
||||
help = "Aide"
|
||||
{{< /code >}}
|
||||
|
||||
Anything not defined in a `[Languages]` block will fall back to the global
|
||||
Anything not defined in a `[languages]` block will fall back to the global
|
||||
value for that key (e.g., `copyright` for the English [`en`] language).
|
||||
|
||||
With the configuration above, all content, sitemap, RSS feeds, paginations,
|
||||
@@ -59,6 +59,52 @@ If you want all of the languages to be put below their respective language code,
|
||||
|
||||
Only the obvious non-global options can be overridden per language. Examples of global options are `baseURL`, `buildDrafts`, etc.
|
||||
|
||||
## Configure Multilingual Multihost
|
||||
|
||||
From **Hugo 0.31** we support multiple languages in a multihost configuration. See [this issue](https://github.com/gohugoio/hugo/issues/4027) for details.
|
||||
|
||||
This means that you can now configure a `baseURL` per `language`:
|
||||
|
||||
|
||||
> If a `baseURL` is set on the `language` level, then all languages must have one and they must all be different.
|
||||
|
||||
Example:
|
||||
|
||||
```bash
|
||||
[languages]
|
||||
[languages.no]
|
||||
baseURL = "https://example.no"
|
||||
languageName = "Norsk"
|
||||
weight = 1
|
||||
title = "På norsk"
|
||||
|
||||
[languages.en]
|
||||
baseURL = "https://example.com"
|
||||
languageName = "English"
|
||||
weight = 2
|
||||
title = "In English"
|
||||
```
|
||||
|
||||
With the above, the two sites will be generated into `public` with their own root:
|
||||
|
||||
```bash
|
||||
public
|
||||
├── en
|
||||
└── no
|
||||
```
|
||||
|
||||
**All URLs (i.e `.Permalink` etc.) will be generated from that root. So the English home page above will have its `.Permalink` set to `https://example.com/`.**
|
||||
|
||||
When you run `hugo server` we will start multiple HTTP servers. You will typlically see something like this in the console:
|
||||
|
||||
```bash
|
||||
Web Server is available at 127.0.0.1:1313 (bind address 127.0.0.1)
|
||||
Web Server is available at 127.0.0.1:1314 (bind address 127.0.0.1)
|
||||
Press Ctrl+C to stop
|
||||
```
|
||||
|
||||
Live reload and `--navigateToChanged` between the servers work as expected.
|
||||
|
||||
## Taxonomies and Blackfriday
|
||||
|
||||
Taxonomies and [Blackfriday configuration][config] can also be set per language:
|
||||
@@ -72,17 +118,17 @@ tag = "tags"
|
||||
angledQuotes = true
|
||||
hrefTargetBlank = true
|
||||
|
||||
[Languages]
|
||||
[Languages.en]
|
||||
[languages]
|
||||
[languages.en]
|
||||
weight = 1
|
||||
title = "English"
|
||||
[Languages.en.blackfriday]
|
||||
[languages.en.blackfriday]
|
||||
angledQuotes = false
|
||||
|
||||
[Languages.fr]
|
||||
[languages.fr]
|
||||
weight = 2
|
||||
title = "Français"
|
||||
[Languages.fr.Taxonomies]
|
||||
[languages.fr.Taxonomies]
|
||||
plaque = "plaques"
|
||||
{{< /code >}}
|
||||
|
||||
@@ -102,22 +148,28 @@ In this example, the `about.md` will be assigned the configured `defaultContentL
|
||||
|
||||
This way, you can slowly start to translate your current content without having to rename everything. If left unspecified, the default value for `defaultContentLanguage` is `en`.
|
||||
|
||||
By having the same *base filename*, the content pieces are linked together as translated pieces.
|
||||
By having the same **directory and base filename**, the content pieces are linked together as translated pieces.
|
||||
|
||||
You can also set the key used to link the translations explicitly in front matter:
|
||||
|
||||
```yaml
|
||||
translationKey: "my-story"
|
||||
```
|
||||
|
||||
|
||||
{{% note %}}
|
||||
**Before Hugo 0.31**, the file's directory was not considered when looking for translations. This did not work when you named all of your content files, say, `index.md`. Now we use the full content path.
|
||||
{{% /note %}}
|
||||
|
||||
If you need distinct URLs per language, you can set the slug in the non-default language file. For example, you can define a custom slug for a French translation in the front matter of `content/about.fr.md` as follows:
|
||||
|
||||
```
|
||||
```yaml
|
||||
slug: "a-propos"
|
||||
|
||||
```
|
||||
|
||||
At render, Hugo will build both `/about/` and `/a-propos/` as properly linked translated pages.
|
||||
|
||||
{{%note %}}
|
||||
Hugo currently uses the base filename as the translation key, which can be an issue with identical filenames in different sections.
|
||||
We will fix this in https://github.com/gohugoio/hugo/issues/2699
|
||||
{{% /note %}}
|
||||
{{< todo >}}Rewrite/remove the above one issue is fixed.{{< /todo >}}
|
||||
|
||||
## Link to Translated Content
|
||||
|
||||
@@ -136,16 +188,36 @@ To create a list of links to translated content, use a template similar to the f
|
||||
{{ end }}
|
||||
{{< /code >}}
|
||||
|
||||
The above can be put in a `partial` (i.e., inside `layouts/partials/`) and included in any template, be it for a [single content page][contenttemplate] or the [homepage][]. It will not print anything if there are no translations for a given page, or if there are translations---in the case of the homepage, section listing, etc.---a site with only render one language.
|
||||
The above can be put in a `partial` (i.e., inside `layouts/partials/`) and included in any template, be it for a [single content page][contenttemplate] or the [homepage][]. It will not print anything if there are no translations for a given page.
|
||||
|
||||
The above also uses the [`i18n` function][i18func] described in the next section.
|
||||
|
||||
## List All Available Languages
|
||||
|
||||
`.AllTranslations` on a `Page` can be used to list all translations, including itself. Called on the home page it can be used to build a language navigator:
|
||||
|
||||
|
||||
{{< code file="layouts/partials/allLanguages.html" >}}
|
||||
<ul>
|
||||
{{ range $.Site.Home.AllTranslations }}
|
||||
<li><a href="{{ .}}">{{ .Language.LanguageName }}</a></li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{< /code >}}
|
||||
|
||||
## Translation of Strings
|
||||
|
||||
Hugo uses [go-i18n][] to support string translations. [See the project's source repository][go-i18n-source] to find tools that will help you manage your translation workflows.
|
||||
|
||||
Translations are collected from the `themes/<THEME>/i18n/` folder (built into the theme), as well as translations present in `i18n/` at the root of your project. In the `i18n`, the translations will be merged and take precedence over what is in the theme folder. Language files should be named according to [RFC 5646][] with names such as `en-US.toml`, `fr.toml`, etc.
|
||||
|
||||
{{% note %}}
|
||||
From **Hugo 0.31** you no longer need to use a valid language code. It _can be_ anything.
|
||||
|
||||
See https://github.com/gohugoio/hugo/issues/3564
|
||||
|
||||
{{% /note %}}
|
||||
|
||||
From within your templates, use the `i18n` function like this:
|
||||
|
||||
```
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 62 KiB |
+27
-30
@@ -6,7 +6,7 @@ date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
lastmod: 2017-02-01
|
||||
categories: [content management,fundamentals]
|
||||
keywords: [sections,content,organization]
|
||||
keywords: [sections,content,organization,bundle,resources]
|
||||
menu:
|
||||
docs:
|
||||
parent: "content-management"
|
||||
@@ -17,20 +17,30 @@ aliases: [/content/sections/]
|
||||
toc: true
|
||||
---
|
||||
|
||||
## Page Bundles
|
||||
|
||||
Hugo `0.32` announced page-relative images and other resources packaged into `Page Bundles`.
|
||||
|
||||
These terms are connected, and you also need to read about [Page Resources]({{< relref "content-management/page-resources" >}}) and [Image Processing]({{< relref "content-management/image-processing" >}}) to get the full picture.
|
||||
|
||||
{{% imgproc 1-featured Resize "300x" %}}
|
||||
The illustration shows 3 bundles. Note that the home page bundle cannot contain other content pages, but other files (images etc.) are fine.
|
||||
{{% /imgproc %}}
|
||||
|
||||
|
||||
{{% note %}}
|
||||
This section is not updated with the new nested sections support in Hugo 0.24, see https://github.com/gohugoio/hugoDocs/issues/36
|
||||
The bundle docuementation is **work in progress**. We will publish more comprehensive docs about this soon.
|
||||
{{% /note %}}
|
||||
{{% todo %}}
|
||||
See above
|
||||
{{% /todo %}}
|
||||
|
||||
{{< youtube 0GZxidrlaRM >}}
|
||||
|
||||
## Organization of Content Source
|
||||
# Organization of Content Source
|
||||
|
||||
|
||||
In Hugo, your content should be organized in a manner that reflects the rendered website.
|
||||
|
||||
While Hugo supports content nested at any level, the top levels (i.e. `content/<DIRECTORIES>`) are special in Hugo and are considered the content [sections][]. Without any additional configuration, the following will just work:
|
||||
While Hugo supports content nested at any level, the top levels (i.e. `content/<DIRECTORIES>`) are special in Hugo and are considered the content type used to determine layouts etc. To read more about sections, including how to nest them, see [sections][].
|
||||
|
||||
Without any additional configuration, the following will just work:
|
||||
|
||||
```
|
||||
.
|
||||
@@ -49,11 +59,16 @@ While Hugo supports content nested at any level, the top levels (i.e. `content/<
|
||||
|
||||
## Path Breakdown in Hugo
|
||||
|
||||
|
||||
The following demonstrates the relationships between your content organization and the output URL structure for your Hugo website when it renders. These examples assume you are [using pretty URLs][pretty], which is the default behavior for Hugo. The examples also assume a key-value of `baseurl = "https://example.com"` in your [site's configuration file][config].
|
||||
|
||||
### Index Pages: `_index.md`
|
||||
|
||||
`_index.md` has a special role in Hugo. It allows you to add front matter and content to your [list templates][lists] as of v0.18. These templates include those for [section templates][], [taxonomy templates][], [taxonomy terms templates][], and your [homepage template][]. In your templates, you can grab information from `_index.md` using the [`.Site.GetPage` function][getpage].
|
||||
`_index.md` has a special role in Hugo. It allows you to add front matter and content to your [list templates][lists]. These templates include those for [section templates][], [taxonomy templates][], [taxonomy terms templates][], and your [homepage template][].
|
||||
|
||||
{{% note %}}
|
||||
**Tip:** You can get a reference to the content and metadata in `_index.md` using the [`.Site.GetPage` function](/functions/getpage/).
|
||||
{{% /note %}}
|
||||
|
||||
You can keep one `_index.md` for your homepage and one in each of your content sections, taxonomies, and taxonomy terms. The following shows typical placement of an `_index.md` that would contain content and front matter for a `posts` section list page on a Hugo website:
|
||||
|
||||
@@ -81,6 +96,9 @@ At build, this will output to the following destination with the associated valu
|
||||
https://example.com/posts/index.html
|
||||
```
|
||||
|
||||
The [sections][] can be nested as deeply as you need. The important part to understand is, that to make the section tree fully navigational, at least the lower-most section needs a content file. (i.e. `_index.md`).
|
||||
|
||||
|
||||
### Single Pages in Sections
|
||||
|
||||
Single content files in each of your sections are going to be rendered as [single page templates][singles]. Here is an example of a single `post` within `posts`:
|
||||
@@ -107,27 +125,6 @@ At the time Hugo builds your site, the content will be output to the following d
|
||||
https://example.com/posts/my-first-hugo-post/index.html
|
||||
```
|
||||
|
||||
### Section with Nested Directories
|
||||
|
||||
To continue the example, the following demonstrates destination paths for a file located at `content/events/chicago/lollapalooza.md` in the same site:
|
||||
|
||||
|
||||
```
|
||||
section
|
||||
⊢--^--⊣
|
||||
url
|
||||
⊢-------------^------------⊣
|
||||
|
||||
baseURL path slug
|
||||
⊢--------^--------⊣ ⊢------^-----⊣⊢----^------⊣
|
||||
permalink
|
||||
⊢----------------------^-----------------------⊣
|
||||
https://example.com/events/chicago/lollapalooza/
|
||||
```
|
||||
|
||||
{{% note %}}
|
||||
As of v0.20, Hugo does not recognize nested sections. While you can nest as many content *directories* as you'd like, any child directory of a section will still be considered the same section as that of its parents. Therefore, in the above example, `{{.Section}}` for `lollapalooza.md` is `events` and *not* `chicago`. See the [related issue on GitHub](https://github.com/gohugoio/hugo/issues/465).
|
||||
{{% /note %}}
|
||||
|
||||
## Paths Explained
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
---
|
||||
title : "Page Bundles"
|
||||
description : "Content organization using Page Bundles"
|
||||
date : 2018-01-24T13:09:00-05:00
|
||||
lastmod : 2018-01-28T22:26:40-05:00
|
||||
linktitle : "Page Bundles"
|
||||
keywords : ["page", "bundle", "leaf", "branch"]
|
||||
categories : ["content management"]
|
||||
draft : true
|
||||
toc : true
|
||||
menu :
|
||||
docs:
|
||||
identifier : "page-bundles"
|
||||
parent : "content-management"
|
||||
weight : 11
|
||||
---
|
||||
|
||||
Page Bundles are a way to organize the content files. It's useful for
|
||||
cases where a page or section's content needs to be split into
|
||||
multiple content pages for convenience or has associated attachments
|
||||
like documents or images.
|
||||
|
||||
A Page Bundle can be one of two types:
|
||||
|
||||
- Leaf Bundle
|
||||
- Branch Bundle
|
||||
|
||||
| | Leaf Bundle | Branch Bundle |
|
||||
|-----------------|--------------------------------------------------------|---------------------------------------------------------|
|
||||
| Usage | Collection of content and attachments for single pages | Collection of content and attachments for section pages |
|
||||
| Index file name | `index.md` [^fn:1] | `_index.md` [^fn:1] |
|
||||
| Layout type | `single` | `list` |
|
||||
| Nesting | Doesn't allow nesting of more bundles under it | Allows nesting of leaf/branch bundles under it |
|
||||
| Example | `content/posts/my-post/index.md` | `content/posts/_index.md` |
|
||||
|
||||
|
||||
## Leaf Bundles {#leaf-bundles}
|
||||
|
||||
A _Leaf Bundle_ is a directory at any hierarchy within the `content/`
|
||||
directory, that contains at least an **`index.md`** file.
|
||||
|
||||
{{% note %}}
|
||||
Here `md` (markdown) is used just as an example. You can use any file
|
||||
type as a content resource as long as it is a MIME type recognized by
|
||||
Hugo (`json` files will, as one example, work fine). If you want to
|
||||
get exotic, you can define your own media type.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
### Examples of Leaf Bundle organization {#examples-of-leaf-bundle-organization}
|
||||
|
||||
```text
|
||||
content/
|
||||
├── about
|
||||
│ ├── index.md
|
||||
├── posts
|
||||
│ ├── my-post
|
||||
│ │ ├── content1.md
|
||||
│ │ ├── content2.md
|
||||
│ │ ├── image1.jpg
|
||||
│ │ ├── image2.png
|
||||
│ │ └── index.md
|
||||
│ └── my-another-post
|
||||
│ └── index.md
|
||||
│
|
||||
└── another-section
|
||||
├── ..
|
||||
└── not-a-leaf-bundle
|
||||
├── ..
|
||||
└── another-leaf-bundle
|
||||
└── index.md
|
||||
```
|
||||
|
||||
In the above example `content/` directory, there are four leaf
|
||||
bundles:
|
||||
|
||||
about
|
||||
: This leaf bundle is at the root level (directly under
|
||||
`content` directory) and has only the `index.md`.
|
||||
|
||||
my-post
|
||||
: This leaf bundle has the `index.md`, two other content
|
||||
Markdown files and two image files.
|
||||
|
||||
my-another-post
|
||||
: This leaf bundle has only the `index.md`.
|
||||
|
||||
another-leaf-bundle
|
||||
: This leaf bundle is nested under couple of
|
||||
directories. This bundle also has only the `index.md`.
|
||||
|
||||
{{% note %}}
|
||||
The hierarchy depth at which a leaf bundle is created does not matter,
|
||||
as long as it is not inside another **leaf** bundle.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
### Headless Bundle {#headless-bundle}
|
||||
|
||||
A headless bundle is a bundle that is configured to not get published
|
||||
anywhere:
|
||||
|
||||
- It will have no `Permalink` and no rendered HTML in `public/`.
|
||||
- It will not be part of `.Site.RegularPages`, etc.
|
||||
|
||||
But you can get it by `.Site.GetPage`. Here is an example:
|
||||
|
||||
```html
|
||||
{{ $headless := .Site.GetPage "page" "some-headless-bundle" }}
|
||||
{{ $reusablePages := $headless.Resources.Match "author*" }}
|
||||
<h2>Authors</h2>
|
||||
{{ range $reusablePages }}
|
||||
<h3>{{ .Title }}</h3>
|
||||
{{ .Content }}
|
||||
{{ end }}
|
||||
```
|
||||
|
||||
A leaf bundle can be made headless by adding below in the Front Matter
|
||||
(in the `index.md`):
|
||||
|
||||
```toml
|
||||
headless = true
|
||||
```
|
||||
|
||||
{{% note %}}
|
||||
Only leaf bundles can be made headless.
|
||||
{{% /note %}}
|
||||
|
||||
There are many use cases of such headless page bundles:
|
||||
|
||||
- Shared media galleries
|
||||
- Reusable page content "snippets"
|
||||
|
||||
|
||||
## Branch Bundles {#branch-bundles}
|
||||
|
||||
A _Branch Bundle_ is any directory at any hierarchy within the
|
||||
`content/` directory, that contains at least an **`_index.md`** file.
|
||||
|
||||
This `_index.md` can also be directly under the `content/` directory.
|
||||
|
||||
{{% note %}}
|
||||
Here `md` (markdown) is used just as an example. You can use any file
|
||||
type as a content resource as long as it is a MIME type recognized by
|
||||
Hugo (`json` files will, as one example, work fine). If you want to
|
||||
get exotic, you can define your own media type.
|
||||
{{% /note %}}
|
||||
|
||||
|
||||
### Examples of Branch Bundle organization {#examples-of-branch-bundle-organization}
|
||||
|
||||
```text
|
||||
content/
|
||||
├── branch-bundle-1
|
||||
│ ├── branch-content1.md
|
||||
│ ├── branch-content2.md
|
||||
│ ├── image1.jpg
|
||||
│ ├── image2.png
|
||||
│ └── _index.md
|
||||
└── branch-bundle-2
|
||||
├── _index.md
|
||||
└── a-leaf-bundle
|
||||
└── index.md
|
||||
```
|
||||
|
||||
In the above example `content/` directory, there are two branch
|
||||
bundles (and a leaf bundle):
|
||||
|
||||
`branch-bundle-1`
|
||||
: This branch bundle has the `_index.md`, two
|
||||
other content Markdown files and two image files.
|
||||
|
||||
`branch-bundle-2`
|
||||
: This branch bundle has the `_index.md` and a
|
||||
nested leaf bundle.
|
||||
|
||||
{{% note %}}
|
||||
The hierarchy depth at which a branch bundle is created does not
|
||||
matter.
|
||||
{{% /note %}}
|
||||
|
||||
[^fn:1]: The `.md` extension is just an example. The extension can be `.html`, `.json` or any of any valid MIME type.
|
||||
@@ -0,0 +1,184 @@
|
||||
---
|
||||
title : "Page Resources"
|
||||
description : "Page Resources -- images, other pages, documents etc. -- have page-relative URLs and their own metadata."
|
||||
date: 2018-01-24
|
||||
categories: ["content management"]
|
||||
keywords: [bundle,content,resources]
|
||||
weight: 4003
|
||||
draft: false
|
||||
toc: true
|
||||
linktitle: "Page Resources"
|
||||
menu:
|
||||
docs:
|
||||
parent: "content-management"
|
||||
weight: 31
|
||||
---
|
||||
|
||||
## Properties
|
||||
|
||||
ResourceType
|
||||
: The main type of the resource. For example, a file of MIME type `image/jpg` has for ResourceType `image`.
|
||||
|
||||
Name
|
||||
: Default value is the filename (relative to the owning page). Can be set in front matter.
|
||||
|
||||
Title
|
||||
: Default blank. Can be set in front matter.
|
||||
|
||||
Permalink
|
||||
: The absolute URL to the resource. Resources of type `page` will have no value.
|
||||
|
||||
RelPermalink
|
||||
: The relative URL to the resource. Resources of type `page` will have no value.
|
||||
|
||||
## Methods
|
||||
ByType
|
||||
: Returns the page resources of the given type.
|
||||
|
||||
```go
|
||||
{{ .Resources.ByType "image" }}
|
||||
```
|
||||
Match
|
||||
: Returns all the page resources (as a slice) whose `Name` matches the given Glob pattern ([examples](https://github.com/gobwas/glob/blob/master/readme.md)). The matching is case-insensitive.
|
||||
|
||||
```go
|
||||
{{ .Resources.Match "images/*" }}
|
||||
```
|
||||
|
||||
GetMatch
|
||||
: Same as `Match` but will return the first match.
|
||||
|
||||
### Pattern Matching
|
||||
```go
|
||||
// Using Match/GetMatch to find this images/sunset.jpg ?
|
||||
.Resources.Match "images/sun*" ✅
|
||||
.Resources.Match "**/Sunset.jpg" ✅
|
||||
.Resources.Match "images/*.jpg" ✅
|
||||
.Resources.Match "**.jpg" ✅
|
||||
.Resources.Match "*" 🚫
|
||||
.Resources.Match "sunset.jpg" 🚫
|
||||
.Resources.Match "*sunset.jpg" 🚫
|
||||
|
||||
```
|
||||
|
||||
## Page Resources Metadata
|
||||
|
||||
Page Resources' metadata is managed from their page's front matter with an array/table parameter named `resources`. You can batch assign values using a [wildcards](http://tldp.org/LDP/GNU-Linux-Tools-Summary/html/x11655.htm).
|
||||
|
||||
{{% note %}}
|
||||
Resources of type `page` get `Title` etc. from their own front matter.
|
||||
{{% /note %}}
|
||||
|
||||
name
|
||||
: Sets the value returned in `Name`.
|
||||
|
||||
{{% warning %}}
|
||||
The methods `Match` and `GetMatch` use `Name` to match the resources.
|
||||
{{%/ warning %}}
|
||||
|
||||
title
|
||||
: Sets the value returned in `Title`
|
||||
|
||||
params
|
||||
: A map of custom key/values.
|
||||
|
||||
|
||||
### Resources metadata: YAML Example
|
||||
|
||||
~~~yaml
|
||||
title: Application
|
||||
date : 2018-01-25
|
||||
resources :
|
||||
- src : "images/sunset.jpg"
|
||||
name : "header"
|
||||
- src : "documents/photo_specs.pdf"
|
||||
title : "Photo Specifications"
|
||||
params:
|
||||
icon : "photo"
|
||||
- src : "documents/guide.pdf"
|
||||
title : "Instruction Guide"
|
||||
- src : "documents/checklist.pdf"
|
||||
title : "Document Checklist"
|
||||
- src : "documents/payment.docx"
|
||||
title : "Proof of Payment"
|
||||
- src : "**.pdf"
|
||||
name : "pdf-file-:counter"
|
||||
params :
|
||||
icon : "pdf"
|
||||
- src : "**.docx"
|
||||
params :
|
||||
icon : "word"
|
||||
~~~
|
||||
|
||||
### Resources metadata: TOML Example
|
||||
|
||||
~~~toml
|
||||
title = Application
|
||||
date : 2018-01-25
|
||||
[[resources]]
|
||||
src = "images/sunset.jpg"
|
||||
name = "header"
|
||||
[[resources]]
|
||||
src = "documents/photo_specs.pdf"
|
||||
title = "Photo Specifications"
|
||||
[resources.params]
|
||||
icon = "photo"
|
||||
[[resources]]
|
||||
src = "documents/guide.pdf"
|
||||
title = "Instruction Guide"
|
||||
[[resources]]
|
||||
src = "documents/checklist.pdf"
|
||||
title = "Document Checklist"
|
||||
[[resources]]
|
||||
src = "documents/payment.docx"
|
||||
title = "Proof of Payment"
|
||||
[[resources]]
|
||||
src = "**.pdf"
|
||||
name = "pdf-file-:counter"
|
||||
[resources.params]
|
||||
icon = "pdf"
|
||||
[[resources]]
|
||||
src = "**.docx"
|
||||
[resources.params]
|
||||
icon = "word"
|
||||
~~~
|
||||
|
||||
|
||||
From the example above:
|
||||
|
||||
- `sunset.jpg` will receive a new `Name` and can now be found with `.GetMatch "header"`.
|
||||
- `documents/photo_specs.pdf` will get the `photo` icon.
|
||||
- `documents/checklist.pdf`, `documents/guide.pdf` and `documents/payment.docx` will get `Title` as set by `title`.
|
||||
- Every `PDF` in the bundle except `documents/photo_specs.pdf` will get the `pdf` icon.
|
||||
- All `PDF` files will get a new `Name`. The `name` parameter contains a special placeholder [`:counter`](#counter), so the `Name` will be `pdf-file-1`, `pdf-file-2`, `pdf-file-3`.
|
||||
- Every docx in the bundle will receive the `word` icon.
|
||||
|
||||
{{% warning %}}
|
||||
The __order matters__ --- Only the **first set** values of the `title`, `name` and `params`-**keys** will be used. Consecutive parameters will be set only for the ones not already set. For example, in the above example, `.Params.icon` is already first set to `"photo"` in `src = "documents/photo_specs.pdf"`. So that would not get overridden to `"pdf"` by the later set `src = "**.pdf"` rule.
|
||||
{{%/ warning %}}
|
||||
|
||||
### The `:counter` placeholder in `name` and `title`
|
||||
|
||||
The `:counter` is a special placeholder recognized in `name` and `title` parameters `resources`.
|
||||
|
||||
The counter starts at 1 the first time they are used in either `name` or `title`.
|
||||
|
||||
For example, if a bundle has the resources `photo_specs.pdf`, `other_specs.pdf`, `guide.pdf` and `checklist.pdf`, and the front matter has specified the `resources` as:
|
||||
|
||||
~~~toml
|
||||
[[resources]]
|
||||
src = "*specs.pdf"
|
||||
title = "Specification #:counter"
|
||||
[[resources]]
|
||||
src = "**.pdf"
|
||||
name = "pdf-file-:counter"
|
||||
~~~
|
||||
|
||||
the `Name` and `Title` will be assigned to the resource files as follows:
|
||||
|
||||
| Resource file | `Name` | `Title` |
|
||||
|-------------------|-------------------|-----------------------|
|
||||
| checklist.pdf | `"pdf-file-1.pdf` | `"checklist.pdf"` |
|
||||
| guide.pdf | `"pdf-file-2.pdf` | `"guide.pdf"` |
|
||||
| other\_specs.pdf | `"pdf-file-3.pdf` | `"Specification #1"` |
|
||||
| photo\_specs.pdf | `"pdf-file-4.pdf` | `"Specification #2"` |
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
title: Content Sections
|
||||
linktitle: Sections
|
||||
description: Hugo supports content sections, which according to Hugo's default behavior, will reflect the structure of the rendered website.
|
||||
description: "Hugo generates a **section tree** that matches your content."
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
lastmod: 2017-02-01
|
||||
@@ -17,53 +17,65 @@ aliases: [/content/sections/]
|
||||
toc: true
|
||||
---
|
||||
|
||||
|
||||
## Nested Sections
|
||||
|
||||
The sections can be nested as deeply as you need.
|
||||
|
||||
```bash
|
||||
blog
|
||||
├── funny-cats
|
||||
│ └── kittens
|
||||
│ └── _index.md
|
||||
└── tech
|
||||
└── _index.md
|
||||
```
|
||||
|
||||
|
||||
**The important part to understand is, that to make the section tree fully navigational, at least the lower-most section needs a content file. (e.g. `_index.md`).**
|
||||
|
||||
|
||||
{{% note %}}
|
||||
This section is not updated with the new nested sections support in Hugo 0.24, see https://github.com/gohugoio/hugoDocs/issues/36
|
||||
When we talk about a **section** in correlation with template selection, it is currently always the root section only (`/blog/funny/mypost/ => blog`).
|
||||
|
||||
It is currently not possible to add a specific layout for one of the sub-sections.
|
||||
{{% /note %}}
|
||||
{{% todo %}}
|
||||
See above
|
||||
{{% /todo %}}
|
||||
|
||||
Hugo believes that you organize your content with a purpose. The same structure that works to organize your source content is used to organize the rendered site (see [directory structure][]).
|
||||
|
||||
Following this pattern, Hugo uses the top level of your content organization as the content **section**.
|
||||
## Example: Breadcrumb Navigation
|
||||
|
||||
The following example shows a content directory structure for a website that has three sections: "authors," "events," and "posts":
|
||||
With the available [section variables and methods](#section-page-variables-and-methods) you can build powerful navigation. One common example would be a partial to show Breadcrumb navigation:
|
||||
|
||||
```
|
||||
.
|
||||
└── content
|
||||
├── authors
|
||||
| ├── _index.md // <- example.com/authors/
|
||||
| ├── john-doe.md // <- example.com/authors/john-doe/
|
||||
| └── jane-doe.md // <- example.com/authors/jane-doe/
|
||||
└── events
|
||||
| ├── _index.md // <- example.com/events/
|
||||
| ├── event-1.md // <- example.com/events/event-1/
|
||||
| ├── event-2.md // <- example.com/events/event-2/
|
||||
| └── event-3.md // <- example.com/events/event-3/
|
||||
└── posts
|
||||
| ├── _index.md // <- example.com/posts/
|
||||
| ├── event-1.md // <- example.com/posts/event-1/
|
||||
| ├── event-2.md // <- example.com/posts/event-2/
|
||||
| ├── event-3.md // <- example.com/posts/event-3/
|
||||
| ├── event-4.md // <- example.com/posts/event-4/
|
||||
| └── event-5.md // <- example.com/posts/event-5/
|
||||
```
|
||||
|
||||
{{< code file="layouts/partials/breadcrumb.html" download="breadcrumb.html" >}}
|
||||
<ol class="nav navbar-nav">
|
||||
{{ template "breadcrumbnav" (dict "p1" . "p2" .) }}
|
||||
</ol>
|
||||
{{ define "breadcrumbnav" }}
|
||||
{{ if .p1.Parent }}
|
||||
{{ template "breadcrumbnav" (dict "p1" .p1.Parent "p2" .p2 ) }}
|
||||
{{ else if not .p1.IsHome }}
|
||||
{{ template "breadcrumbnav" (dict "p1" .p1.Site.Home "p2" .p2 ) }}
|
||||
{{ end }}
|
||||
<li{{ if eq .p1 .p2 }} class="active"{{ end }}>
|
||||
<a href="{{ .p1.Permalink }}">{{ .p1.Title }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
{{< /code >}}
|
||||
|
||||
## Section Page Variables and Methods
|
||||
|
||||
Also see [Page Variables](/variables/page/).
|
||||
|
||||
{{< readfile file="/content/readfiles/sectionvars.md" markdown="true" >}}
|
||||
|
||||
## Content Section Lists
|
||||
|
||||
Hugo will automatically create pages for each section root that list all of the content in that section. See the documentation on [section templates][] for details on customizing the way these pages are rendered.
|
||||
|
||||
As of Hugo v0.18, section pages can also have a content file and front matter. These section content files must be placed in their corresponding section folder and named `_index.md` in order for Hugo to correctly render the front matter and content.
|
||||
|
||||
{{% warning "`index.md` vs `_index.md`" %}}
|
||||
Hugo themes developed before v0.18 often used an `index.md`(i.e., without the leading underscore [`_`]) in a content section as a hack to emulate the behavior of `_index.md`. The hack may work...*sometimes*; however, the order of page rendering can be unpredictable in Hugo. What works now may fail to render appropriately as your site grows. It is **strongly advised** to use `_index.md` as content for your section index pages. **Note:** `_index.md`'s layout, as representative of a section, is a [list page template](/templates/section-templates/) and *not* a [single page template](/templates/single-page-templates/). If you want to alter the new default behavior for `_index.md`, configure `disableKinds` accordingly in your [site's configuration](/getting-started/configuration/).
|
||||
{{% /warning %}}
|
||||
|
||||
## Content *Section* vs Content *Type*
|
||||
|
||||
By default, everything created within a section will use the [content type][] that matches the section name. For example, Hugo will assume that `posts/post-1.md` has a `posts` content type. If you are using an [archetype][] for your posts section, Hugo will generate front matter according to what it finds in `archetypes/posts.md`.
|
||||
By default, everything created within a section will use the [content type][] that matches the root section name. For example, Hugo will assume that `posts/post-1.md` has a `posts` content type. If you are using an [archetype][] for your posts section, Hugo will generate front matter according to what it finds in `archetypes/posts.md`.
|
||||
|
||||
[archetype]: /content-management/archetypes/
|
||||
[content type]: /content-management/types/
|
||||
|
||||
@@ -88,6 +88,7 @@ The `figure` shortcode can use the following named parameters:
|
||||
* `attr` (i.e., attribution)
|
||||
* `attrlink`
|
||||
* `alt`
|
||||
* `width`
|
||||
|
||||
#### Example `figure` Input
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: Static Files
|
||||
description: "The `static` folder is where you place all your **static files**."
|
||||
date: 2017-11-18
|
||||
categories: [content management]
|
||||
keywords: [source, directories]
|
||||
menu:
|
||||
docs:
|
||||
parent: "content-management"
|
||||
weight: 130
|
||||
weight: 130 #rem
|
||||
aliases: [/static-files]
|
||||
toc: true
|
||||
---
|
||||
|
||||
The `static` folder is where you place all your **static files**, e.g. stylesheets, JavaScript, images etc.
|
||||
|
||||
You can set the name of the static folder to use in your configuration file, for example `config.toml`. From **Hugo 0.31** you can configure as many static directories as you need. All the files in all the static directories will form a union filesystem.
|
||||
|
||||
Example:
|
||||
|
||||
```toml
|
||||
staticDir = ["static1", "static2"]
|
||||
[languages]
|
||||
[languages.no]
|
||||
staticDir = ["staticDir_override", "static_no"]
|
||||
baseURL = "https://example.no"
|
||||
languageName = "Norsk"
|
||||
weight = 1
|
||||
title = "På norsk"
|
||||
|
||||
[languages.en]
|
||||
staticDir2 = "static_en"
|
||||
baseURL = "https://example.com"
|
||||
languageName = "English"
|
||||
weight = 2
|
||||
title = "In English"
|
||||
```
|
||||
|
||||
In the above, with no theme used:
|
||||
|
||||
* The English site will get its static files as a union of "static1", "static2" and "static_en". On file duplicates, the right-most version will win.
|
||||
* The Norwegian site will get its static files as a union of "staticDir_override" and "static_no".
|
||||
|
||||
**Note:** The `2` `static2` (can be a number between 0 and 10) is added to tell Hugo that you want to **add** this directory to the global set of static directories. Using `staticDir` on the language level would replace the global value.
|
||||
|
||||
|
||||
**Note:** The example above is a [multihost setup](/content-management/multilingual/#configure-multilingual-multihost). In a regular setup, all the static directories will be available to all sites.
|
||||
@@ -22,21 +22,21 @@ If you want to continue to use Pygments (see below), set `pygmentsUseClassic=tru
|
||||
|
||||
The example below shows a simple code snippet from the Hugo source highlighted with the `highlight` shortcode. Note that the gohugo.io site is generated with `pygmentsUseClasses=true` (see [Generate Syntax Highlighter CSS](#generate-syntax-highlighter-css)).
|
||||
|
||||
* `linenos=inline` turns on line numbers. Note that the `inline` value only has an effect in Pygments.
|
||||
* `linenos=inline` or `linenos=table` (`table` will give copy-and-paste friendly code blocks) turns on line numbers.
|
||||
* `hl_lines` lists a set of line numbers or line number ranges to be highlighted. Note that the hyphen range syntax is only supported for Chroma.
|
||||
* `linenostart=199` starts the line number count from 199.
|
||||
|
||||
With that, this:
|
||||
|
||||
```
|
||||
{{</* highlight go "linenos=inline,hl_lines=8 15-17,linenostart=199" */>}}
|
||||
{{</* highlight go "linenos=table,hl_lines=8 15-17,linenostart=199" */>}}
|
||||
// ... code
|
||||
{{</* / highlight */>}}
|
||||
```
|
||||
|
||||
Gives this:
|
||||
|
||||
{{< highlight go "linenos=inline,hl_lines=8 15-17,linenostart=199" >}}
|
||||
{{< highlight go "linenos=table,hl_lines=8 15-17,linenostart=199" >}}
|
||||
// GetTitleFunc returns a func that can be used to transform a string to
|
||||
// title case.
|
||||
//
|
||||
@@ -101,12 +101,12 @@ hl_lines
|
||||
: Highlight a space separated list of line numbers. For Chroma, you can provide a list of ranges, i.e. "3-8 10-20".
|
||||
|
||||
|
||||
The full set of supported options for Pygments is: `encoding`, `outencoding`, `nowrap`, `full`, `title`, `style`, `noclasses`, `classprefix`, `cssclass`, `cssstyles`, `prestyles`, `linenos`, `hl_lines`, `linenostart`, `linenostep`, `linenospecial`, `nobackground`, `lineseparator`, `lineanchors`, `linespans`, `anchorlinenos`, `startinline`. See the [Pygments Documentation](http://pygments.org/) for details.
|
||||
The full set of supported options for Pygments is: `encoding`, `outencoding`, `nowrap`, `full`, `title`, `style`, `noclasses`, `classprefix`, `cssclass`, `cssstyles`, `prestyles`, `linenos`, `hl_lines`, `linenostart`, `linenostep`, `linenospecial`, `nobackground`, `lineseparator`, `lineanchors`, `linespans`, `anchorlinenos`, `startinline`. See the [Pygments HTML Formatter Documentation](http://pygments.org/docs/formatters/#HtmlFormatter) for details.
|
||||
|
||||
|
||||
## Generate Syntax Highlighter CSS
|
||||
|
||||
If you run with `pygmentsUseClassic=true` in your site config, you need a style sheet.
|
||||
If you run with `pygmentsUseClasses=true` in your site config, you need a style sheet.
|
||||
|
||||
You can generate one with Hugo:
|
||||
|
||||
|
||||
@@ -54,26 +54,26 @@ To continue with the example of a movie site, the following demonstrates content
|
||||
```
|
||||
Actor <- Taxonomy
|
||||
Bruce Willis <- Term
|
||||
The Sixth Sense <- Content
|
||||
Unbreakable <- Content
|
||||
Moonrise Kingdom <- Content
|
||||
The Sixth Sense <- Value
|
||||
Unbreakable <- Value
|
||||
Moonrise Kingdom <- Value
|
||||
Samuel L. Jackson <- Term
|
||||
Unbreakable <- Content
|
||||
The Avengers <- Content
|
||||
xXx <- Content
|
||||
Unbreakable <- Value
|
||||
The Avengers <- Value
|
||||
xXx <- Value
|
||||
```
|
||||
|
||||
From the perspective of the content, the relationships would appear differently, although the data and labels used are the same:
|
||||
|
||||
```
|
||||
Unbreakable <- Content
|
||||
Unbreakable <- Value
|
||||
Actors <- Taxonomy
|
||||
Bruce Willis <- Term
|
||||
Samuel L. Jackson <- Term
|
||||
Director <- Taxonomy
|
||||
M. Night Shyamalan <- Term
|
||||
...
|
||||
Moonrise Kingdom <- Content
|
||||
Moonrise Kingdom <- Value
|
||||
Actors <- Taxonomy
|
||||
Bruce Willis <- Term
|
||||
Bill Murray <- Term
|
||||
@@ -132,7 +132,7 @@ Note that if you use `preserveTaxonomyNames` and intend to manually construct UR
|
||||
{{% note %}}
|
||||
You can add content and front matter to your taxonomy list and taxonomy terms pages. See [Content Organization](/content-management/organization/) for more information on how to add an `_index.md` for this purpose.
|
||||
|
||||
Note also that taxonomy [permalinks](/content-management/urls/) are *not* configurable.
|
||||
Much like regular pages, taxonomy list [permalinks](/content-management/urls/) are configurable, but taxonomy term page permalinks are not.
|
||||
{{% /note %}}
|
||||
|
||||
## Add Taxonomies to Content
|
||||
@@ -240,7 +240,7 @@ If you need to add custom metadata to your taxonomy terms, you will need to crea
|
||||
---
|
||||
{{< /code >}}
|
||||
|
||||
You can later use your custom metadata as shown in the [Taxonomy Terms Templates documentation](/templates/taxonomy-templates/#displaying-custom-meta-data-in-taxonomy-terms-templates).
|
||||
You can later use your custom metadata as shown in the [Taxonomy Terms Templates documentation](/templates/taxonomy-templates/#displaying-custom-metadata-in-taxonomy-terms-templates).
|
||||
|
||||
[`urlize` template function]: /functions/urlize/
|
||||
[content section]: /content-management/sections/
|
||||
|
||||
@@ -45,6 +45,10 @@ Hugo will take this Markdown and create a table of contents from `## Introductio
|
||||
|
||||
The built-in `.TableOfContents` variables outputs a `<nav id="TableOfContents">` element with a child `<ul>`, whose child `<li>` elements begin with any `<h1>`'s (i.e., `#` in markdown) inside your content.'
|
||||
|
||||
{{% note "Table of contents not available for MMark" %}}
|
||||
Hugo documents created in the [MMark](/content-management/formats/#mmark) Markdown dialect do not currently display TOCs. TOCs are, however, compatible with all other supported Markdown formats.
|
||||
{{% /note %}}
|
||||
|
||||
## Template Example: Basic TOC
|
||||
|
||||
The following is an example of a very basic [single page template][]:
|
||||
|
||||
@@ -43,7 +43,9 @@ permalinks:
|
||||
post = "/:year/:month/:title/"
|
||||
{{< /code >}}
|
||||
|
||||
Only the content under `post/` will have the new URL structure. For example, the file `content/post/sample-entry.md` with `date: 2017-02-27T19:20:00-05:00` in its front matter will render to `public/2017/02/sample-entry/index.html` at build time and therefore be reachable at `https://example.com/2013/11/sample-entry/`.
|
||||
Only the content under `post/` will have the new URL structure. For example, the file `content/post/sample-entry.md` with `date: 2017-02-27T19:20:00-05:00` in its front matter will render to `public/2017/02/sample-entry/index.html` at build time and therefore be reachable at `https://example.com/2017/02/sample-entry/`.
|
||||
|
||||
You can also configure permalinks of taxonomies with the same syntax, by using the plural form of the taxonomy instead of the section. You will probably only want to use the configuration values `:slug` or `:title`.
|
||||
|
||||
### Permalink Configuration Values
|
||||
|
||||
@@ -73,6 +75,9 @@ The following is a list of values that can be used in a `permalink` definition i
|
||||
`:section`
|
||||
: the content's section
|
||||
|
||||
`:sections`
|
||||
: the content's sections hierarchy
|
||||
|
||||
`:title`
|
||||
: the content's title
|
||||
|
||||
|
||||
@@ -46,10 +46,10 @@ Once you have cloned the Hugo repository, you can create a new function via the
|
||||
hugo new functions/newfunction.md
|
||||
```
|
||||
|
||||
The archetype for `functions` according to the Hugo theme is as follows:
|
||||
The archetype for `functions` according to the Hugo docs is as follows:
|
||||
|
||||
{{< code file="archetypes/functions.md" >}}
|
||||
{{< readfile file="/themes/gohugoioTheme/archetypes/functions.md">}}
|
||||
{{< readfile file="/archetypes/functions.md">}}
|
||||
{{< /code >}}
|
||||
|
||||
#### New Function Required Fields
|
||||
@@ -143,8 +143,7 @@ This example HTML code block tells Hugo users the following:
|
||||
2. This snippet is complete enough to be downloaded and implemented in a Hugo project, as demonstrated by `download="single.html"`.
|
||||
|
||||
```
|
||||
{{%/* code file="layouts/_default/single.html" download="single.html" */%}}
|
||||
```
|
||||
{{</* code file="layouts/_default/single.html" download="single.html" */>}}
|
||||
{{ define "main" }}
|
||||
<main>
|
||||
<article>
|
||||
@@ -162,8 +161,7 @@ This example HTML code block tells Hugo users the following:
|
||||
</article>
|
||||
</main>
|
||||
{{ end }}
|
||||
```
|
||||
{{%/* /code */%}}
|
||||
{{</* /code */>}}
|
||||
```
|
||||
|
||||
##### Example 'code' Display
|
||||
|
||||
@@ -105,7 +105,7 @@ min_version = 0.13
|
||||
|
||||
{{% note %}}
|
||||
1. This is different from the `theme.toml` file created by `hugo new theme` in Hugo versions before v0.14.
|
||||
2. Only `theme.toml` is accepted; ie. not `theme.yaml` andnot `theme.json`.
|
||||
2. Only `theme.toml` is accepted; ie. not `theme.yaml` and `theme.json`.
|
||||
{{% /note %}}
|
||||
|
||||
### Images
|
||||
@@ -147,4 +147,4 @@ If you add screenshots to the README, please make use of absolute file paths ins
|
||||
{{% /note %}}
|
||||
|
||||
[artistexample]: https://github.com/digitalcraftsman/hugo-artists-theme/tree/master/exampleSite
|
||||
[themeissuenew]: https://github.com/gohugoio/hugoThemes/issues/new
|
||||
[themeissuenew]: https://github.com/gohugoio/hugoThemes/issues/new
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: "cond"
|
||||
date: 2017-09-08
|
||||
description: "Return one of two arguments, depending on the value of a third argument."
|
||||
categories: [functions]
|
||||
menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
signature: ["cond CONTROL VAR1 VAR2"]
|
||||
aliases: [/functions/cond/]
|
||||
hugoversion: 0.27
|
||||
relatedfuncs: [default]
|
||||
toc: false
|
||||
draft: false
|
||||
needsexamples: false
|
||||
---
|
||||
|
||||
`cond` returns *VAR1* if *CONTROL* is true, or *VAR2* if it is not.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
{{ cond (eq (len $geese) 1) "goose" "geese" }}
|
||||
```
|
||||
|
||||
Would emit "goose" if the `$geese` array has exactly 1 item, or "geese" otherwise.
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: errorf
|
||||
linktitle: errorf
|
||||
description: Evaluates a format string and logs it to ERROR.
|
||||
date: 2017-09-30
|
||||
publishdate: 2017-09-30
|
||||
lastmod: 2017-09-30
|
||||
categories: [functions]
|
||||
menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
keywords: [strings, log, error]
|
||||
signature: ["errorf FORMAT INPUT"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: [printf]
|
||||
deprecated: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
`errorf` will evaluate a format string, then output the result to the ERROR log.
|
||||
This will also cause the build to fail.
|
||||
|
||||
```
|
||||
{{ errorf "Something went horribly wrong! %s" err }}
|
||||
```
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: "fileExists"
|
||||
linktitle: "fileExists"
|
||||
date: 2017-08-31T22:38:22+02:00
|
||||
description: Checks whether a file exists under the given path.
|
||||
godocref:
|
||||
publishdate: 2017-08-31T22:38:22+02:00
|
||||
lastmod: 2017-08-31T22:38:22+02:00
|
||||
categories: [functions]
|
||||
menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
signature: ["fileExists PATH"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: []
|
||||
deprecated: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
`fileExists` allows you to check if a file exists under a given path, e.g. before inserting code into a template:
|
||||
|
||||
```
|
||||
{{ if (fileExists "static/img/banner.jpg") -}}
|
||||
<img src="{{ "img/banner.jpg" | absURL }}" />
|
||||
{{- end }}
|
||||
```
|
||||
|
||||
In the example above, a banner from the `static` folder should be shown if the given path points to an existing file.
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: float
|
||||
linktitle: float
|
||||
description: Creates a `float` from the argument passed into the function.
|
||||
godocref:
|
||||
date: 2017-09-28
|
||||
publishdate: 2017-09-28
|
||||
lastmod: 2017-09-28
|
||||
categories: [functions]
|
||||
menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
keywords: [strings,floats]
|
||||
signature: ["float INPUT"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: []
|
||||
deprecated: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
Useful for turning strings into floating point numbers.
|
||||
|
||||
```
|
||||
{{ float "1.23" }} → 1.23
|
||||
```
|
||||
@@ -25,4 +25,4 @@ See [Installing Hugo][installpygments] for more information on Pygments or [Synt
|
||||
|
||||
[highlight]: /content-management/shortcodes/#highlight
|
||||
[installpygments]: /getting-started/installing/#installing-pygments-optional
|
||||
[syntax]: /tools/syntax-highlighting/
|
||||
[syntax]: /content-management/syntax-highlighting/
|
||||
|
||||
@@ -24,3 +24,28 @@ Useful for turning strings into numbers.
|
||||
```
|
||||
{{ int "123" }} → 123
|
||||
```
|
||||
|
||||
{{% note "Usage Note" %}}
|
||||
If the input string is supposed to represent a decimal number, and if it has
|
||||
leading 0's, then those 0's will have to be removed before passing the string
|
||||
to the `int` function, else that string will be tried to be parsed as an octal
|
||||
number representation.
|
||||
|
||||
The [`strings.TrimLeft` function](/functions/strings.trimleft/) can be used for
|
||||
this purpose.
|
||||
|
||||
```
|
||||
{{ int ("0987" | strings.TrimLeft "0") }}
|
||||
{{ int ("00987" | strings.TrimLeft "0") }}
|
||||
```
|
||||
|
||||
**Explanation**
|
||||
|
||||
The `int` function eventually calls the `ParseInt` function from the Go library
|
||||
`strconv`.
|
||||
|
||||
From its [documentation](https://golang.org/pkg/strconv/#ParseInt):
|
||||
|
||||
> the base is implied by the string's prefix: base 16 for "0x", base 8 for "0",
|
||||
> and base 10 otherwise.
|
||||
{{% /note %}}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: Math
|
||||
description: Hugo provides six mathematical operators in templates.
|
||||
description: Hugo provides nine mathematical operators in templates.
|
||||
godocref:
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
@@ -20,14 +20,14 @@ draft: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
There are 6 basic mathematical operators that can be used in Hugo templates:
|
||||
|
||||
| Function | Description | Example |
|
||||
| -------- | ------------------------ | ----------------------------- |
|
||||
| `add` | Adds two integers. | `{{add 1 2}}` → 3 |
|
||||
| `div` | Divides two integers. | `{{div 6 3}}` → 2 |
|
||||
| `mod` | Modulus of two integers. | `{{mod 15 3}}` → 0 |
|
||||
| `modBool`| Boolean of modulus of two integers. Evaluates to `true` if = 0. | `{{modBool 15 3}}` → true |
|
||||
| `mul` | Multiplies two integers. | `{{mul 2 3}}` → 6 |
|
||||
| `sub` | Subtracts two integers. | `{{sub 3 2}}` → 1 |
|
||||
|
||||
| Function | Description | Example |
|
||||
|----------------|-------------------------------------------------------------------------------|----------------------------------|
|
||||
| `add` | Adds two integers. | `{{add 1 2}}` → 3 |
|
||||
| `div` | Divides two integers. | `{{div 6 3}}` → 2 |
|
||||
| `mod` | Modulus of two integers. | `{{mod 15 3}}` → 0 |
|
||||
| `modBool` | Boolean of modulus of two integers. Evaluates to `true` if result equals 0. | `{{modBool 15 3}}` → true |
|
||||
| `mul` | Multiplies two integers. | `{{mul 2 3}}` → 6 |
|
||||
| `sub` | Subtracts two integers. | `{{sub 3 2}}` → 1 |
|
||||
| `math.Ceil` | Returns the least integer value greater than or equal to the given number. | `{{math.Ceil 2.1}}` → 3 |
|
||||
| `math.Floor` | Returns the greatest integer value less than or equal to the given number. | `{{math.Floor 1.9}}` → 1 |
|
||||
| `math.Round` | Returns the nearest integer, rounding half away from zero. | `{{math.Round 1.5}}` → 2 |
|
||||
|
||||
@@ -10,7 +10,7 @@ categories: [functions]
|
||||
menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
keywords: []
|
||||
keywords: [performance]
|
||||
signature: ["partialCached LAYOUT INPUT [VARIANT...]"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
title: print
|
||||
linktitle: print
|
||||
description: Prints the default representation of the given argument using the standard `fmt.Print` function.
|
||||
godocref: https://golang.org/pkg/fmt/
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
lastmod: 2017-02-01
|
||||
categories: [functions]
|
||||
menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
keywords: [strings]
|
||||
signature: ["print INPUT"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: []
|
||||
deprecated: false
|
||||
---
|
||||
|
||||
See [the go doc](https://golang.org/pkg/fmt/) for additional information.
|
||||
|
||||
```
|
||||
{{ print "foo" }} → "foo"
|
||||
{{ print (slice 1 2 3) }} → [1 2 3]
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: println
|
||||
linktitle: println
|
||||
description: Prints the default representation of the given argument using the standard `fmt.Print` function and enforces a linebreak.
|
||||
godocref: https://golang.org/pkg/fmt/
|
||||
date: 2017-02-01
|
||||
publishdate: 2017-02-01
|
||||
lastmod: 2017-02-01
|
||||
categories: [functions]
|
||||
menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
keywords: [strings]
|
||||
signature: ["println INPUT"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: []
|
||||
deprecated: false
|
||||
---
|
||||
|
||||
See [the go doc](https://golang.org/pkg/fmt/) for additional information. `\n` denotes the linebreak but isn't printed in the templates as seen below:
|
||||
|
||||
```
|
||||
{{ println "foo" }} → "foo\n"
|
||||
```
|
||||
@@ -11,7 +11,7 @@ menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
keywords: [cross references, anchors]
|
||||
signature: ["ref PAGE CONTENT"]
|
||||
signature: ["ref . CONTENT"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: [relref]
|
||||
@@ -19,12 +19,16 @@ deprecated: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
`ref` and `relRef` look up a content page by relative path (`relref`) or logical name (`ref`) to return the permalink. Both functions require a `Page` object (usually satisfied with a "`.`"):
|
||||
`ref` and `relref` look up a content page by logical name (`ref`) or relative path (`relref`) to return the permalink:
|
||||
|
||||
```
|
||||
{{ relref . "about.md" }}
|
||||
{{ ref . "about.md" }}
|
||||
```
|
||||
|
||||
{{% note "Usage Note" %}}
|
||||
`ref` looks up Hugo "Regular Pages" only. It can't be used for the homepage, section pages, etc.
|
||||
{{% /note %}}
|
||||
|
||||
These functions are used in two of Hugo's built-in shortcodes. You can see basic usage examples of both `ref` and `relref` in the [shortcode documentation](/content-management/shortcodes/#ref-and-relref).
|
||||
|
||||
For an extensive explanation of how to leverage `ref` and `relref` for content management, see [Cross References](/content-management/cross-references/).
|
||||
|
||||
@@ -11,20 +11,24 @@ menu:
|
||||
docs:
|
||||
parent: "functions"
|
||||
keywords: [cross references, anchors]
|
||||
signature: ["relref PAGE CONTENT"]
|
||||
signature: ["relref . CONTENT"]
|
||||
workson: []
|
||||
hugoversion:
|
||||
relatedfuncs: [relref]
|
||||
relatedfuncs: [ref]
|
||||
deprecated: false
|
||||
aliases: []
|
||||
---
|
||||
|
||||
`ref` and `relRef` look up a content page by relative path (`relref`) or logical name (`ref`) to return the permalink. Both functions require a `Page` object (usually satisfied with a "`.`"):
|
||||
`ref` and `relref` look up a content page by logical name (`ref`) or relative path (`relref`) to return the permalink:
|
||||
|
||||
```
|
||||
{{ relref . "about.md" }}
|
||||
```
|
||||
|
||||
{{% note "Usage Note" %}}
|
||||
`relref` looks up Hugo "Regular Pages" only. It can't be used for the homepage, section pages, etc.
|
||||
{{% /note %}}
|
||||
|
||||
These functions are used in two of Hugo's built-in shortcodes. You can see basic usage examples of both `ref` and `relref` in the [shortcode documentation](/content-management/shortcodes/#ref-and-relref).
|
||||
|
||||
For an extensive explanation of how to leverage `ref` and `relref` for content management, see [Cross References](/content-management/cross-references/).
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user