mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-31 10:42:38 +00:00
Compare commits
527 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 05875153bc | |||
| 2b90779f0f | |||
| a3d6e7c46f | |||
| 012823a32a | |||
| b9bba2b977 | |||
| 0c2544608c | |||
| c502f078bc | |||
| 4ebaec8906 | |||
| 35a605976e | |||
| 7a8b754cad | |||
| 4076d77029 | |||
| 280df4e380 | |||
| e98f0014f2 | |||
| d65061dffb | |||
| 79767f5617 | |||
| 1ba63f15c8 | |||
| 2a44ca543b | |||
| 79dd1d02b4 | |||
| 57ad3abe7b | |||
| a87f171bd4 | |||
| aeb06c7bcc | |||
| 9173022ea7 | |||
| e799100395 | |||
| 6b8244ba67 | |||
| df4bbcef30 | |||
| be1ee22032 | |||
| 60ed5bda2b | |||
| 296d218e67 | |||
| b520f8852d | |||
| b198cb26ba | |||
| a4a1e39a51 | |||
| 4f75ec985d | |||
| 025a37df2f | |||
| 05b76dcb6f | |||
| 73cbefdbc8 | |||
| 667a047cea | |||
| 0053be979a | |||
| 2194cc77de | |||
| 5df0cf7eca | |||
| 35926dcf37 | |||
| 6049c3a10c | |||
| 2a902bbca6 | |||
| f8e675d064 | |||
| 179225449c | |||
| 4e0208d448 | |||
| c38d694f56 | |||
| ec4b152678 | |||
| 9b192e6793 | |||
| bc9f69e7c5 | |||
| 6b9d4a93da | |||
| be3e5592dc | |||
| 28ffb92b36 | |||
| 08c30b6e44 | |||
| bff1f1e689 | |||
| ef2ad4d91f | |||
| 6d9a2d2497 | |||
| fb7d45e613 | |||
| 3395e1cb92 | |||
| 859a78e1bd | |||
| 1302ef9f63 | |||
| cbd9506c29 | |||
| 58f8b43fee | |||
| f271faea06 | |||
| 5581e33a34 | |||
| 96b6ae81eb | |||
| b52e946381 | |||
| 2e954d8551 | |||
| bdf7cd9f9d | |||
| ac82fe32af | |||
| ef87dffb2f | |||
| 4f813c09ea | |||
| 11fe227b9e | |||
| 9ecf58e29b | |||
| 69c1944f1f | |||
| 4a8de8ea46 | |||
| 41adafbc3e | |||
| 8afff8c7c4 | |||
| c0a046cbfb | |||
| bb9bcdcf30 | |||
| 93bcddebb3 | |||
| aae6fa0b6b | |||
| be37c0b37a | |||
| bd022534bc | |||
| c8269d6dbc | |||
| 4161d542ce | |||
| d1c500c124 | |||
| af1acfbce7 | |||
| ad34be9d77 | |||
| a6170154cf | |||
| 9a83f7a01b | |||
| 62dd1d45c1 | |||
| a01056b98a | |||
| a7ca39ccd7 | |||
| 2e4158b0b4 | |||
| e50b9d8ac1 | |||
| 2fa3761ec9 | |||
| c02a02070f | |||
| 5ee0a3b9a1 | |||
| 895fe536fd | |||
| f733e70e80 | |||
| 51b078a703 | |||
| 6205a16b6e | |||
| 85c04ca2f3 | |||
| 7135d897a2 | |||
| 17fdf7d604 | |||
| 1b3525d638 | |||
| 38131837ba | |||
| d5c58b457f | |||
| eec0e512f9 | |||
| 3dfb475136 | |||
| d84f707da1 | |||
| 3a0ab5a3dd | |||
| 0447c7598b | |||
| 0a775650b5 | |||
| 2540d884d8 | |||
| 2c0ded7f9f | |||
| e53bc948a5 | |||
| 0becad727a | |||
| ea8d0981d5 | |||
| 732b5d42b2 | |||
| ae954d5165 | |||
| 14227351fa | |||
| 64572d2d60 | |||
| dc068ccb87 | |||
| 8fe78f6ff5 | |||
| de05a0d942 | |||
| e74d1b8607 | |||
| 30e804eee5 | |||
| 82fdfa2c72 | |||
| 5cff3e6219 | |||
| ed0fe9ddf7 | |||
| b41622bc49 | |||
| e4af4f652e | |||
| 0bfe9276c2 | |||
| 1dbed5ee06 | |||
| 8ebb85f1f7 | |||
| 1bead0ed7a | |||
| 56dfdfe86c | |||
| bf6407759b | |||
| 8008675983 | |||
| dca7a90181 | |||
| 75c260fa1c | |||
| 11ca84f8cb | |||
| 24ffe04360 | |||
| 5cfb690e31 | |||
| 72ba6d633d | |||
| 3e87d7a86e | |||
| ae9cc09b04 | |||
| c1b9380dfd | |||
| 6dd2e9a49a | |||
| ff9f6e1b2a | |||
| 0ce6f05f59 | |||
| 18b9948f1e | |||
| 1882ffabc6 | |||
| 1da3fd039a | |||
| f45c6bc38a | |||
| 9666f33e2f | |||
| f82c645b33 | |||
| d0825a211a | |||
| f62e3e9940 | |||
| 4f1807c7a7 | |||
| 9564e6e9d8 | |||
| 0e013b5291 | |||
| 3851117c25 | |||
| 50a7f97a62 | |||
| f0634ec059 | |||
| ae15ff0968 | |||
| 44186c6af1 | |||
| fa2e58fd4a | |||
| cb04053385 | |||
| 303be735fb | |||
| c51d040e3d | |||
| 845d09763a | |||
| f8243624e4 | |||
| 438c219892 | |||
| 2ff108fcb7 | |||
| 13b5c10dd7 | |||
| 74d7ae1f8f | |||
| 01da9a40e6 | |||
| 3fd6c1a24e | |||
| 13b067b506 | |||
| f78e2cb854 | |||
| a70acd110e | |||
| 247db151fa | |||
| b82baa285b | |||
| 5550c4148e | |||
| e5aa08ff0c | |||
| 8b84156f87 | |||
| 8055838c70 | |||
| 1c60d5bf20 | |||
| 8d80f9b39e | |||
| 1979f7d9c7 | |||
| e46148f948 | |||
| 065928fcf0 | |||
| 34ac562ce4 | |||
| 70745e8cb5 | |||
| 6aa3e51228 | |||
| c7083a5d36 | |||
| 950d9f55a5 | |||
| de670ced86 | |||
| 6da23f7449 | |||
| 1abc2f0b86 | |||
| a10519643d | |||
| dd574628a0 | |||
| ceb708052a | |||
| f09505a657 | |||
| 6410965b97 | |||
| 357ab956ea | |||
| 0e04b9a029 | |||
| d0ef3d43bd | |||
| f432b187a0 | |||
| a45de56db1 | |||
| db29f57cc4 | |||
| fa29e94edb | |||
| 44d57fdc0c | |||
| 10c7cf2942 | |||
| ba5dadff79 | |||
| 32d9345bba | |||
| b351731f72 | |||
| 860f982cc4 | |||
| e425226a28 | |||
| 07978e4a49 | |||
| 4f335f0c7f | |||
| 445b7d23fb | |||
| aedfa6a2c4 | |||
| ad2c0b5616 | |||
| 13fa7cb748 | |||
| 50d9046b64 | |||
| 40d05f12a7 | |||
| 6017599a3c | |||
| ef595aedfc | |||
| 90a902c843 | |||
| b69694a3ae | |||
| 532e2e7b93 | |||
| 0b6a11c9e3 | |||
| adc559b09f | |||
| ad04f6c899 | |||
| 86233c00a0 | |||
| 1cebce12ad | |||
| b22364570b | |||
| 1fbcaf9279 | |||
| 226bc8f59f | |||
| 23a5711d26 | |||
| 23a711a29a | |||
| 9af47f07d3 | |||
| f4cb8e1688 | |||
| 789aa6ad76 | |||
| 861472bea5 | |||
| 1d0d280e20 | |||
| a7dae30a8f | |||
| bc7c9221f3 | |||
| 90355eec79 | |||
| df0523ff7f | |||
| 5003f7f7af | |||
| d20b41a2cf | |||
| 9388f23606 | |||
| b580a25d1f | |||
| 764abd2067 | |||
| dde965a5cd | |||
| cd71eb7389 | |||
| a5606b06ca | |||
| 471fb1ff69 | |||
| f3c816eabd | |||
| 3558e3d6f0 | |||
| 90090175f8 | |||
| 678ddef46a | |||
| 4d333e81ee | |||
| 4263094d75 | |||
| be5ace1588 | |||
| e58d8fe791 | |||
| f5fda80486 | |||
| 0318f7c149 | |||
| e6ace71fec | |||
| 4993152dda | |||
| 6e1268f45b | |||
| 895638433e | |||
| 9500ec1b6b | |||
| 197aacb647 | |||
| 06da609138 | |||
| 6fa6f69a4a | |||
| d712d6f331 | |||
| 9032a228b0 | |||
| 54a2790fce | |||
| 689cda1740 | |||
| 19cb6c7819 | |||
| 2176d2c197 | |||
| ff8b52758d | |||
| 80009b427f | |||
| 94a3184ad0 | |||
| 5a66fa3954 | |||
| eb117eb904 | |||
| f0211b84a1 | |||
| 03d1a57fea | |||
| 5e14af957a | |||
| 7468292c4e | |||
| d829e05036 | |||
| 2aaf92b515 | |||
| be7ba0e98f | |||
| 266f583a8c | |||
| dcfcbac589 | |||
| 18f2b82658 | |||
| 48e1068e3e | |||
| 8efb90ebd5 | |||
| 3ae8dda203 | |||
| aa9b9d596e | |||
| 8ce4bc7ab8 | |||
| 94d7fe52f8 | |||
| 92cff05582 | |||
| ff2b98c9dd | |||
| f34ea6108d | |||
| db50154e75 | |||
| 4250bf8e30 | |||
| c9223cfd7b | |||
| 8df88496e2 | |||
| bffe4baf42 | |||
| 52e8c7a0ac | |||
| 784077da4d | |||
| 311e102223 | |||
| 5374242ff7 | |||
| c510140c0c | |||
| 67b2abaf09 | |||
| d8e1834910 | |||
| a82efe5bb1 | |||
| 6b0752e8c0 | |||
| c6fe87b14e | |||
| c75da346e1 | |||
| 172ff5ea7a | |||
| d45fb72f67 | |||
| 803a0fce1e | |||
| 2ebfb33fe0 | |||
| 2f10da1570 | |||
| 74b55fc7c8 | |||
| 998b2f73f8 | |||
| 6274aa0a64 | |||
| 610c06e658 | |||
| d4d9da9f3a | |||
| cb00917af6 | |||
| 4004687fb2 | |||
| 7919603fb5 | |||
| c6ad532b94 | |||
| 13d2c55206 | |||
| 79d9f82e79 | |||
| 207d8fb7af | |||
| 3ecc698f5e | |||
| a591a10626 | |||
| d841d522f1 | |||
| ba82a20321 | |||
| ee5865f239 | |||
| 0a9dc705f3 | |||
| b268e639ba | |||
| 6c8e7edbb4 | |||
| 4349216deb | |||
| 0fdea0c2c2 | |||
| 097b782a80 | |||
| b14b61af37 | |||
| bc3c229002 | |||
| c32f401b15 | |||
| a792ec09ce | |||
| 4ed43e8076 | |||
| 71678a7183 | |||
| 3ab5245049 | |||
| 1bb00b8c19 | |||
| 554375b2ad | |||
| 1de1992664 | |||
| 9930011ea2 | |||
| 7b1f0960e3 | |||
| f28a8fa0c2 | |||
| 9d15262ee5 | |||
| 0fabd51ab1 | |||
| 7461ed63ae | |||
| 599e6672f7 | |||
| ae7112977d | |||
| eb4288e3cd | |||
| 00839567c7 | |||
| 35b35a7004 | |||
| 6f424175bf | |||
| 3d0dc1acb1 | |||
| 301d2bafcd | |||
| 5aa47a7b07 | |||
| 8415c5e6c7 | |||
| acd5ea0e75 | |||
| 8058abd707 | |||
| eff8457ac9 | |||
| 2dcdd67378 | |||
| c4bcdebc59 | |||
| e2744d403c | |||
| 2542836bbc | |||
| 8f330626bc | |||
| c713beba4d | |||
| ec821739bc | |||
| 8eca8f8aa0 | |||
| e66ba5d2a7 | |||
| 0a79edd48a | |||
| 3ae8078d3a | |||
| 8c0ab4def1 | |||
| b76b80c564 | |||
| b9e835b101 | |||
| 23a98ad05c | |||
| 0f143dcf14 | |||
| 9308cd6a7a | |||
| 3c3fc45d3c | |||
| 480e01eb15 | |||
| 7a51a8a5a3 | |||
| b4bcc591e4 | |||
| 6e27239485 | |||
| ca5a94a988 | |||
| c661d9803e | |||
| ec02fa4bdd | |||
| 8968524900 | |||
| 97eb9225a7 | |||
| 5664780cca | |||
| 2d11d1bd67 | |||
| 31a1ade1b4 | |||
| c689d46aa1 | |||
| b13afc4178 | |||
| 023567b05e | |||
| 2f9b582dbe | |||
| cb39f052d1 | |||
| 8c03141307 | |||
| ec1a3a8db9 | |||
| 3fdcd0ba7c | |||
| 0305c82513 | |||
| f610d45cd8 | |||
| dd19d0cc77 | |||
| 17aafb39dd | |||
| 5b3b0f9556 | |||
| 0233708907 | |||
| ac26de205e | |||
| d5518c0966 | |||
| 45ce6e2b30 | |||
| bb273df4cd | |||
| 733c0207cb | |||
| 2bf24877a6 | |||
| 2bbecc7bc8 | |||
| 309db474c7 | |||
| e26b43f6d9 | |||
| e67db666c8 | |||
| 085ce15f7c | |||
| 274d324c8b | |||
| fa55cd9857 | |||
| 0595f27e6d | |||
| 19538a1bd6 | |||
| fc5e92cc24 | |||
| e2a28114d1 | |||
| 4f17ad69a7 | |||
| 7a13434dd9 | |||
| a8b3e1537f | |||
| 04a0dbbf73 | |||
| 6a5e4b363a | |||
| 49b8ac5fbc | |||
| a870f4d955 | |||
| d89c7ec7a2 | |||
| 780e2f311b | |||
| 42de9bd8bb | |||
| 0e57fcc9c2 | |||
| 783f0d6154 | |||
| 6789b6c5ce | |||
| 78afe8d344 | |||
| c5715e9800 | |||
| f31ec3c280 | |||
| de9f9ae16e | |||
| 57b206ca11 | |||
| f6e590e536 | |||
| 6a1a038c57 | |||
| 6efbd93a38 | |||
| def5f10183 | |||
| dff86cb22c | |||
| 21a7b72535 | |||
| 52c089ffbd | |||
| ddad1e04ac | |||
| 66610a65d1 | |||
| d36d7fba6a | |||
| 47783c1f03 | |||
| 3e539c7126 | |||
| 03e804ffd2 | |||
| c9a09418e7 | |||
| 4efdb90943 | |||
| 61258858af | |||
| 736677a21d | |||
| 7ab28c564f | |||
| 92c31bbe10 | |||
| d5f5543061 | |||
| e08d14ad49 | |||
| b7bbc28caf | |||
| c560a7537a | |||
| b2385f062a | |||
| dd9a7e6455 | |||
| 16b1f284ca | |||
| f2e4c9d709 | |||
| 3ad3f2f0e0 | |||
| 580bb9bb5b | |||
| 2dde27f0dc | |||
| 627cf26571 | |||
| 8fae5f0dd6 | |||
| dcd8ff716a | |||
| f199004989 | |||
| 8d50dd9160 | |||
| c24112ce86 | |||
| 649560fca2 | |||
| 7a521ad1a1 | |||
| b7b6f054a9 | |||
| 75a2e6d4e8 | |||
| d9b5f9cd9e | |||
| f857f4caba | |||
| d4caa8ee95 | |||
| 51e3098548 | |||
| e76c3feb52 | |||
| a6914e9c4c | |||
| 8403dba3ee | |||
| 4951ff998c | |||
| aee48725eb | |||
| d2a6267ad7 | |||
| 3c80cd323c | |||
| 94e577740d | |||
| d0ff31269a | |||
| f851c4162b | |||
| b024454ea9 | |||
| 67f4da30b1 | |||
| 6c42d3d490 | |||
| 431fa0e2d7 | |||
| a7f5f97bc2 | |||
| 4d2fbfc760 | |||
| 8aff6cc373 | |||
| f875577197 | |||
| 77d142ba17 | |||
| 1aa125cf68 | |||
| 0d63bf00c3 |
@@ -0,0 +1,7 @@
|
||||
hugo
|
||||
docs/public*
|
||||
hugo.exe
|
||||
*.swp
|
||||
*.swo
|
||||
.DS_Store
|
||||
*~
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
language: go
|
||||
go:
|
||||
- 1.1
|
||||
- tip
|
||||
script:
|
||||
- go test ./...
|
||||
- go build
|
||||
- ./hugo -s docs/
|
||||
install:
|
||||
- go get github.com/stretchr/testify
|
||||
- go get -v ./...
|
||||
@@ -1,438 +1,101 @@
|
||||
# Hugo
|
||||
A Fast and Flexible Static Site Generator built with love by [spf13](http://spf13.com)
|
||||
and [friends](http://github.com/spf13/hugo/graphs/contributors) in Go.
|
||||
|
||||
A really fast static site generator written in GoLang.
|
||||
[](https://travis-ci.org/spf13/hugo)
|
||||
[](https://app.wercker.com/project/bykey/1a0de7d703ce3b80527f00f675e1eb32)
|
||||
|
||||
## Overview
|
||||
|
||||
Hugo is a static site generator written in GoLang. It is optimized for
|
||||
Hugo is a static site generator written in Go. It is optimized for
|
||||
speed, easy use and configurability. Hugo takes a directory with content and
|
||||
templates and renders them into a full html website.
|
||||
|
||||
Hugo makes use of markdown files with front matter for meta data.
|
||||
Hugo makes use of markdown files with front matter for meta data.
|
||||
|
||||
A typical website of moderate size can be
|
||||
rendered in a fraction of a second. It is written to work well with any
|
||||
kind of website including blogs, tumbles and docs.
|
||||
A typical website of moderate size can be
|
||||
rendered in a fraction of a second. A good rule of thumb is that Hugo
|
||||
takes around 1 millisecond for each piece of content.
|
||||
|
||||
It is written to work well with any
|
||||
kind of website including blogs, tumbles and docs.
|
||||
|
||||
**Complete documentation is available at [Hugo Documentation](http://hugo.spf13.com).**
|
||||
|
||||
# Getting Started
|
||||
|
||||
## Installing Hugo
|
||||
|
||||
Installation is very easy. Simply download the appropriate version for your
|
||||
platform. Hugo is written in GoLang with support for Windows, Linux and OSX.
|
||||
Hugo is written in Go with support for Windows, Linux, FreeBSD and OSX.
|
||||
|
||||
Please make sure that you place the executable in your path. `/usr/local/bin`
|
||||
The latest release can be found at [hugo releases](https://github.com/spf13/hugo/releases).
|
||||
We currently build for Windows, Linux, FreeBSD and OS X for x64
|
||||
and 386 architectures.
|
||||
|
||||
### Installing Hugo (binary)
|
||||
|
||||
Installation is very easy. Simply download the appropriate version for your
|
||||
platform from [hugo releases](https://github.com/spf13/hugo/releases).
|
||||
Once downloaded it can be run from anywhere. You don't need to install
|
||||
it into a global location. This works well for shared hosts and other systems
|
||||
where you don't have a privileged account.
|
||||
|
||||
Ideally you should install it somewhere in your path for easy use. `/usr/local/bin`
|
||||
is the most probable location.
|
||||
|
||||
Hugo doesn't have any external dependencies, but can benefit from external
|
||||
programs.
|
||||
*The Hugo executable has no external dependencies.*
|
||||
|
||||
## Installing from source
|
||||
### Installing from source
|
||||
|
||||
Make sure you have a recent version of go installed. Hugo requires go 1.1+.
|
||||
#### Dependencies
|
||||
|
||||
* Git
|
||||
* Go 1.1+
|
||||
* Mercurial
|
||||
* Bazaar
|
||||
|
||||
#### Clone locally (for contributors):
|
||||
|
||||
git clone https://github.com/spf13/hugo
|
||||
cd hugo
|
||||
go get
|
||||
|
||||
Because go expects all of your libraries to be found in either $GOROOT or $GOPATH,
|
||||
it's helpful to symlink the project to one of the following paths:
|
||||
|
||||
* ln -s /path/to/your/hugo $GOPATH/src/github.com/spf13/hugo
|
||||
* ln -s /path/to/your/hugo $GOROOT/src/pkg/github.com/spf13/hugo
|
||||
|
||||
#### Get directly from Github:
|
||||
|
||||
If you only want to build from source, it's even easier.
|
||||
|
||||
go get github.com/spf13/hugo
|
||||
|
||||
#### Building Hugo
|
||||
|
||||
cd /path/to/hugo
|
||||
go build -o hugo main.go
|
||||
mv hugo /usr/local/bin/
|
||||
|
||||
#### Running Hugo
|
||||
|
||||
## Source Directory Organization
|
||||
cd /path/to/hugo
|
||||
go install github.com/spf13/hugo/hugolib
|
||||
go run main.go
|
||||
|
||||
Hugo takes a single directory and uses it as the input for creating a complete website.
|
||||
#### Contribution Guidelines
|
||||
|
||||
Hugo has a very small amount of configuration, while remaining highly customizable.
|
||||
It accomplishes by assuming that you will only provide templates with the intent of
|
||||
using them.
|
||||
We welcome your contributions. To make the process as seamless as possible, we ask for the following:
|
||||
|
||||
An example directory may look like:
|
||||
* Go ahead and fork the project and make your changes. We encourage pull requests to discuss code changes.
|
||||
* When you're ready to create a pull request, be sure to:
|
||||
* Have test cases for the new code. If you have questions about how to do it, please ask in your pull request.
|
||||
* Run `go fmt`
|
||||
* Squash your commits into a single commit. `git rebase -i`. It's okay to force update your pull request.
|
||||
* Make sure `go test ./...` passes, and go build completes. Our Travis CI loop will catch most things that are missing. The exception: Windows. We run on windows from time to time, but if you have access please check on a Windows machine too.
|
||||
|
||||
.
|
||||
├── config.json
|
||||
├── content
|
||||
| ├── post
|
||||
| | ├── firstpost.md
|
||||
| | └── secondpost.md
|
||||
| └── quote
|
||||
| | ├── first.md
|
||||
| | └── second.md
|
||||
├── layouts
|
||||
| ├── chrome
|
||||
| | ├── header.html
|
||||
| | └── footer.html
|
||||
| ├── indexes
|
||||
| | ├── category.html
|
||||
| | ├── post.html
|
||||
| | ├── quote.html
|
||||
| | └── tag.html
|
||||
| ├── post
|
||||
| | ├── li.html
|
||||
| | ├── single.html
|
||||
| | └── summary.html
|
||||
| ├── quote
|
||||
| | ├── li.html
|
||||
| | ├── single.html
|
||||
| | └── summary.html
|
||||
| ├── shortcodes
|
||||
| | ├── img.html
|
||||
| | ├── vimeo.html
|
||||
| | └── youtube.html
|
||||
| ├── index.html
|
||||
| └── rss.xml
|
||||
└── public
|
||||
**Complete documentation is available at [Hugo Documentation](http://hugo.spf13.com).**
|
||||
|
||||
This directory structure tells us a lot about this site:
|
||||
|
||||
1. the website intends to have two different types of content, posts and quotes.
|
||||
2. It will also apply two different indexes to that content, categories and tags.
|
||||
3. It will be displaying content in 3 different views, a list, a summary and a full page view.
|
||||
|
||||
Included with the repository is an example site ready to be rendered.
|
||||
|
||||
## Configuration
|
||||
|
||||
The directory structure and templates provide the majority of the
|
||||
configuration for a site. In fact a config file isn't even needed for many websites
|
||||
since the defaults used follow commonly used patterns.
|
||||
|
||||
The following is an example of a config file with the default values
|
||||
|
||||
{
|
||||
"SourceDir" : "content",
|
||||
"LayoutDir" : "layouts",
|
||||
"PublishDir" : "public",
|
||||
"BuildDrafts" : false,
|
||||
"Tags" : { "category" : "categories", "tag" : "tags" },
|
||||
"BaseUrl" : "http://yourSite.com/"
|
||||
}
|
||||
|
||||
## Usage
|
||||
Make sure either hugo is in your path or provide a path to it.
|
||||
|
||||
$ hugo --help
|
||||
usage: hugo [flags] []
|
||||
-b="": hostname (and path) to the root eg. http://spf13.com/
|
||||
-c="config.json": config file (default is path/config.json)
|
||||
-d=false: include content marked as draft
|
||||
-h=false: show this help
|
||||
-k=false: analyze content and provide feedback
|
||||
-p="": filesystem path to read files relative from
|
||||
-w=false: watch filesystem for changes and recreate as needed
|
||||
-s=false: a (very) simple webserver
|
||||
-p="1313": port for webserver to run on
|
||||
|
||||
The most common use is probably to run hugo with your current
|
||||
directory being the input directory.
|
||||
|
||||
|
||||
$ hugo
|
||||
> X pages created
|
||||
> Y indicies created
|
||||
|
||||
|
||||
If you are working on things and want to see the changes
|
||||
immediately, tell Hugo to watch for changes. **It will
|
||||
recreate the site faster than you can tab over to
|
||||
your browser to view the changes.**
|
||||
|
||||
$ hugo -p ~/mysite -w
|
||||
|
||||
|
||||
# Layout
|
||||
|
||||
Hugo is very flexible about how you organize and structure your content.
|
||||
|
||||
## Templates
|
||||
|
||||
Hugo uses the excellent golang html/template library for it's template engine. It is an extremely
|
||||
lightweight engine that provides a very small amount of logic. In our
|
||||
experience that it is just the right amount of logic to be able to create a good static website
|
||||
|
||||
This document will not cover how to use golang templates, but the [golang docs](http://golang.org/pkg/html/template/)
|
||||
provide a good introduction.
|
||||
|
||||
### Template roles
|
||||
|
||||
There are 5 different kinds of templates that Hugo works with.
|
||||
|
||||
#### index.html
|
||||
This file must exist in the layouts directory. It is the template used to render the
|
||||
homepage of your site.
|
||||
|
||||
#### rss.xml
|
||||
This file must exist in the layouts directory. It will be used to render all rss documents.
|
||||
The one provided in the example application will generate an ATOM format.
|
||||
|
||||
*Important: Hugo will automatically add the following header line to this file.*
|
||||
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
|
||||
#### Indexes
|
||||
An index is a page that list multiple pieces of content. If you think of a typical blog, the tag
|
||||
pages are good examples of indexes.
|
||||
|
||||
|
||||
#### Content Type(s)
|
||||
Hugo supports multiple types of content. Another way of looking at this is that Hugo has the ability
|
||||
to render content in a variety of ways as determined by the type.
|
||||
|
||||
#### Chrome
|
||||
Chrome is simply the decoration of your site. It's not a requirement to have this, but in practice
|
||||
it's very convenient. Hugo doesn't know anything about Chrome, it's simply a convention that you may
|
||||
likely find beneficial. As you create the rest of your templates you will include templates from the
|
||||
/layout/chrome directory. I've found it helpful to include a header and footer template
|
||||
in Chrome so I can include those in the other full page layouts (index.html, indexes/ type/single.html).
|
||||
|
||||
### Adding a new content type
|
||||
|
||||
Adding a type is easy.
|
||||
|
||||
**Step 1:**
|
||||
Create a directory with the name of the type in layouts.Type is always singular. *Eg /layouts/post*.
|
||||
|
||||
**Step 2:**
|
||||
Create a file called single.html inside your directory. *Eg /layouts/post/single.html*.
|
||||
|
||||
**Step 3:**
|
||||
Create a file with the same name as your directory in /layouts/indexes/. *Eg /layouts/index/post.html*.
|
||||
|
||||
**Step 4:**
|
||||
Many sites support rendering content in a few different ways, for instance a single page view and a
|
||||
summary view to be used when displaying a list of contents on a single page. Hugo makes no assumptions
|
||||
here about how you want to display your content, and will support as many different views of a content
|
||||
type as your site requires. All that is required for these additional views is that a template
|
||||
exists in each layout/type directory with the same name.
|
||||
|
||||
For these, reviewing the example site will be very helpful in order to understand how these types work.
|
||||
|
||||
## Variables
|
||||
|
||||
Hugo makes a set of values available to the templates. Go templates are context based. The following
|
||||
are available in the context for the templates.
|
||||
|
||||
**.Title** The title for the content. <br>
|
||||
**.Description** The description for the content.<br>
|
||||
**.Keywords** The meta keywords for this content.<br>
|
||||
**.Date** The date the content is published on.<br>
|
||||
**.Indexes** These will use the field name of the plural form of the index (see tags and categories above)<br>
|
||||
**.Permalink** The Permanent link for this page.<br>
|
||||
**.FuzzyWordCount** The approximate number of words in the content.<br>
|
||||
**.RSSLink** Link to the indexes' rss link <br>
|
||||
|
||||
Any value defined in the front matter, including indexes will be made available under `.Params`.
|
||||
Take for example I'm using tags and categories as my indexes. The following would be how I would access them:
|
||||
|
||||
**.Params.Tags** <br>
|
||||
**.Params.Categories** <br>
|
||||
|
||||
Also available is `.Site` which has the following:
|
||||
|
||||
**.Site.BaseUrl** The base URL for the site as defined in the config.json file.<br>
|
||||
**.Site.Indexes** The names of the indexes of the site.<br>
|
||||
**.Site.LastChange** The date of the last change of the most recent content.<br>
|
||||
**.Site.Recent** Array of all content ordered by Date, newest first<br>
|
||||
|
||||
# Content
|
||||
Hugo uses markdown files with headers commonly called the front matter. Hugo respects the organization
|
||||
that you provide for your content to minimize any extra configuration, though this can be overridden
|
||||
by additional configuration in the front matter.
|
||||
|
||||
## Organization
|
||||
In Hugo the content should be arranged in the same way they are intended for the rendered website.
|
||||
Without any additional configuration the following will just work.
|
||||
|
||||
.
|
||||
└── content
|
||||
├── post
|
||||
| ├── firstpost.md // <- http://site.com/post/firstpost.html
|
||||
| └── secondpost.md // <- http://site.com/post/secondpost.html
|
||||
└── quote
|
||||
├── first.md // <- http://site.com/quote/first.html
|
||||
└── second.md // <- http://site.com/quote/second.html
|
||||
|
||||
|
||||
## Front Matter
|
||||
|
||||
The front matter is one of the features that gives Hugo it's strength. It enables
|
||||
you to include the meta data of the content right with it. Hugo supports a few
|
||||
different formats. The main format supported is JSON. Here is an example:
|
||||
|
||||
{
|
||||
"Title": "spf13-vim 3.0 release and new website",
|
||||
"Description": "spf13-vim is a cross platform distribution of vim plugins and resources for Vim.",
|
||||
"Tags": [ ".vimrc", "plugins", "spf13-vim", "vim" ],
|
||||
"Pubdate": "2012-04-06",
|
||||
"Categories": [ "Development", "VIM" ],
|
||||
"Slug": "spf13-vim-3-0-release-and-new-website"
|
||||
}
|
||||
|
||||
### Variables
|
||||
There are a few predefined variables that Hugo is aware of and utilizes. The user can also create
|
||||
any variable they want to. These will be placed into the `.Params` variable available to the templates.
|
||||
|
||||
#### Required
|
||||
|
||||
**Title** The title for the content. <br>
|
||||
**Description** The description for the content.<br>
|
||||
**Pubdate** The date the content will be sorted by.<br>
|
||||
**Indexes** These will use the field name of the plural form of the index (see tags and categories above)
|
||||
|
||||
#### Optional
|
||||
|
||||
**Draft** If true the content will not be rendered unless `hugo` is called with -d<br>
|
||||
**Type** The type of the content (will be derived from the directory automatically if unset).<br>
|
||||
**Slug** The token to appear in the tail of the url.<br>
|
||||
*or*<br>
|
||||
**Url** The full path to the content from the web root.<br>
|
||||
*If neither is present the filename will be used.*
|
||||
|
||||
## Example
|
||||
Somethings are better shown than explained. The following is a very basic example of a content file:
|
||||
|
||||
**mysite/project/nitro.md <- http://mysite.com/project/nitro.html**
|
||||
|
||||
{
|
||||
"Title": "Nitro : A quick and simple profiler for golang",
|
||||
"Description": "",
|
||||
"Keywords": [ "Development", "golang", "profiling" ],
|
||||
"Tags": [ "Development", "golang", "profiling" ],
|
||||
"Pubdate": "2013-06-19",
|
||||
"Topics": [ "Development", "GoLang" ],
|
||||
"Slug": "nitro",
|
||||
"project_url": "http://github.com/spf13/nitro"
|
||||
}
|
||||
|
||||
# Nitro
|
||||
|
||||
Quick and easy performance analyzer library for golang.
|
||||
|
||||
## Overview
|
||||
|
||||
Nitro is a quick and easy performance analyzer library for golang.
|
||||
It is useful for comparing A/B against different drafts of functions
|
||||
or different functions.
|
||||
|
||||
## Implementing Nitro
|
||||
|
||||
Using Nitro is simple. First use go get to install the latest version
|
||||
of the library.
|
||||
|
||||
$ go get github.com/spf13/nitro
|
||||
|
||||
Next include nitro in your application.
|
||||
|
||||
|
||||
|
||||
# Extras
|
||||
|
||||
## Shortcodes
|
||||
Because Hugo uses markdown for it's content format, it was clear that there's a lot of things that
|
||||
markdown doesn't support well. This is good, the simple nature of markdown is exactly why we chose it.
|
||||
|
||||
However we cannot accept being constrained by our simple format. Also unacceptable is writing raw
|
||||
html in our markdown every time we want to include unsupported content such as a video. To do
|
||||
so is in complete opposition to the intent of using a bare bones format for our content and
|
||||
utilizing templates to apply styling for display.
|
||||
|
||||
To avoid both of these limitations Hugo has full support for shortcodes.
|
||||
|
||||
### What is a shortcode?
|
||||
A shortcode is a simple snippet inside a markdown file that Hugo will render using a template.
|
||||
|
||||
Short codes are designated by the opening and closing characters of '{{%' and '%}}' respectively.
|
||||
Short codes are space delimited. The first word is always the name of the shortcode. Following the
|
||||
name are the parameters. The author of the shortcode can choose if the short code
|
||||
will use positional parameters or named parameters (but not both). A good rule of thumb is that if a
|
||||
short code has a single required value in the case of the youtube example below then positional
|
||||
works very well. For more complex layouts with optional parameters named parameters work best.
|
||||
|
||||
The format for named parameters models that of html with the format name="value"
|
||||
|
||||
### Example: youtube
|
||||
|
||||
{{% youtube 09jf3ow9jfw %}}
|
||||
|
||||
This would be rendered as
|
||||
|
||||
<div class="embed video-player">
|
||||
<iframe class="youtube-player" type="text/html"
|
||||
width="640" height="385"
|
||||
src="http://www.youtube.com/embed/09jf3ow9jfw"
|
||||
allowfullscreen frameborder="0">
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
### Example: image with caption
|
||||
|
||||
{{% img src="/media/spf13.jpg" title="Steve Francia" %}}
|
||||
|
||||
Would be rendered as:
|
||||
|
||||
<figure >
|
||||
<img src="/media/spf13.jpg" />
|
||||
<figcaption>
|
||||
<h4>Steve Francia</h4>
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
|
||||
### Creating a shortcode
|
||||
|
||||
All that you need to do to create a shortcode is place a template in the layouts/shortcodes directory.
|
||||
|
||||
The template name will be the name of the shortcode.
|
||||
|
||||
**Inside the template**
|
||||
|
||||
To access a parameter by either position or name the index method can be used.
|
||||
|
||||
{{ index .Params 0 }}
|
||||
or
|
||||
{{ index .Params "class" }}
|
||||
|
||||
To check if a parameter has been provided use the isset method provided by Hugo.
|
||||
|
||||
{{ if isset .Params "class"}} class="{{ index .Params "class"}}" {{ end }}
|
||||
|
||||
|
||||
# Meta
|
||||
|
||||
## Release Notes
|
||||
|
||||
* **0.7.0** July 4, 2013
|
||||
* Hugo now includes a simple server
|
||||
* First public release
|
||||
* **0.6.0** July 2, 2013
|
||||
* Hugo includes an example documentation site which it builds
|
||||
* **0.5.0** June 25, 2013
|
||||
* Hugo is quite usable and able to build spf13.com
|
||||
|
||||
## Roadmap
|
||||
In no particular order, here is what I'm working on:
|
||||
|
||||
* Pagination
|
||||
* Support for top level pages (other than homepage)
|
||||
* Series support
|
||||
* Syntax highlighting
|
||||
* Previous & Next
|
||||
* Related Posts
|
||||
* Support for TOML front matter
|
||||
* Proper YAML support for front matter
|
||||
* Support for other formats
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork it
|
||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||
4. Push to the branch (`git push origin my-new-feature`)
|
||||
5. Create new Pull Request
|
||||
|
||||
## Contributors
|
||||
|
||||
* [spf13](https://github.com/spf13)
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Hugo is released under the Simple Public License. See [LICENSE.md](https://github.com/spf13/hugo/blob/master/LICENSE.md).
|
||||
[](https://github.com/igrigorik/ga-beacon)
|
||||
[](https://bitdeli.com/free "Bitdeli Badge")
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
PASS
|
||||
BenchmarkChain 500000 7074 ns/op 3913 B/op 15 allocs/op
|
||||
ok github.com/spf13/hugo/transform 3.669s
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright © 2013 Steve Francia <spf@spf13.com>.
|
||||
//
|
||||
// Licensed under the Simple Public 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://opensource.org/licenses/Simple-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
)
|
||||
|
||||
var cpuProfilefile string
|
||||
var benchmarkTimes int
|
||||
|
||||
var benchmark = &cobra.Command{
|
||||
Use: "benchmark",
|
||||
Short: "Benchmark hugo by building a site a number of times",
|
||||
Long: `Hugo can build a site many times over and anlyze the
|
||||
running process creating a `,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
InitializeConfig()
|
||||
bench(cmd, args)
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
benchmark.Flags().StringVar(&cpuProfilefile, "outputfile", "/tmp/hugo-cpuprofile", "path/filename for the profile file")
|
||||
benchmark.Flags().IntVarP(&benchmarkTimes, "count", "n", 13, "number of times to build the site")
|
||||
}
|
||||
|
||||
func bench(cmd *cobra.Command, args []string) {
|
||||
f, err := os.Create(cpuProfilefile)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pprof.StartCPUProfile(f)
|
||||
defer pprof.StopCPUProfile()
|
||||
|
||||
for i := 0; i < benchmarkTimes; i++ {
|
||||
_ = buildSite()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright © 2013 Steve Francia <spf@spf13.com>.
|
||||
//
|
||||
// Licensed under the Simple Public 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://opensource.org/licenses/Simple-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/hugolib"
|
||||
)
|
||||
|
||||
var check = &cobra.Command{
|
||||
Use: "check",
|
||||
Short: "Check content in the source directory",
|
||||
Long: `Hugo will perform some basic analysis on the
|
||||
content provided and will give feedback.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
InitializeConfig()
|
||||
site := hugolib.Site{}
|
||||
site.Analyze()
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
// Copyright © 2013 Steve Francia <spf@spf13.com>.
|
||||
//
|
||||
// Licensed under the Simple Public 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://opensource.org/licenses/Simple-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 (
|
||||
"fmt"
|
||||
"path"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/hugolib"
|
||||
"github.com/spf13/hugo/parser"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
|
||||
var OutputDir string
|
||||
var Unsafe bool
|
||||
|
||||
var convertCmd = &cobra.Command{
|
||||
Use: "convert",
|
||||
Short: "Convert will modify your content to different formats",
|
||||
Long: `Convert will modify your content to different formats`,
|
||||
Run: nil,
|
||||
}
|
||||
|
||||
var toJSONCmd = &cobra.Command{
|
||||
Use: "toJSON",
|
||||
Short: "Convert front matter to JSON",
|
||||
Long: `toJSON will convert all front matter in the content
|
||||
directory to use JSON for the front matter`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := convertContents(rune([]byte(parser.JSON_LEAD)[0]))
|
||||
if err != nil {
|
||||
jww.ERROR.Println(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var toTOMLCmd = &cobra.Command{
|
||||
Use: "toTOML",
|
||||
Short: "Convert front matter to TOML",
|
||||
Long: `toTOML will convert all front matter in the content
|
||||
directory to use TOML for the front matter`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := convertContents(rune([]byte(parser.TOML_LEAD)[0]))
|
||||
if err != nil {
|
||||
jww.ERROR.Println(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
var toYAMLCmd = &cobra.Command{
|
||||
Use: "toYAML",
|
||||
Short: "Convert front matter to YAML",
|
||||
Long: `toYAML will convert all front matter in the content
|
||||
directory to use YAML for the front matter`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := convertContents(rune([]byte(parser.YAML_LEAD)[0]))
|
||||
if err != nil {
|
||||
jww.ERROR.Println(err)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
convertCmd.AddCommand(toJSONCmd)
|
||||
convertCmd.AddCommand(toTOMLCmd)
|
||||
convertCmd.AddCommand(toYAMLCmd)
|
||||
convertCmd.PersistentFlags().StringVarP(&OutputDir, "output", "o", "", "filesystem path to write files to")
|
||||
convertCmd.PersistentFlags().BoolVar(&Unsafe, "unsafe", false, "enable less safe operations, please backup first")
|
||||
}
|
||||
|
||||
func convertContents(mark rune) (err error) {
|
||||
InitializeConfig()
|
||||
site := &hugolib.Site{}
|
||||
|
||||
if err := site.Initialise(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if site.Source == nil {
|
||||
panic(fmt.Sprintf("site.Source not set"))
|
||||
}
|
||||
if len(site.Source.Files()) < 1 {
|
||||
return fmt.Errorf("No source files found")
|
||||
}
|
||||
|
||||
jww.FEEDBACK.Println("processing", len(site.Source.Files()), "content files")
|
||||
for _, file := range site.Source.Files() {
|
||||
jww.INFO.Println("Attempting to convert", file.LogicalName)
|
||||
page, err := hugolib.NewPage(file.LogicalName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
psr, err := parser.ReadFrom(file.Contents)
|
||||
if err != nil {
|
||||
jww.ERROR.Println("Error processing file:", path.Join(file.Dir, file.LogicalName))
|
||||
return err
|
||||
}
|
||||
metadata, err := psr.Metadata()
|
||||
if err != nil {
|
||||
jww.ERROR.Println("Error processing file:", path.Join(file.Dir, file.LogicalName))
|
||||
return err
|
||||
}
|
||||
|
||||
// better handling of dates in formats that don't have support for them
|
||||
if mark == parser.FormatToLeadRune("json") || mark == parser.FormatToLeadRune("yaml") {
|
||||
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.Dir = file.Dir
|
||||
page.SetSourceContent(psr.Content())
|
||||
page.SetSourceMetaData(metadata, mark)
|
||||
|
||||
if OutputDir != "" {
|
||||
page.SaveSourceAs(path.Join(OutputDir, page.FullFilePath()))
|
||||
} else {
|
||||
if Unsafe {
|
||||
page.SaveSource()
|
||||
} else {
|
||||
jww.FEEDBACK.Println("Unsafe operation not allowed, use --unsafe or set a different output path")
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
// Copyright © 2013 Steve Francia <spf@spf13.com>.
|
||||
//
|
||||
// Licensed under the Simple Public 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://opensource.org/licenses/Simple-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 (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/mostafah/fsync"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"github.com/spf13/hugo/hugolib"
|
||||
"github.com/spf13/hugo/livereload"
|
||||
"github.com/spf13/hugo/utils"
|
||||
"github.com/spf13/hugo/watcher"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
"github.com/spf13/nitro"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
//var Config *hugolib.Config
|
||||
var HugoCmd = &cobra.Command{
|
||||
Use: "hugo",
|
||||
Short: "Hugo is a very fast static site generator",
|
||||
Long: `A Fast and Flexible Static Site Generator built with
|
||||
love by spf13 and friends in Go.
|
||||
|
||||
Complete documentation is available at http://hugo.spf13.com`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
InitializeConfig()
|
||||
build()
|
||||
},
|
||||
}
|
||||
|
||||
var hugoCmdV *cobra.Command
|
||||
|
||||
var BuildWatch, Draft, Future, UglyUrls, Verbose, Logging, VerboseLog, DisableRSS, DisableSitemap bool
|
||||
var Source, Destination, Theme, BaseUrl, CfgFile, LogFile string
|
||||
|
||||
func Execute() {
|
||||
AddCommands()
|
||||
utils.StopOnErr(HugoCmd.Execute())
|
||||
}
|
||||
|
||||
func AddCommands() {
|
||||
HugoCmd.AddCommand(serverCmd)
|
||||
HugoCmd.AddCommand(version)
|
||||
HugoCmd.AddCommand(check)
|
||||
HugoCmd.AddCommand(benchmark)
|
||||
HugoCmd.AddCommand(convertCmd)
|
||||
HugoCmd.AddCommand(newCmd)
|
||||
}
|
||||
|
||||
func init() {
|
||||
HugoCmd.PersistentFlags().BoolVarP(&Draft, "buildDrafts", "D", false, "include content marked as draft")
|
||||
HugoCmd.PersistentFlags().BoolVarP(&Future, "buildFuture", "F", false, "include content with datePublished in the future")
|
||||
HugoCmd.PersistentFlags().BoolVar(&DisableRSS, "disableRSS", false, "Do not build RSS files")
|
||||
HugoCmd.PersistentFlags().BoolVar(&DisableSitemap, "disableSitemap", false, "Do not build Sitemap file")
|
||||
HugoCmd.PersistentFlags().StringVarP(&Source, "source", "s", "", "filesystem path to read files relative from")
|
||||
HugoCmd.PersistentFlags().StringVarP(&Destination, "destination", "d", "", "filesystem path to write files to")
|
||||
HugoCmd.PersistentFlags().StringVarP(&Theme, "theme", "t", "", "theme to use (located in /themes/THEMENAME/)")
|
||||
HugoCmd.PersistentFlags().BoolVarP(&Verbose, "verbose", "v", false, "verbose output")
|
||||
HugoCmd.PersistentFlags().BoolVar(&UglyUrls, "uglyUrls", false, "if true, use /filename.html instead of /filename/")
|
||||
HugoCmd.PersistentFlags().StringVarP(&BaseUrl, "baseUrl", "b", "", "hostname (and path) to the root eg. http://spf13.com/")
|
||||
HugoCmd.PersistentFlags().StringVar(&CfgFile, "config", "", "config file (default is path/config.yaml|json|toml)")
|
||||
HugoCmd.PersistentFlags().BoolVar(&Logging, "log", false, "Enable Logging")
|
||||
HugoCmd.PersistentFlags().StringVar(&LogFile, "logFile", "", "Log File path (if set, logging enabled automatically)")
|
||||
HugoCmd.PersistentFlags().BoolVar(&VerboseLog, "verboseLog", false, "verbose logging")
|
||||
HugoCmd.PersistentFlags().BoolVar(&nitro.AnalysisOn, "stepAnalysis", false, "display memory and timing of different steps of the program")
|
||||
HugoCmd.Flags().BoolVarP(&BuildWatch, "watch", "w", false, "watch filesystem for changes and recreate as needed")
|
||||
hugoCmdV = HugoCmd
|
||||
}
|
||||
|
||||
func InitializeConfig() {
|
||||
viper.SetConfigName(CfgFile)
|
||||
viper.AddConfigPath(Source)
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
jww.ERROR.Println("Config not found... using only defaults, stuff may not work")
|
||||
}
|
||||
|
||||
viper.RegisterAlias("taxonomies", "indexes")
|
||||
|
||||
viper.SetDefault("Watch", false)
|
||||
viper.SetDefault("MetaDataFormat", "toml")
|
||||
viper.SetDefault("DisableRSS", false)
|
||||
viper.SetDefault("DisableSitemap", false)
|
||||
viper.SetDefault("ContentDir", "content")
|
||||
viper.SetDefault("LayoutDir", "layouts")
|
||||
viper.SetDefault("StaticDir", "static")
|
||||
viper.SetDefault("ArchetypeDir", "archetypes")
|
||||
viper.SetDefault("PublishDir", "public")
|
||||
viper.SetDefault("DefaultLayout", "post")
|
||||
viper.SetDefault("BuildDrafts", false)
|
||||
viper.SetDefault("BuildFuture", false)
|
||||
viper.SetDefault("UglyUrls", false)
|
||||
viper.SetDefault("Verbose", false)
|
||||
viper.SetDefault("CanonifyUrls", false)
|
||||
viper.SetDefault("Indexes", map[string]string{"tag": "tags", "category": "categories"})
|
||||
viper.SetDefault("Permalinks", make(hugolib.PermalinkOverrides, 0))
|
||||
viper.SetDefault("Sitemap", hugolib.Sitemap{Priority: -1})
|
||||
viper.SetDefault("PygmentsStyle", "monokai")
|
||||
viper.SetDefault("PygmentsUseClasses", false)
|
||||
viper.SetDefault("DisableLiveReload", false)
|
||||
|
||||
if hugoCmdV.PersistentFlags().Lookup("buildDrafts").Changed {
|
||||
viper.Set("BuildDrafts", Draft)
|
||||
}
|
||||
|
||||
if hugoCmdV.PersistentFlags().Lookup("buildFuture").Changed {
|
||||
viper.Set("BuildFuture", Future)
|
||||
}
|
||||
|
||||
if hugoCmdV.PersistentFlags().Lookup("uglyUrls").Changed {
|
||||
viper.Set("UglyUrls", UglyUrls)
|
||||
}
|
||||
|
||||
if hugoCmdV.PersistentFlags().Lookup("disableRSS").Changed {
|
||||
viper.Set("DisableRSS", DisableRSS)
|
||||
}
|
||||
|
||||
if hugoCmdV.PersistentFlags().Lookup("disableSitemap").Changed {
|
||||
viper.Set("DisableSitemap", DisableSitemap)
|
||||
}
|
||||
|
||||
if hugoCmdV.PersistentFlags().Lookup("verbose").Changed {
|
||||
viper.Set("Verbose", Verbose)
|
||||
}
|
||||
|
||||
if hugoCmdV.PersistentFlags().Lookup("logFile").Changed {
|
||||
viper.Set("LogFile", LogFile)
|
||||
}
|
||||
if BaseUrl != "" {
|
||||
if !strings.HasSuffix(BaseUrl, "/") {
|
||||
BaseUrl = BaseUrl + "/"
|
||||
}
|
||||
viper.Set("BaseUrl", BaseUrl)
|
||||
}
|
||||
|
||||
if Theme != "" {
|
||||
viper.Set("theme", Theme)
|
||||
}
|
||||
|
||||
if Destination != "" {
|
||||
viper.Set("PublishDir", Destination)
|
||||
}
|
||||
|
||||
if Source != "" {
|
||||
viper.Set("WorkingDir", Source)
|
||||
} else {
|
||||
dir, _ := helpers.FindCWD()
|
||||
viper.Set("WorkingDir", dir)
|
||||
}
|
||||
|
||||
if VerboseLog || Logging || (viper.IsSet("LogFile") && viper.GetString("LogFile") != "") {
|
||||
if viper.IsSet("LogFile") && viper.GetString("LogFile") != "" {
|
||||
jww.SetLogFile(viper.GetString("LogFile"))
|
||||
} else {
|
||||
jww.UseTempLogFile("hugo")
|
||||
}
|
||||
} else {
|
||||
jww.DiscardLogging()
|
||||
}
|
||||
|
||||
if viper.GetBool("verbose") {
|
||||
jww.SetStdoutThreshold(jww.LevelInfo)
|
||||
}
|
||||
|
||||
if VerboseLog {
|
||||
jww.SetLogThreshold(jww.LevelInfo)
|
||||
}
|
||||
|
||||
jww.INFO.Println("Using config file:", viper.ConfigFileUsed())
|
||||
}
|
||||
|
||||
func build(watches ...bool) {
|
||||
utils.CheckErr(copyStatic(), fmt.Sprintf("Error copying static files to %s", helpers.AbsPathify(viper.GetString("PublishDir"))))
|
||||
watch := false
|
||||
if len(watches) > 0 && watches[0] {
|
||||
watch = true
|
||||
}
|
||||
utils.StopOnErr(buildSite(BuildWatch || watch))
|
||||
|
||||
if BuildWatch {
|
||||
jww.FEEDBACK.Println("Watching for changes in", helpers.AbsPathify(viper.GetString("ContentDir")))
|
||||
jww.FEEDBACK.Println("Press ctrl+c to stop")
|
||||
utils.CheckErr(NewWatcher(0))
|
||||
}
|
||||
}
|
||||
|
||||
func copyStatic() error {
|
||||
staticDir := helpers.AbsPathify(viper.GetString("StaticDir")) + "/"
|
||||
if _, err := os.Stat(staticDir); os.IsNotExist(err) {
|
||||
jww.ERROR.Println("Unable to find Static Directory:", viper.GetString("theme"), "in", staticDir)
|
||||
return nil
|
||||
}
|
||||
|
||||
publishDir := helpers.AbsPathify(viper.GetString("PublishDir")) + "/"
|
||||
|
||||
if themeSet() {
|
||||
themeDir := helpers.AbsPathify("themes/"+viper.GetString("theme")) + "/static/"
|
||||
if _, err := os.Stat(themeDir); os.IsNotExist(err) {
|
||||
jww.ERROR.Println("Unable to find static directory for theme :", viper.GetString("theme"), "in", themeDir)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Copy Static to Destination
|
||||
jww.INFO.Println("syncing from", themeDir, "to", publishDir)
|
||||
fsync.Sync(publishDir, themeDir)
|
||||
}
|
||||
|
||||
// Copy Static to Destination
|
||||
jww.INFO.Println("syncing from", staticDir, "to", publishDir)
|
||||
return fsync.Sync(publishDir, staticDir)
|
||||
}
|
||||
|
||||
func getDirList() []string {
|
||||
var a []string
|
||||
walker := func(path string, fi os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
jww.ERROR.Println("Walker: ", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
a = append(a, path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
filepath.Walk(helpers.AbsPathify(viper.GetString("ContentDir")), walker)
|
||||
filepath.Walk(helpers.AbsPathify(viper.GetString("LayoutDir")), walker)
|
||||
filepath.Walk(helpers.AbsPathify(viper.GetString("StaticDir")), walker)
|
||||
if themeSet() {
|
||||
filepath.Walk(helpers.AbsPathify("themes/"+viper.GetString("theme")), walker)
|
||||
}
|
||||
|
||||
return a
|
||||
}
|
||||
|
||||
func themeSet() bool {
|
||||
return viper.GetString("theme") != ""
|
||||
}
|
||||
|
||||
func buildSite(watching ...bool) (err error) {
|
||||
startTime := time.Now()
|
||||
site := &hugolib.Site{}
|
||||
if len(watching) > 0 && watching[0] {
|
||||
site.RunMode.Watching = true
|
||||
}
|
||||
err = site.Build()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
site.Stats()
|
||||
jww.FEEDBACK.Printf("in %v ms\n", int(1000*time.Since(startTime).Seconds()))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewWatcher(port int) error {
|
||||
if runtime.GOOS == "darwin" {
|
||||
tweakLimit()
|
||||
}
|
||||
|
||||
watcher, err := watcher.New(1 * time.Second)
|
||||
var wg sync.WaitGroup
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
defer watcher.Close()
|
||||
|
||||
wg.Add(1)
|
||||
|
||||
for _, d := range getDirList() {
|
||||
if d != "" {
|
||||
_ = watcher.Watch(d)
|
||||
}
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
select {
|
||||
case evs := <-watcher.Event:
|
||||
jww.INFO.Println(evs)
|
||||
|
||||
static_changed := false
|
||||
dynamic_changed := false
|
||||
|
||||
for _, ev := range evs {
|
||||
ext := filepath.Ext(ev.Name)
|
||||
istemp := strings.HasSuffix(ext, "~") || (ext == ".swp") || (ext == ".tmp")
|
||||
if istemp {
|
||||
continue
|
||||
}
|
||||
// renames are always followed with Create/Modify
|
||||
if ev.IsRename() {
|
||||
continue
|
||||
}
|
||||
|
||||
isstatic := strings.HasPrefix(ev.Name, helpers.AbsPathify(viper.GetString("StaticDir"))) || strings.HasPrefix(ev.Name, helpers.AbsPathify("themes/"+viper.GetString("theme"))+"/static/")
|
||||
static_changed = static_changed || isstatic
|
||||
dynamic_changed = dynamic_changed || !isstatic
|
||||
|
||||
// add new directory to watch list
|
||||
if s, err := os.Stat(ev.Name); err == nil && s.Mode().IsDir() {
|
||||
if ev.IsCreate() {
|
||||
watcher.Watch(ev.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if static_changed {
|
||||
fmt.Print("Static file changed, syncing\n\n")
|
||||
utils.StopOnErr(copyStatic(), fmt.Sprintf("Error copying static files to %s", helpers.AbsPathify(viper.GetString("PublishDir"))))
|
||||
|
||||
livereload.ForceRefresh()
|
||||
}
|
||||
|
||||
if dynamic_changed {
|
||||
fmt.Print("Change detected, rebuilding site\n\n")
|
||||
utils.StopOnErr(buildSite(true))
|
||||
|
||||
livereload.ForceRefresh()
|
||||
}
|
||||
case err := <-watcher.Error:
|
||||
if err != nil {
|
||||
fmt.Println("error:", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
if port > 0 {
|
||||
if !viper.GetBool("DisableLiveReload") {
|
||||
livereload.Initialize()
|
||||
http.HandleFunc("/livereload.js", livereload.ServeJS)
|
||||
http.HandleFunc("/livereload", livereload.Handler)
|
||||
}
|
||||
|
||||
go serve(port)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// +build darwin
|
||||
// Copyright © 2013 Steve Francia <spf@spf13.com>.
|
||||
//
|
||||
// Licensed under the Simple Public 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://opensource.org/licenses/Simple-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 (
|
||||
"syscall"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
|
||||
func init() {
|
||||
check.AddCommand(limit)
|
||||
}
|
||||
|
||||
var limit = &cobra.Command{
|
||||
Use: "ulimit",
|
||||
Short: "Check system ulimit settings",
|
||||
Long: `Hugo will inspect the current ulimit settings on the system.
|
||||
This is primarily to ensure that Hugo can watch enough files on some OSs`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
var rLimit syscall.Rlimit
|
||||
err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)
|
||||
if err != nil {
|
||||
jww.ERROR.Println("Error Getting Rlimit ", err)
|
||||
}
|
||||
jww.FEEDBACK.Println("Current rLimit:", rLimit)
|
||||
|
||||
jww.FEEDBACK.Println("Attempting to increase limit")
|
||||
rLimit.Max = 999999
|
||||
rLimit.Cur = 999999
|
||||
err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit)
|
||||
if err != nil {
|
||||
jww.ERROR.Println("Error Setting rLimit ", err)
|
||||
}
|
||||
err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)
|
||||
if err != nil {
|
||||
jww.ERROR.Println("Error Getting rLimit ", err)
|
||||
}
|
||||
jww.FEEDBACK.Println("rLimit after change:", rLimit)
|
||||
},
|
||||
}
|
||||
|
||||
func tweakLimit() {
|
||||
var rLimit syscall.Rlimit
|
||||
err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)
|
||||
if err != nil {
|
||||
jww.ERROR.Println("Unable to obtain rLimit", err)
|
||||
}
|
||||
if rLimit.Cur < rLimit.Max {
|
||||
rLimit.Max = 999999
|
||||
rLimit.Cur = 999999
|
||||
err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit)
|
||||
if err != nil {
|
||||
jww.ERROR.Println("Unable to increase number of open files limit", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// +build !darwin
|
||||
// Copyright © 2013 Steve Francia <spf@spf13.com>.
|
||||
//
|
||||
// Licensed under the Simple Public 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://opensource.org/licenses/Simple-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
|
||||
|
||||
func tweakLimit() {
|
||||
// nothing to do
|
||||
}
|
||||
+253
@@ -0,0 +1,253 @@
|
||||
// Licensed under the Simple Public 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://opensource.org/licenses/Simple-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"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/create"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"github.com/spf13/hugo/parser"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var siteType string
|
||||
var configFormat string
|
||||
var contentType string
|
||||
var contentFormat string
|
||||
var contentFrontMatter string
|
||||
|
||||
func init() {
|
||||
newSiteCmd.Flags().StringVarP(&configFormat, "format", "f", "toml", "config & frontmatter format")
|
||||
newCmd.Flags().StringVarP(&configFormat, "format", "f", "toml", "frontmatter format")
|
||||
newCmd.Flags().StringVarP(&contentType, "kind", "k", "", "Content type to create")
|
||||
newCmd.AddCommand(newSiteCmd)
|
||||
newCmd.AddCommand(newThemeCmd)
|
||||
}
|
||||
|
||||
var newCmd = &cobra.Command{
|
||||
Use: "new [path]",
|
||||
Short: "Create new content for your site",
|
||||
Long: `Create will 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.
|
||||
You can also specify the kind with -k KIND
|
||||
If archetypes are provided in your theme or site, they will be used.
|
||||
`,
|
||||
Run: NewContent,
|
||||
}
|
||||
|
||||
var newSiteCmd = &cobra.Command{
|
||||
Use: "site [path]",
|
||||
Short: "Create a new site (skeleton)",
|
||||
Long: `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.
|
||||
`,
|
||||
Run: NewSite,
|
||||
}
|
||||
|
||||
var newThemeCmd = &cobra.Command{
|
||||
Use: "theme [name]",
|
||||
Short: "Create a new theme",
|
||||
Long: `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
|
||||
as you see fit.
|
||||
`,
|
||||
Run: NewTheme,
|
||||
}
|
||||
|
||||
func NewContent(cmd *cobra.Command, args []string) {
|
||||
InitializeConfig()
|
||||
|
||||
if cmd.Flags().Lookup("format").Changed {
|
||||
viper.Set("MetaDataFormat", configFormat)
|
||||
}
|
||||
|
||||
if len(args) < 1 {
|
||||
cmd.Usage()
|
||||
jww.FATAL.Fatalln("path needs to be provided")
|
||||
}
|
||||
|
||||
createpath := args[0]
|
||||
|
||||
var kind string
|
||||
|
||||
// assume the first directory is the section (kind)
|
||||
if strings.Contains(createpath[1:], "/") {
|
||||
kind = helpers.GuessSection(createpath)
|
||||
}
|
||||
|
||||
if contentType != "" {
|
||||
kind = contentType
|
||||
}
|
||||
|
||||
err := create.NewContent(kind, createpath)
|
||||
if err != nil {
|
||||
jww.ERROR.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
func NewSite(cmd *cobra.Command, args []string) {
|
||||
if len(args) < 1 {
|
||||
cmd.Usage()
|
||||
jww.FATAL.Fatalln("path needs to be provided")
|
||||
}
|
||||
|
||||
createpath, err := filepath.Abs(filepath.Clean(args[0]))
|
||||
if err != nil {
|
||||
cmd.Usage()
|
||||
jww.FATAL.Fatalln(err)
|
||||
}
|
||||
|
||||
if x, _ := helpers.Exists(createpath); x {
|
||||
y, _ := helpers.IsDir(createpath)
|
||||
if z, _ := helpers.IsEmpty(createpath); y && z {
|
||||
jww.INFO.Println(createpath, "already exists and is empty")
|
||||
} else {
|
||||
jww.FATAL.Fatalln(createpath, "already exists and is not empty")
|
||||
}
|
||||
}
|
||||
|
||||
mkdir(createpath, "layouts")
|
||||
mkdir(createpath, "content")
|
||||
mkdir(createpath, "archetypes")
|
||||
mkdir(createpath, "static")
|
||||
|
||||
createConfig(createpath, configFormat)
|
||||
}
|
||||
|
||||
func NewTheme(cmd *cobra.Command, args []string) {
|
||||
InitializeConfig()
|
||||
|
||||
if len(args) < 1 {
|
||||
cmd.Usage()
|
||||
jww.FATAL.Fatalln("theme name needs to be provided")
|
||||
}
|
||||
|
||||
createpath := helpers.AbsPathify(path.Join("themes", args[0]))
|
||||
jww.INFO.Println("creating theme at", createpath)
|
||||
|
||||
if x, _ := helpers.Exists(createpath); x {
|
||||
jww.FATAL.Fatalln(createpath, "already exists")
|
||||
}
|
||||
|
||||
mkdir(createpath, "layouts", "_default")
|
||||
mkdir(createpath, "layouts", "partials")
|
||||
|
||||
touchFile(createpath, "layouts", "index.html")
|
||||
touchFile(createpath, "layouts", "_default", "list.html")
|
||||
touchFile(createpath, "layouts", "_default", "single.html")
|
||||
|
||||
touchFile(createpath, "layouts", "partials", "header.html")
|
||||
touchFile(createpath, "layouts", "partials", "footer.html")
|
||||
|
||||
mkdir(createpath, "archetypes")
|
||||
touchFile(createpath, "archetypes", "default.md")
|
||||
|
||||
mkdir(createpath, "static", "js")
|
||||
mkdir(createpath, "static", "css")
|
||||
|
||||
by := []byte(`The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 YOUR_NAME_HERE
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
`)
|
||||
|
||||
err := helpers.WriteToDisk(path.Join(createpath, "LICENSE.md"), bytes.NewReader(by))
|
||||
if err != nil {
|
||||
jww.FATAL.Fatalln(err)
|
||||
}
|
||||
|
||||
createThemeMD(createpath)
|
||||
}
|
||||
|
||||
func mkdir(x ...string) {
|
||||
p := path.Join(x...)
|
||||
|
||||
err := os.MkdirAll(p, 0777) // rwx, rw, r
|
||||
if err != nil {
|
||||
jww.FATAL.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func touchFile(x ...string) {
|
||||
inpath := path.Join(x...)
|
||||
mkdir(filepath.Dir(inpath))
|
||||
err := helpers.WriteToDisk(inpath, bytes.NewReader([]byte{}))
|
||||
if err != nil {
|
||||
jww.FATAL.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func createThemeMD(inpath string) (err error) {
|
||||
|
||||
in := map[string]interface{}{
|
||||
"name": helpers.MakeTitle(filepath.Base(inpath)),
|
||||
"license": "MIT",
|
||||
"source_repo": "",
|
||||
"author": "",
|
||||
"description": "",
|
||||
"tags": []string{"", ""},
|
||||
}
|
||||
|
||||
by, err := parser.InterfaceToConfig(in, parser.FormatToLeadRune("toml"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = helpers.WriteToDisk(path.Join(inpath, "theme.toml"), bytes.NewReader(by))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func createConfig(inpath string, kind string) (err error) {
|
||||
in := map[string]string{"baseurl": "http://yourSiteHere", "title": "my new hugo site", "languageCode": "en-us"}
|
||||
kind = parser.FormatSanitize(kind)
|
||||
|
||||
by, err := parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = helpers.WriteToDisk(path.Join(inpath, "config."+kind), bytes.NewReader(by))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
// Copyright © 2013 Steve Francia <spf@spf13.com>.
|
||||
//
|
||||
// Licensed under the Simple Public 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://opensource.org/licenses/Simple-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 (
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var serverPort int
|
||||
var serverWatch bool
|
||||
var serverAppend bool
|
||||
var disableLiveReload bool
|
||||
|
||||
//var serverCmdV *cobra.Command
|
||||
|
||||
var serverCmd = &cobra.Command{
|
||||
Use: "server",
|
||||
Short: "Hugo runs it's own a webserver to render the files",
|
||||
Long: `Hugo is able to run it's own high performance web server.
|
||||
Hugo will render all the files defined in the source directory and
|
||||
Serve them up.`,
|
||||
//Run: server,
|
||||
}
|
||||
|
||||
func init() {
|
||||
serverCmd.Flags().IntVarP(&serverPort, "port", "p", 1313, "port to run the server on")
|
||||
serverCmd.Flags().BoolVarP(&serverWatch, "watch", "w", false, "watch filesystem for changes and recreate as needed")
|
||||
serverCmd.Flags().BoolVarP(&serverAppend, "appendPort", "", true, "append port to baseurl")
|
||||
serverCmd.Flags().BoolVar(&disableLiveReload, "disableLiveReload", false, "watch without enabling live browser reload on rebuild")
|
||||
serverCmd.Run = server
|
||||
}
|
||||
|
||||
func server(cmd *cobra.Command, args []string) {
|
||||
InitializeConfig()
|
||||
|
||||
if BaseUrl == "" {
|
||||
BaseUrl = "http://localhost"
|
||||
}
|
||||
|
||||
if cmd.Flags().Lookup("disableLiveReload").Changed {
|
||||
viper.Set("DisableLiveReload", disableLiveReload)
|
||||
}
|
||||
|
||||
if serverWatch {
|
||||
viper.Set("Watch", true)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(BaseUrl, "http://") {
|
||||
BaseUrl = "http://" + BaseUrl
|
||||
}
|
||||
|
||||
l, err := net.Listen("tcp", ":"+strconv.Itoa(serverPort))
|
||||
if err == nil {
|
||||
l.Close()
|
||||
} else {
|
||||
jww.ERROR.Println("port", serverPort, "already in use, attempting to use an available port")
|
||||
sp, err := helpers.FindAvailablePort()
|
||||
if err != nil {
|
||||
jww.ERROR.Println("Unable to find alternative port to use")
|
||||
jww.ERROR.Fatalln(err)
|
||||
}
|
||||
serverPort = sp.Port
|
||||
}
|
||||
|
||||
viper.Set("port", serverPort)
|
||||
|
||||
if serverAppend {
|
||||
viper.Set("BaseUrl", strings.TrimSuffix(BaseUrl, "/")+":"+strconv.Itoa(serverPort))
|
||||
} else {
|
||||
viper.Set("BaseUrl", strings.TrimSuffix(BaseUrl, "/"))
|
||||
}
|
||||
|
||||
build(serverWatch)
|
||||
|
||||
// Watch runs its own server as part of the routine
|
||||
if serverWatch {
|
||||
jww.FEEDBACK.Println("Watching for changes in", helpers.AbsPathify(viper.GetString("ContentDir")))
|
||||
err := NewWatcher(serverPort)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
|
||||
serve(serverPort)
|
||||
}
|
||||
|
||||
func serve(port int) {
|
||||
jww.FEEDBACK.Println("Serving pages from " + helpers.AbsPathify(viper.GetString("PublishDir")))
|
||||
jww.FEEDBACK.Printf("Web Server is available at %s\n", viper.GetString("BaseUrl"))
|
||||
fmt.Println("Press ctrl+c to stop")
|
||||
|
||||
http.Handle("/", http.FileServer(http.Dir(helpers.AbsPathify(viper.GetString("PublishDir")))))
|
||||
err := http.ListenAndServe(":"+strconv.Itoa(port), nil)
|
||||
if err != nil {
|
||||
jww.ERROR.Printf("Error: %s\n", err.Error())
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright © 2013 Steve Francia <spf@spf13.com>.
|
||||
//
|
||||
// Licensed under the Simple Public 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://opensource.org/licenses/Simple-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 (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var version = &cobra.Command{
|
||||
Use: "version",
|
||||
Short: "Print the version number of Hugo",
|
||||
Long: `All software has versions. This is Hugo's`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("Hugo Static Site Generator v0.11")
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
// Copyright © 2014 Steve Francia <spf@spf13.com>.
|
||||
//
|
||||
// Licensed under the Simple Public 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://opensource.org/licenses/Simple-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 create
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"github.com/spf13/hugo/hugolib"
|
||||
"github.com/spf13/hugo/parser"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
func NewContent(kind, name string) (err error) {
|
||||
jww.INFO.Println("attempting to create", name, "of", kind)
|
||||
|
||||
location := FindArchetype(kind)
|
||||
|
||||
var by []byte
|
||||
|
||||
if location != "" {
|
||||
by, err = ioutil.ReadFile(location)
|
||||
if err != nil {
|
||||
jww.ERROR.Println(err)
|
||||
}
|
||||
}
|
||||
if location == "" || err != nil {
|
||||
by = []byte("+++\n title = \"title\"\n draft = true \n+++\n")
|
||||
}
|
||||
|
||||
psr, err := parser.ReadFrom(bytes.NewReader(by))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
metadata, err := psr.Metadata()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newmetadata, err := cast.ToStringMapE(metadata)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for k, _ := range newmetadata {
|
||||
switch strings.ToLower(k) {
|
||||
case "date":
|
||||
newmetadata[k] = time.Now()
|
||||
case "title":
|
||||
newmetadata[k] = helpers.MakeTitle(helpers.Filename(name))
|
||||
}
|
||||
}
|
||||
|
||||
caseimatch := func(m map[string]interface{}, key string) bool {
|
||||
for k, _ := range m {
|
||||
if strings.ToLower(k) == strings.ToLower(key) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if !caseimatch(newmetadata, "date") {
|
||||
newmetadata["date"] = time.Now()
|
||||
}
|
||||
|
||||
if !caseimatch(newmetadata, "title") {
|
||||
newmetadata["title"] = helpers.MakeTitle(helpers.Filename(name))
|
||||
}
|
||||
|
||||
page, err := hugolib.NewPage(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if x := viper.GetString("MetaDataFormat"); x == "json" || x == "yaml" {
|
||||
newmetadata["date"] = time.Now().Format(time.RFC3339)
|
||||
}
|
||||
|
||||
page.Dir = viper.GetString("sourceDir")
|
||||
page.SetSourceMetaData(newmetadata, parser.FormatToLeadRune(viper.GetString("MetaDataFormat")))
|
||||
|
||||
if err = page.SafeSaveSourceAs(path.Join(viper.GetString("contentDir"), name)); err != nil {
|
||||
return
|
||||
}
|
||||
jww.FEEDBACK.Println(helpers.AbsPathify(path.Join(viper.GetString("contentDir"), name)), "created")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func FindArchetype(kind string) (outpath string) {
|
||||
search := []string{helpers.AbsPathify(viper.GetString("archetypeDir"))}
|
||||
|
||||
if viper.GetString("theme") != "" {
|
||||
themeDir := path.Join(helpers.AbsPathify("themes/"+viper.GetString("theme")), "/archetypes/")
|
||||
if _, err := os.Stat(themeDir); os.IsNotExist(err) {
|
||||
jww.ERROR.Println("Unable to find archetypes directory for theme :", viper.GetString("theme"), "in", themeDir)
|
||||
} else {
|
||||
search = append(search, themeDir)
|
||||
}
|
||||
}
|
||||
|
||||
for _, x := range search {
|
||||
pathsToCheck := []string{kind + ".md", kind, "default.md", "default"}
|
||||
for _, p := range pathsToCheck {
|
||||
curpath := path.Join(x, p)
|
||||
jww.DEBUG.Println("checking", curpath, "for archetypes")
|
||||
if exists, _ := helpers.Exists(curpath); exists {
|
||||
return curpath
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
+++
|
||||
weight = 5
|
||||
[menu]
|
||||
[menu.main]
|
||||
parent = "x"
|
||||
+++
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"Indexes" : {"tag": "tags"},
|
||||
"BaseUrl" : "http://localhost"
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
baseurl = "http://hugo.spf13.com"
|
||||
MetaDataFormat = "yaml"
|
||||
|
||||
[indexes]
|
||||
tag = "tags"
|
||||
group = "groups"
|
||||
|
||||
[[menu.main]]
|
||||
name = "Download Hugo"
|
||||
pre = "<i class='fa fa-download'></i>"
|
||||
url = "https://github.com/spf13/hugo/releases"
|
||||
weight = -200
|
||||
[[menu.main]]
|
||||
name = "about hugo"
|
||||
pre = "<i class='fa fa-heart'></i>"
|
||||
weight = -110
|
||||
identifier = "about"
|
||||
[[menu.main]]
|
||||
name = "getting started"
|
||||
pre = "<i class='fa fa-road'></i>"
|
||||
weight = -100
|
||||
[[menu.main]]
|
||||
name = "content"
|
||||
pre = "<i class='fa fa-file-text'></i>"
|
||||
weight = -90
|
||||
[[menu.main]]
|
||||
name = "themes"
|
||||
pre = "<i class='fa fa-desktop'></i>"
|
||||
weight = -85
|
||||
[[menu.main]]
|
||||
name = "templates"
|
||||
identifier = "layout"
|
||||
pre = "<i class='fa fa-columns'></i>"
|
||||
weight = -80
|
||||
[[menu.main]]
|
||||
name = "taxonomies"
|
||||
identifier = "taxonomy"
|
||||
pre = "<i class='fa fa-tags'></i>"
|
||||
weight = -70
|
||||
[[menu.main]]
|
||||
name = "extras"
|
||||
pre = "<i class='fa fa-gift'></i>"
|
||||
weight = -60
|
||||
[[menu.main]]
|
||||
name = "tutorials"
|
||||
pre = "<i class='fa fa-book'></i>"
|
||||
weight = -40
|
||||
[[menu.main]]
|
||||
name = "community"
|
||||
pre = "<i class='fa fa-group'></i>"
|
||||
weight = -50
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/contributing/
|
||||
- /meta/contributing/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: community
|
||||
next: /tutorials/github_pages_blog
|
||||
prev: /community/press
|
||||
title: Contributing to Hugo
|
||||
weight: 30
|
||||
---
|
||||
|
||||
All contributions to Hugo are welcome. Whether you want to scratch an itch, or simply contribute to the project. Feel free to pick something from the roadmap
|
||||
or contact [spf13](http://spf13.com) about what may make sense
|
||||
to do next.
|
||||
|
||||
You should fork the project and make your changes. *We encourage pull requests to discuss code changes.*
|
||||
|
||||
|
||||
When you're ready to create a pull request, be sure to:
|
||||
|
||||
* Have test cases for the new code. If you have questions about how to do it, please ask in your pull request.
|
||||
* Run `go fmt`
|
||||
* Squash your commits into a single commit. `git rebase -i`. It's okay to force update your pull request.
|
||||
* Make sure `go test ./...` passes, and go build completes. Our Travis CI loop will catch most things that are missing. The exception: Windows. We run on windows from time to time, but if you have access please check on a Windows machine too.
|
||||
|
||||
## Contribution Overview
|
||||
|
||||
1. Fork Hugo from https://github.com/spf13/hugo
|
||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||
4. Commit passing tests to validate changes.
|
||||
5. Run `go fmt`
|
||||
6. Squash commits into a single (or logically grouped) commits (`git rebase -i`)
|
||||
7. Push to the branch (`git push origin my-new-feature`)
|
||||
8. Create new Pull Request
|
||||
|
||||
|
||||
# Building from source
|
||||
|
||||
## Clone locally (for contributors):
|
||||
|
||||
git clone https://github.com/spf13/hugo
|
||||
cd hugo
|
||||
go get
|
||||
|
||||
Because go expects all of your libraries to be found in either
|
||||
$GOROOT or $GOPATH, it's helpful to symlink the project to one
|
||||
of the following paths:
|
||||
|
||||
* ln -s /path/to/your/hugo $GOPATH/src/github.com/spf13/hugo
|
||||
* ln -s /path/to/your/hugo $GOROOT/src/pkg/github.com/spf13/hugo
|
||||
|
||||
## Running Hugo
|
||||
|
||||
cd /path/to/hugo
|
||||
go install github.com/spf13/hugo/hugo
|
||||
go run main.go
|
||||
|
||||
## Building Hugo
|
||||
|
||||
cd /path/to/hugo
|
||||
go build -o hugo main.go
|
||||
mv hugo /usr/local/bin/
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: community
|
||||
next: /community/press
|
||||
prev: /extras/urls
|
||||
title: Mailing List
|
||||
weight: 10
|
||||
---
|
||||
|
||||
Hugo has two mailing lists:
|
||||
|
||||
## Announcements
|
||||
Very low traffic. Only releases will be emailed here.
|
||||
|
||||
https://groups.google.com/forum/#!forum/hugo-announce
|
||||
|
||||
## Discussion
|
||||
For all questions and discussions:
|
||||
|
||||
https://groups.google.com/forum/#!forum/hugo-discuss
|
||||
|
||||
# Other Resources
|
||||
|
||||
## GoNuts
|
||||
|
||||
For general go questions or discussion please refer to the go mailing list.
|
||||
|
||||
https://groups.google.com/forum/#!forum/golang-nuts
|
||||
|
||||
## Github Issues
|
||||
|
||||
https://github.com/spf13/hugo/issues
|
||||
|
||||
## Twitter
|
||||
|
||||
Hugo doesn't have it's own twitter handle, but feel free to tweet [@spf13](http://twitter.com/spf13).
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
date: 2014-03-24T20:00:00Z
|
||||
linktitle: Press
|
||||
menu:
|
||||
main:
|
||||
parent: community
|
||||
next: /community/contributing
|
||||
notoc: true
|
||||
prev: /community/mailing-list
|
||||
title: Press, Blogs and Media Coverage
|
||||
weight: 20
|
||||
---
|
||||
|
||||
Hugo has been featured in the following Blog Posts, Press and Media.
|
||||
|
||||
|
||||
| Title | Author | Date |
|
||||
| ------ | ------ | -----: |
|
||||
| [Hugo - A Static Site Builder in Go](http://deepfriedcode.com/post/hugo/) | Deep Fried Code | 30 Mar 2014 |
|
||||
| [Hugo](http://bra.am/post/hugo/) | bra.am | 23 Mar 2014 |
|
||||
| [Converting Blogger To Markdown](http://trishagee.github.io/project/atom-to-hugo/) | Trisha Gee | 20 Mar 2014 |
|
||||
| [Moving to Hugo Static Web Pages](http://tepid.org/tech/hugo-web/) | Tobias Weingartner | 16 Mar 2014 |
|
||||
| [Hugo and Github Pages](http://sglyon.com/blog/2014/creating-the-site/) | Spencer Lyon | 15 Mar 2014 |
|
||||
| [Hugo + gulp.js = Huggle](http://ktmud.github.io/huggle/intro/) | Jesse Yang | 8 Mar 2014 |
|
||||
| [Powered by Hugo](http://kieranhealy.org/blog/archives/2014/02/24/powered-by-hugo/) | Kieran Healy | 24 Feb 2014 |
|
||||
| [Latest Roundup of Useful Tools For Developers](http://codegeekz.com/latest-roundup-of-useful-tools-for-developers/) | CodeGeekz | 13 Feb 2014 |
|
||||
| [Hugo: Static Site Generator written in Go](http://www.braveterry.com/2014/02/06/hugo-static-site-generator-written-in-go/) | Brave Terry | 6 Feb 2014 |
|
||||
| [10 Useful HTML5 Tools for Web Designers and Developers](http://designdizzy.com/10-useful-html5-tools-for-web-designers-and-developers/) | Design Dizzy | 4 Feb 2014 |
|
||||
| [Hugo – Fast, Flexible Static Site Generator](http://cube3x.com/hugo-fast-flexible-static-site-generator/) | Joby Joseph | 18 Jan 2014 |
|
||||
| [Xaprb now uses Hugo](http://xaprb.com/blog/2014/01/15/using-hugo/) | Baron Schwartz | 15 Jan 2014 |
|
||||
| [New jQuery Plugins And Resources That Web Designers Need](http://www.designyourway.net/blog/resources/new-jquery-plugins-and-resources-that-web-designers-need/) | Design Your Way | 2014 |
|
||||
| [Hugo](http://onethingwell.org/post/69070926608/hugo) | One Thing Well | 5 Dec 2013 |
|
||||
| [Hosting a blog on S3 and Cloudfront](http://www.danesparza.net/2013/07/hosting-a-blog-on-s3-and-cloudfront/) | Dan Esparza | 24 July 2013 |
|
||||
|
||||
### Wrote a post, article or tutorial?
|
||||
|
||||
Have you written a post, article or tutorial on hugo? Send us a pull request or issue with the addition.
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
date: 2014-05-14T02:13:50Z
|
||||
menu:
|
||||
main:
|
||||
parent: content
|
||||
next: /content/ordering
|
||||
prev: /content/types
|
||||
title: Archetypes
|
||||
weight: 50
|
||||
---
|
||||
|
||||
Hugo v0.11 introduced the concept of a content builder. Using the
|
||||
command: `hugo new [relative new content path]` you can start a content file
|
||||
with the date and title automatically set. This is a welcome feature, but
|
||||
active writers need more.
|
||||
|
||||
Hugo presents the concept of archetypes which are archetypal content files.
|
||||
|
||||
## Example archetype
|
||||
|
||||
In this example scenario I have a blog with a single content type (blog post).
|
||||
I use ‘tags’ and ‘categories’ for my taxonomies.
|
||||
|
||||
### archetypes/default.md
|
||||
|
||||
+++
|
||||
tags = ["x", "y"]
|
||||
categories = ["x", "y"]
|
||||
+++
|
||||
|
||||
|
||||
## using archetypes
|
||||
|
||||
If I wanted to create a new post in the `posts` section I would run the following command...
|
||||
|
||||
`hugo new posts/my-new-post.md`
|
||||
|
||||
Hugo would create the file with the following contents:
|
||||
|
||||
### contents/posts/my-new-post.md
|
||||
|
||||
+++
|
||||
title = "my new post"
|
||||
date = 2014-05-14T02:13:50Z
|
||||
tags = ["x", "y"]
|
||||
categories = ["x", "y"]
|
||||
+++
|
||||
|
||||
|
||||
## Using a different front matter format
|
||||
|
||||
By default the front matter will be created in the TOML format
|
||||
regardless of what format the archetype is using.
|
||||
|
||||
You can specify a different default format in your config file using
|
||||
the `MetaDataFormat` directive. Possible values are `toml`, `yaml` and `json`.
|
||||
|
||||
|
||||
## Which archtype is being used
|
||||
|
||||
The following rules apply:
|
||||
|
||||
* If an archetype with a filename that matches the content type being created it will be used.
|
||||
* If no match is found `archetypes/default.md` will be used.
|
||||
* If neither are present and a theme is in use then within the theme...
|
||||
* If an archetype with a filename that matches the content type being created it will be used.
|
||||
* If no match is found `archetypes/default.md` will be used.
|
||||
* If no archetype files are present then the one that ships with hugo will be used.
|
||||
|
||||
Hugo provides a simple archetype which sets the title (based on the
|
||||
file name) and the date based on now().
|
||||
|
||||
Content type is automatically detected based on the path. You are welcome to declare which
|
||||
type to create using the `--kind` flag during creation.
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/example/
|
||||
date: 2013-07-01
|
||||
linktitle: Example
|
||||
menu:
|
||||
main:
|
||||
parent: content
|
||||
next: /themes/overview
|
||||
notoc: true
|
||||
prev: /content/ordering
|
||||
title: Example Content File
|
||||
weight: 70
|
||||
---
|
||||
|
||||
Somethings are better shown than explained. The following is a very basic example of a content file:
|
||||
|
||||
**mysite/project/nitro.md <- http://mysite.com/project/nitro.html**
|
||||
|
||||
---
|
||||
Title: "Nitro : A quick and simple profiler for Go"
|
||||
Description: "Nitro is a simple profiler for you go lang applications"
|
||||
Tags: [ "Development", "Go", "profiling" ]
|
||||
date: "2013-06-19"
|
||||
Topics: [ "Development", "Go" ]
|
||||
Slug: "nitro"
|
||||
project_url: "http://github.com/spf13/nitro"
|
||||
---
|
||||
|
||||
# Nitro
|
||||
|
||||
Quick and easy performance analyzer library for Go.
|
||||
|
||||
## Overview
|
||||
|
||||
Nitro is a quick and easy performance analyzer library for Go.
|
||||
It is useful for comparing A/B against different drafts of functions
|
||||
or different functions.
|
||||
|
||||
## Implementing Nitro
|
||||
|
||||
Using Nitro is simple. First use go get to install the latest version
|
||||
of the library.
|
||||
|
||||
$ go get github.com/spf13/nitro
|
||||
|
||||
Next include nitro in your application.
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/front-matter/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: content
|
||||
next: /content/sections
|
||||
prev: /content/organization
|
||||
title: Front Matter
|
||||
weight: 20
|
||||
---
|
||||
|
||||
The front matter is one of the features that gives Hugo its strength. It enables
|
||||
you to include the meta data of the content right with it. Hugo supports a few
|
||||
different formats each with their own identifying tokens.
|
||||
|
||||
Supported formats: <br>
|
||||
**YAML**, identified by '\-\-\-'. <br>
|
||||
**TOML**, indentified with '+++'.<br>
|
||||
**JSON**, a single JSON object which is surrounded by '{' and '}' each on their own line.
|
||||
|
||||
### YAML Example
|
||||
|
||||
---
|
||||
title: "spf13-vim 3.0 release and new website"
|
||||
description: "spf13-vim is a cross platform distribution of vim plugins and resources for Vim."
|
||||
tags: [ ".vimrc", "plugins", "spf13-vim", "vim" ]
|
||||
date: "2012-04-06"
|
||||
categories:
|
||||
- "Development"
|
||||
- "VIM"
|
||||
slug: "spf13-vim-3-0-release-and-new-website"
|
||||
---
|
||||
Content of the file goes Here
|
||||
|
||||
### TOML Example
|
||||
|
||||
+++
|
||||
title = "spf13-vim 3.0 release and new website"
|
||||
description = "spf13-vim is a cross platform distribution of vim plugins and resources for Vim."
|
||||
tags = [ ".vimrc", "plugins", "spf13-vim", "vim" ]
|
||||
date = "2012-04-06"
|
||||
categories = [
|
||||
"Development",
|
||||
"VIM"
|
||||
]
|
||||
slug = "spf13-vim-3-0-release-and-new-website"
|
||||
+++
|
||||
Content of the file goes Here
|
||||
|
||||
### JSON Example
|
||||
|
||||
{
|
||||
"title": "spf13-vim 3.0 release and new website",
|
||||
"description": "spf13-vim is a cross platform distribution of vim plugins and resources for Vim.",
|
||||
"tags": [ ".vimrc", "plugins", "spf13-vim", "vim" ],
|
||||
"date": "2012-04-06",
|
||||
"categories": [
|
||||
"Development",
|
||||
"VIM"
|
||||
],
|
||||
"slug": "spf13-vim-3-0-release-and-new-website",
|
||||
}
|
||||
Content of the file goes Here
|
||||
|
||||
## Variables
|
||||
|
||||
There are a few predefined variables that Hugo is aware of and utilizes. The user can also create
|
||||
any variable they want to. These will be placed into the `.Params` variable available to the templates.
|
||||
**Field names are case insensitive.**
|
||||
|
||||
### Required
|
||||
|
||||
* **title** The title for the content
|
||||
* **description** The description for the content
|
||||
* **date** The date the content will be sorted by
|
||||
* **taxonomies** These will use the field name of the plural form of the index (see tags and categories above)
|
||||
|
||||
### Optional
|
||||
|
||||
* **redirect** Mark the post as a redirect post
|
||||
* **draft** If true the content will not be rendered unless hugo is called with --buildDrafts
|
||||
* **publishdate** If in the future, content will not be rendered unless hugo is called with --buildFuture
|
||||
* **type** The type of the content (will be derived from the directory automatically if unset)
|
||||
* **weight** Used for sorting
|
||||
* **markup** (Experimental) Specify "rst" for reStructuredText (requires
|
||||
`rst2html`,) or "md" (default) for the Markdown
|
||||
* **slug** The token to appear in the tail of the url
|
||||
*or*<br>
|
||||
* **url** The full path to the content from the web root.<br>
|
||||
|
||||
*If neither slug or url is present the filename will be used.*
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
date: 2014-03-06
|
||||
linktitle: Ordering
|
||||
menu:
|
||||
main:
|
||||
parent: content
|
||||
next: /content/example
|
||||
prev: /content/archetypes
|
||||
title: Ordering Content
|
||||
weight: 60
|
||||
---
|
||||
|
||||
Hugo provides you with all the flexibility you need to organize how your content is ordered.
|
||||
|
||||
By default, content is ordered by weight, then by date with the most
|
||||
recent date first, but alternative sorting (by title and linktitle) is
|
||||
also available. The order the content will appear will be specified in
|
||||
the [list template](/templates/list).
|
||||
|
||||
_Both the date and weight fields are optional._
|
||||
|
||||
Unweighted pages appear at the end of the list. If no weights are provided (or
|
||||
if weights are the same) date will be used to sort. If neither are provided
|
||||
content will be ordered based on how it's read off the disk and no order is
|
||||
guaranteed.
|
||||
|
||||
## Assigning Weight to content
|
||||
|
||||
+++
|
||||
weight = "4"
|
||||
title = "Three"
|
||||
date = "2012-04-06"
|
||||
+++
|
||||
Front Matter with Ordered Pages 3
|
||||
|
||||
|
||||
## Ordering Content Within Taxonomies
|
||||
|
||||
Please see the [Taxonomy Ordering Documentation](/taxonomies/ordering/)
|
||||
@@ -0,0 +1,164 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/organization/
|
||||
date: 2013-07-01
|
||||
linktitle: Organization
|
||||
menu:
|
||||
main:
|
||||
parent: content
|
||||
next: /content/front-matter
|
||||
prev: /overview/source-directory
|
||||
title: Content Organization
|
||||
weight: 10
|
||||
---
|
||||
|
||||
Hugo uses markdown files with headers commonly called the front matter. Hugo
|
||||
respects the organization that you provide for your content to minimize any
|
||||
extra configuration, though this can be overridden by additional configuration
|
||||
in the front matter.
|
||||
|
||||
## Organization
|
||||
|
||||
In Hugo the content should be arranged in the same way they are intended for
|
||||
the rendered website. Without any additional configuration the following will
|
||||
just work. Hugo supports content nested at any level. The top level is special
|
||||
in Hugo and is used as the [section](/content/sections).
|
||||
|
||||
.
|
||||
└── content
|
||||
├── post
|
||||
| ├── firstpost.md // <- http://1.com/post/firstpost/
|
||||
| ├── happy
|
||||
| | └── ness.md // <- http://1.com/post/happy/ness/
|
||||
| └── secondpost.md // <- http://1.com/post/secondpost/
|
||||
└── quote
|
||||
├── first.md // <- http://1.com/quote/first/
|
||||
└── second.md // <- http://1.com/quote/second/
|
||||
|
||||
**Here's the same organization run with hugo -\-uglyurls**
|
||||
|
||||
.
|
||||
└── content
|
||||
├── post
|
||||
| ├── firstpost.md // <- http://1.com/post/firstpost.html
|
||||
| ├── happy
|
||||
| | └── ness.md // <- http://1.com/post/happy/ness.html
|
||||
| └── secondpost.md // <- http://1.com/post/secondpost.html
|
||||
└── quote
|
||||
├── first.md // <- http://1.com/quote/first.html
|
||||
└── second.md // <- http://1.com/quote/second.html
|
||||
|
||||
## Destinations
|
||||
|
||||
Hugo thinks 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. As displayed above, the organization of the source content will be
|
||||
mirrored in the destination.
|
||||
|
||||
There are times when one would need more control over their content. In these
|
||||
cases there are a variety of things that can be specified in the front matter to
|
||||
determine the destination of a specific piece of content.
|
||||
|
||||
The following items are defined in order, latter items in the list will override
|
||||
earlier settings.
|
||||
|
||||
### filename
|
||||
This isn't in the front matter, but is the actual name of the file minus the
|
||||
extension. This will be the name of the file in the destination.
|
||||
|
||||
### slug
|
||||
Defined in the front matter, the slug can take the place of the filename for the
|
||||
destination.
|
||||
|
||||
### filepath
|
||||
The actual path to the file on disk. Destination will create the destination
|
||||
with the same path. Includes [section](/content/sections).
|
||||
|
||||
### section
|
||||
section can be provided in the front matter overriding the section derived from
|
||||
the source content location on disk. See [section](/content/sections).
|
||||
|
||||
### path
|
||||
path can be provided in the front matter. This will replace the actual
|
||||
path to the file on disk. Destination will create the destination with the same
|
||||
path. Includes [section](/content/sections).
|
||||
|
||||
### url
|
||||
A complete url can be provided. This will override all the above as it pertains
|
||||
to the end destination. This must be the path from the baseurl (starting with a "/").
|
||||
When a url is provided it will be used exactly. Using url will ignore the
|
||||
-\-uglyurls setting.
|
||||
|
||||
|
||||
## Path breakdown in hugo
|
||||
|
||||
### Content
|
||||
|
||||
. path slug
|
||||
. ⊢-------^----⊣ ⊢------^-------⊣
|
||||
content/extras/indexes/category-example/index.html
|
||||
|
||||
|
||||
. section slug
|
||||
. ⊢--^--⊣ ⊢------^-------⊣
|
||||
content/extras/indexes/category-example/index.html
|
||||
|
||||
|
||||
. section slug
|
||||
. ⊢--^--⊣⊢--^--⊣
|
||||
content/extras/indexes/index.html
|
||||
|
||||
### Destination
|
||||
|
||||
|
||||
permalink
|
||||
⊢--------------^-------------⊣
|
||||
http://spf13.com/projects/hugo
|
||||
|
||||
|
||||
baseUrl section slug
|
||||
⊢-----^--------⊣ ⊢--^---⊣ ⊢-^⊣
|
||||
http://spf13.com/projects/hugo
|
||||
|
||||
|
||||
baseUrl section slug
|
||||
⊢-----^--------⊣ ⊢--^--⊣ ⊢--^--⊣
|
||||
http://spf13.com/extras/indexes/example
|
||||
|
||||
|
||||
baseUrl path slug
|
||||
⊢-----^--------⊣ ⊢------^-----⊣ ⊢--^--⊣
|
||||
http://spf13.com/extras/indexes/example
|
||||
|
||||
|
||||
baseUrl url
|
||||
⊢-----^--------⊣ ⊢-----^-----⊣
|
||||
http://spf13.com/projects/hugo
|
||||
|
||||
|
||||
baseUrl url
|
||||
⊢-----^--------⊣ ⊢--------^-----------⊣
|
||||
http://spf13.com/extras/indexes/example
|
||||
|
||||
|
||||
|
||||
**section** = which type the content is by default
|
||||
|
||||
* based on content location
|
||||
* front matter overrides
|
||||
|
||||
**slug** = name.ext or name/
|
||||
|
||||
* based on content-name.md
|
||||
* front matter overrides
|
||||
|
||||
**path** = section + path to file exluding slug
|
||||
|
||||
* based on path to content location
|
||||
|
||||
|
||||
**url** = relative url
|
||||
|
||||
* defined in front matter
|
||||
* overrides all the above
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: content
|
||||
next: /content/types
|
||||
notoc: true
|
||||
prev: /content/front-matter
|
||||
title: Sections
|
||||
weight: 30
|
||||
---
|
||||
|
||||
Hugo thinks 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 organization](/content/organization) ). Following this pattern Hugo
|
||||
uses the top level of your content organization as **the Section**.
|
||||
|
||||
The following example site uses two sections, "post" and "quote".
|
||||
|
||||
.
|
||||
└── content
|
||||
├── post
|
||||
| ├── firstpost.md // <- http://1.com/post/firstpost/
|
||||
| ├── happy
|
||||
| | └── ness.md // <- http://1.com/post/happy/ness/
|
||||
| └── secondpost.md // <- http://1.com/post/secondpost/
|
||||
└── quote
|
||||
├── first.md // <- http://1.com/quote/first/
|
||||
└── second.md // <- http://1.com/quote/second/
|
||||
|
||||
|
||||
## Section Lists
|
||||
|
||||
Hugo will automatically create pages for each section root that list all
|
||||
of the content in that section. See [List Templates](/templates/list)
|
||||
for details on customizing the way they appear.
|
||||
|
||||
## Sections and Types
|
||||
|
||||
By default everything created within a section will use the content type
|
||||
that matches the section name.
|
||||
|
||||
Section defined in the front matter have the same impact.
|
||||
|
||||
To change the type of a given piece of content simply define the type
|
||||
in the front matter.
|
||||
|
||||
If a layout for a given type hasn't been provided a default type template will
|
||||
be used instead provided is exists.
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
date: 2013-07-01
|
||||
linktitle: Types
|
||||
menu:
|
||||
main:
|
||||
parent: content
|
||||
next: /content/archetypes
|
||||
prev: /content/sections
|
||||
title: Content Types
|
||||
weight: 40
|
||||
---
|
||||
|
||||
Hugo has full support for different types of content. A content type can have a
|
||||
unique set of meta data, template and can be automatically created by the new
|
||||
command through using content [archetypes](/content/archetypes).
|
||||
|
||||
A good example of when multiple types are needed is to look at Tumblr. A piece
|
||||
of content could be a photo, quote or post, each with different meta data and
|
||||
rendered differently.
|
||||
|
||||
## Assigning a content type
|
||||
|
||||
Hugo assumes that your site will be organized into [sections](/content/sections)
|
||||
and each section will use the corresponding type. If you are taking advantage of
|
||||
this then each new piece of content you place into a section will automatically
|
||||
inherit the type.
|
||||
|
||||
Alternatively you can set the type in the meta data under the key "type".
|
||||
|
||||
|
||||
## Creating new content of a specific type
|
||||
|
||||
Hugo has the ability to create a new content file and populate the front matter
|
||||
with the data set corresponding to that type. Hugo does this by utilizing
|
||||
[archetypes](/content/archetypes).
|
||||
|
||||
To create a new piece of content use:
|
||||
|
||||
hugo new relative/path/to/content.md
|
||||
|
||||
For example if I wanted to create a new post inside the post section I would type:
|
||||
|
||||
hugo new post/my-newest-post.md
|
||||
|
||||
|
||||
## Defining a content type
|
||||
|
||||
Creating a new content type is easy in Hugo. You simply provide the templates and archetype
|
||||
that the new type will use. You only need to define the templates, archetypes and/or views
|
||||
unique to that content type. Hugo will fall back to using the general templates and default archetype
|
||||
whenever a specific file is not present.
|
||||
|
||||
*Remember, all of the following are optional:*
|
||||
|
||||
### Create Type Directory
|
||||
Create a directory with the name of the type in layouts.Type is always singular. *Eg /layouts/post*.
|
||||
|
||||
### Create single template
|
||||
Create a file called single.html inside your directory. *Eg /layouts/post/single.html*.
|
||||
|
||||
### Create list template
|
||||
Create a file called list.html inside your directory *Eg /layouts/post/list.html*.
|
||||
|
||||
### Create views
|
||||
Many sites support rendering content in a few different ways, for
|
||||
instance a single page view and a summary view to be used when displaying a list
|
||||
of contents on a single page. Hugo makes no assumptions here about how you want
|
||||
to display your content, and will support as many different views of a content
|
||||
type as your site requires. All that is required for these additional views is
|
||||
that a template exists in each layout/type directory with the same name.
|
||||
|
||||
### Create a corresponding archetype
|
||||
|
||||
Create a file called `type`.md in the /archetypes directory *Eg /archetypes/post.md*.
|
||||
|
||||
More details about archetypes can be found at the [archetypes docs](/content/archetypes)
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"title": "Configuring Hugo",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
|
||||
The directory structure and templates provide the majority of the
|
||||
configuration for a site. In fact a config file isn't even needed for many websites
|
||||
since the defaults used follow commonly used patterns.
|
||||
|
||||
The following is an example of a config file with the default values
|
||||
|
||||
{
|
||||
"SourceDir" : "content",
|
||||
"LayoutDir" : "layouts",
|
||||
"PublishDir" : "public",
|
||||
"BuildDrafts" : false,
|
||||
"Tags" : { "category" : "categories", "tag" : "tags" },
|
||||
"BaseUrl" : "http://yourSite.com/"
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"title": "Contributing to Hugo",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
|
||||
1. Fork it from https://github.com/spf13/hugo
|
||||
2. Create your feature branch (`git checkout -b my-new-feature`)
|
||||
3. Commit your changes (`git commit -am 'Add some feature'`)
|
||||
4. Push to the branch (`git push origin my-new-feature`)
|
||||
5. Create new Pull Request
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"title": "Contributors",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
|
||||
Hugo was built with love and golang by:
|
||||
|
||||
* [spf13](https://github.com/spf13)
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
{
|
||||
"title": "Example Content File",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
|
||||
Somethings are better shown than explained. The following is a very basic example of a content file:
|
||||
|
||||
**mysite/project/nitro.md <- http://mysite.com/project/nitro.html**
|
||||
|
||||
{
|
||||
"Title": "Nitro : A quick and simple profiler for golang",
|
||||
"Description": "",
|
||||
"Keywords": [ "Development", "golang", "profiling" ],
|
||||
"Tags": [ "Development", "golang", "profiling" ],
|
||||
"Pubdate": "2013-06-19",
|
||||
"Topics": [ "Development", "GoLang" ],
|
||||
"Slug": "nitro",
|
||||
"project_url": "http://github.com/spf13/nitro"
|
||||
}
|
||||
|
||||
# Nitro
|
||||
|
||||
Quick and easy performance analyzer library for golang.
|
||||
|
||||
## Overview
|
||||
|
||||
Nitro is a quick and easy performance analyzer library for golang.
|
||||
It is useful for comparing A/B against different drafts of functions
|
||||
or different functions.
|
||||
|
||||
## Implementing Nitro
|
||||
|
||||
Using Nitro is simple. First use go get to install the latest version
|
||||
of the library.
|
||||
|
||||
$ go get github.com/spf13/nitro
|
||||
|
||||
Next include nitro in your application.
|
||||
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"title": "Front Matter",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
|
||||
The front matter is one of the features that gives Hugo it's strength. It enables
|
||||
you to include the meta data of the content right with it. Hugo supports a few
|
||||
different formats. The main format supported is JSON. Here is an example:
|
||||
|
||||
{
|
||||
"Title": "spf13-vim 3.0 release and new website",
|
||||
"Description": "spf13-vim is a cross platform distribution of vim plugins and resources for Vim.",
|
||||
"Tags": [ ".vimrc", "plugins", "spf13-vim", "vim" ],
|
||||
"Pubdate": "2012-04-06",
|
||||
"Categories": [ "Development", "VIM" ],
|
||||
"Slug": "spf13-vim-3-0-release-and-new-website"
|
||||
}
|
||||
|
||||
### Variables
|
||||
There are a few predefined variables that Hugo is aware of and utilizes. The user can also create
|
||||
any variable they want to. These will be placed into the `.Params` variable available to the templates.
|
||||
|
||||
#### Required
|
||||
|
||||
**Title** The title for the content. <br>
|
||||
**Description** The description for the content.<br>
|
||||
**Pubdate** The date the content will be sorted by.<br>
|
||||
**Indexes** These will use the field name of the plural form of the index (see tags and categories above)
|
||||
|
||||
#### Optional
|
||||
|
||||
**Draft** If true the content will not be rendered unless `hugo` is called with -d<br>
|
||||
**Type** The type of the content (will be derived from the directory automatically if unset).<br>
|
||||
**Slug** The token to appear in the tail of the url.<br>
|
||||
*or*<br>
|
||||
**Url** The full path to the content from the web root.<br>
|
||||
*If neither is present the filename will be used.*
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
{
|
||||
"title": "Installing Hugo",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
|
||||
Installation is very easy. Simply download the appropriate version for your
|
||||
platform.
|
||||
|
||||
Hugo is written in GoLang with support for Windows, Linux and OSX.
|
||||
|
||||
<div class="alert alert-info">
|
||||
Please make sure that you place the executable in your path. `/usr/local/bin`
|
||||
is the most probable location.
|
||||
</div>
|
||||
|
||||
|
||||
Hugo doesn't have any external dependencies, but can benefit from external
|
||||
programs.
|
||||
|
||||
|
||||
## Installing from source
|
||||
|
||||
Make sure you have a recent version of go installed. Hugo requires go 1.1+.
|
||||
|
||||
git clone https://github.com/spf13/hugo
|
||||
cd hugo
|
||||
go build -o hugo main.go
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"title": "Organization",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
|
||||
Hugo uses markdown files with headers commonly called the front matter. Hugo respects the organization
|
||||
that you provide for your content to minimize any extra configuration, though this can be overridden
|
||||
by additional configuration in the front matter.
|
||||
|
||||
## Organization
|
||||
In Hugo the content should be arranged in the same way they are intended for the rendered website.
|
||||
Without any additional configuration the following will just work.
|
||||
|
||||
.
|
||||
└── content
|
||||
├── post
|
||||
| ├── firstpost.md // <- http://site.com/post/firstpost.html
|
||||
| └── secondpost.md // <- http://site.com/post/secondpost.html
|
||||
└── quote
|
||||
├── first.md // <- http://site.com/quote/first.html
|
||||
└── second.md // <- http://site.com/quote/second.html
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
{
|
||||
"title": "Release Notes",
|
||||
"Pubdate": "2013-07-01"
|
||||
|
||||
}
|
||||
|
||||
* **0.7.0** July 4, 2013
|
||||
* Hugo now includes a simple server
|
||||
* First public release
|
||||
* **0.6.0** July 2, 2013
|
||||
* Hugo includes an example documentation site which it builds
|
||||
* **0.5.0** June 25, 2013
|
||||
* Hugo is quite usable and able to build spf13.com
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"title": "Roadmap",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
|
||||
In no particular order, here is what I'm working on:
|
||||
|
||||
* Pagination
|
||||
* Support for top level pages (other than homepage)
|
||||
* Series support
|
||||
* Syntax highlighting
|
||||
* Previous & Next
|
||||
* Related Posts
|
||||
* Support for TOML front matter
|
||||
* Proper YAML support for front matter
|
||||
* Support for other formats
|
||||
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
{
|
||||
"title": "Shortcodes",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
|
||||
Because Hugo uses markdown for it's content format, it was clear that there's a lot of things that
|
||||
markdown doesn't support well. This is good, the simple nature of markdown is exactly why we chose it.
|
||||
|
||||
However we cannot accept being constrained by our simple format. Also unacceptable is writing raw
|
||||
html in our markdown every time we want to include unsupported content such as a video. To do
|
||||
so is in complete opposition to the intent of using a bare bones format for our content and
|
||||
utilizing templates to apply styling for display.
|
||||
|
||||
To avoid both of these limitations Hugo has full support for shortcodes.
|
||||
|
||||
### What is a shortcode?
|
||||
A shortcode is a simple snippet inside a markdown file that Hugo will render using a template.
|
||||
|
||||
Short codes are designated by the opening and closing characters of '{{%' and '%}}' respectively.
|
||||
Short codes are space delimited. The first word is always the name of the shortcode. Following the
|
||||
name are the parameters. The author of the shortcode can choose if the short code
|
||||
will use positional parameters or named parameters (but not both). A good rule of thumb is that if a
|
||||
short code has a single required value in the case of the youtube example below then positional
|
||||
works very well. For more complex layouts with optional parameters named parameters work best.
|
||||
|
||||
The format for named parameters models that of html with the format name="value"
|
||||
|
||||
### Example: youtube
|
||||
*Example has an extra space so Hugo doesn't actually render it*
|
||||
|
||||
{{ % youtube 09jf3ow9jfw %}}
|
||||
|
||||
This would be rendered as
|
||||
|
||||
<div class="embed video-player">
|
||||
<iframe class="youtube-player" type="text/html"
|
||||
width="640" height="385"
|
||||
src="http://www.youtube.com/embed/09jf3ow9jfw"
|
||||
allowfullscreen frameborder="0">
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
### Example: image with caption
|
||||
*Example has an extra space so Hugo doesn't actually render it*
|
||||
|
||||
{{ % img src="/media/spf13.jpg" title="Steve Francia" %}}
|
||||
|
||||
Would be rendered as:
|
||||
|
||||
<figure >
|
||||
<img src="/media/spf13.jpg" />
|
||||
<figcaption>
|
||||
<h4>Steve Francia</h4>
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
|
||||
### Creating a shortcode
|
||||
|
||||
All that you need to do to create a shortcode is place a template in the layouts/shortcodes directory.
|
||||
|
||||
The template name will be the name of the shortcode.
|
||||
|
||||
**Inside the template**
|
||||
|
||||
To access a parameter by either position or name the index method can be used.
|
||||
|
||||
{{ index .Params 0 }}
|
||||
or
|
||||
{{ index .Params "class" }}
|
||||
|
||||
To check if a parameter has been provided use the isset method provided by Hugo.
|
||||
|
||||
{{ if isset .Params "class"}} class="{{ index .Params "class"}}" {{ end }}
|
||||
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
{
|
||||
"title": "Templates",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
|
||||
Hugo uses the excellent golang html/template library for it's template engine. It is an extremely
|
||||
lightweight engine that provides a very small amount of logic. In our
|
||||
experience that it is just the right amount of logic to be able to create a good static website
|
||||
|
||||
This document will not cover how to use golang templates, but the [golang docs](http://golang.org/pkg/html/template/)
|
||||
provide a good introduction.
|
||||
|
||||
### Template roles
|
||||
|
||||
There are 5 different kinds of templates that Hugo works with.
|
||||
|
||||
#### index.html
|
||||
This file must exist in the layouts directory. It is the template used to render the
|
||||
homepage of your site.
|
||||
|
||||
#### rss.xml
|
||||
This file must exist in the layouts directory. It will be used to render all rss documents.
|
||||
The one provided in the example application will generate an ATOM format.
|
||||
|
||||
*Important: Hugo will automatically add the following header line to this file.*
|
||||
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
|
||||
#### Indexes
|
||||
An index is a page that list multiple pieces of content. If you think of a typical blog, the tag
|
||||
pages are good examples of indexes.
|
||||
|
||||
|
||||
#### Content Type(s)
|
||||
Hugo supports multiple types of content. Another way of looking at this is that Hugo has the ability
|
||||
to render content in a variety of ways as determined by the type.
|
||||
|
||||
#### Chrome
|
||||
Chrome is simply the decoration of your site. It's not a requirement to have this, but in practice
|
||||
it's very convenient. Hugo doesn't know anything about Chrome, it's simply a convention that you may
|
||||
likely find beneficial. As you create the rest of your templates you will include templates from the
|
||||
/layout/chrome directory. I've found it helpful to include a header and footer template
|
||||
in Chrome so I can include those in the other full page layouts (index.html, indexes/ type/single.html).
|
||||
|
||||
### Adding a new content type
|
||||
|
||||
Adding a type is easy.
|
||||
|
||||
**Step 1:**
|
||||
Create a directory with the name of the type in layouts.Type is always singular. *Eg /layouts/post*.
|
||||
|
||||
**Step 2:**
|
||||
Create a file called single.html inside your directory. *Eg /layouts/post/single.html*.
|
||||
|
||||
**Step 3:**
|
||||
Create a file with the same name as your directory in /layouts/indexes/. *Eg /layouts/index/post.html*.
|
||||
|
||||
**Step 4:**
|
||||
Many sites support rendering content in a few different ways, for instance a single page view and a
|
||||
summary view to be used when displaying a list of contents on a single page. Hugo makes no assumptions
|
||||
here about how you want to display your content, and will support as many different views of a content
|
||||
type as your site requires. All that is required for these additional views is that a template
|
||||
exists in each layout/type directory with the same name.
|
||||
|
||||
For these, reviewing this example site will be very helpful in order to understand how these types work.
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
{
|
||||
"title": "Using Hugo",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
|
||||
Make sure either hugo is in your path or provide a path to it.
|
||||
|
||||
$ hugo --help
|
||||
usage: hugo [flags] []
|
||||
-b="": hostname (and path) to the root eg. http://spf13.com/
|
||||
-c="config.json": config file (default is path/config.json)
|
||||
-d=false: include content marked as draft
|
||||
-h=false: show this help
|
||||
-k=false: analyze content and provide feedback
|
||||
-p="": filesystem path to read files relative from
|
||||
-w=false: watch filesystem for changes and recreate as needed
|
||||
-s=false: a (very) simple webserver
|
||||
-p="1313": port for webserver to run on
|
||||
|
||||
## Common Usage Example:
|
||||
|
||||
The most common use is probably to run hugo with your current
|
||||
directory being the input directory.
|
||||
|
||||
|
||||
$ hugo
|
||||
> X pages created
|
||||
> Y indicies created
|
||||
|
||||
|
||||
If you are working on things and want to see the changes
|
||||
immediately, tell Hugo to watch for changes.
|
||||
<br>
|
||||
**It will
|
||||
recreate the site faster than you can tab over to
|
||||
your browser to view the changes.**
|
||||
|
||||
$ hugo -p ~/mysite -w
|
||||
Watching for changes. Press ctrl+c to stop
|
||||
15 pages created
|
||||
0 tags created
|
||||
|
||||
Hugo can even run a server and create your site at the same time!
|
||||
|
||||
$hugo -p ~/mysite -w -s
|
||||
Watching for changes. Press ctrl+c to stop
|
||||
15 pages created
|
||||
0 tags created
|
||||
Web Server is available at http://localhost:1313
|
||||
Press ctrl+c to stop
|
||||
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"title": "Variables",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
|
||||
Hugo makes a set of values available to the templates. Go templates are context based. The following
|
||||
are available in the context for the templates.
|
||||
|
||||
**.Title** The title for the content. <br>
|
||||
**.Description** The description for the content.<br>
|
||||
**.Keywords** The meta keywords for this content.<br>
|
||||
**.Date** The date the content is published on.<br>
|
||||
**.Indexes** These will use the field name of the plural form of the index (see tags and categories above)<br>
|
||||
**.Permalink** The Permanent link for this page.<br>
|
||||
**.FuzzyWordCount** The approximate number of words in the content.<br>
|
||||
**.RSSLink** Link to the indexes' rss link <br>
|
||||
|
||||
Any value defined in the front matter, including indexes will be made available under `.Params`.
|
||||
Take for example I'm using tags and categories as my indexes. The following would be how I would access them:
|
||||
|
||||
**.Params.Tags** <br>
|
||||
**.Params.Categories** <br>
|
||||
|
||||
Also available is `.Site` which has the following:
|
||||
|
||||
**.Site.BaseUrl** The base URL for the site as defined in the config.json file.<br>
|
||||
**.Site.Indexes** The names of the indexes of the site.<br>
|
||||
**.Site.LastChange** The date of the last change of the most recent content.<br>
|
||||
**.Site.Recent** Array of all content ordered by Date, newest first<br>
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/redirects/
|
||||
- /doc/alias/
|
||||
- /doc/aliases/
|
||||
date: 2013-07-09
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/builders
|
||||
prev: /taxonomies/ordering
|
||||
title: Aliases
|
||||
weight: 10
|
||||
---
|
||||
|
||||
For people migrating existing published content to Hugo theres a good chance
|
||||
you need a mechanism to handle redirecting old urls.
|
||||
|
||||
Luckily, this can be handled easily with aliases in Hugo.
|
||||
|
||||
## Example
|
||||
**content/posts/my-awesome-blog-post.md**
|
||||
|
||||
---
|
||||
aliases:
|
||||
- /posts/my-original-url/
|
||||
- /2010/even-earlier-url.html
|
||||
---
|
||||
|
||||
Now when you go to any of the aliases locations they
|
||||
will redirect to the page.
|
||||
|
||||
## Important Behaviors
|
||||
|
||||
1. *Hugo makes no assumptions about aliases. They also don't change based
|
||||
on your UglyUrls setting. You need to provide absolute path to your webroot and the
|
||||
complete filename or directory.*
|
||||
|
||||
2. *Aliases are rendered prior to any content and will be overwritten by
|
||||
any content with the same location.*
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
date: 2014-05-26
|
||||
linktitle: Builders
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/comments
|
||||
prev: /extras/aliases
|
||||
title: Hugo Builders
|
||||
weight: 12
|
||||
---
|
||||
|
||||
Hugo provides the functionality to quickly get a site, theme or page
|
||||
started.
|
||||
|
||||
|
||||
## New Site
|
||||
|
||||
Want to get a site built quickly?.
|
||||
|
||||
hugo new site /path/to/site
|
||||
|
||||
Hugo will create all the needed directories and files to get started
|
||||
quickly.
|
||||
|
||||
Hugo will only touch the files and create the directories (in the right
|
||||
places), [configuration](/overview/configuration) and content are up to
|
||||
you... but luckily we have builders for content (see below).
|
||||
|
||||
## New Theme
|
||||
|
||||
Want to design a new theme?
|
||||
|
||||
hugo new theme `THEME_NAME`
|
||||
|
||||
Run from your working directory, this will create a new theme with all
|
||||
the needed files in your themes directory. Hugo will provide you with a
|
||||
license and theme.toml file with most of the work done for you.
|
||||
|
||||
Follow the [Theme Creation Guide](/themes/creation) once the builder is
|
||||
done.
|
||||
|
||||
## New Content
|
||||
|
||||
You will use this builder the most of all. Every time you want to create
|
||||
a new piece of content, the content builder will get you started right.
|
||||
|
||||
Leveraging [content archetypes](/content/archetypes) the content builder
|
||||
will not only insert the current date and appropriate metadata, but it
|
||||
will pre-populate values based on the content type.
|
||||
|
||||
hugo new relative/path/to/content
|
||||
|
||||
This assumes it is being run from your working directory and the content
|
||||
path starts from your content directory.
|
||||
|
||||
I typically keep two different terminals open, one to run `hugo server
|
||||
--watch`, and another to use the builders to create new content.
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
date: 2014-05-26
|
||||
linktitle: Comments
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/livereload
|
||||
prev: /extras/builders
|
||||
title: Comments in Hugo
|
||||
weight: 14
|
||||
---
|
||||
|
||||
As Hugo is a static site generator, the content produced is static and
|
||||
doesn’t interact with the users. The most common interaction people ask
|
||||
for is comment capability.
|
||||
|
||||
Hugo ships with support for [disqus](http://disqus.com), a third party
|
||||
service that provides comment and community capabilities to website via
|
||||
javascript.
|
||||
|
||||
Your theme may already support disqus, but even it if doesn’t it is easy
|
||||
to add.
|
||||
|
||||
# Disqus Support
|
||||
|
||||
## Adding Disqus to a template
|
||||
|
||||
Hugo comes with all the code you would need to include load disqus.
|
||||
Simply include the following line where you want your comments to appear
|
||||
|
||||
{{ template "_internal/disqus.html" . }}
|
||||
|
||||
|
||||
## Configuring Disqus
|
||||
|
||||
That template requires you to set a single value in your site config file, eg. config.yaml.
|
||||
|
||||
disqusShortname = "XYW"
|
||||
|
||||
Additionally you can optionally set the following in the front matter
|
||||
for a given piece of content
|
||||
|
||||
* **disqus_identifier**
|
||||
* **disqus_title**
|
||||
* **disqus_url**
|
||||
|
||||
# Alternatives
|
||||
|
||||
A few alternatives exist to Disqus.
|
||||
|
||||
* [Intense Debate](http://intensedebate.com/)
|
||||
* [LiveFyre](http://livefyre.com/)
|
||||
* [Moot](http://muut.com)
|
||||
* [Kaiju](http://github.com/spf13/kaiju)
|
||||
|
||||
|
||||
[Kaiju](http://github.com/spf13/kaiju) is a open source project started
|
||||
by [spf13](http://spf13.com) (Hugo’s author) to bring easy and fast real
|
||||
time discussions to the web.
|
||||
|
||||
Written using Go, Socket.io and MongoDB it is very fast and easy to
|
||||
deploy.
|
||||
|
||||
It is in early development but shows promise.. If you have interest
|
||||
please help by contributing whether via a pull request, an issue or even
|
||||
just a tweet. Everything helps.
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
---
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/toc
|
||||
prev: /extras/shortcodes
|
||||
title: Syntax Highlighting
|
||||
weight: 50
|
||||
---
|
||||
|
||||
Hugo provides the ability for you to highlight source code in two different
|
||||
ways — either pre-processed server side from your content, or to defer
|
||||
the processing to the client side, using a JavaScript library. The advantage of
|
||||
server side is that it doesn’t depend on a JavaScript library and consequently
|
||||
works very well when read from an rss feed. The advantage of client side is that
|
||||
it doesn’t cost anything when building your site and some of the highlighting
|
||||
scripts available cover more languages than pygments does.
|
||||
|
||||
For the pre-processed approach, Highlighting is performed by an external
|
||||
python based program called [pygments](http://pygments.org) and is triggered
|
||||
via an embedded shortcode. If pygments is absent from the path, it will
|
||||
silently simply pass the content along unhighlighted.
|
||||
|
||||
## Server Side
|
||||
|
||||
### Disclaimers
|
||||
|
||||
* **Warning** pygments is relatively slow. Expect much longer build times when using server side highlighting.
|
||||
* Languages available depends on your pygments installation.
|
||||
* Styles are inline in order to be supported in syndicated content when references
|
||||
to style sheets are not carried over.
|
||||
* We have sought to have the simplest interface possible, which consequently
|
||||
limits configuration. An ambitious user is encouraged to extend the current
|
||||
functionality to offer more customization.
|
||||
* You can change appearance with config options `pygmentsstyle`(default
|
||||
`"monokai"`) and `pygmentsuseclasses`(defaut `false`).
|
||||
|
||||
### Usage
|
||||
Highlight takes exactly one required parameter of language and requires a
|
||||
closing shortcode.
|
||||
|
||||
### Example
|
||||
The example has an extra space between the “{{” and “%” characters to prevent rendering here.
|
||||
|
||||
{{ % highlight html %}}
|
||||
<section id="main">
|
||||
<div>
|
||||
<h1 id="title">{{ .Title }}</h1>
|
||||
{{ range .Data.Pages }}
|
||||
{{ .Render "summary"}}
|
||||
{{ end }}
|
||||
</div>
|
||||
</section>
|
||||
{{ % /highlight %}}
|
||||
|
||||
|
||||
### Example Output
|
||||
|
||||
<span style="color: #f92672"><section</span> <span style="color: #a6e22e">id=</span><span style="color: #e6db74">"main"</span><span style="color: #f92672">></span>
|
||||
<span style="color: #f92672"><div></span>
|
||||
<span style="color: #f92672"><h1</span> <span style="color: #a6e22e">id=</span><span style="color: #e6db74">"title"</span><span style="color: #f92672">></span>{{ .Title }}<span style="color: #f92672"></h1></span>
|
||||
{{ range .Data.Pages }}
|
||||
{{ .Render "summary"}}
|
||||
{{ end }}
|
||||
<span style="color: #f92672"></div></span>
|
||||
<span style="color: #f92672"></section></span>
|
||||
|
||||
## Client-side
|
||||
|
||||
Alternatively, code highlighting can be done in client-side JavaScript.
|
||||
|
||||
Client-side syntax highlighting is very simple to add. You'll need to pick
|
||||
a library and a corresponding theme. Some popular libraries are:
|
||||
|
||||
- [Highlight.js]
|
||||
- [Rainbow]
|
||||
- [Syntax Highlighter]
|
||||
- [Google Prettify]
|
||||
|
||||
This example uses the popular [Highlight.js] library, hosted by [Yandex], a
|
||||
popular Russian search engine.
|
||||
|
||||
In your `./layouts/chrome/` folder, depending on your specific theme, there
|
||||
will be a snippet that will be included in every generated HTML page, such
|
||||
as `header.html` or `header.includes.html`. Simply add:
|
||||
|
||||
<link rel="stylesheet" href="https://yandex.st/highlightjs/8.0/styles/default.min.css">
|
||||
<script src="https://yandex.st/highlightjs/8.0/highlight.min.js"></script>
|
||||
|
||||
You can of course use your own copy of these files, typically in `./static/`.
|
||||
|
||||
[Highlight.js]: http://highlightjs.org/
|
||||
[Rainbow]: http://craig.is/making/rainbows
|
||||
[Syntax Highlighter]: http://alexgorbatchev.com/SyntaxHighlighter/
|
||||
[Google Prettify]: https://code.google.com/p/google-code-prettify/
|
||||
[Yandex]: http://yandex.ru/
|
||||
|
||||
Please see individual libraries documentation for how to implement the JavaScript based libraries.
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
date: 2014-05-26
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/menus
|
||||
prev: /extras/comments
|
||||
title: Live Reload
|
||||
weight: 15
|
||||
---
|
||||
|
||||
Hugo may not be the first static site generator to utilize live reload
|
||||
technology, but it’s the first to do it right.
|
||||
|
||||
The combination of Hugo’s insane build speed and live reload make
|
||||
crafting your content pure joy. Virtually instantly after you hit save
|
||||
your rebuilt content will appear in your browser.
|
||||
|
||||
## Using livereload
|
||||
|
||||
Hugo comes with livereload built in. There are no additional packages to
|
||||
install. A common way to use hugo while developing a site is to have
|
||||
hugo run a server and watch for changes.
|
||||
|
||||
hugo server --watch
|
||||
|
||||
This will run a full functioning web server while simultaneously
|
||||
watching your file system for additions, deletions or changes within
|
||||
your:
|
||||
|
||||
* static files
|
||||
* content
|
||||
* layouts
|
||||
* current theme
|
||||
|
||||
Whenever anything changes Hugo will rebuild the site, continue to serve
|
||||
the content and as soon as the build is finished it will tell the
|
||||
browser and silently reload the page. Because most hugo builds are so
|
||||
fast they are barely noticeable, you merely need to glance at your open
|
||||
browser and you will see the change already there.
|
||||
|
||||
This means that keeping the site open on a second monitor (or another
|
||||
half of your current monitor), allows you to see exactly what your
|
||||
content looks like without even leaving your text editor.
|
||||
|
||||
## Disabling livereload
|
||||
|
||||
Live reload accomplishes this by injecting javascript into the pages it
|
||||
creates that creates a web socket client to the hugo web socket server.
|
||||
|
||||
Awesome for development, but not something you would want to do in
|
||||
production. Since many people use `hugo server --watch` in production to
|
||||
instantly display any updated content, we’ve made it easy to disable the
|
||||
live reload functionality.
|
||||
|
||||
hugo server --watch --disableLiveReload
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
---
|
||||
date: 2014-05-14T02:36:37Z
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/permalinks
|
||||
prev: /extras/livereload
|
||||
title: Menus
|
||||
weight: 20
|
||||
---
|
||||
|
||||
Hugo has a simple yet powerful menu system that permits content to be
|
||||
placed in menus with a good degree of control without a lot of work.
|
||||
|
||||
Some of the features of Hugo Menus:
|
||||
|
||||
* Place content in one or many menus
|
||||
* Handle nested menus with unlimited depth
|
||||
* Create menu entries without being attached to any content
|
||||
* Distinguish active element (and active branch)
|
||||
|
||||
## What is a menu?
|
||||
|
||||
A menus is a named array of menu entries accessible on the site under
|
||||
.Site.Menus by name. For example if I have a menu called `main` I would
|
||||
access it via .Site.Menus.main.
|
||||
|
||||
A menu entry has the following properties:
|
||||
|
||||
* **Url** string
|
||||
* **Name** string
|
||||
* **Menu** string
|
||||
* **Identifier** string
|
||||
* **Pre** template.HTML
|
||||
* **Post** template.HTML
|
||||
* **Weight** int
|
||||
* **Parent** string
|
||||
* **Children** Menu
|
||||
|
||||
And the following functions:
|
||||
|
||||
* **HasChildren** bool
|
||||
|
||||
Additionally there are some relevant functions available on the page:
|
||||
|
||||
* **IsMenuCurrent** (menu string, menuEntry *MenuEntry ) bool
|
||||
* **HasMenuCurrent** (menu string, menuEntry *MenuEntry) bool
|
||||
|
||||
|
||||
## Adding content to menus
|
||||
|
||||
Hugo supports a couple of different methods of adding a piece of content
|
||||
to the front matter.
|
||||
|
||||
### Simple
|
||||
|
||||
If all you need to do is add an entry to a menu, the simple form works
|
||||
well.
|
||||
|
||||
**A single menu:**
|
||||
|
||||
---
|
||||
menu: "main"
|
||||
---
|
||||
|
||||
**Multiple menus:**
|
||||
|
||||
---
|
||||
menu: ["main", "footer"]
|
||||
---
|
||||
|
||||
|
||||
### Advanced
|
||||
|
||||
If more control is required, then the advanced approach gives you the
|
||||
control you want. All of the menu entry properties listed above are
|
||||
available.
|
||||
|
||||
---
|
||||
menu:
|
||||
main:
|
||||
parent: 'extras'
|
||||
weight: 20
|
||||
---
|
||||
|
||||
|
||||
## Adding (non-content) entries to a menu
|
||||
|
||||
You can also add entries to menus that aren’t attached to a piece of
|
||||
content. This takes place in the site wide config file.
|
||||
|
||||
Here’s an example (in toml):
|
||||
|
||||
[[menu.main]]
|
||||
name = "about hugo"
|
||||
pre = "<i class='fa fa-heart'></i>"
|
||||
weight = -110
|
||||
identifier = "about"
|
||||
[[menu.main]]
|
||||
name = "getting started"
|
||||
pre = "<i class='fa fa-road'></i>"
|
||||
weight = -100
|
||||
|
||||
## Nesting
|
||||
|
||||
All nesting of content is done via the `parent` field.
|
||||
|
||||
The parent of an entry should be the identifier of another entry.
|
||||
Identifier should be unique (within a menu).
|
||||
|
||||
The following order is used to determine identity Identifier > Name >
|
||||
LinkTitle > Title. This means that the title will be used unless
|
||||
linktitle is present, etc. In practice Name and Identifier are never
|
||||
displayed and only used to structure relationships.
|
||||
|
||||
In this example, the top level of the menu is defined in the config file
|
||||
and all content entries are attached to one of these entries via the
|
||||
`parent` field.
|
||||
|
||||
## Rendering menus
|
||||
|
||||
Hugo makes no assumptions about how your rendered HTML will be
|
||||
structured, instead it provides all of the functions you will need to be
|
||||
able to build your menu however you want.
|
||||
|
||||
|
||||
The following is an example:
|
||||
|
||||
<!--sidebar start-->
|
||||
<aside>
|
||||
<div id="sidebar" class="nav-collapse ">
|
||||
<!-- sidebar menu start-->
|
||||
<ul class="sidebar-menu">
|
||||
{{ $currentNode := . }}
|
||||
{{ range .Site.Menus.main }}
|
||||
{{ if .HasChildren }}
|
||||
|
||||
<li class="sub-menu{{if $currentNode.HasMenuCurrent "main" . }} active{{end}}">
|
||||
<a href="javascript:;" class="">
|
||||
{{ .Pre }}
|
||||
<span>{{ .Name }}</span>
|
||||
<span class="menu-arrow arrow_carrot-right"></span>
|
||||
</a>
|
||||
<ul class="sub">
|
||||
{{ range .Children }}
|
||||
<li{{if $currentNode.IsMenuCurrent "main" . }} class="active"{{end}}><a href="{{.Url}}"> {{ .Name }} </a> </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{else}}
|
||||
<li>
|
||||
<a class="" href="{{.Url}}">
|
||||
{{ .Pre }}
|
||||
<span>{{ .Name }}</span>
|
||||
</a>
|
||||
{{end}}
|
||||
</li>
|
||||
{{end}}
|
||||
<li> <a href="https://github.com/spf13/hugo/issues" target="blank">Questions and Issues</a> </li>
|
||||
<li> <a href="#" target="blank">Edit this Page</a> </li>
|
||||
</ul>
|
||||
<!-- sidebar menu end-->
|
||||
</div>
|
||||
</aside>
|
||||
<!--sidebar end-->
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/permalinks/
|
||||
date: 2013-11-18
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/shortcodes
|
||||
notoc: true
|
||||
prev: /extras/menus
|
||||
title: Permalinks
|
||||
weight: 30
|
||||
---
|
||||
|
||||
By default, content is laid out into the target `publishdir` (public)
|
||||
namespace matching its layout within the `contentdir` hierarchy.
|
||||
The `permalinks` site configuration option allows you to adjust this on a
|
||||
per-section basis.
|
||||
This will change where the files are written to and will change the page's
|
||||
internal "canonical" location, such that template references to
|
||||
`.RelPermalink` will honour the adjustments made as a result of the mappings
|
||||
in this option.
|
||||
|
||||
For instance, if one of your sections is called `post` and you want to adjust
|
||||
the canonical path to be hierarchical based on the year and month, then you
|
||||
might use:
|
||||
|
||||
```yaml
|
||||
permalinks:
|
||||
post: /:year/:month/:title/
|
||||
```
|
||||
|
||||
Only the content under `post/` will be so rewritten.
|
||||
A file named `content/post/sample-entry` which contains a line
|
||||
`date: 2013-11-18T19:20:00-05:00` might end up with the rendered page
|
||||
appearing at `public/2013/11/sample-entry/index.html` and be reachable via
|
||||
the URL <http://yoursite.example.com/2013/11/sample-entry/>.
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/shortcodes/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/highlighting
|
||||
prev: /extras/permalinks
|
||||
title: Shortcodes
|
||||
weight: 40
|
||||
---
|
||||
|
||||
Because Hugo uses markdown for its simple content format, however there's a lot
|
||||
of things that markdown doesn't support well.
|
||||
|
||||
We are unwilling to accept being constrained by our simple format. Also
|
||||
unacceptable is writing raw html in our markdown every time we want to include
|
||||
unsupported content such as a video. To do so is in complete opposition to the
|
||||
intent of using a bare bones format for our content and utilizing templates to
|
||||
apply styling for display.
|
||||
|
||||
To avoid both of these limitations Hugo created shortcodes.
|
||||
|
||||
A shortcode is a simple snippet inside a markdown file that Hugo will render
|
||||
using a predefined template.
|
||||
|
||||
## Using a shortcode
|
||||
|
||||
In your content files a shortcode can be called by using '{{% name parameters
|
||||
%}}' respectively. Shortcodes are space delimited (parameters with spaces
|
||||
can be quoted).
|
||||
|
||||
The first word is always the name of the shortcode. Parameters follow the name.
|
||||
The format for named parameters models that of html with the format
|
||||
name="value". The current implementation only supports this exact format. Extra
|
||||
spaces or different quote marks will not parse properly.
|
||||
|
||||
Some shortcodes use or require closing shortcodes. Like HTML, the opening and closing
|
||||
shortcodes match (name only), the closing being prepended with a slash.
|
||||
|
||||
Example of a paired shortcode:
|
||||
|
||||
{{ % highlight go %}} A bunch of code here {{ % /highlight %}}
|
||||
|
||||
|
||||
## Hugo Shortcodes
|
||||
|
||||
Hugo ships with a set of predefined shortcodes.
|
||||
|
||||
### highlight
|
||||
|
||||
This shortcode will convert the source code provided into syntax highlighted
|
||||
html. Read more on [highlighting](/extras/highlighting).
|
||||
|
||||
#### Usage
|
||||
Highlight takes exactly one required parameter of language and requires a
|
||||
closing shortcode.
|
||||
|
||||
#### Example
|
||||
The example has an extra space between the “{{” and “%” characters to prevent rendering here.
|
||||
|
||||
{{ % highlight html %}}
|
||||
<section id="main">
|
||||
<div>
|
||||
<h1 id="title">{{ .Title }}</h1>
|
||||
{{ range .Data.Pages }}
|
||||
{{ .Render "summary"}}
|
||||
{{ end }}
|
||||
</div>
|
||||
</section>
|
||||
{{ % /highlight %}}
|
||||
|
||||
|
||||
#### Example Output
|
||||
|
||||
<span style="color: #f92672"><section</span> <span style="color: #a6e22e">id=</span><span style="color: #e6db74">"main"</span><span style="color: #f92672">></span>
|
||||
<span style="color: #f92672"><div></span>
|
||||
<span style="color: #f92672"><h1</span> <span style="color: #a6e22e">id=</span><span style="color: #e6db74">"title"</span><span style="color: #f92672">></span>{{ .Title }}<span style="color: #f92672"></h1></span>
|
||||
{{ range .Data.Pages }}
|
||||
{{ .Render "summary"}}
|
||||
{{ end }}
|
||||
<span style="color: #f92672"></div></span>
|
||||
<span style="color: #f92672"></section></span>
|
||||
|
||||
### figure
|
||||
Figure is simply an extension of the image capabilities present with Markdown.
|
||||
figure provides the ability to add captions, css classes, alt text, links etc.
|
||||
|
||||
#### Usage
|
||||
|
||||
figure can use the following parameters
|
||||
|
||||
* src
|
||||
* link
|
||||
* title
|
||||
* caption
|
||||
* attr (attribution)
|
||||
* attrlink
|
||||
* alt
|
||||
|
||||
#### Example
|
||||
*Example has an extra space so Hugo doesn't actually render it*.
|
||||
|
||||
{{ % figure src="/media/spf13.jpg" title="Steve Francia" %}}
|
||||
|
||||
#### Example output
|
||||
|
||||
<figure>
|
||||
<img src="/media/spf13.jpg" />
|
||||
<figcaption>
|
||||
<h4>Steve Francia</h4>
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
## Creating your own shortcodes
|
||||
|
||||
To create a shortcode, place a template in the layouts/shortcodes directory. The
|
||||
template name will be the name of the shortcode.
|
||||
|
||||
In creating a shortcode you can choose if the short code will use positional
|
||||
parameters or named parameters (but not both). A good rule of thumb is that if a
|
||||
short code has a single required value in the case of the youtube example below
|
||||
then positional works very well. For more complex layouts with optional
|
||||
parameters named parameters work best.
|
||||
|
||||
**Inside the template**
|
||||
|
||||
To access a parameter by position the .Get method can be used.
|
||||
|
||||
{{ .Get 0 }}
|
||||
|
||||
To access a parameter by name the .Get method should be utilized
|
||||
|
||||
{{ .Get "class" }}
|
||||
|
||||
|
||||
With is great when the output depends on a parameter being set
|
||||
|
||||
{{ with .Get "class"}} class="{{.}}"{{ end }}
|
||||
|
||||
Get can also be used to check if a parameter has been provided. This is
|
||||
most helpful when the condition depends on either one value or another...
|
||||
or both.
|
||||
|
||||
{{ or .Get "title" | .Get "alt" | if }} alt="{{ with .Get "alt"}}{{.}}{{else}}{{.Get "title"}}{{end}}"{{ end }}
|
||||
|
||||
If a closing shortcode is used, the variable .Inner will be populated with all
|
||||
of the content between the opening and closing shortcodes. If a closing
|
||||
shortcode is required, you can check the length of .Inner and provide a warning
|
||||
to the user.
|
||||
|
||||
## Single Positional Example: youtube
|
||||
|
||||
{{% youtube 09jf3ow9jfw %}}
|
||||
|
||||
Would load the template /layouts/shortcodes/youtube.html
|
||||
|
||||
<div class="embed video-player">
|
||||
<iframe class="youtube-player" type="text/html" width="640" height="385" src="http://www.youtube.com/embed/{{ index .Params 0 }}" allowfullscreen frameborder="0">
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
This would be rendered as
|
||||
|
||||
<div class="embed video-player">
|
||||
<iframe class="youtube-player" type="text/html"
|
||||
width="640" height="385"
|
||||
src="http://www.youtube.com/embed/09jf3ow9jfw"
|
||||
allowfullscreen frameborder="0">
|
||||
</iframe>
|
||||
</div>
|
||||
|
||||
## Single Named Example: image with caption
|
||||
*Example has an extra space so Hugo doesn't actually render it*
|
||||
|
||||
{{ % img src="/media/spf13.jpg" title="Steve Francia" %}}
|
||||
|
||||
Would load the template /layouts/shortcodes/img.html
|
||||
|
||||
<!-- image -->
|
||||
<figure {{ with .Get "class" }}class="{{.}}"{{ end }}>
|
||||
{{ with .Get "link"}}<a href="{{.}}">{{ end }}
|
||||
<img src="{{ .Get "src" }}" {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt"}}{{.}}{{else}}{{ .Get "caption" }}{{ end }}"{{ end }} />
|
||||
{{ if .Get "link"}}</a>{{ end }}
|
||||
{{ if or (or (.Get "title") (.Get "caption")) (.Get "attr")}}
|
||||
<figcaption>{{ if isset .Params "title" }}
|
||||
<h4>{{ .Get "title" }}</h4>{{ end }}
|
||||
{{ if or (.Get "caption") (.Get "attr")}}<p>
|
||||
{{ .Get "caption" }}
|
||||
{{ with .Get "attrlink"}}<a href="{{.}}"> {{ end }}
|
||||
{{ .Get "attr" }}
|
||||
{{ if .Get "attrlink"}}</a> {{ end }}
|
||||
</p> {{ end }}
|
||||
</figcaption>
|
||||
{{ end }}
|
||||
</figure>
|
||||
<!-- image -->
|
||||
|
||||
Would be rendered as:
|
||||
|
||||
<figure >
|
||||
<img src="/media/spf13.jpg" />
|
||||
<figcaption>
|
||||
<h4>Steve Francia</h4>
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
## Paired Example: Highlight
|
||||
*Hugo already ships with the highlight shortcode*
|
||||
|
||||
*Example has an extra space so Hugo doesn't actually render it*.
|
||||
|
||||
<html>
|
||||
<body> This HTML </body>
|
||||
</html>
|
||||
|
||||
The template for this utilizes the following code (already include in hugo)
|
||||
{{ .Get 0 | highlight .Inner }}
|
||||
|
||||
And will be rendered as:
|
||||
|
||||
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span style="color: #f92672"><html></span>
|
||||
<span style="color: #f92672"><body></span> This HTML <span style="color: #f92672"></body></span>
|
||||
<span style="color: #f92672"></html></span>
|
||||
</pre></div>
|
||||
|
||||
Please notice that this template makes use of a hugo specific template function
|
||||
called highlight which uses pygments to add the highlighting code.
|
||||
|
||||
More shortcode examples can be found at [spf13.com](https://github.com/spf13/spf13.com/tree/master/layouts/shortcodes)
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
date: 2013-07-09
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/urls
|
||||
prev: /extras/highlighting
|
||||
title: Table of Contents
|
||||
weight: 60
|
||||
---
|
||||
|
||||
Hugo will automatically parse the markdown for your content and create
|
||||
a Table of Contents you can use to guide readers to the sections within
|
||||
your content.
|
||||
|
||||
## Usage
|
||||
|
||||
Simply create content like you normally would with the appropriate
|
||||
headers.
|
||||
|
||||
Hugo will take this markdown and create a table of contents stored in the
|
||||
[content variable](/layout/variables) .TableOfContents
|
||||
|
||||
|
||||
## Template Example
|
||||
|
||||
This is example code of a [single.html template](/layout/content).
|
||||
|
||||
{{ template "partials/header.html" . }}
|
||||
<div id="toc" class="well col-md-4 col-sm-6">
|
||||
{{ .TableOfContents }}
|
||||
</div>
|
||||
<h1>{{ .Title }}</h1>
|
||||
{{ .Content }}
|
||||
{{ template "partials/footer.html" . }}
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/urls/
|
||||
date: 2014-01-03
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /community/mailing-list
|
||||
notoc: true
|
||||
prev: /extras/toc
|
||||
title: URLs
|
||||
weight: 70
|
||||
---
|
||||
|
||||
## Pretty Urls
|
||||
|
||||
By default Hugo will create content with 'pretty' urls. For example
|
||||
content created at /content/extras/urls.md will be rendered at
|
||||
/content/extras/urls/index.html and accessible at /content/extras/urls. No
|
||||
no standard server side configuration is required for these pretty urls to
|
||||
work.
|
||||
|
||||
If you would like to have uglyurls you are in luck. Hugo supports the
|
||||
ability to create your entire site with ugly urls. Simply use the
|
||||
`--uglyurls=true` flag on the command line.
|
||||
|
||||
If you want a specific piece of content to have an exact url you can
|
||||
specify this in the front matter under the url key. See [Content
|
||||
Organization](/content/organization/) for more details.
|
||||
|
||||
## Canonicalization
|
||||
|
||||
By default, all relative URLs encountered in the input will be canonicalized
|
||||
using `baseurl`, so that a link `/css/foo.css` becomes
|
||||
`http://yoursite.example.com/css/foo.css`.
|
||||
|
||||
Setting `canonifyurls` to `false` will prevent this canonicalization.
|
||||
|
||||
Benefits of canonicalization include fixing all URLs to be absolute, which may
|
||||
aid with some parsing tasks. Note though that all real browsers handle this
|
||||
client-side without issues.
|
||||
|
||||
Benefits of non-canonicalization include being able to have resource inclusion
|
||||
be scheme-relative, so that http vs https can be decided based on how this
|
||||
page was retrieved.
|
||||
@@ -1,16 +1,21 @@
|
||||
{
|
||||
"title": "License",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
---
|
||||
aliases:
|
||||
- /doc/license/
|
||||
- /license/
|
||||
- /meta/license/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: about
|
||||
title: License
|
||||
weight: 50
|
||||
---
|
||||
|
||||
Hugo is released under the Simple Public License.
|
||||
|
||||
## Simple Public License (SimPL-2.0)
|
||||
|
||||
Simple Public License (SimPL-2.0)
|
||||
=================================
|
||||
|
||||
Preamble
|
||||
--------
|
||||
### Preamble
|
||||
|
||||
This Simple Public License 2.0 (SimPL-2.0 for short) is a plain language
|
||||
implementation of GPL 2.0. The words are different, but the goal is the
|
||||
@@ -19,8 +24,7 @@ software. If anyone wonders about the meaning of the SimPL, they should
|
||||
interpret it as consistent with GPL 2.0.
|
||||
|
||||
|
||||
Simple Public License (SimPL) 2.0
|
||||
=================================
|
||||
## Simple Public License (SimPL) 2.0
|
||||
|
||||
The SimPL applies to the software's source and object code and comes
|
||||
with any rights that I have in it (other than trademarks). You agree to
|
||||
@@ -65,8 +69,7 @@ automatically if:
|
||||
- Anyone prevents you from distributing the software under the terms
|
||||
of the SimPL.
|
||||
|
||||
License for the License
|
||||
-----------------------
|
||||
## License for the License
|
||||
|
||||
You may do anything that you want with the SimPL text; it's a license
|
||||
form to use in any way that you find helpful. To avoid confusion,
|
||||
@@ -0,0 +1,102 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/release-notes/
|
||||
- /meta/release-notes/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: about
|
||||
title: Release Notes
|
||||
weight: 10
|
||||
---
|
||||
|
||||
## **0.11.0** May 28, 2014
|
||||
* Considerably faster... about 3 - 4x faster on average
|
||||
* [Live Reload](/extras/livereload). Hugo will automatically reload the browser when the build is complete
|
||||
* Theme engine w/[Theme Repository](http://github.com/spf13/hugoThemes)
|
||||
* [Menu system](/extras/menus) with support for active page
|
||||
* [Builders](/extras/builders) to quickly create a new site, content or theme
|
||||
* [XML sitemap](/templates/sitemap) generation
|
||||
* [Integrated Disqus](/extras/comments) support
|
||||
* Streamlined [template organization](/templates/overview)
|
||||
* [Brand new docs site](http://hugo.spf13.com)
|
||||
* Support for publishDate which allows for posts to be dated in the future
|
||||
* More [sort](/content/ordering) options
|
||||
* Logging support
|
||||
* Much better error handling
|
||||
* More informative verbose output
|
||||
* Renamed Indexes > [Taxonomies](/taxonomies/overview)
|
||||
* Renamed Chrome > [Partials](/templates/partials)
|
||||
|
||||
## **0.10.0** March 1, 2014
|
||||
* [Syntax highlighting](/extras/highlighting) powered by pygments (**slow**)
|
||||
* Ability to [sort content](/content/ordering) many more ways
|
||||
* Automatic [table of contents](/extras/toc) generation
|
||||
* Support for unicode urls, aliases and indexes
|
||||
* Configurable per-section [permalink](/extras/permalinks) pattern support
|
||||
* Support for [paired shortcodes](/extras/shortcodes)
|
||||
* Shipping with some [shortcodes](/extras/shortcodes) (highlight & figure)
|
||||
* Adding [canonify](/extras/urls) option to keep urls relative
|
||||
* A bunch of [additional template functions](/layout/functions)
|
||||
* Watching very large sites now works on mac
|
||||
* RSS generation improved. Limited to 50 items by default, can limit further in [template](/layout/rss)
|
||||
* Boolean params now supported in [frontmatter](/content/front-matter)
|
||||
* Launched website [showcase](/showcase). Show off your own hugo site!
|
||||
* A bunch of [bug fixes](https://github.com/spf13/hugo/commits/master)
|
||||
|
||||
## **0.9.0** November 15, 2013
|
||||
* New [command based interface](/overview/usage) similar to git (hugo server -s ./ )
|
||||
* Amber template support
|
||||
* [Aliases](/extras/aliases) (redirects)
|
||||
* Support for top level pages (in addition to homepage)
|
||||
* Complete overhaul of the documentation site
|
||||
* Full Windows support
|
||||
* Better index support including [ordering by content weight](/content/ordering)
|
||||
* Add params to site config, available in .Site.Params from templates
|
||||
* Friendlier json support
|
||||
* Support for html & xml content (with frontmatter support)
|
||||
* Support for [summary](/content/summaries) content divider (<!–more–>)
|
||||
* HTML in [summary](/content/summaries) (when using divider)
|
||||
* Added ["Minutes to Read"](/layout/variables) functionality
|
||||
* Support for a custom 404 page
|
||||
* Cleanup of how content organization is handled
|
||||
* Loads of unit and performance tests
|
||||
* Integration with travis ci
|
||||
* Static directory now watched and copied on any addition or modification
|
||||
* Support for relative permalinks
|
||||
* Fixed watching being triggered multiple times for the same event
|
||||
* Watch now ignores temp files (as created by Vim)
|
||||
* Configurable number of posts on [homepage](/layout/homepage/)
|
||||
* [Front matter](/content/front-matter) supports multiple types (int, string, date, float)
|
||||
* Indexes can now use a default template
|
||||
* Addition of truncated bool to content to determine if should show 'more' link
|
||||
* Support for [linkTitles](/layout/variables)
|
||||
* Better handling of most errors with directions on how to resolve
|
||||
* Support for more date / time formats
|
||||
* Support for go 1.2
|
||||
* Support for `first` in templates
|
||||
|
||||
## **0.8.0** August 2, 2013
|
||||
* Added support for pretty urls (filename/index.html vs filename.html)
|
||||
* Hugo supports a destination directory
|
||||
* Will efficiently sync content in static to destination directory
|
||||
* Cleaned up options.. now with support for short and long options
|
||||
* Added support for TOML
|
||||
* Added support for YAML
|
||||
* Added support for Previous & Next
|
||||
* Added support for indexes for the indexes
|
||||
* Better Windows compatibility
|
||||
* Support for series
|
||||
* Adding verbose output
|
||||
* Loads of bugfixes
|
||||
|
||||
## **0.7.0** July 4, 2013
|
||||
* Hugo now includes a simple server
|
||||
* First public release
|
||||
|
||||
## **0.6.0** July 2, 2013
|
||||
* Hugo includes an example documentation site which it builds
|
||||
|
||||
## **0.5.0** June 25, 2013
|
||||
* Hugo is quite usable and able to build spf13.com
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/roadmap/
|
||||
- /meta/roadmap/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: about
|
||||
notoc: true
|
||||
title: Hugo Roadmap
|
||||
weight: 20
|
||||
---
|
||||
|
||||
In no particular order, here is what we are working on:
|
||||
|
||||
* Intelligently Related Posts
|
||||
* Even easier deployment to S3, SSH, Github, rsync
|
||||
* Import from other website systems (wordpress, jekyll)
|
||||
* An interactive web based editor
|
||||
* Additional Themes
|
||||
* Dynamic image resizing via shortcodes
|
||||
* Support for additional formats
|
||||
* Pagination
|
||||
* Your best ideas
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/configuration/
|
||||
date: 2013-07-01
|
||||
linktitle: Configuration
|
||||
menu:
|
||||
main:
|
||||
parent: getting started
|
||||
next: /overview/source-directory
|
||||
notoc: true
|
||||
prev: /overview/usage
|
||||
title: Configuring Hugo
|
||||
weight: 40
|
||||
---
|
||||
|
||||
The directory structure and templates provide the majority of the
|
||||
configuration for a site. In fact a config file isn't even needed for many
|
||||
websites since the defaults follow commonly used patterns.
|
||||
|
||||
Hugo expects to find the config file in the root of the source directory and
|
||||
will look there first for a `config.toml` file. If none is present it will
|
||||
then look for a `config.yaml` file, followed by a `config.json` file.
|
||||
|
||||
The config file is a site-wide config. The config file provides directions to
|
||||
hugo on how to build the site as well as site-wide parameters and menus.
|
||||
|
||||
## Examples
|
||||
|
||||
The following is an example of a typical yaml config file:
|
||||
|
||||
---
|
||||
baseurl: "http://yoursite.example.com/"
|
||||
...
|
||||
|
||||
The following is an example of a toml config file with some of the default values:
|
||||
|
||||
contentdir = "content"
|
||||
layoutdir = "layouts"
|
||||
publishdir = "public"
|
||||
builddrafts = false
|
||||
baseurl = "http://yoursite.example.com/"
|
||||
canonifyurls = true
|
||||
[indexes]
|
||||
category = "categories"
|
||||
tag = "tags"
|
||||
|
||||
Here is a yaml configuration file which sets a few more options
|
||||
|
||||
---
|
||||
baseurl: "http://yoursite.example.com/"
|
||||
title: "Yoyodyne Widget Blogging"
|
||||
permalinks:
|
||||
post: /:year/:month/:title/
|
||||
params:
|
||||
Subtitle: "Spinning the cogs in the widgets"
|
||||
AuthorName: "John Doe"
|
||||
GitHubUser: "spf13"
|
||||
ListOfFoo:
|
||||
- "foo1"
|
||||
- "foo2"
|
||||
SidebarRecentLimit: 5
|
||||
...
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/installing/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: getting started
|
||||
next: /overview/usage
|
||||
prev: /overview/quickstart
|
||||
title: Installing Hugo
|
||||
weight: 20
|
||||
---
|
||||
|
||||
Hugo is written in Go with support for Windows, Linux, FreeBSD and OSX.
|
||||
|
||||
The latest release can be found at [hugo releases](https://github.com/spf13/hugo/releases).
|
||||
We currently build for Windows, Linux, FreeBSD and OS X for x64
|
||||
and 386 architectures.
|
||||
|
||||
## Installing Hugo (binary)
|
||||
|
||||
Installation is very easy. Simply download the appropriate version for your
|
||||
platform from [hugo releases](https://github.com/spf13/hugo/releases).
|
||||
Once downloaded it can be run from anywhere. You don't need to install
|
||||
it into a global location. This works well for shared hosts and other systems
|
||||
where you don't have a privileged account.
|
||||
|
||||
Ideally you should install it somewhere in your path for easy use. `/usr/local/bin`
|
||||
is the most probable location.
|
||||
|
||||
### Installing pygments (optional)
|
||||
|
||||
The Hugo executable has one *optional* external dependency for source code highlighting (pygments).
|
||||
|
||||
If you want to have source code highlighting using the [highlight shortcode](/extras/highlighting)
|
||||
you need to install the python-based pygments program. The procedure is outlined on the [pygments home page](http://pygments.org).
|
||||
|
||||
## Upgrading Hugo
|
||||
|
||||
Upgrading hugo is as easy as downloading and replacing the executable you’ve
|
||||
placed in your path.
|
||||
|
||||
|
||||
## Installing from source
|
||||
|
||||
### Dependencies
|
||||
|
||||
* Git
|
||||
* Go 1.1+
|
||||
* Mercurial
|
||||
* Bazaar
|
||||
|
||||
### Get directly from Github:
|
||||
|
||||
go get github.com/spf13/hugo
|
||||
|
||||
### Building Hugo
|
||||
|
||||
cd /path/to/hugo
|
||||
go build -o hugo main.go
|
||||
mv hugo /usr/local/bin/
|
||||
|
||||
## Contributing
|
||||
|
||||
Please see the [contributing guide](/doc/contributing)
|
||||
@@ -0,0 +1,125 @@
|
||||
---
|
||||
date: 2013-07-01
|
||||
linktitle: Introduction
|
||||
menu:
|
||||
main:
|
||||
parent: getting started
|
||||
next: /overview/quickstart
|
||||
title: Introduction to Hugo
|
||||
weight: 5
|
||||
---
|
||||
|
||||
## What is Hugo?
|
||||
|
||||
Hugo is a general purpose website framework. Technically speaking, Hugo is
|
||||
a static site generator. This means that unlike systems like Wordpress,
|
||||
Ghost & Drupal which run on your web server expensively building a page
|
||||
every time a visitor requests one, Hugo does the building when you create
|
||||
your content. Since websites are viewed far more often then they are
|
||||
edited, Hugo is optimized for website viewing while providing a great
|
||||
writing experience.
|
||||
|
||||
Sites built with hugo are extremely fast and very secure. Hugo sites can
|
||||
be hosted anywhere including Heroku, GoDaddy, GitHub pages, S3
|
||||
& Cloudfront and work well with CDNs. Hugo sites run without dependencies
|
||||
on expensive run times like Ruby, Python or PHP and without dependencies
|
||||
on any databases.
|
||||
|
||||
We think of Hugo as the ideal website creation tool. With nearly instant
|
||||
built times and the ability to rebuild whenever a change is made Hugo
|
||||
provides a very fast feedback loop. This is essential when you are
|
||||
designing websites, but also very useful when creating content.
|
||||
|
||||
## What does Hugo do?
|
||||
|
||||
In technical terms Hugo takes a source directory of markdown files and
|
||||
templates and uses these as input to create a complete website.
|
||||
|
||||
Hugo boasts the following features:
|
||||
|
||||
### General
|
||||
|
||||
* Extremely fast built times (~1ms per page)
|
||||
* Completely cross platform: Runs on Mac OSX, Linux and Windows
|
||||
* Easy [installation](/overview/installing)
|
||||
* Render changes [on the fly](/overview/usage) with [live reload](#) as you develop
|
||||
* Complete theme support
|
||||
* Host your site anywhere
|
||||
|
||||
### Organization
|
||||
|
||||
* Straightforward [organization](/content/organization)
|
||||
* Support for [website sections](/content/sections)
|
||||
* Completely customizable [urls](/extras/urls)
|
||||
* Support for [categories](/indexes/category) and tags
|
||||
* Support for configurable [taxonomies](/indexes/overview) to create your own organization
|
||||
* Ability to [sort content](/content/ordering) as you desire
|
||||
* Automatic [table of contents](/extras/toc) generation
|
||||
* Dynamic menu creation
|
||||
* [pretty urls](/extras/urls) support
|
||||
* [permalink](/extras/permalinks) pattern support
|
||||
* [Aliases](/extras/aliases) (redirects)
|
||||
|
||||
### Content
|
||||
|
||||
* Content written in [Markdown](/content/example)
|
||||
* Support for TOML, YAML and JSON metadata in [frontmatter](/content/front-matter)
|
||||
* Completely [customizable homepage](/layout/homepage)
|
||||
* Support for multiple [content types](/content/types)
|
||||
* Automatic and user defined [summaries](/content/summaries)
|
||||
* [shortcodes](/extras/shortcodes) to enable rich content inside of markdown
|
||||
* ["Minutes to Read"](/layout/variables) functionality
|
||||
* ["Wordcount"](/layout/variables) functionality
|
||||
|
||||
### Additional Features
|
||||
|
||||
* Integrated Disqus comment support
|
||||
* Automatic [RSS](/layout/rss) creation
|
||||
* Support for go and amber templates
|
||||
* Syntax [highlighting](/extras/highlighting) powered by pygments
|
||||
|
||||
See what's coming next in the [roadmap](/meta/roadmap)
|
||||
|
||||
## Who should use Hugo?
|
||||
|
||||
Hugo is for people that prefer writing in a text editor over
|
||||
a browser.
|
||||
|
||||
Hugo is for people who want to hand code their own website without
|
||||
worrying about setting up complicated runtimes, dependencies and
|
||||
databases.
|
||||
|
||||
Hugo is for people building a blog, company site, portfolio, tumblog,
|
||||
documentation, single page site or a site with thousands of
|
||||
pages.
|
||||
|
||||
## Why did you write Hugo?
|
||||
|
||||
I wrote Hugo ultimately for a few reasons. First I was disappointed with
|
||||
wordpress, my then website solution. It rendered slowly. I couldn't create
|
||||
content as efficiently as I wanted to and needed to be online to write
|
||||
posts. The constant security updates and the horror stories of people's
|
||||
hacked blogs. I hated how content was written in HTML instead of the much
|
||||
simpler markdown. Overall I felt like it got in my way more than it helped
|
||||
my from writing great content.
|
||||
|
||||
I looked at existing static site generators like Jekyll, Middle and Nanoc.
|
||||
All had complicated dependencies to install and took far longer to render
|
||||
my blog with hundreds of posts than I felt was acceptable. I wanted
|
||||
a framework to be able to get rapid feedback while making changes to the
|
||||
templates and the 5+ minute render times was just too slow. In general
|
||||
they were also very blog minded and didn't have the ability to have
|
||||
different content types and flexible urls.
|
||||
|
||||
I wanted to develop a fast and full featured website framework without
|
||||
dependencies. The Go language seemed to have all of the features I needed
|
||||
in a language. I began developing Hugo in Go and fell in love with the
|
||||
language. I hope you will enjoy using (and contributing to) Hugo as much
|
||||
as I have writing it.
|
||||
|
||||
## Next Steps
|
||||
|
||||
* [Install Hugo](/overview/installing)
|
||||
* [Quick start](/overview/quickstart)
|
||||
* [Join the Mailing List](/community/mailing-list)
|
||||
* [Star us on Github](http://github.com/spf13/hugo)
|
||||
@@ -0,0 +1,159 @@
|
||||
---
|
||||
date: 2013-07-01
|
||||
linktitle: Quickstart
|
||||
menu:
|
||||
main:
|
||||
parent: getting started
|
||||
next: /overview/installing
|
||||
prev: /overview/introduction
|
||||
title: Hugo Quickstart Guide
|
||||
weight: 10
|
||||
---
|
||||
|
||||
_This quickstart depends on features introduced in hugo v0.11. If you
|
||||
have an earlier version of hugo you will need to [upgrade](/overview/installing/) before
|
||||
proceeding._
|
||||
|
||||
## Step 1. Install Hugo
|
||||
|
||||
Goto [hugo releases](https://github.com/spf13/hugo/releases) and download the
|
||||
appropriate version for your os and architecture.
|
||||
|
||||
Save it somewhere specific as we will be using it in the next step.
|
||||
|
||||
More complete instructions are available at [installing hugo](/overview/installing/)
|
||||
|
||||
## Step 2. Have Hugo Create a site for you
|
||||
|
||||
Hugo has the ability to create a skeleton site.
|
||||
|
||||
hugo new site /path/to/site
|
||||
|
||||
For the rest of the operations we will be executing all commands from within the site directory
|
||||
|
||||
cd /path/to/site
|
||||
|
||||
The new site will have the following structure
|
||||
|
||||
▸ archetypes/
|
||||
▸ content/
|
||||
▸ layouts/
|
||||
▸ static/
|
||||
config.toml
|
||||
|
||||
Currently the site doesn’t have any content, nor is it configured.
|
||||
|
||||
## Step 3. Create Some Content
|
||||
|
||||
Hugo also has the ability to create content for you.
|
||||
|
||||
hugo new about.md
|
||||
|
||||
A new file is now created in `content/` with the following contents
|
||||
|
||||
+++
|
||||
draft = true
|
||||
title = "about"
|
||||
date = 2014-05-20T10:04:31Z
|
||||
+++
|
||||
|
||||
Notice the date is automatically set to the moment you created the content.
|
||||
|
||||
Place some content in this file below the `+++` in the markdown format.
|
||||
|
||||
For example you could put this
|
||||
|
||||
## A headline
|
||||
|
||||
Some Content
|
||||
|
||||
For fun, let’s create another piece of content and place some markdown in it as well.
|
||||
|
||||
hugo new post/first.md
|
||||
|
||||
The new file is located at `content/post/first.md`
|
||||
|
||||
We still lack any templates to tell us how to display the content.
|
||||
|
||||
## Step 4. Install some themes
|
||||
|
||||
Hugo has rich theme support and a growing set of themes to choose from.
|
||||
|
||||
git clone --recursive https://github.com/spf13/hugoThemes themes
|
||||
|
||||
|
||||
## Step 5. Run Hugo
|
||||
|
||||
Hugo contains it’s own high performance web server. Simply run `hugo
|
||||
server` and Hugo will find an available port and run a server with
|
||||
your content
|
||||
|
||||
hugo server --theme=hyde --buildDrafts
|
||||
2 pages created
|
||||
0 tags created
|
||||
0 categories created
|
||||
in 5 ms
|
||||
Serving pages from exampleHugoSite/public
|
||||
Web Server is available at http://localhost:1313
|
||||
Press ctrl+c to stop
|
||||
|
||||
We specified two options here.
|
||||
* --theme to pick which theme.
|
||||
* --buildDrafts because we want to display our content, both set to draft status
|
||||
|
||||
To learn about what other options hugo has run
|
||||
|
||||
hugo help
|
||||
|
||||
To learn about the server options
|
||||
|
||||
hugo help server
|
||||
|
||||
## Step 6. Edit Content
|
||||
|
||||
Not only can Hugo run a server, but it can also watch your files for
|
||||
changes and automatically rebuild your site. Hugo will then
|
||||
communicate with your browser and automatically reload any open page.
|
||||
This even works in mobile browsers.
|
||||
|
||||
Stop the Hugo process by hitting ctrl+c. Then run the following:
|
||||
|
||||
hugo server --theme=hyde --buildDrafts --watch
|
||||
2 pages created
|
||||
0 tags created
|
||||
0 categories created
|
||||
in 5 ms
|
||||
Watching for changes in exampleHugoSite/content
|
||||
Serving pages from exampleHugoSite/public
|
||||
Web Server is available at http://localhost:1313
|
||||
Press ctrl+c to stop
|
||||
Open your [favorite editor](http://vim.spf13.com), edit and save your content and watch as Hugo rebuilds and reloads automatically.
|
||||
|
||||
It’s especially productive to leave a browser open on a second monitor
|
||||
and just glance at it whenever you save. You don’t even need to tab to
|
||||
your browser. Hugo is so fast, that the new site will be there before
|
||||
you can look at the browser in most cases.
|
||||
|
||||
|
||||
Change and save this file.. Notice what happened in your terminal.
|
||||
|
||||
Change detected, rebuilding site
|
||||
|
||||
2 pages created
|
||||
0 tags created
|
||||
0 categories created
|
||||
in 5 ms
|
||||
|
||||
## Step 7. Have fun
|
||||
|
||||
The best way to learn something is to play with it.
|
||||
|
||||
Things to try:
|
||||
|
||||
* Add a [new content file](/content/organization/)
|
||||
* Create a [new section](/content/sections/)
|
||||
* Modify [a template](/layout/templates/)
|
||||
* Create content with [toml front matter](/content/front-matter/)
|
||||
* Define your own field in [front matter](/content/front-matter/)
|
||||
* Display that [field in the template](/layout/variables/)
|
||||
* Create a [new content type](/content/types/)
|
||||
@@ -1,18 +1,48 @@
|
||||
{
|
||||
"title": "Source Directory Organization",
|
||||
"Pubdate": "2013-07-01"
|
||||
}
|
||||
---
|
||||
aliases:
|
||||
- /doc/source-directory/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: getting started
|
||||
next: /content/organization
|
||||
notoc: true
|
||||
prev: /overview/configuration
|
||||
title: Source Organization
|
||||
weight: 50
|
||||
---
|
||||
|
||||
Hugo takes a single directory and uses it as the input for creating a complete website.
|
||||
Hugo takes a single directory and uses it as the input for creating a complete
|
||||
website.
|
||||
|
||||
Hugo has a very small amount of configuration, while remaining highly customizable.
|
||||
It accomplishes by assuming that you will only provide templates with the intent of
|
||||
using them.
|
||||
|
||||
The top level of a source directory will typically have the following elements:
|
||||
|
||||
▸ archetypes/
|
||||
▸ content/
|
||||
▸ layouts/
|
||||
▸ static/
|
||||
▸ themes/
|
||||
config.toml
|
||||
|
||||
Learn more about the different directories and what their purpose is
|
||||
|
||||
* [config](/overview/configuration)
|
||||
* [archetypes](/content/archetypes)
|
||||
* [content](/content/organization)
|
||||
* [layouts](/layout/overview)
|
||||
* [static]()
|
||||
* [themes](/themes/overview)
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
An example directory may look like:
|
||||
|
||||
.
|
||||
├── config.json
|
||||
├── config.toml
|
||||
├── archetypes
|
||||
| └── default.md
|
||||
├── content
|
||||
| ├── post
|
||||
| | ├── firstpost.md
|
||||
@@ -21,10 +51,13 @@ An example directory may look like:
|
||||
| | ├── first.md
|
||||
| | └── second.md
|
||||
├── layouts
|
||||
| ├── chrome
|
||||
| ├── _default
|
||||
| | ├── single.html
|
||||
| | └── list.html
|
||||
| ├── partials
|
||||
| | ├── header.html
|
||||
| | └── footer.html
|
||||
| ├── indexes
|
||||
| ├── taxonomies
|
||||
| | ├── category.html
|
||||
| | ├── post.html
|
||||
| | ├── quote.html
|
||||
@@ -42,13 +75,16 @@ An example directory may look like:
|
||||
| | ├── vimeo.html
|
||||
| | └── youtube.html
|
||||
| ├── index.html
|
||||
| └── rss.xml
|
||||
└── public
|
||||
| └── sitemap.xml
|
||||
├── themes
|
||||
| ├── hyde
|
||||
| └── doc
|
||||
└── static
|
||||
├── css
|
||||
└── js
|
||||
|
||||
This directory structure tells us a lot about this site:
|
||||
|
||||
1. the website intends to have two different types of content, posts and quotes.
|
||||
2. It will also apply two different indexes to that content, categories and tags.
|
||||
3. It will be displaying content in 3 different views, a list, a summary and a full page view.
|
||||
|
||||
Included with the repository is this example site ready to be rendered.
|
||||
@@ -0,0 +1,89 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/usage/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: getting started
|
||||
next: /overview/configuration
|
||||
notoc: true
|
||||
prev: /overview/installing
|
||||
title: Using Hugo
|
||||
weight: 30
|
||||
---
|
||||
|
||||
Make sure either hugo is in your path or provide a path to it.
|
||||
|
||||
|
||||
|
||||
$ hugo help
|
||||
A Fast and Flexible Static Site Generator
|
||||
built with love by spf13 and friends in Go.
|
||||
|
||||
Complete documentation is available at http://hugo.spf13.com
|
||||
|
||||
Usage:
|
||||
hugo [flags]
|
||||
hugo [command]
|
||||
|
||||
Available Commands:
|
||||
server :: Hugo runs it's own a webserver to render the files
|
||||
version :: Print the version number of Hugo
|
||||
check :: Check content in the source directory
|
||||
benchmark :: Benchmark hugo by building a site a number of times
|
||||
new [path] :: Create new content for your site
|
||||
help [command] :: Help about any command
|
||||
|
||||
Available Flags:
|
||||
-b, --baseUrl="": hostname (and path) to the root eg. http://spf13.com/
|
||||
-D, --buildDrafts=false: build content marked as draft
|
||||
-F, --buildFuture=false: build content with PublishDate in the future
|
||||
--config="": config file (default is path/config.yaml|json|toml)
|
||||
-d, --destination="": filesystem path to write files to
|
||||
--disableRSS=false: Do not build RSS files
|
||||
--disableSitemap=false: Do not build Sitemap file
|
||||
--log=false: Enable Logging
|
||||
--logFile="": Log File path (if set, logging enabled automatically)
|
||||
-s, --source="": filesystem path to read files relative from
|
||||
--stepAnalysis=false: display memory and timing of different steps of the program
|
||||
-t, --theme="": theme to use (located in /themes/THEMENAME/)
|
||||
--uglyUrls=false: if true, use /filename.html instead of /filename/
|
||||
-v, --verbose=false: verbose output
|
||||
--verboseLog=false: verbose logging
|
||||
-w, --watch=false: watch filesystem for changes and recreate as needed
|
||||
|
||||
Use "hugo help [command]" for more information about that command.
|
||||
|
||||
## Common Usage Example:
|
||||
|
||||
The most common use is probably to run hugo with your current
|
||||
directory being the input directory.
|
||||
|
||||
$ hugo
|
||||
> X pages created
|
||||
in 8 ms
|
||||
|
||||
If you are working on things and want to see the changes
|
||||
immediately, tell Hugo to watch for changes.
|
||||
|
||||
Hugo will watch the filesystem for changes, rebuild your site as soon as a file
|
||||
is saved.
|
||||
|
||||
$ hugo -s ~/mysite --watch
|
||||
28 pages created
|
||||
in 18 ms
|
||||
Watching for changes in /Users/spf13/Code/hugo/docs/content
|
||||
Press ctrl+c to stop
|
||||
|
||||
Hugo can even run a server and create your site at the same time! Hugo
|
||||
implements [live reload](/extras/livereload) technology to automatically reload any open pages in
|
||||
all browsers (including mobile).
|
||||
|
||||
$ hugo server -ws ~/mysite
|
||||
Watching for changes in /Users/spf13/Code/hugo/docs/content
|
||||
Web Server is available at http://localhost:1313
|
||||
Press ctrl+c to stop
|
||||
28 pages created
|
||||
0 tags created
|
||||
in 18 ms
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
date: 2014-02-03T20:00:00Z
|
||||
description: Ant Zucaro's Blog
|
||||
license: GPL
|
||||
licenseLink: ""
|
||||
sitelink: http://antzucaro.com
|
||||
sourceLink: http://github.com/antzucaro/az.com
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
- foundation
|
||||
thumbnail: /static/img/antzucaro-tn.jpg
|
||||
title: Ant Zucaro
|
||||
---
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
date: 2014-01-22T07:32:00Z
|
||||
description: ""
|
||||
license: CC-BY-SA
|
||||
licenseLink: ""
|
||||
sitelink: http://andrewcodispoti.com
|
||||
sourceLink: https://gitlab.com/acodispo/andrewcodispoti-com
|
||||
tags:
|
||||
- personal
|
||||
- bootstrap
|
||||
thumbnail: /static/img/asc-tn.jpg
|
||||
title: Andrew S Codispoti
|
||||
---
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
date: 2013-10-02T07:32:00Z
|
||||
description: ""
|
||||
license: CC-SA
|
||||
licenseLink: ""
|
||||
sitelink: http://chimeraarts.org
|
||||
sourceLink: https://github.com/chimera/chimeraarts.org
|
||||
tags:
|
||||
- company
|
||||
- bootstrap
|
||||
thumbnail: /static/img/chimera-tn.jpg
|
||||
title: Chimera Art Space
|
||||
---
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
date: 2014-03-27T09:45:00Z
|
||||
description: CloudShark Appliance homepage and documentation
|
||||
license: ""
|
||||
licenseLink: ""
|
||||
sitelink: https://appliance.cloudshark.org
|
||||
tags:
|
||||
- company
|
||||
- documentation
|
||||
- foundation
|
||||
thumbnail: /static/img/cloudshark-tn.jpg
|
||||
title: CloudShark
|
||||
---
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
date: 2014-03-09T06:00:00Z
|
||||
description: ""
|
||||
license: MIT
|
||||
licenseLink: ""
|
||||
sitelink: http://heyitsalex.net
|
||||
sourceLink: https://github.com/alexandre-normand/alexandre-normand
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
thumbnail: /static/img/heyitsalex-tn.jpg
|
||||
title: Hey, it's Alex
|
||||
---
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
date: 2013-07-01T07:32:00Z
|
||||
description: This site
|
||||
license: Simpl
|
||||
licenseLink: ""
|
||||
sitelink: http://hugo.spf13.com
|
||||
sourceLink: http://github.com/spf13/hugo/docs
|
||||
tags:
|
||||
- documentation
|
||||
- bootstrap
|
||||
thumbnail: /static/img/hugo-tn.jpg
|
||||
title: Hugo
|
||||
---
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
date: 2013-11-02T07:32:00Z
|
||||
description: ""
|
||||
license: MIT
|
||||
licenseLink: ""
|
||||
sitelink: http://ifup.org
|
||||
sourceLink: http://www.ifup.org
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
thumbnail: /static/img/ifup-tn.jpg
|
||||
title: ifup
|
||||
---
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
date: 2014-02-27T20:35:00Z
|
||||
description: Kieran Healy's Website
|
||||
license: ""
|
||||
licenseLink: ""
|
||||
sitelink: http://kieranhealy.org
|
||||
sourceLink: http://github.com/kjhealy/kieranhealy.hugo
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
- academic
|
||||
thumbnail: /static/img/kjhealy-tn.jpg
|
||||
title: Kieran Healy
|
||||
---
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
date: 2013-07-01T07:32:00Z
|
||||
description: The first Hugo powered website.
|
||||
license: MIT
|
||||
licenseLink: ""
|
||||
sitelink: http://spf13.com
|
||||
sourceLink: http://github.com/spf13/spf13.com
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
thumbnail: /static/img/spf13-tn.jpg
|
||||
title: spf13.com
|
||||
---
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
date: 2014-05-22T19:54:00Z
|
||||
description: Tech Coaching site
|
||||
license: ""
|
||||
licenseLink: ""
|
||||
sitelink: http://techmadeplain.com
|
||||
tags:
|
||||
- personal
|
||||
- blog
|
||||
thumbnail: /static/img/techmadeplain-tn.jpg
|
||||
title: Tech Made Plain
|
||||
---
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
date: 2014-04-07T10:45:00Z
|
||||
description: Community project of YSlow rules translations
|
||||
license: MIT License
|
||||
licenseLink: https://raw.github.com/checkmyws/yslow-rules/master/LICENSE
|
||||
sitelink: http://checkmyws.github.io/yslow-rules/
|
||||
sourceLink: https://github.com/checkmyws/yslow-rules
|
||||
tags:
|
||||
- community
|
||||
- documentation
|
||||
- translation
|
||||
thumbnail: /static/img/yslow-rules.jpg
|
||||
title: YSlow Rules
|
||||
---
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
---
|
||||
aliases:
|
||||
- /indexes/displaying/
|
||||
date: 2013-07-01
|
||||
linktitle: Displaying
|
||||
menu:
|
||||
main:
|
||||
parent: taxonomy
|
||||
next: /taxonomies/templates
|
||||
prev: /taxonomies/usage
|
||||
title: Displaying Taxonomies
|
||||
weight: 20
|
||||
---
|
||||
|
||||
There are four common ways you can display the data in your
|
||||
taxonomies in addition to the automatic taxonomy pages created by hugo
|
||||
using the [list templates](/templates/list).
|
||||
|
||||
1. For a given piece of content you can list the terms attached
|
||||
2. For a given piece of content you can list other content with the same
|
||||
term
|
||||
3. You can list all terms for a taxonomy
|
||||
4. You can list all taxonomies (with their terms)
|
||||
|
||||
## 1. Displaying taxonomy terms assigned to this content
|
||||
|
||||
Within your content templates you may wish to display
|
||||
the taxonomies that that piece of content is assigned to.
|
||||
|
||||
Because we are leveraging the front matter system to
|
||||
define taxonomies for content, the taxonomies assigned to
|
||||
each content piece are located in the usual place
|
||||
(.Params.`plural`)
|
||||
|
||||
### Example
|
||||
|
||||
<ul id="tags">
|
||||
{{ range .Params.tags }}
|
||||
<li><a href="tags/{{ . | urlize }}">{{ . }}</a> </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
|
||||
## 2. Listing content with the same taxonomy term
|
||||
|
||||
First you may be asking why you would use this. If you are using a
|
||||
taxonomy for something like a series of posts, this is exactly how you
|
||||
would do it. It’s also an quick and dirty way to show some related
|
||||
content.
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
<ul>
|
||||
{{ range .Site.Taxonomies.series.golang }}
|
||||
<li><a href="{{ .Url }}">{{ .Name }}</a></li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
|
||||
## 3. Listing all content in a given taxonomy
|
||||
|
||||
This would be very useful in a sidebar as “featured content”. You could
|
||||
even have different sections of “featured content” by assigning
|
||||
different terms to the content.
|
||||
|
||||
### Example
|
||||
|
||||
<section id="menu">
|
||||
<ul>
|
||||
{{ range $key, $taxonomy := .Site.Taxonomies.featured }}
|
||||
<li> {{ $key }} </li>
|
||||
<ul>
|
||||
{{ range $taxonomy.Pages }}
|
||||
<li hugo-nav="{{ .RelPermalink}}"><a href="{{ .Permalink}}"> {{ .LinkTitle }} </a> </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
||||
## 4. Rendering a Site's Taxonomies
|
||||
|
||||
If you wish to display the list of all keys for an taxonomy you can find retrieve
|
||||
them from the `.Site` variable which is available on every page.
|
||||
|
||||
This may take the form of a tag cloud, a menu or simply a list.
|
||||
|
||||
The following example displays all tag keys:
|
||||
|
||||
### Example
|
||||
|
||||
<ul id="all-tags">
|
||||
{{ range .Site.Taxonomies.tags }}
|
||||
<li><a href="/tags/{{ .Name | urlize }}">{{ .Name }}</a></li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
|
||||
### Complete Example
|
||||
This example will list all taxonomies, each of their keys and all the content assigned to each key.
|
||||
|
||||
<section>
|
||||
<ul>
|
||||
{{ range $taxonomyname, $taxonomy := .Site.Taxonomies }}
|
||||
<li><a href="/{{ $taxonomyname | urlize }}">{{ $taxonomyname }}</a>
|
||||
<ul>
|
||||
{{ range $key, $value := $taxonomy }}
|
||||
<li> {{ $key }} </li>
|
||||
<ul>
|
||||
{{ range $value.Pages }}
|
||||
<li hugo-nav="{{ .RelPermalink}}"><a href="{{ .Permalink}}"> {{ .LinkTitle }} </a> </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
aliases:
|
||||
- /indexes/ordering/
|
||||
date: 2013-07-01
|
||||
linktitle: Ordering
|
||||
menu:
|
||||
main:
|
||||
identifier: Ordering Taxonomies
|
||||
parent: taxonomy
|
||||
next: /extras/aliases
|
||||
prev: /taxonomies/templates
|
||||
title: Ordering Taxonomies
|
||||
weight: 60
|
||||
---
|
||||
|
||||
Hugo provides the ability to both:
|
||||
|
||||
1. Order the way the keys for an taxonomy are displayed
|
||||
2. Order the way taxonomyed content appears
|
||||
|
||||
|
||||
## Ordering Taxonomies
|
||||
Taxonomies can be ordered by either alphabetical key or by the number of content pieces assigned to that key.
|
||||
|
||||
### Order Alphabetically Example:
|
||||
|
||||
<ul>
|
||||
{{ $data := .Data }}
|
||||
{{ range $key, $value := .Data.Taxonomy.Alphabetical }}
|
||||
<li><a href="{{ $data.Plural }}/{{ $value.Name | urlize }}"> {{ $value.Name }} </a> {{ $value.Count }} </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
|
||||
### Order by Popularity Example:
|
||||
|
||||
<ul>
|
||||
{{ $data := .Data }}
|
||||
{{ range $key, $value := .Data.Taxonomy.ByCount }}
|
||||
<li><a href="{{ $data.Plural }}/{{ $value.Name | urlize }}"> {{ $value.Name }} </a> {{ $value.Count }} </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
|
||||
|
||||
[See Also Taxonomy Lists](/taxonomies/lists/)
|
||||
|
||||
## Ordering Content within Taxonomies
|
||||
|
||||
Hugo uses both **Date** and **Weight** to order content within taxonomies.
|
||||
|
||||
Each piece of content in Hugo can optionally be assigned a date.
|
||||
It can also be assigned a weight for each taxonomy it is assigned to.
|
||||
|
||||
When iterating over content within taxonomies the default sort is first by weight then by date. This means that if the weights for two pieces of content are the same, than the more recent content will be displayed first. The default weight for any piece of content is 0.
|
||||
|
||||
### Assigning Weight
|
||||
|
||||
Content can be assigned weight for each taxonomy that it's assigned to.
|
||||
|
||||
+++
|
||||
tags = [ "a", "b", "c" ]
|
||||
tags_weight = 22
|
||||
categories = ["d"]
|
||||
title = "foo"
|
||||
categories_weight = 44
|
||||
+++
|
||||
Front Matter with weighted tags and categories
|
||||
|
||||
|
||||
The convention is `taxonomyname_weight`.
|
||||
|
||||
In the above example, this piece of content has a weight of 22 which applies to the sorting when rendering the pages assigned to the "a", "b" and "c" values of the 'tag' taxonomy.
|
||||
|
||||
It has also been assigned the weight of 44 when rendering the 'd' category.
|
||||
|
||||
With this the same piece of content can appear in different positions in different taxonomies.
|
||||
|
||||
Currently taxonomies only support the default ordering of content which is weight -> date.
|
||||
@@ -0,0 +1,92 @@
|
||||
---
|
||||
aliases:
|
||||
- /indexes/overview/
|
||||
- /doc/indexes/
|
||||
- /extras/indexes
|
||||
date: 2013-07-01
|
||||
linktitle: Overview
|
||||
menu:
|
||||
main:
|
||||
identifier: taxonomy overview
|
||||
parent: taxonomy
|
||||
next: /taxonomies/usage
|
||||
prev: /templates/404
|
||||
title: Taxonomy Overview
|
||||
weight: 10
|
||||
---
|
||||
|
||||
Hugo includes support for user defined groupings of content called
|
||||
taxonomies. Taxonomies give us a way to classify our content so we can
|
||||
demonstrate relationships in a variety of logical ways.
|
||||
|
||||
The default taxonomies for Hugo are tags and categories. These
|
||||
taxonomies are common to many websites systems (Wordpress, Drupal,
|
||||
Jekyll). Unlike all of those Systems, Hugo makes it trivial to customize
|
||||
the taxonomies you will be using for your site however you wish. Another
|
||||
good use for taxonomies is to group a set of posts into a series. Other
|
||||
common uses would include categories, tags, groups, series and many
|
||||
more.
|
||||
|
||||
When taxonomies are used (and templates are provided) Hugo will
|
||||
automatically create pages listing all of the taxonomies, their terms
|
||||
and all of the content attached to those terms.
|
||||
|
||||
## Definitions
|
||||
|
||||
**Taxonomy:** A categorization that can be used to classify content
|
||||
|
||||
**Term:** A key within that taxonomy
|
||||
|
||||
**Value:** A piece of content assigned to that Term
|
||||
|
||||
## Example
|
||||
|
||||
For example if I was writing about movies I may want the following
|
||||
taxonomies:
|
||||
|
||||
* Actors
|
||||
* Directors
|
||||
* Studios
|
||||
* Genre
|
||||
* Year
|
||||
* Awards
|
||||
|
||||
I would then specify in each movies front-matter the specific terms for
|
||||
each of those taxonomies. Hugo would then automatically create pages for
|
||||
each Actor, Director, Studio, Genre, Year and Award listing all of the
|
||||
Movies that matched that specific Actor, Director, etc.
|
||||
|
||||
|
||||
### Taxonomy Organization
|
||||
|
||||
Let’s use an example to demonstrate the different labels in action.
|
||||
From the perspective of the taxonomy it could be visualized as:
|
||||
|
||||
Actor <- Taxonomy
|
||||
Bruce Willis <- Term
|
||||
The Six Sense <- Content
|
||||
Unbreakable <- Content
|
||||
Moonrise Kingdom <- Content
|
||||
Samuel L. Jackson <- Term
|
||||
Unbreakable <- Content
|
||||
The Avengers <- Content
|
||||
xXx <- Content
|
||||
|
||||
From the perspective of the content if would appear differently, though
|
||||
the data and labels used are the same:
|
||||
|
||||
Unbreakable <- Content
|
||||
Actors <- Taxonomy
|
||||
Bruce Willis <- Term
|
||||
Samuel L. Jackson <- Term
|
||||
Director <- Taxonomy
|
||||
M. Night Shyamalan <- Term
|
||||
...
|
||||
Moonrise Kingdom <- Content
|
||||
Actors <- Taxonomy
|
||||
Bruce Willis <- Term
|
||||
Bill Murray <- Term
|
||||
Director <- Taxonomy
|
||||
Wes Anderson <- Term
|
||||
...
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
aliases:
|
||||
- /indexes/templates/
|
||||
date: 2013-07-01
|
||||
linktitle: Templates
|
||||
menu:
|
||||
main:
|
||||
parent: taxonomy
|
||||
next: /taxonomies/ordering
|
||||
prev: /templates/displaying
|
||||
title: Taxonomy Templates
|
||||
weight: 30
|
||||
---
|
||||
|
||||
There are two different templates that the use of taxonomies will require you to provide.
|
||||
|
||||
Both templates are covered in detail in the templates section.
|
||||
|
||||
A [list template](/templates/list/) is any template that will be used to render multiple pieces of
|
||||
content in a single html page. This template will be used to generate
|
||||
all the automatically created taxonomy pages.
|
||||
|
||||
A [taxonomy terms template](/templates/terms/) is a template used to
|
||||
generate the list of terms for a given template.
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
date: 2014-05-26
|
||||
linktitle: Usage
|
||||
menu:
|
||||
main:
|
||||
parent: taxonomy
|
||||
next: /taxonomies/displaying
|
||||
prev: /taxonomies/overview
|
||||
title: Using Taxonomies
|
||||
weight: 15
|
||||
---
|
||||
|
||||
## Defining taxonomies for a site
|
||||
|
||||
Taxonomies must be defined in the site configuration, before they can be
|
||||
used throughout the site. You need to provide both the plural and
|
||||
singular labels for each taxonomy.
|
||||
|
||||
Here is an example configuration in YAML that specifies two taxonomies.
|
||||
|
||||
Notice the format is **singular key** : *plural value*.
|
||||
### config.yaml
|
||||
|
||||
---
|
||||
taxonomies:
|
||||
tag: "tags"
|
||||
category: "categories"
|
||||
series: "series"
|
||||
---
|
||||
|
||||
## Assigning taxonomy values to content
|
||||
|
||||
Once an taxonomy is defined at the site level, any piece of content
|
||||
can be assigned to it regardless of content type or section.
|
||||
|
||||
Assigning content to an taxonomy is done in the front matter.
|
||||
Simply create a variable with the *plural* name of the taxonomy
|
||||
and assign all terms you want to apply to this content.
|
||||
|
||||
**taxonomy values are case insensitive**
|
||||
|
||||
### Front Matter Example (in JSON)
|
||||
|
||||
{
|
||||
"title": "Hugo: A fast and flexible static site generator",
|
||||
"tags": [
|
||||
"Development",
|
||||
"Go",
|
||||
"fast",
|
||||
"Blogging"
|
||||
],
|
||||
"categories" : [
|
||||
"Development"
|
||||
],
|
||||
"series" : [
|
||||
"Go Web Dev"
|
||||
],
|
||||
"slug": "hugo",
|
||||
"project_url": "http://github.com/spf13/hugo"
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
aliases:
|
||||
- /layout/404/
|
||||
date: 2013-08-21
|
||||
linktitle: "404"
|
||||
menu:
|
||||
main:
|
||||
parent: layout
|
||||
next: /taxonomies/overview
|
||||
notoc: true
|
||||
prev: /templates/sitemap
|
||||
title: 404.html Templates
|
||||
weight: 100
|
||||
---
|
||||
|
||||
When using Hugo with [github pages](http://pages.github.com/) you can provide
|
||||
your own 404 template by creating a 404.html file in the root.
|
||||
|
||||
404 pages are of the type "node" and have all the [node
|
||||
variables](/layout/variables/) available to use in the templates.
|
||||
|
||||
In addition to the standard node variables, the homepage has access to
|
||||
all site content accessible from .Data.Pages
|
||||
|
||||
▾ layouts/
|
||||
404.html
|
||||
|
||||
## 404.html
|
||||
This is a basic example of a 404.html template:
|
||||
|
||||
{{ template "chrome/header.html" . }}
|
||||
{{ template "chrome/subheader.html" . }}
|
||||
|
||||
<section id="main">
|
||||
<div>
|
||||
<h1 id="title">{{ .Title }}</h1>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{ template "chrome/footer.html" }}
|
||||
|
||||
@@ -0,0 +1,161 @@
|
||||
---
|
||||
aliases:
|
||||
- /layout/functions/
|
||||
date: 2013-07-01
|
||||
linktitle: Single
|
||||
menu:
|
||||
main:
|
||||
parent: layout
|
||||
next: /templates/list
|
||||
prev: /templates/variables
|
||||
title: Single Content Template
|
||||
weight: 30
|
||||
---
|
||||
|
||||
The primary view of content in hugo is the single view. Hugo for every
|
||||
markdown file provided hugo will render it with a single template.
|
||||
|
||||
|
||||
## Which Template will be rendered?
|
||||
Hugo uses a set of rules to figure out which template to use when
|
||||
rendering a specific page.
|
||||
|
||||
Hugo will use the following prioritized list. If a file isn’t present
|
||||
than the next one in the list will be used. This enables you to craft
|
||||
specific layouts when you want to without creating more templates
|
||||
then necessary. For most sites only the \_default file at the end of
|
||||
the list will be needed.
|
||||
|
||||
Users can specify the `type` and `layout` in the [front-matter](/content/front-matter). `Section`
|
||||
is determined based on the content file’s location. If `type` is provide
|
||||
it will be used instead of `section`.
|
||||
|
||||
### Single
|
||||
|
||||
* /layouts/`TYPE` or `SECTION`/`LAYOUT`.html
|
||||
* /layouts/`TYPE` or `SECTION`/single.html
|
||||
* /layouts/\_default/single.html
|
||||
* /themes/`THEME`/layouts/`TYPE` or `SECTION`/`LAYOUT`.html
|
||||
* /themes/`THEME`/layouts/`TYPE` or `SECTION`/single.html
|
||||
* /themes/`THEME`/layouts/\_default/single.html
|
||||
|
||||
## Example Single Template File
|
||||
|
||||
Content pages are of the type "page" and have all the [page
|
||||
variables](/layout/variables/) and [site
|
||||
variables](/templates/variables/) available to use in the templates.
|
||||
|
||||
In the following examples we have created two different content types as well as
|
||||
a default content type.
|
||||
|
||||
The default content template to be used in the event that a specific
|
||||
template has not been provided for that type. The default type works the
|
||||
same as the other types but the directory must be called "\_default".
|
||||
|
||||
▾ layouts/
|
||||
▾ _default/
|
||||
single.html
|
||||
▾ post/
|
||||
single.html
|
||||
▾ project/
|
||||
single.html
|
||||
|
||||
|
||||
## post/single.html
|
||||
This content template is used for [spf13.com](http://spf13.com).
|
||||
It makes use of [partial templates](/layout/partials)
|
||||
|
||||
{{ template "partials/header.html" . }}
|
||||
{{ template "partials/subheader.html" . }}
|
||||
{{ $baseurl := .Site.BaseUrl }}
|
||||
|
||||
<section id="main">
|
||||
<h1 id="title">{{ .Title }}</h1>
|
||||
<div>
|
||||
<article id="content">
|
||||
{{ .Content }}
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<aside id="meta">
|
||||
<div>
|
||||
<section>
|
||||
<h4 id="date"> {{ .Date.Format "Mon Jan 2, 2006" }} </h4>
|
||||
<h5 id="wc"> {{ .FuzzyWordCount }} Words </h5>
|
||||
</section>
|
||||
<ul id="categories">
|
||||
{{ range .Params.topics }}
|
||||
<li><a href="{{ $baseurl }}/topics/{{ . | urlize }}">{{ . }}</a> </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
<ul id="tags">
|
||||
{{ range .Params.tags }}
|
||||
<li> <a href="{{ $baseurl }}/tags/{{ . | urlize }}">{{ . }}</a> </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
{{ if .Prev }}
|
||||
<a class="previous" href="{{.Prev.Permalink}}"> {{.Prev.Title}}</a>
|
||||
{{ end }}
|
||||
{{ if .Next }}
|
||||
<a class="next" href="{{.Next.Permalink}}"> {{.Next.Title}}</a>
|
||||
{{ end }}
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
{{ template "partials/disqus.html" . }}
|
||||
{{ template "partials/footer.html" . }}
|
||||
|
||||
|
||||
## project/single.html
|
||||
This content template is used for [spf13.com](http://spf13.com).
|
||||
It makes use of [partial templates](/layout/partials)
|
||||
|
||||
|
||||
{{ template "partials/header.html" . }}
|
||||
{{ template "partials/subheader.html" . }}
|
||||
{{ $baseurl := .Site.BaseUrl }}
|
||||
|
||||
<section id="main">
|
||||
<h1 id="title">{{ .Title }}</h1>
|
||||
<div>
|
||||
<article id="content">
|
||||
{{ .Content }}
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<aside id="meta">
|
||||
<div>
|
||||
<section>
|
||||
<h4 id="date"> {{ .Date.Format "Mon Jan 2, 2006" }} </h4>
|
||||
<h5 id="wc"> {{ .FuzzyWordCount }} Words </h5>
|
||||
</section>
|
||||
<ul id="categories">
|
||||
{{ range .Params.topics }}
|
||||
<li><a href="{{ $baseurl }}/topics/{{ . | urlize }}">{{ . }}</a> </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
<ul id="tags">
|
||||
{{ range .Params.tags }}
|
||||
<li> <a href="{{ $baseurl }}/tags/{{ . | urlize }}">{{ . }}</a> </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
|
||||
{{if isset .Params "project_url" }}
|
||||
<div id="ribbon">
|
||||
<a href="{{ index .Params "project_url" }}" rel="me">Fork me on GitHub</a>
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
{{ template "partials/footer.html" }}
|
||||
|
||||
Notice how the project/single.html template uses an additional parameter unique
|
||||
to this template. This doesn't need to be defined ahead of time. If the key is
|
||||
present in the front matter than it can be used in the template. To
|
||||
easily generate new content of this type with these keys ready use
|
||||
[content archetypes](/content/archetypes).
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
aliases:
|
||||
- /layout/functions/
|
||||
date: 2013-07-01
|
||||
linktitle: Functions
|
||||
menu:
|
||||
main:
|
||||
parent: layout
|
||||
next: /templates/variables
|
||||
prev: /templates/go-templates
|
||||
title: Hugo Template Functions
|
||||
weight: 20
|
||||
---
|
||||
|
||||
Hugo uses the excellent go html/template library for its template engine.
|
||||
It is an extremely lightweight engine that provides a very small amount of
|
||||
logic. In our experience that it is just the right amount of logic to be able
|
||||
to create a good static website.
|
||||
|
||||
Go templates are lightweight but extensible. Hugo has added the following
|
||||
functions to the basic template logic.
|
||||
|
||||
Go documentation for the built-in functions can be found [here](http://golang.org/pkg/text/template/)
|
||||
|
||||
## General
|
||||
|
||||
### isset
|
||||
Return true if the parameter is set.
|
||||
Takes either a slice, array or channel and an index or a map and a key as input.
|
||||
|
||||
eg. {{ if isset .Params "project_url" }} {{ index .Params "project_url" }}{{ end }}
|
||||
|
||||
### echoParam
|
||||
If parameter is set, then echo it.
|
||||
|
||||
eg. {{echoParam .Params "project_url" }}
|
||||
|
||||
### first
|
||||
Slices an array to only the first X elements.
|
||||
|
||||
eg.
|
||||
{{ range first 10 .Data.Pages }}
|
||||
{{ .Render "summary"}}
|
||||
{{ end }}
|
||||
|
||||
|
||||
## Math
|
||||
|
||||
### add
|
||||
Adds two integers.
|
||||
|
||||
eg {{add 1 2}} -> 3
|
||||
|
||||
### sub
|
||||
Subtracts two integers.
|
||||
|
||||
eg {{sub 3 2}} -> 1
|
||||
|
||||
### div
|
||||
Divides two integers.
|
||||
|
||||
eg {{div 6 3}} -> 2
|
||||
|
||||
### mul
|
||||
Multiplies two integers.
|
||||
|
||||
eg {{mul 2 3}} -> 6
|
||||
|
||||
### mod
|
||||
Modulus of two integers.
|
||||
|
||||
eg {{mod 15 3}} -> 0
|
||||
|
||||
### modBool
|
||||
Boolean of modulus of two integers.
|
||||
true if modulus is 0.
|
||||
|
||||
eg {{modBool 15 3}} -> true
|
||||
|
||||
## Strings
|
||||
|
||||
### urlize
|
||||
Takes a string and sanitizes it for usage in urls, converts spaces to "-".
|
||||
|
||||
eg. <a href="/tags/{{ . | urlize }}">{{ . }}</a>
|
||||
|
||||
### safeHtml
|
||||
Declares the provided string as "safe" so go templates will not filter it.
|
||||
|
||||
eg. {{ .Params.CopyrightHTML | safeHtml }}
|
||||
|
||||
### lower
|
||||
Convert all characters in string to lowercase.
|
||||
|
||||
eg {{lower "BatMan"}} -> "batman"
|
||||
|
||||
### upper
|
||||
Convert all characters in string to uppercase.
|
||||
|
||||
eg {{upper "BatMan"}} -> "BATMAN"
|
||||
|
||||
### title
|
||||
Convert all characters in string to titlecase.
|
||||
|
||||
eg {{title "BatMan"}} -> "Batman"
|
||||
|
||||
### highlight
|
||||
Take a string of code and a language, uses pygments to return the syntax
|
||||
highlighted code in html. Used in the [highlight shortcode](/extras/highlight).
|
||||
@@ -0,0 +1,339 @@
|
||||
---
|
||||
aliases:
|
||||
- /layout/go-templates/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: layout
|
||||
next: /templates/functions
|
||||
prev: /templates/overview
|
||||
title: Go Template Primer
|
||||
weight: 15
|
||||
---
|
||||
|
||||
Hugo uses the excellent [go][] [html/template][gohtmltemplate] library for
|
||||
its template engine. It is an extremely lightweight engine that provides a very
|
||||
small amount of logic. In our experience that it is just the right amount of
|
||||
logic to be able to create a good static website. If you have used other
|
||||
template systems from different languages or frameworks you will find a lot of
|
||||
similarities in go templates.
|
||||
|
||||
This document is a brief primer on using go templates. The [go docs][gohtmltemplate]
|
||||
provide more details.
|
||||
|
||||
## Introduction to Go Templates
|
||||
|
||||
Go templates provide an extremely simple template language. It adheres to the
|
||||
belief that only the most basic of logic belongs in the template or view layer.
|
||||
One consequence of this simplicity is that go templates parse very quickly.
|
||||
|
||||
A unique characteristic of go templates is they are content aware. Variables and
|
||||
content will be sanitized depending on the context of where they are used. More
|
||||
details can be found in the [go docs][gohtmltemplate].
|
||||
|
||||
## Basic Syntax
|
||||
|
||||
Go lang templates are html files with the addition of variables and
|
||||
functions.
|
||||
|
||||
**Go variables and functions are accessible within {{ }}**
|
||||
|
||||
Accessing a predefined variable "foo":
|
||||
|
||||
{{ foo }}
|
||||
|
||||
**Parameters are separated using spaces**
|
||||
|
||||
Calling the add function with input of 1, 2:
|
||||
|
||||
{{ add 1 2 }}
|
||||
|
||||
**Methods and fields are accessed via dot notation**
|
||||
|
||||
Accessing the Page Parameter "bar"
|
||||
|
||||
{{ .Params.bar }}
|
||||
|
||||
**Parentheses can be used to group items together**
|
||||
|
||||
{{ if or (isset .Params "alt") (isset .Params "caption") }} Caption {{ end }}
|
||||
|
||||
|
||||
## Variables
|
||||
|
||||
Each go template has a struct (object) made available to it. In hugo each
|
||||
template is passed either a page or a node struct depending on which type of
|
||||
page you are rendering. More details are available on the
|
||||
[variables](/layout/variables) page.
|
||||
|
||||
A variable is accessed by referencing the variable name.
|
||||
|
||||
<title>{{ .Title }}</title>
|
||||
|
||||
Variables can also be defined and referenced.
|
||||
|
||||
{{ $address := "123 Main St."}}
|
||||
{{ $address }}
|
||||
|
||||
|
||||
## Functions
|
||||
|
||||
Go template ship with a few functions which provide basic functionality. The go
|
||||
template system also provides a mechanism for applications to extend the
|
||||
available functions with their own. [Hugo template
|
||||
functions](/layout/functions) provide some additional functionality we believe
|
||||
are useful for building websites. Functions are called by using their name
|
||||
followed by the required parameters separated by spaces. Template
|
||||
functions cannot be added without recompiling hugo.
|
||||
|
||||
**Example:**
|
||||
|
||||
{{ add 1 2 }}
|
||||
|
||||
## Includes
|
||||
|
||||
When including another template you will pass to it the data it will be
|
||||
able to access. To pass along the current context please remember to
|
||||
include a trailing dot. The templates location will always be starting at
|
||||
the /layout/ directory within Hugo.
|
||||
|
||||
**Example:**
|
||||
|
||||
{{ template "chrome/header.html" . }}
|
||||
|
||||
|
||||
## Logic
|
||||
|
||||
Go templates provide the most basic iteration and conditional logic.
|
||||
|
||||
### Iteration
|
||||
|
||||
Just like in go, the go templates make heavy use of range to iterate over
|
||||
a map, array or slice. The following are different examples of how to use
|
||||
range.
|
||||
|
||||
**Example 1: Using Context**
|
||||
|
||||
{{ range array }}
|
||||
{{ . }}
|
||||
{{ end }}
|
||||
|
||||
**Example 2: Declaring value variable name**
|
||||
|
||||
{{range $element := array}}
|
||||
{{ $element }}
|
||||
{{ end }}
|
||||
|
||||
**Example 2: Declaring key and value variable name**
|
||||
|
||||
{{range $index, $element := array}}
|
||||
{{ $index }}
|
||||
{{ $element }}
|
||||
{{ end }}
|
||||
|
||||
### Conditionals
|
||||
|
||||
If, else, with, or, & and provide the framework for handling conditional
|
||||
logic in Go Templates. Like range, each statement is closed with `end`.
|
||||
|
||||
|
||||
Go Templates treat the following values as false:
|
||||
|
||||
* false
|
||||
* 0
|
||||
* any array, slice, map, or string of length zero
|
||||
|
||||
**Example 1: If**
|
||||
|
||||
{{ if isset .Params "title" }}<h4>{{ index .Params "title" }}</h4>{{ end }}
|
||||
|
||||
**Example 2: If -> Else**
|
||||
|
||||
{{ if isset .Params "alt" }}
|
||||
{{ index .Params "alt" }}
|
||||
{{else}}
|
||||
{{ index .Params "caption" }}
|
||||
{{ end }}
|
||||
|
||||
**Example 3: And & Or**
|
||||
|
||||
{{ if and (or (isset .Params "title") (isset .Params "caption")) (isset .Params "attr")}}
|
||||
|
||||
**Example 4: With**
|
||||
|
||||
An alternative way of writing "if" and then referencing the same value
|
||||
is to use "with" instead. With rebinds the context `.` within its scope,
|
||||
and skips the block if the variable is absent.
|
||||
|
||||
The first example above could be simplified as:
|
||||
|
||||
{{ with .Params.title }}<h4>{{ . }}</h4>{{ end }}
|
||||
|
||||
**Example 5: If -> Else If**
|
||||
|
||||
{{ if isset .Params "alt" }}
|
||||
{{ index .Params "alt" }}
|
||||
{{ else if isset .Params "caption" }}
|
||||
{{ index .Params "caption" }}
|
||||
{{ end }}
|
||||
|
||||
## Pipes
|
||||
|
||||
One of the most powerful components of go templates is the ability to
|
||||
stack actions one after another. This is done by using pipes. Borrowed
|
||||
from unix pipes, the concept is simple, each pipeline's output becomes the
|
||||
input of the following pipe.
|
||||
|
||||
Because of the very simple syntax of go templates, the pipe is essential
|
||||
to being able to chain together function calls. One limitation of the
|
||||
pipes is that they only can work with a single value and that value
|
||||
becomes the last parameter of the next pipeline.
|
||||
|
||||
A few simple examples should help convey how to use the pipe.
|
||||
|
||||
**Example 1 :**
|
||||
|
||||
{{ if eq 1 1 }} Same {{ end }}
|
||||
|
||||
is the same as
|
||||
|
||||
{{ eq 1 1 | if }} Same {{ end }}
|
||||
|
||||
It does look odd to place the if at the end, but it does provide a good
|
||||
illustration of how to use the pipes.
|
||||
|
||||
**Example 2 :**
|
||||
|
||||
{{ index .Params "disqus_url" | html }}
|
||||
|
||||
Access the page parameter called "disqus_url" and escape the HTML.
|
||||
|
||||
**Example 3 :**
|
||||
|
||||
{{ if or (or (isset .Params "title") (isset .Params "caption")) (isset .Params "attr")}}
|
||||
Stuff Here
|
||||
{{ end }}
|
||||
|
||||
Could be rewritten as
|
||||
|
||||
{{ isset .Params "caption" | or isset .Params "title" | or isset .Params "attr" | if }}
|
||||
Stuff Here
|
||||
{{ end }}
|
||||
|
||||
|
||||
## Context (aka. the dot)
|
||||
|
||||
The most easily overlooked concept to understand about go templates is that {{ . }}
|
||||
always refers to the current context. In the top level of your template this
|
||||
will be the data set made available to it. Inside of a iteration it will have
|
||||
the value of the current item. When inside of a loop the context has changed. .
|
||||
will no longer refer to the data available to the entire page. If you need to
|
||||
access this from within the loop you will likely want to set it to a variable
|
||||
instead of depending on the context.
|
||||
|
||||
**Example:**
|
||||
|
||||
{{ $title := .Site.Title }}
|
||||
{{ range .Params.tags }}
|
||||
<li> <a href="{{ $baseurl }}/tags/{{ . | urlize }}">{{ . }}</a> - {{ $title }} </li>
|
||||
{{ end }}
|
||||
|
||||
Notice how once we have entered the loop the value of {{ . }} has changed. We
|
||||
have defined a variable outside of the loop so we have access to it from within
|
||||
the loop.
|
||||
|
||||
# Hugo Parameters
|
||||
|
||||
Hugo provides the option of passing values to the template language
|
||||
through the site configuration (for sitewide values), or through the meta
|
||||
data of each specific piece of content. You can define any values of any
|
||||
type (supported by your front matter/config format) and use them however
|
||||
you want to inside of your templates.
|
||||
|
||||
|
||||
## Using Content (page) Parameters
|
||||
|
||||
In each piece of content you can provide variables to be used by the
|
||||
templates. This happens in the [front matter](/content/front-matter).
|
||||
|
||||
An example of this is used in this documentation site. Most of the pages
|
||||
benefit from having the table of contents provided. Sometimes the TOC just
|
||||
doesn't make a lot of sense. We've defined a variable in our front matter
|
||||
of some pages to turn off the TOC from being displayed.
|
||||
|
||||
Here is the example front matter:
|
||||
|
||||
```
|
||||
---
|
||||
title: "Permalinks"
|
||||
date: "2013-11-18"
|
||||
aliases:
|
||||
- "/doc/permalinks/"
|
||||
groups: ["extras"]
|
||||
groups_weight: 30
|
||||
notoc: true
|
||||
---
|
||||
```
|
||||
|
||||
Here is the corresponding code inside of the template:
|
||||
|
||||
{{ if not .Params.notoc }}
|
||||
<div id="toc" class="well col-md-4 col-sm-6">
|
||||
{{ .TableOfContents }}
|
||||
</div>
|
||||
{{ end }}
|
||||
|
||||
|
||||
|
||||
## Using Site (config) Parameters
|
||||
In your top-level configuration file (eg, `config.yaml`) you can define site
|
||||
parameters, which are values which will be available to you in chrome.
|
||||
|
||||
For instance, you might declare:
|
||||
|
||||
```yaml
|
||||
params:
|
||||
CopyrightHTML: "Copyright © 2013 John Doe. All Rights Reserved."
|
||||
TwitterUser: "spf13"
|
||||
SidebarRecentLimit: 5
|
||||
```
|
||||
|
||||
Within a footer layout, you might then declare a `<footer>` which is only
|
||||
provided if the `CopyrightHTML` parameter is provided, and if it is given,
|
||||
you would declare it to be HTML-safe, so that the HTML entity is not escaped
|
||||
again. This would let you easily update just your top-level config file each
|
||||
January 1st, instead of hunting through your templates.
|
||||
|
||||
```
|
||||
{{if .Site.Params.CopyrightHTML}}<footer>
|
||||
<div class="text-center">{{.Site.Params.CopyrightHTML | safeHtml}}</div>
|
||||
</footer>{{end}}
|
||||
```
|
||||
|
||||
An alternative way of writing the "if" and then referencing the same value
|
||||
is to use "with" instead. With rebinds the context `.` within its scope,
|
||||
and skips the block if the variable is absent:
|
||||
|
||||
```
|
||||
{{with .Site.Params.TwitterUser}}<span class="twitter">
|
||||
<a href="https://twitter.com/{{.}}" rel="author">
|
||||
<img src="/images/twitter.png" width="48" height="48" title="Twitter: {{.}}"
|
||||
alt="Twitter"></a>
|
||||
</span>{{end}}
|
||||
```
|
||||
|
||||
Finally, if you want to pull "magic constants" out of your layouts, you can do
|
||||
so, such as in this example:
|
||||
|
||||
```
|
||||
<nav class="recent">
|
||||
<h1>Recent Posts</h1>
|
||||
<ul>{{range first .Site.Params.SidebarRecentLimit .Site.Recent}}
|
||||
<li><a href="{{.RelPermalink}}">{{.Title}}</a></li>
|
||||
{{end}}</ul>
|
||||
</nav>
|
||||
```
|
||||
|
||||
|
||||
[go]: <http://golang.org/>
|
||||
[gohtmltemplate]: <http://golang.org/pkg/html/template/>
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
aliases:
|
||||
- /layout/homepage/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: layout
|
||||
next: /templates/terms
|
||||
notoc: true
|
||||
prev: /templates/list
|
||||
title: Homepage
|
||||
weight: 50
|
||||
---
|
||||
|
||||
The home page of a website is often formatted differently than the other
|
||||
pages. In Hugo you can define your own homepage template.
|
||||
|
||||
Homepage is of the type "node" and have all the [node
|
||||
variables](/templates/variables/) and [site
|
||||
variables](/templates/variables/) available to use in the templates.
|
||||
|
||||
*This is the only required template for building a site and useful when
|
||||
bootstrapping a new site and template. It is also the only required
|
||||
template when using a single page site.*
|
||||
|
||||
In addition to the standard node variables, the homepage has access to
|
||||
all site content accessible from .Data.Pages . Details on how to use the
|
||||
list of pages can be found in the [Lists Template](/templates/list/)
|
||||
|
||||
## Which Template will be rendered?
|
||||
Hugo uses a set of rules to figure out which template to use when
|
||||
rendering a specific page.
|
||||
|
||||
Hugo will use the following prioritized list. If a file isn’t present
|
||||
than the next one in the list will be used. This enables you to craft
|
||||
specific layouts when you want to without creating more templates
|
||||
then necessary. For most sites only the \_default file at the end of
|
||||
the list will be needed.
|
||||
|
||||
* /layouts/index.html
|
||||
* /layouts/\_default/list.html
|
||||
* /layouts/\_default/single.html
|
||||
* /themes/`THEME`/layouts/index.html
|
||||
* /themes/`THEME`/layouts/\_default/list.html
|
||||
* /themes/`THEME`/layouts/\_default/single.html
|
||||
|
||||
## example index.html
|
||||
This content template is used for [spf13.com](http://spf13.com).
|
||||
|
||||
It makes use of [partial templates](/templates/partials) and uses a similar approach as a [List](/templates/list/).
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html class="no-js" lang="en-US" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
{{ template "partials/meta.html" . }}
|
||||
|
||||
<base href="{{ .Site.BaseUrl }}">
|
||||
<title>{{ .Site.Title }}</title>
|
||||
<link rel="canonical" href="{{ .Permalink }}">
|
||||
<link href="{{ .RSSlink }}" rel="alternate" type="application/rss+xml" title="{{ .Site.Title }}" />
|
||||
|
||||
{{ template "partials/head_includes.html" . }}
|
||||
</head>
|
||||
<body lang="en">
|
||||
|
||||
{{ template "partials/subheader.html" . }}
|
||||
|
||||
<section id="main">
|
||||
<div>
|
||||
{{ range first 10 .Data.Pages }}
|
||||
{{ .Render "summary"}}
|
||||
{{ end }}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{ template "partials/footer.html" }}
|
||||
@@ -0,0 +1,217 @@
|
||||
---
|
||||
aliases:
|
||||
- /layout/indexes/
|
||||
date: 2013-07-01
|
||||
linktitle: List
|
||||
menu:
|
||||
main:
|
||||
parent: layout
|
||||
next: /templates/homepage
|
||||
prev: /templates/content
|
||||
title: Content List Template
|
||||
weight: 40
|
||||
---
|
||||
|
||||
A list template is any template that will be used to render multiple pieces of
|
||||
content in a single html page (with the exception of the [homepage](/layout/homepage) which has a
|
||||
dedicated template).
|
||||
|
||||
We are using the term list in its truest sense, a sequential arrangement
|
||||
of material, especially in alphabetical or numerical order. Hugo uses
|
||||
list templates to render anyplace where content is being listed such as
|
||||
taxonomies and sections.
|
||||
|
||||
## Which Template will be rendered?
|
||||
|
||||
Hugo uses a set of rules to figure out which template to use when
|
||||
rendering a specific page.
|
||||
|
||||
Hugo will use the following prioritized list. If a file isn’t present
|
||||
than the next one in the list will be used. This enables you to craft
|
||||
specific layouts when you want to without creating more templates
|
||||
then necessary. For most sites only the \_default file at the end of
|
||||
the list will be needed.
|
||||
|
||||
|
||||
### Section Lists
|
||||
|
||||
A Section will be rendered at /`SECTION`/
|
||||
|
||||
* /layouts/section/`SECTION`.html
|
||||
* /layouts/\_default/section.html
|
||||
* /layouts/\_default/list.html
|
||||
* /themes/`THEME`/layouts/section/`SECTION`.html
|
||||
* /themes/`THEME`/\_default/section.html
|
||||
* /themes/`THEME`/layouts/\_default/list.html
|
||||
|
||||
|
||||
### Taxonomy Lists
|
||||
|
||||
A Taxonomy will be rendered at /`PLURAL`/`TERM`/
|
||||
|
||||
* /layouts/taxonomy/`SINGULAR`.html
|
||||
* /layouts/\_default/taxonomy.html
|
||||
* /layouts/\_default/list.html
|
||||
* /themes/`THEME`/layouts/taxonomy/`SINGULAR`.html
|
||||
* /themes/`THEME`/\_default/taxonomy.html
|
||||
* /themes/`THEME`/layouts/\_default/list.html
|
||||
|
||||
### Section RSS
|
||||
|
||||
A Section’s RSS will be rendered at /`SECTION`/index.xml
|
||||
|
||||
*Hugo ships with it’s own ATOM 2.0 RSS template. In most cases this will
|
||||
be sufficient and an RSS template will not need to be provided by the
|
||||
user.*
|
||||
|
||||
Hugo provides the ability for you to define any RSS type you wish, and
|
||||
can have different RSS files for each section and taxonomy.
|
||||
|
||||
* /layouts/section/`SECTION`.rss.xml
|
||||
* /layouts/\_default/rss.xml
|
||||
* /themes/`THEME`/layouts/section/`SECTION`.rss.xml
|
||||
* /themes/`THEME`/layouts/\_default/rss.xml
|
||||
|
||||
### Taxonomy RSS
|
||||
|
||||
A Taxonomy’s RSS will be rendered at /`PLURAL`/`TERM`/index.xml
|
||||
|
||||
*Hugo ships with it’s own ATOM 2.0 RSS template. In most cases this will
|
||||
be sufficient and an RSS template will not need to be provided by the
|
||||
user.*
|
||||
|
||||
Hugo provides the ability for you to define any RSS type you wish, and
|
||||
can have different RSS files for each section and taxonomy.
|
||||
|
||||
* /layouts/taxonomy/`SINGULAR`.rss.xml
|
||||
* /layouts/\_default/rss.xml
|
||||
* /themes/`THEME`/layouts/taxonomy/`SINGULAR`.rss.xml
|
||||
* /themes/`THEME`/layouts/\_default/rss.xml
|
||||
|
||||
|
||||
## Variables
|
||||
|
||||
List pages are of the type "node" and have all the [node
|
||||
variables](/templates/variables/) and [site
|
||||
variables](/templates/variables/) available to use in the templates.
|
||||
|
||||
Taxonomy pages will additionally have:
|
||||
|
||||
**.Data.`singular`** The taxonomy itself.<br>
|
||||
|
||||
## Example List Template Pages
|
||||
|
||||
### Example section template (post.html)
|
||||
This content template is used for [spf13.com](http://spf13.com).
|
||||
It makes use of [partial templates](/templates/partials). All examples use a
|
||||
[view](/templates/views/) called either "li" or "summary" which this example site
|
||||
defined.
|
||||
|
||||
{{ template "partials/header.html" . }}
|
||||
{{ template "partials/subheader.html" . }}
|
||||
|
||||
<section id="main">
|
||||
<div>
|
||||
<h1 id="title">{{ .Title }}</h1>
|
||||
<ul id="list">
|
||||
{{ range .Data.Pages }}
|
||||
{{ .Render "li"}}
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{ template "partials/footer.html" }}
|
||||
|
||||
### Example taxonomy template (tag.html)
|
||||
This content template is used for [spf13.com](http://spf13.com).
|
||||
It makes use of [partial templates](/templates/partials). All examples use a
|
||||
[view](/templates/views/) called either "li" or "summary" which this example site
|
||||
defined.
|
||||
|
||||
{{ template "partials/header.html" . }}
|
||||
{{ template "partials/subheader.html" . }}
|
||||
|
||||
<section id="main">
|
||||
<div>
|
||||
<h1 id="title">{{ .Title }}</h1>
|
||||
{{ range .Data.Pages }}
|
||||
{{ .Render "summary"}}
|
||||
{{ end }}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{ template "partials/footer.html" }}
|
||||
|
||||
## Ordering Content
|
||||
|
||||
In the case of Hugo each list will render the content based on metadata provided in the [front
|
||||
matter](/content/front-matter). See [ordering content](/content/ordering) for more information.
|
||||
|
||||
Here are a variety of different ways you can order the content items in
|
||||
your list templates:
|
||||
|
||||
### Order by Weight -> Date (default)
|
||||
|
||||
{{ range .Data.Pages }}
|
||||
<li>
|
||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
||||
<div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
|
||||
### Order by Weight -> Date
|
||||
|
||||
{{ range .Data.Pages.ByWeight }}
|
||||
<li>
|
||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
||||
<div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
|
||||
### Order by Date
|
||||
|
||||
{{ range .Data.Pages.ByDate }}
|
||||
<li>
|
||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
||||
<div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
|
||||
### Order by Length
|
||||
|
||||
{{ range .Data.Pages.ByLength }}
|
||||
<li>
|
||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
||||
<div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
|
||||
|
||||
### Order by Title
|
||||
|
||||
{{ range .Data.Pages.ByTitle }}
|
||||
<li>
|
||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
||||
<div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
|
||||
### Order by LinkTitle
|
||||
|
||||
{{ range .Data.Pages.ByLinkTitle }}
|
||||
<li>
|
||||
<a href="{{ .Permalink }}">{{ .LinkTitle }}</a>
|
||||
<div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
|
||||
### Reverse Order
|
||||
Can be applied to any of the above. Using Date for an example.
|
||||
|
||||
{{ range .Data.Pages.ByDate.Reverse }}
|
||||
<li>
|
||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
||||
<div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
|
||||
</li>
|
||||
{{ end }}
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/templates/
|
||||
- /layout/templates/
|
||||
date: 2013-07-01
|
||||
linktitle: Overview
|
||||
menu:
|
||||
main:
|
||||
parent: layout
|
||||
next: /templates/go-templates
|
||||
prev: /themes/creation
|
||||
title: Hugo Templates
|
||||
weight: 10
|
||||
---
|
||||
|
||||
Hugo uses the excellent go html/template library for its template engine.
|
||||
It is an extremely lightweight engine that provides a very small amount of
|
||||
logic. In our experience that it is just the right amount of logic to be able
|
||||
to create a good static website.
|
||||
|
||||
While Hugo has a number of different template roles, most complete
|
||||
websites can be built using just a small number of template files.
|
||||
Please don’t be afraid of the variety of different template roles. They
|
||||
are enable Hugo to build very complicated sites. Most sites will only
|
||||
need to create a [/layouts/\_default/single.html](/templates/content) & [/layouts/\_default/list.html](/templates/list)
|
||||
|
||||
If you are new to go's templates the [go template primer](/layout/go-templates)
|
||||
is a great place to start.
|
||||
|
||||
If you are familiar with go’s templates, Hugo provides some [additional
|
||||
template functions](/templates/functions) and [variables](/templates/variables) you will want to be familiar
|
||||
with.
|
||||
|
||||
## Primary Template roles
|
||||
|
||||
There are 3 primary kinds of templates that Hugo works with.
|
||||
|
||||
### [Single](/templates/content)
|
||||
Render a single piece of content
|
||||
|
||||
### [List](/templates/list)
|
||||
Page that list multiple pieces of content
|
||||
|
||||
### [Homepage](/templates/homepage/)
|
||||
The homepage of your site
|
||||
|
||||
## Supporting Template Roles (optional)
|
||||
|
||||
Hugo also has additional kinds of templates all of which are optional
|
||||
|
||||
### [Partial Templates](/templates/partials)
|
||||
Common page parts to be included in the above mentioned templates
|
||||
|
||||
### [Content Views](/templates/views)
|
||||
Different ways of rendering a (single) content type
|
||||
|
||||
### [Taxonomy Terms](/templates/terms)
|
||||
A list of the terms used for a specific taxonomy eg. a Tag cloud
|
||||
|
||||
## Other Templates (generally unncessary)
|
||||
|
||||
### [RSS](/templates/rss/)
|
||||
Used to render all rss documents
|
||||
|
||||
### [Sitemap](/templates/sitemap/)
|
||||
Used to render the XML sitemap
|
||||
|
||||
### [404](/templates/404)
|
||||
This template will create a 404.html page used when hosting on github pages
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
aliases:
|
||||
- /layout/chrome/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: layout
|
||||
next: /templates/rss
|
||||
prev: /templates/views
|
||||
title: Partial Templates
|
||||
weight: 80
|
||||
---
|
||||
|
||||
It's not a requirement to have this, but in practice it's very
|
||||
convenient to split out common template portions into a partial template
|
||||
that can be included anywhere. As you create the rest of your templates
|
||||
you will include templates from the /layout/partials directory. Hugo
|
||||
doesn't know anything about partials, it's simply a convention that you
|
||||
may likely find beneficial.
|
||||
|
||||
|
||||
I've found it helpful to include a header and footer template in
|
||||
partials so I can include those in all the full page layouts. There is
|
||||
nothing special about header.html and footer.html other than they seem
|
||||
like good names to use for inclusion in your other templates.
|
||||
|
||||
▾ layouts/
|
||||
▾ partials/
|
||||
header.html
|
||||
footer.html
|
||||
|
||||
By ensuring that we only reference [variables](/layout/variables/)
|
||||
used for both nodes and pages we can use the same partials for both.
|
||||
|
||||
## example header.html
|
||||
This header template is used for [spf13.com](http://spf13.com).
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html class="no-js" lang="en-US" prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb#">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
{{ template "partials/meta.html" . }}
|
||||
|
||||
<base href="{{ .Site.BaseUrl }}">
|
||||
<title> {{ .Title }} : spf13.com </title>
|
||||
<link rel="canonical" href="{{ .Permalink }}">
|
||||
{{ if .RSSlink }}<link href="{{ .RSSlink }}" rel="alternate" type="application/rss+xml" title="{{ .Title }}" />{{ end }}
|
||||
|
||||
{{ template "partials/head_includes.html" . }}
|
||||
</head>
|
||||
<body lang="en">
|
||||
|
||||
## example footer.html
|
||||
This header template is used for [spf13.com](http://spf13.com).
|
||||
|
||||
<footer>
|
||||
<div>
|
||||
<p>
|
||||
© 2013 Steve Francia.
|
||||
<a href="http://creativecommons.org/licenses/by/3.0/" title="Creative Commons Attribution">Some rights reserved</a>;
|
||||
please attribute properly and link back. Hosted by <a href="http://servergrove.com">ServerGrove</a>.
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
<script type="text/javascript">
|
||||
|
||||
var _gaq = _gaq || [];
|
||||
_gaq.push(['_setAccount', 'UA-XYSYXYSY-X']);
|
||||
_gaq.push(['_trackPageview']);
|
||||
|
||||
(function() {
|
||||
var ga = document.createElement('script');
|
||||
ga.src = ('https:' == document.location.protocol ? 'https://ssl' :
|
||||
'http://www') + '.google-analytics.com/ga.js';
|
||||
ga.setAttribute('async', 'true');
|
||||
document.documentElement.firstChild.appendChild(ga);
|
||||
})();
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
**For examples of referencing these templates, see [single content
|
||||
templates](/templates/content), [list templates](/templates/list) and [homepage templates](/templates/homepage)**
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
aliases:
|
||||
- /layout/rss/
|
||||
date: 2013-07-01
|
||||
linktitle: RSS
|
||||
menu:
|
||||
main:
|
||||
parent: layout
|
||||
next: /templates/sitemap
|
||||
notoc: one
|
||||
prev: /templates/partials
|
||||
title: RSS (feed) Templates
|
||||
weight: 90
|
||||
---
|
||||
|
||||
Like all other templates, you can use a single RSS template to generate
|
||||
all of your RSS feeds or you can create a specific template for each
|
||||
individual feed. Unlinke other templates, *Hugo ships with it’s own ATOM
|
||||
2.0 RSS template. In most cases this will be sufficient and an RSS
|
||||
template will not need to be provided by the user.*
|
||||
|
||||
RSS pages are of the type "node" and have all the [node
|
||||
variables](/layout/variables/) available to use in the templates.
|
||||
|
||||
|
||||
## Which Template will be rendered?
|
||||
Hugo uses a set of rules to figure out which template to use when
|
||||
rendering a specific page.
|
||||
|
||||
Hugo will use the following prioritized list. If a file isn’t present
|
||||
than the next one in the list will be used. This enables you to craft
|
||||
specific layouts when you want to without creating more templates
|
||||
then necessary. For most sites only the \_default file at the end of
|
||||
the list will be needed.
|
||||
|
||||
### Main RSS
|
||||
|
||||
* /layouts/rss.xml
|
||||
* /layouts/\_default/rss.xml
|
||||
* \__internal/rss.xml
|
||||
|
||||
### Section RSS
|
||||
|
||||
* /layouts/section/`SECTION`.rss.xml
|
||||
* /layouts/\_default/rss.xml
|
||||
* /themes/`THEME`/layouts/section/`SECTION`.rss.xml
|
||||
* /themes/`THEME`/layouts/\_default/rss.xml
|
||||
* \__internal/rss.xml
|
||||
|
||||
### Taxonomy RSS
|
||||
|
||||
* /layouts/taxonomy/`SINGULAR`.rss.xml
|
||||
* /layouts/\_default/rss.xml
|
||||
* /themes/`THEME`/layouts/taxonomy/`SINGULAR`.rss.xml
|
||||
* /themes/`THEME`/layouts/\_default/rss.xml
|
||||
* \__internal/rss.xml
|
||||
|
||||
|
||||
## Configuring RSS
|
||||
|
||||
If the following are provided in the site’s config file then then they
|
||||
will be included in the RSS output. Example values are provided.
|
||||
|
||||
languageCode = "en-us"
|
||||
copyright = "This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License."
|
||||
|
||||
[author]
|
||||
name = "My Name Here"
|
||||
|
||||
|
||||
## The Embedded rss.xml
|
||||
This is the RSS template that ships with Hugo. It adheres to the
|
||||
ATOM 2.0 Spec.
|
||||
|
||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
||||
<channel>
|
||||
<title>{{ .Title }} on {{ .Site.Title }} </title>
|
||||
<generator uri="https://hugo.spf13.com">Hugo</generator>
|
||||
<link>{{ .Permalink }}</link>
|
||||
{{ with .Site.LanguageCode }}<language>{{.}}</language>{{end}}
|
||||
{{ with .Site.Author.name }}<author>{{.}}</author>{{end}}
|
||||
{{ with .Site.Copyright }}<copyright>{{.}}</copyright>{{end}}
|
||||
<updated>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 MST" }}</updated>
|
||||
{{ range first 15 .Data.Pages }}
|
||||
<item>
|
||||
<title>{{ .Title }}</title>
|
||||
<link>{{ .Permalink }}</link>
|
||||
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 MST" }}</pubDate>
|
||||
{{with .Site.Author.name}}<author>{{.}}</author>{{end}}
|
||||
<guid>{{ .Permalink }}</guid>
|
||||
<description>{{ .Content | html }}</description>
|
||||
</item>
|
||||
{{ end }}
|
||||
</channel>
|
||||
</rss>
|
||||
|
||||
*Important: Hugo will automatically add the following header line to this file
|
||||
on render...please don't include this in the template as it's not valid HTML.*
|
||||
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
aliases:
|
||||
- /layout/sitemap/
|
||||
date: 2014-05-07
|
||||
linktitle: Sitemap
|
||||
menu:
|
||||
main:
|
||||
parent: layout
|
||||
next: /templates/404
|
||||
notoc: true
|
||||
prev: /templates/rss
|
||||
title: Sitemap Template
|
||||
weight: 95
|
||||
---
|
||||
|
||||
A single Sitemap template is used to generate the `sitemap.xml` file.
|
||||
Hugo Automatically comes with this template file. **No work is needed on
|
||||
the users part unless they want to customize the sitemap.xml.**
|
||||
|
||||
This page is of the type "node" and have all the [node
|
||||
variables](/layout/variables/) available to use in this template
|
||||
along with Sitemap-specific ones:
|
||||
|
||||
**.Sitemap.ChangeFreq** The page change frequency<br>
|
||||
**.Sitemap.Priority** The priority of the page<br>
|
||||
|
||||
In addition to the standard node variables, the homepage has access to all
|
||||
site pages through `.Data.Pages`.
|
||||
|
||||
If provided Hugo will use /layouts/sitemap.xml instead of the internal
|
||||
one.
|
||||
|
||||
## Hugo’s sitemap.xml
|
||||
|
||||
This template respects the version 0.9 of the [Sitemap
|
||||
Protocol](http://www.sitemaps.org/protocol.html).
|
||||
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
{{ range .Data.Pages }}
|
||||
<url>
|
||||
<loc>{{ .Permalink }}</loc>
|
||||
<lastmod>{{ safeHtml ( .Date.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod>{{ with .Sitemap.ChangeFreq }}
|
||||
<changefreq>{{ . }}</changefreq>{{ end }}{{ if ge .Sitemap.Priority 0.0 }}
|
||||
<priority>{{ .Sitemap.Priority }}</priority>{{ end }}
|
||||
</url>
|
||||
{{ end }}
|
||||
</urlset>
|
||||
|
||||
*Important: Hugo will automatically add the following header line to this file
|
||||
on render...please don't include this in the template as it's not valid HTML.*
|
||||
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
@@ -0,0 +1,134 @@
|
||||
---
|
||||
aliases:
|
||||
- /indexes/lists/
|
||||
- /doc/indexes/
|
||||
- /extras/indexes
|
||||
date: 2014-05-21
|
||||
linktitle: Taxonomy Terms
|
||||
menu:
|
||||
main:
|
||||
parent: layout
|
||||
next: /templates/views
|
||||
prev: /templates/homepage
|
||||
title: Taxonomy Terms Template
|
||||
weight: 60
|
||||
---
|
||||
|
||||
A unique template is needed to create a list of the terms for a given
|
||||
taxonomy. This is different from the [list template](/templates/list/)
|
||||
as that template is a list of content, where this is a list of meta data.
|
||||
|
||||
## Which Template will be rendered?
|
||||
Hugo uses a set of rules to figure out which template to use when
|
||||
rendering a specific page.
|
||||
|
||||
Hugo will use the following prioritized list. If a file isn’t present
|
||||
than the next one in the list will be used. This enables you to craft
|
||||
specific layouts when you want to without creating more templates
|
||||
then necessary. For most sites only the \_default file at the end of
|
||||
the list will be needed.
|
||||
|
||||
A Taxonomy Terms List will be rendered at /`PLURAL`/
|
||||
|
||||
* /layouts/taxonomy/`SINGLE`.terms.html
|
||||
* /layouts/\_default/terms.html
|
||||
|
||||
If that neither file is found in either the /layouts or /theme/layouts
|
||||
directory than hugo will not render the taxonomy terms pages. It is also
|
||||
common for people to render taxonomy terms lists on other pages such as
|
||||
the homepage or the sidebar (such as a tag cloud) and not have a
|
||||
dedicated page for the terms.
|
||||
|
||||
## Variables
|
||||
|
||||
Taxonomy Terms pages are of the type "node" and have all the [node
|
||||
variables](/templates/variables/) and [site
|
||||
variables](/templates/variables/) available to use in the templates.
|
||||
|
||||
Taxonomy Terms pages will additionally have:
|
||||
|
||||
**.Data.Singular** The singular name of the taxonomy <br>
|
||||
**.Data.Plural** The plural name of the taxonomy<br>
|
||||
**.Data.Terms** The taxonomy itself<br>
|
||||
**.Data.Terms.Alphabetical** The Terms alphabetized<br>
|
||||
**.Data.Terms.ByCount** The Terms ordered by popularity<br>
|
||||
|
||||
## Example terms.html file
|
||||
|
||||
List pages are of the type "node" and have all the [node
|
||||
variables](/templates/variables/) and [site
|
||||
variables](/templates/variables/) available to use in the templates.
|
||||
|
||||
This content template is used for [spf13.com](http://spf13.com).
|
||||
It makes use of [partial templates](/templates/partials). The list of indexes
|
||||
templates cannot use a [content view](/templates/views) as they don't display the content, but
|
||||
rather information about the content.
|
||||
|
||||
This particular template lists all of the Tags used on
|
||||
[spf13.com](http://spf13.com) and provides a count for the number of pieces of
|
||||
content tagged with each tag.
|
||||
|
||||
.Data.Terms is an map of terms => [contents]
|
||||
|
||||
{{ template "partials/header.html" . }}
|
||||
{{ template "partials/subheader.html" . }}
|
||||
|
||||
<section id="main">
|
||||
<div>
|
||||
<h1 id="title">{{ .Title }}</h1>
|
||||
|
||||
<ul>
|
||||
{{ $data := .Data }}
|
||||
{{ range $key, $value := .Data.Terms }}
|
||||
<li><a href="{{ $data.Plural }}/{{ $key | urlize }}"> {{ $key }} </a> {{ len $value }} </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{ template "partials/footer.html" }}
|
||||
|
||||
|
||||
## Ordering
|
||||
|
||||
Hugo can order the meta data in two different ways. It can be ordered by the
|
||||
number of content assigned to that key or alphabetically.
|
||||
|
||||
|
||||
## Example indexes.html file (alphabetical)
|
||||
|
||||
{{ template "partials/header.html" . }}
|
||||
{{ template "partials/subheader.html" . }}
|
||||
|
||||
<section id="main">
|
||||
<div>
|
||||
<h1 id="title">{{ .Title }}</h1>
|
||||
<ul>
|
||||
{{ $data := .Data }}
|
||||
{{ range $key, $value := .Data.Terms.Alphabetical }}
|
||||
<li><a href="{{ $data.Plural }}/{{ $value.Name | urlize }}"> {{ $value.Name }} </a> {{ $value.Count }} </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
{{ template "partials/footer.html" }}
|
||||
|
||||
## Example indexes.html file (ordered)
|
||||
|
||||
{{ template "partials/header.html" . }}
|
||||
{{ template "partials/subheader.html" . }}
|
||||
|
||||
<section id="main">
|
||||
<div>
|
||||
<h1 id="title">{{ .Title }}</h1>
|
||||
<ul>
|
||||
{{ $data := .Data }}
|
||||
{{ range $key, $value := .Data.Terms.ByCount }}
|
||||
<li><a href="{{ $data.Plural }}/{{ $value.Name | urlize }}"> {{ $value.Name }} </a> {{ $value.Count }} </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{{ template "partials/footer.html" }}
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/variables/
|
||||
- /layout/variables/
|
||||
date: 2013-07-01
|
||||
linktitle: Variables
|
||||
menu:
|
||||
main:
|
||||
parent: layout
|
||||
next: /templates/content
|
||||
prev: /templates/functions
|
||||
title: Template Variables
|
||||
weight: 20
|
||||
---
|
||||
|
||||
Hugo makes a set of values available to the templates. Go templates are context based. The following
|
||||
are available in the context for the templates.
|
||||
|
||||
## Page Variables
|
||||
|
||||
The following is a list of most of the accessible variables which can be
|
||||
defined for a piece of content. Many of these will be defined in the front
|
||||
matter, content or derived from file location.
|
||||
|
||||
**.Title** The title for the content.<br>
|
||||
**.Content** The content itself, defined below the front matter.<br>
|
||||
**.Summary** A generated summary of the content for easily showing a snippet in a summary view.<br>
|
||||
**.Description** The description for the content.<br>
|
||||
**.Keywords** The meta keywords for this content.<br>
|
||||
**.Date** The date the content is associated with.<br>
|
||||
**.PublishDate** The date the content is published on.<br>
|
||||
**.Type** The content [type](/content/types/) (eg. post)<br>
|
||||
**.Section** The [section](/content/sections/) this content belongs to<br>
|
||||
**.Permalink** The Permanent link for this page.<br>
|
||||
**.RelPermalink** The Relative permanent link for this page.<br>
|
||||
**.LinkTitle** Access when creating links to this content. Will use linktitle if set in front-matter, else title<br>
|
||||
**.Indexes** These will use the field name of the plural form of the index (see tags and categories above)<br>
|
||||
**.RSSLink** Link to the indexes' rss link <br>
|
||||
**.TableOfContents** The rendered table of contents for this content<br>
|
||||
**.Prev** Pointer to the previous content (based on pub date)<br>
|
||||
**.Next** Pointer to the following content (based on pub date)<br>
|
||||
**.FuzzyWordCount** The approximate number of words in the content.<br>
|
||||
**.WordCount** The number of words in the content.<br>
|
||||
**.ReadingTime** The estimated time it takes to read the content in minutes.<br>
|
||||
**.Weight** Assigned weight (in the front matter) to this content, used in sorting.<br>
|
||||
**.Site** See site variables below<br>
|
||||
|
||||
## Page Params
|
||||
|
||||
Any other value defined in the front matter, including indexes will be made available under `.Params`.
|
||||
Take for example I'm using tags and categories as my indexes. The following would be how I would access them:
|
||||
|
||||
**.Params.tags** <br>
|
||||
**.Params.categories** <br>
|
||||
<br>
|
||||
**All Params are only accessible using all lowercase characters**<br>
|
||||
|
||||
## Node Variables
|
||||
In Hugo a node is any page not rendered directly by a content file. This
|
||||
includes indexes, lists and the homepage.
|
||||
|
||||
**.Title** The title for the content.<br>
|
||||
**.Date** The date the content is published on.<br>
|
||||
**.Permalink** The Permanent link for this node<br>
|
||||
**.Url** The relative url for this node.<br>
|
||||
**.RSSLink** Link to the indexes' rss link <br>
|
||||
**.Data** The data specific to this type of node.<br>
|
||||
**.Site** See site variables below<br>
|
||||
|
||||
## Site Variables
|
||||
|
||||
Also available is `.Site` which has the following:
|
||||
|
||||
**.Site.BaseUrl** The base URL for the site as defined in the config.json file.<br>
|
||||
**.Site.Indexes** The indexes for the entire site.<br>
|
||||
**.Site.LastChange** The date of the last change of the most recent content.<br>
|
||||
**.Site.Recent** Array of all content ordered by Date, newest first.<br>
|
||||
**.Site.Params** A container holding the values from `params` in your site configuration file.<br>
|
||||
@@ -0,0 +1,127 @@
|
||||
---
|
||||
aliases:
|
||||
- /templates/views/
|
||||
date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: layout
|
||||
next: /templates/partials
|
||||
prev: /templates/terms
|
||||
title: Content Views
|
||||
weight: 70
|
||||
---
|
||||
|
||||
In addition to the [single content template](/templates/content/), Hugo can render alternative views of
|
||||
your content. These are especially useful in [list templates](/templates/list).
|
||||
|
||||
For example you may want content of every type to be shown on the
|
||||
homepage, but only a summary view of it there. Perhaps on a taxonomy
|
||||
list page you would only want a bulleted list of your content. Views
|
||||
make this very straightforward by delegating the rendering of each
|
||||
different type of content to the content itself.
|
||||
|
||||
|
||||
## Creating a content view
|
||||
|
||||
To create a new view simple create a template in each of your different
|
||||
content type directories with the view name. In the following example we
|
||||
have created a "li" view and a "summary" view for our two content types
|
||||
of post and project. As you can see these sit next to the [single
|
||||
content view](/templates/content) template "single.html". You can even
|
||||
provide a specific view for a given type and continue to use the
|
||||
\_default/single.html for the primary view.
|
||||
|
||||
▾ layouts/
|
||||
▾ post/
|
||||
li.html
|
||||
single.html
|
||||
summary.html
|
||||
▾ project/
|
||||
li.html
|
||||
single.html
|
||||
summary.html
|
||||
|
||||
Hugo also has support for a default content template to be used in the event
|
||||
that a specific template has not been provided for that type. The default type
|
||||
works the same as the other types but the directory must be called "_default".
|
||||
Content views can also be defined in the "_default" directory.
|
||||
|
||||
|
||||
▾ layouts/
|
||||
▾ _default/
|
||||
li.html
|
||||
single.html
|
||||
summary.html
|
||||
|
||||
|
||||
## Which Template will be rendered?
|
||||
Hugo uses a set of rules to figure out which template to use when
|
||||
rendering a specific page.
|
||||
|
||||
Hugo will use the following prioritized list. If a file isn’t present
|
||||
than the next one in the list will be used. This enables you to craft
|
||||
specific layouts when you want to without creating more templates
|
||||
then necessary. For most sites only the \_default file at the end of
|
||||
the list will be needed.
|
||||
|
||||
* /layouts/`TYPE`/`VIEW`.html
|
||||
* /layouts/\_default/`VIEW`.html
|
||||
* /themes/`THEME`/layouts/`TYPE`/`VIEW`.html
|
||||
* /themes/`THEME`/layouts/\_default/`view`.html
|
||||
|
||||
|
||||
## Example using views
|
||||
|
||||
### rendering view inside of a list
|
||||
|
||||
Using the summary view (defined below) inside of a ([list
|
||||
templates](/templates/list)).
|
||||
|
||||
<section id="main">
|
||||
<div>
|
||||
<h1 id="title">{{ .Title }}</h1>
|
||||
{{ range .Data.Pages }}
|
||||
{{ .Render "summary"}}
|
||||
{{ end }}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
In the above example you will notice that we have called .Render and passed in
|
||||
which view to render the content with. Render is a special function available on
|
||||
a content which tells the content to render itself with the provided view template.
|
||||
In this example we are not using the li view. To use this we would
|
||||
change the render line to `{{ .Render "li" }}`.
|
||||
|
||||
|
||||
### li.html
|
||||
|
||||
Hugo will pass the entire page object to the view template. See [page
|
||||
variables](/templates/variables) for a complete list.
|
||||
|
||||
This content template is used for [spf13.com](http://spf13.com).
|
||||
|
||||
<li>
|
||||
<a href="{{ .Permalink }}">{{ .Title }}</a>
|
||||
<div class="meta">{{ .Date.Format "Mon, Jan 2, 2006" }}</div>
|
||||
</li>
|
||||
|
||||
### summary.html
|
||||
|
||||
Hugo will pass the entire page object to the view template. See [page
|
||||
variables](/templates/variables) for a complete list.
|
||||
|
||||
This content template is used for [spf13.com](http://spf13.com).
|
||||
|
||||
<article class="post">
|
||||
<header>
|
||||
<h2><a href='{{ .Permalink }}'> {{ .Title }}</a> </h2>
|
||||
<div class="post-meta">{{ .Date.Format "Mon, Jan 2, 2006" }} - {{ .FuzzyWordCount }} Words </div>
|
||||
</header>
|
||||
|
||||
{{ .Summary }}
|
||||
<footer>
|
||||
<a href='{{ .Permalink }}'><nobr>Read more →</nobr></a>
|
||||
</footer>
|
||||
</article>
|
||||
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
date: 2014-05-12T10:09:17Z
|
||||
menu:
|
||||
main:
|
||||
parent: themes
|
||||
next: /templates/overview
|
||||
prev: /themes/customizing
|
||||
title: Creating a Theme
|
||||
weight: 50
|
||||
---
|
||||
|
||||
Hugo has the ability to create a new theme in your themes directory for you
|
||||
using the `hugo new` command.
|
||||
|
||||
`hugo new theme [name]`
|
||||
|
||||
This command will initialize all of the files and directories a basic theme
|
||||
would need. Hugo themes are written in the go template language. If you are new
|
||||
to Go, the [go template primer](/templates/primer/) will help you get started.
|
||||
|
||||
## Theme Components
|
||||
|
||||
A theme consists of templates and static assets such as javascript and css
|
||||
files. Themes can also optionally provide [archetypes](/content/archetypes)
|
||||
which are archetypal content types used by the `hugo new` command.
|
||||
|
||||
### Layouts
|
||||
|
||||
Hugo is built around the concept that things should be as simple as possible.
|
||||
Fundamentally website content is displayed in two different ways, a single
|
||||
piece of content and a list of content items. With Hugo a theme layout starts
|
||||
with the defaults. As additional layouts are defined they are used for the
|
||||
content type or section they apply to. This keeps layouts simple, but permits
|
||||
a large amount of flexibility.
|
||||
|
||||
### Single Content
|
||||
|
||||
The default single file layout is located at `layouts/_default/single.html`.
|
||||
|
||||
|
||||
### List of Contents
|
||||
|
||||
The default list file layout is located at `layouts/_default/list.html`
|
||||
|
||||
|
||||
### Static
|
||||
|
||||
Everything in the static directory will be copied directly into the final site
|
||||
when rendered. No structure is provided here to enable complete freedom. It is
|
||||
common to organize the static content into
|
||||
|
||||
/css
|
||||
/js
|
||||
/img
|
||||
|
||||
The actual structure is entirely up to you, the theme creator, on how you would like to organize your files.
|
||||
|
||||
|
||||
### Archetypes
|
||||
|
||||
If your theme makes use of specific keys in the front matter it is a good idea
|
||||
to provide an archetype for each content type you have. Archetypes follow the
|
||||
[guidelines provided](/content/archetypes).
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
date: 2014-05-12T10:09:34Z
|
||||
menu:
|
||||
main:
|
||||
parent: themes
|
||||
next: /themes/creation
|
||||
prev: /themes/usage
|
||||
title: Customizing a Theme
|
||||
weight: 40
|
||||
---
|
||||
|
||||
Hugo themes permit you to supplement or override any template or file
|
||||
from within your working directory.
|
||||
|
||||
|
||||
## Replacing Static files
|
||||
|
||||
If you would like to include a different file than the theme ships
|
||||
with.. For example you would like to use a more recent version of jquery
|
||||
then the theme happens to include simply place an identically name file in the same
|
||||
relative location but in your working directory. For example if the
|
||||
theme has jquery 1.6 in /themes/themename/static/js/jQuery.min.js, simply place your file
|
||||
in the same relative path /static/js/jQuery.min.js.
|
||||
|
||||
## Replace a single template file
|
||||
|
||||
Anytime Hugo looks for a matching template it will first check the
|
||||
working directory before looking in the theme directory. If you would
|
||||
like to modify a template simply create that template in your local
|
||||
layouts directory. In the [template documentation](/templates/overview/)
|
||||
each different template type explains the rules it uses to determine
|
||||
which template to use.
|
||||
|
||||
**warning.. This only works for templates that Hugo knows about. If the
|
||||
theme creates partial template files in a creatively named directory
|
||||
Hugo won’t know to look for the local /layouts first**
|
||||
|
||||
## Replace an archetype
|
||||
|
||||
If the archetype that ships with the theme for a given content type (or
|
||||
all content types) doesn’t fit with how you are using the theme, feel
|
||||
free to copy it to your /archetypes directory and make modifications as
|
||||
you see fit.
|
||||
|
||||
## Beware of the default
|
||||
|
||||
**Default** is a very powerful force in Hugo... Especially as it pertains to
|
||||
overwriting theme files. If a default is located in the local archetype
|
||||
directory or /layouts/\_default/ directory it will be used instead of
|
||||
any of the similar files in the theme.
|
||||
|
||||
It is usually better to override specific files rather than using the
|
||||
default in your working directory.
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
date: 2014-05-12T10:09:49Z
|
||||
menu:
|
||||
main:
|
||||
parent: themes
|
||||
next: /themes/usage
|
||||
prev: /themes/overview
|
||||
title: Installing Themes
|
||||
weight: 20
|
||||
---
|
||||
|
||||
Hugo themes are located in a centralized github repository. [Hugo Themes
|
||||
Repo](http://github.com/spf13/hugoThemes) itself is really a meta
|
||||
repository which contains pointers to set of contributed themes.
|
||||
|
||||
## Installing all themes
|
||||
|
||||
If you would like to install all of the available hugo themes, simply
|
||||
clone the entire repository from within your working directory.
|
||||
|
||||
git clone --recursive https://github.com/spf13/hugoThemes.git themes
|
||||
|
||||
|
||||
## Installing a specific theme
|
||||
|
||||
mkdir themes
|
||||
cd themes
|
||||
git clone URL_TO_THEME
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
date: 2014-05-12T10:03:52Z
|
||||
menu:
|
||||
main:
|
||||
parent: themes
|
||||
next: /themes/installing
|
||||
prev: /content/example
|
||||
title: Themes Overview
|
||||
weight: 10
|
||||
---
|
||||
|
||||
Hugo provides a robust theming system which is simple, yet capable of producing
|
||||
even the most complicated websites.
|
||||
|
||||
The Hugo community has created a set of themes ready for using in your own
|
||||
site.
|
||||
|
||||
Hugo themes have been designed to be the perfect balance between
|
||||
simplicity and functionality. Hugo themes are powered by the excellent
|
||||
go template library. If you are new to go templates, see our [primer on
|
||||
go templates](/layouts/go-templates).
|
||||
|
||||
Hugo themes support all modern features you come to expect. They are
|
||||
structured in such a way to eliminate code duplication. Themes are also
|
||||
designed to be very easy to customize while retaining the ability to
|
||||
maintain upgradeability as the upstream theme changes.
|
||||
|
||||
Hugo currently doesn’t ship with a “default” theme, allowing the user to
|
||||
pick whichever theme best suits their project.
|
||||
|
||||
We hope you will find Hugo themes perfect for your site.
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
date: 2014-05-12T10:09:27Z
|
||||
menu:
|
||||
main:
|
||||
parent: themes
|
||||
next: /themes/customizing
|
||||
prev: /themes/installing
|
||||
title: Using a Theme
|
||||
weight: 30
|
||||
---
|
||||
|
||||
Please make certain you have installed the themes you want to use in the
|
||||
/themes directory.
|
||||
|
||||
To use a theme for a site:
|
||||
|
||||
hugo -t ThemeName
|
||||
|
||||
The ThemeName must match the name of the directory inside /themes
|
||||
|
||||
Hugo will then apply the theme first, then apply anything that is in the local
|
||||
directory. To learn more, goto [customizing themes](/themes/customizing)
|
||||
@@ -0,0 +1,186 @@
|
||||
---
|
||||
author: Spencer Lyon
|
||||
date: 2014-03-21
|
||||
linktitle: Hosting on GitHub
|
||||
menu:
|
||||
main:
|
||||
parent: tutorials
|
||||
next: /tutorials/mathjax
|
||||
prev: /community/contributing
|
||||
title: Hosting on GitHub Pages
|
||||
weight: 10
|
||||
---
|
||||
|
||||
## Intro
|
||||
|
||||
Many Hugo users have expressed interest in seeing a tutorial for how to set up a blog that generated by Hugo and hosted on GitHub pages. This tutorial will do just that. We only require that the reader has Hugo installed correctly and is comfortable with git and GitHub.
|
||||
|
||||
During this tutorial, I will walk you through the main steps I took to create an example blog available at [http://spencerlyon2.github.io/hugo_gh_blog](http://spencerlyon2.github.io/hugo_gh_blog). The source code for this blog is on [GitHub](https://github.com/spencerlyon2/hugo_gh_blog). Readers are encouraged to download the example repository and follow along.
|
||||
|
||||
### Find a Home for Your Files
|
||||
|
||||
As our goal is to host a website using GitHub pages, it is natural for us to host the content of the page in a GitHub repository. Thus, the first step is to either create a new repository on GitHub or create a new directory within an existing repository where the content of the website will live. To do this I created the repository [spencerlyon2/hugo_gh_blog](https://github.com/spencerlyon2/hugo_gh_blog).
|
||||
|
||||
## Create the Blog
|
||||
|
||||
### Write a `config.yaml` File
|
||||
|
||||
The very first step in creating a new Hugo site is to [write the config file](/overview/configuration). This config file is important for at least two reasons: (1) this is where site-wide settings (like the websites `baseurl`) go and (2) the config file dictates to some extent how Hugo will generate the website. For the example website I created a file `config.yaml` with the following contents
|
||||
|
||||
---
|
||||
contentdir: "content"
|
||||
layoutdir: "layouts"
|
||||
publishdir: "public"
|
||||
indexes:
|
||||
category: "categories"
|
||||
baseurl: "http://spencerlyon2.github.io/hugo_gh_blog"
|
||||
title: "Hugo Blog Template for GitHub Pages"
|
||||
...
|
||||
|
||||
### Define Structure of Website
|
||||
|
||||
Hugo assumes that you organize the content of your site in a meaningful way and uses the same structure to render the website. Notice that we have the line `contentdir: "content"` in our configuration file. This means that all the actual content of the website should be placed somewhere within a folder named `content`. Hugo treats all directories in `content` as sections. For our example we only need one section: a place to hold our blog posts. So we created two new folders:
|
||||
|
||||
```
|
||||
▾ <root>/
|
||||
▾ content/
|
||||
▾ posts/
|
||||
```
|
||||
|
||||
### Create html Templates
|
||||
|
||||
The next step is to define the look and feel of your new website. Because Hugo will generate the site using html templates written by the user (you), this step is very subjective. I will merely present one possible theme that could be used to generate a blog. I decided to base the example project on a Jekyll theme called [lanyon](http://lanyon.getpoole.com). The lanyon theme is pure css and a slightly modified version of the css is in the `/static/css` directory of the example repository. If you are following along, you should grab the `static` folder from the example repository and put it alongside the `content` folder you just created.
|
||||
|
||||
Because there are so many files needed to fully compose a complete website, I will not be able to go trough each of them here. I will, however, show what the directory structure should look like when all is said and done:
|
||||
|
||||
```
|
||||
▾ <root>/
|
||||
▾ content/
|
||||
▾ posts/
|
||||
<blog posts>.md
|
||||
▾ static/
|
||||
▾ css/
|
||||
lanyon.css
|
||||
poole.css
|
||||
▾ layouts/
|
||||
▾ chrome/
|
||||
<templates to be used in other files>.html
|
||||
▾ posts/
|
||||
li.html
|
||||
single.html
|
||||
summary.html
|
||||
▾ indexes/
|
||||
category.html
|
||||
indexes.html
|
||||
posts.html
|
||||
index.html
|
||||
README.md
|
||||
```
|
||||
|
||||
Each of the files in the example repository is well commented with a description of what the file as a whole does as well as an explanation of all major components in the file. If you are new to web development and/or Hugo I encourage you to search through these files to get a feel for how Hugo templates work and how the site is stitched together.
|
||||
|
||||
### Add Some Content
|
||||
|
||||
The final step in creating the blog is to add some actual blog posts. To do this simply create one markdown file (with extension .md) for each new blog post. At the top of each file you should include a metadata section that tells Hugo some things about the post (see [docs](/content/front-matter)). For example, consider the yaml metadata section from the top of the file `/content/posts/newest.md` from the example repository
|
||||
|
||||
---
|
||||
title: "Just another sample post"
|
||||
date: "2014-03-29"
|
||||
description: "This should be a more useful description"
|
||||
categories:
|
||||
- "hugo"
|
||||
- "fun"
|
||||
- "test"
|
||||
---
|
||||
|
||||
The keys set in this section are the mandatory `title` and `date` as well as the optional `description` and `categories`. Each of these items is used throughout the templates found in the `/layouts` directory and gives Hugo information about the post from other pages in the website.
|
||||
|
||||
## Configure `git` Workflow
|
||||
|
||||
Once the site is set up and working properly, we need to push it to the correct branch of a GitHub repository so the website can be served through GitHub Pages. There are many ways to do this. Here I will show the workflow I currently use to manage my websites that are hosted through GitHub pages.
|
||||
|
||||
GitHub pages will serve up a website for any repository that has a branch called `gh-pages` with a valid `index.html` file at that branch's root. A typical workflow might be to keep the content of a website on the `master` branch of a repository and the generated website on the `gh-pages` branch. This provides nice separation between input and output, but can be very tedious to work with. As a workaround we will use the `git subtree` family of commands to have the `public` directory (or whatever `publishdir` is set to in your `config.yaml`) mirror the root of the `gh-pages` branch of the repository. This will allow us to do all our work on the `master` branch, run Hugo have have the site output into the `public` directory, and then push that directory directly to the correct place for GitHub Pages to serve our site.
|
||||
|
||||
To get this properly set up we will execute a series of commands at the terminal. I will include all of them in one place here for easy copy and paste, and will explain what each line does via comments. Note that this is to be run from the `<root>` directory (wherever the `content` and `layout` folders of your Hugo project live). Also note that you will need to change the commands that have the example repository GitHub address so that they point to your repo.
|
||||
|
||||
# Create a new orphand branch (no commit history) named gh-pages
|
||||
git checkout --orphan gh-pages
|
||||
|
||||
# Unstage all files
|
||||
git rm --cached $(git ls-files)
|
||||
|
||||
# Grab one file from the master branch so we can make a commit
|
||||
git checkout master README.md
|
||||
|
||||
# Add and commit that file
|
||||
git add .
|
||||
git commit -m "INIT: initial commit on gh-pages branch"
|
||||
|
||||
# Push to remote gh-pages branch
|
||||
git push origin gh-pages
|
||||
|
||||
# Return to master branch
|
||||
git checkout master
|
||||
|
||||
# Remove the public folder to make room for the gh-pages subtree
|
||||
rm -rf public
|
||||
|
||||
# Add the gh-pages branch of the repository. It will look like a folder named public
|
||||
git subtree add --prefix public git@github.com:spencerlyon2/hugo_gh_blog.git gh-pages --squash
|
||||
|
||||
# Pull down the file we just committed. This helps avoid merge conflicts
|
||||
git subtree pull --prefix=public
|
||||
|
||||
# Run hugo. Generated site will be placed in public directory
|
||||
hugo
|
||||
|
||||
# Add everything
|
||||
git add -A
|
||||
|
||||
# Commit and push to master
|
||||
git commit -m "Updating site" && git push origin master
|
||||
|
||||
# Push the public subtree to the gh-pages branch
|
||||
git subtree push --prefix=public git@github.com:spencerlyon2/hugo_gh_blog.git gh-pages
|
||||
|
||||
After executing these commands and waiting for the GitHub servers to update, the website we just created was live at [http://spencerlyon2.github.io/hugo_gh_blog](http://spencerlyon2.github.io/hugo_gh_blog).
|
||||
|
||||
### `deploy.sh`
|
||||
|
||||
Now, as you add new posts to your blog, you will follow steps that look something like the following:
|
||||
|
||||
* Create the markdown source for the new post within the `content/posts` directory
|
||||
* Preview your work by running Hugo in server mode with `hugo server --watch`
|
||||
* Run Hugo not in server mode so that the generated urls will be correct for the website
|
||||
* Add and commit the new post in `master` branch
|
||||
* Push the `master` branch
|
||||
* Push the public subtree to the remote `gh-pages` branch
|
||||
|
||||
The first two items in the previous list are simply a way to conveniently preview your content as you write. This is a dynamic and fairly streamlined process. All the remaining items, however, are the same every time you want to add new content to the website. To make this repetitive process easier, I have adapted a script from the source repository for the [Chimer Arta & Maker Space](https://github.com/chimera/chimeraarts.org) website that is highlighted in the [Hugo Showcase](/showcase). The script lives in a file called `deploy.sh` and has the following contents
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
echo -e "\033[0;32mDeploying updates to Github...\033[0m"
|
||||
|
||||
# Build the project.
|
||||
hugo
|
||||
|
||||
# Add changes to git.
|
||||
git add -A
|
||||
|
||||
# Commit changes.
|
||||
msg="rebuilding site `date`"
|
||||
if [ $# -eq 1 ]
|
||||
then msg="$1"
|
||||
fi
|
||||
git commit -m "$msg"
|
||||
|
||||
# Push source and build repos.
|
||||
git push origin master
|
||||
git subtree push --prefix=public git@github.com:spencerlyon2/hugo_gh_blog.git gh-pages
|
||||
|
||||
Now I can replace the last four items from our workflow list with a single command `bash deploy.sh`. This script accepts as an optional argument the commit message that git should use when committing your changes. If you wish to include a custom commit message, do so by putting it quotes after calling bash on the script: `bash deploy.sh "<my commit msg>"`. If you choose not to specify the commit message, one will be generated for you using the current time.
|
||||
|
||||
## Conclusion
|
||||
|
||||
Hopefully this tutorial helped you get your website off its feet and out into the open! If you have any further questions feel free to contact the community through the [mailing lists](/community/mailing-list).
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
author: Spencer Lyon
|
||||
date: 2014-03-20
|
||||
menu:
|
||||
main:
|
||||
parent: tutorials
|
||||
next: /tutorials/migrate-from-jekyll
|
||||
prev: /tutorials/github_pages_blog
|
||||
title: MathJax Support
|
||||
weight: 10
|
||||
---
|
||||
|
||||
## What is MathJax?
|
||||
|
||||
[MathJax](http://www.mathjax.org/) is a JavaScript library that allows allows the display of mathematical expressions described via a LaTeX-style syntax in the html (or markdown) source of a web page. As it is a pure a JavaScript library, getting it to work within Hugo is fairly straightforward, but does have some oddities that will be discussed here.
|
||||
|
||||
This is not an introduction into actually using MathJax to render typeset mathematics on your website. Instead this page is a collection of tips and hints for one way to get MathJax working on a website built with Hugo.
|
||||
|
||||
## Enabling MathJax
|
||||
|
||||
The first step is to enable MathJax on pages that you would like to have typeset math. There are multiple ways to do this (adventerous readers can consult the [Loading and Configuring](http://docs.mathjax.org/en/latest/configuration.html) section of the MathJax documentation for additional methods of including MathJax), but the easiest way is to use the secure MathJax CDN by including the following html snippet in the source of a page:
|
||||
|
||||
<script type="text/javascript"
|
||||
src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
|
||||
</script>
|
||||
|
||||
One way to ensure that this code is included in all pages is to put it in one of the templates that live in the `layouts/chrome/` directory. For example, I have included this in the bottom of my template `footer.html` because I know that the footer will be included in every page of my website.
|
||||
|
||||
### Options and Features
|
||||
|
||||
MathJax is a stable open-source library with many features. I encourage the interested reader to view the [MathJax Documentation](http://docs.mathjax.org/en/latest/index.html), specifically the sections on [Basic Usage](http://docs.mathjax.org/en/latest/index.html#basic-usage) and [MathJax Configuration Options](http://docs.mathjax.org/en/latest/index.html#mathjax-configuration-options).
|
||||
|
||||
## Issues with Markdown
|
||||
|
||||
After enabling MathJax, any math entered in-between proper markers (see documentation) will be processed and typeset in the web page. One issue that comes up, however, with markdown is that the underscore character (`_`) is interpreted by markdown as a way to wrap text in `emph` blocks while LaTex (MathJax) interprets the underscore as a way to create a subscript. This "double speak" of the underscore can result in some unexpected and unwanted behavior.
|
||||
|
||||
### Solution
|
||||
|
||||
There are multiple ways to remedy this problem. One solution is to simply escape each underscore in your math code by entering `\_` instead of `_`. This can become quite tedious if the equations you are entering are full of subscripts.
|
||||
|
||||
Another option is to tell markdown to treat the MathJax code as verbatim code and not process it. One way to do this is to wrap the math expression inside a `<div>` `</div>` block. Markdown would ignore these sections and they would get passed directly on to MathJax and processed correctly. This works great for display style mathematics, but for inline math expressions the line break induced by the `<div>` is not acceptable. The syntax for instructing markdown to treat inline text as verbatim is by wrapping it in backticks (`` ` ``). You might have noticed, however, that the text included in between backticks is rendered differently than standard text (on this site these are items highlighted in red). To get around this problem we could create a new css entry that would apply standard styling to all inline verbatim text that includes MathJax code. Below I will show the html and css source that would accomplish this (note this solution adapted from [this blog post](http://doswa.com/2011/07/20/mathjax-in-markdown.html) -- all credit goes to the original author).
|
||||
|
||||
<script type="text/x-mathjax-config">
|
||||
MathJax.Hub.Config({
|
||||
tex2jax: {
|
||||
inlineMath: [['$','$'], ['\\(','\\)']],
|
||||
displayMath: [['$$','$$'], ['\[','\]']],
|
||||
processEscapes: true,
|
||||
processEnvironments: true,
|
||||
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
|
||||
TeX: { equationNumbers: { autoNumber: "AMS" },
|
||||
extensions: ["AMSmath.js", "AMSsymbols.js"] }
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<script type="text/x-mathjax-config">
|
||||
MathJax.Hub.Queue(function() {
|
||||
// Fix <code> tags after MathJax finishes running. This is a
|
||||
// hack to overcome a shortcoming of Markdown. Discussion at
|
||||
// https://github.com/mojombo/jekyll/issues/199
|
||||
var all = MathJax.Hub.getAllJax(), i;
|
||||
for(i = 0; i < all.length; i += 1) {
|
||||
all[i].SourceElement().parentNode.className += ' has-jax';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
As before, this content should be included in the html source of each page that will be using MathJax. The next code snippet contains the CSS that is used to have verbatim MathJax blocks render with the same font style as the body of the page.
|
||||
|
||||
|
||||
code.has-jax {font: inherit;
|
||||
font-size: 100%;
|
||||
background: inherit;
|
||||
border: inherit;
|
||||
color: #515151;}
|
||||
|
||||
In the css snippet notice the line `color: #515151;`. `#515151` is the value assigned to the `color` attribute of the `body` class in my css. In order for the equations to fit in with the body of a web page, this value should be the same as the color of the body.
|
||||
|
||||
### Usage
|
||||
|
||||
With this setup, everything is inplace for a natural usage of MathJax on pages generated using Hugo. In order to include inline mathematics, just put LaTeX code in between `` `$ TeX Code $` `` or `` `\( TeX Code \)` ``. To include display style mathematics, just put LaTeX code in between `<div>$$TeX Code$$</div>`. All the math will be properly typeset and displayed within your Hugo generated web page!
|
||||
@@ -0,0 +1,156 @@
|
||||
---
|
||||
date: 2014-03-10
|
||||
linktitle: Migrating from Jekyll
|
||||
menu:
|
||||
main:
|
||||
parent: tutorials
|
||||
prev: /tutorials/mathjax
|
||||
title: Migrate to Hugo from Jekyll
|
||||
weight: 10
|
||||
---
|
||||
|
||||
## Move static content to `static`
|
||||
Jekyll has a rule that any directory not starting with `_` will be copied as-is to the `_site` output. Hugo keeps all static content under `static`. You should therefore move it all there.
|
||||
With Jekyll, something that looked like
|
||||
|
||||
▾ <root>/
|
||||
▾ images/
|
||||
logo.png
|
||||
|
||||
Should become
|
||||
|
||||
▾ <root>/
|
||||
▾ static/
|
||||
▾ images/
|
||||
logo.png
|
||||
|
||||
Additionally, you'll want any files that should reside at the root (such as `CNAME`) to be moved to `static`.
|
||||
|
||||
## Create your Hugo configuration file
|
||||
Hugo can read your configuration as json, yaml or toml. Hugo supports parameters custom configuration too. Refer to the [Hugo configuration documentation](/overview/configuration/) for details.
|
||||
|
||||
## Set your configuration publish folder to `_site`
|
||||
The default is for Jekyll to publish to `_site` and for Hugo to publish to `public`. If, like me, you have [`_site` mapped to a git submodule on the `gh-pages` branch](http://blog.blindgaenger.net/generate_github_pages_in_a_submodule.html), you'll want to do one of two alternatives:
|
||||
|
||||
1. Change your submodule to point to map `gh-pages` to public instead of `_site` (recommended).
|
||||
|
||||
git submodule deinit _site
|
||||
git rm _site
|
||||
git submodule add -b gh-pages git@github.com:your-username/your-repo.git public
|
||||
|
||||
1. Or, change the Hugo configuration to use `_site` instead of `public`.
|
||||
|
||||
{
|
||||
..
|
||||
"publishdir": "_site",
|
||||
..
|
||||
}
|
||||
|
||||
## Convert Jekyll templates to Hugo templates
|
||||
That's the bulk of the work right here. The documentation is your friend. You should refer to [Jekyll's template documentation](http://jekyllrb.com/docs/templates/) if you need to refresh your memory on how you built your blog and [Hugo's template](/layout/templates/) to learn Hugo's way.
|
||||
|
||||
As a single reference data point, converting my templates for [heyitsalex.net](http://heyitsalex.net) took me no more than a few hours.
|
||||
|
||||
## Convert Jekyll plugins to Hugo shortcodes
|
||||
Jekyll has [plugins](http://jekyllrb.com/docs/plugins/), Hugo has [shortcodes](/doc/shortcodes/). It's fairly trivial to do a port.
|
||||
|
||||
### Implementation
|
||||
As an example, I was using a custom [`image_tag`](https://github.com/alexandre-normand/alexandre-normand/blob/74bb12036a71334fdb7dba84e073382fc06908ec/_plugins/image_tag.rb) plugin to generate figures with caption when running Jekyll. As I read about shortcodes, I found Hugo had a nice built-in shortcode that does exactly the same thing.
|
||||
|
||||
Jekyll's plugin:
|
||||
|
||||
module Jekyll
|
||||
class ImageTag < Liquid::Tag
|
||||
@url = nil
|
||||
@caption = nil
|
||||
@class = nil
|
||||
@link = nil
|
||||
// Patterns
|
||||
IMAGE_URL_WITH_CLASS_AND_CAPTION =
|
||||
IMAGE_URL_WITH_CLASS_AND_CAPTION_AND_LINK = /(\w+)(\s+)((https?:\/\/|\/)(\S+))(\s+)"(.*?)"(\s+)->((https?:\/\/|\/)(\S+))(\s*)/i
|
||||
IMAGE_URL_WITH_CAPTION = /((https?:\/\/|\/)(\S+))(\s+)"(.*?)"/i
|
||||
IMAGE_URL_WITH_CLASS = /(\w+)(\s+)((https?:\/\/|\/)(\S+))/i
|
||||
IMAGE_URL = /((https?:\/\/|\/)(\S+))/i
|
||||
def initialize(tag_name, markup, tokens)
|
||||
super
|
||||
if markup =~ IMAGE_URL_WITH_CLASS_AND_CAPTION_AND_LINK
|
||||
@class = $1
|
||||
@url = $3
|
||||
@caption = $7
|
||||
@link = $9
|
||||
elsif markup =~ IMAGE_URL_WITH_CLASS_AND_CAPTION
|
||||
@class = $1
|
||||
@url = $3
|
||||
@caption = $7
|
||||
elsif markup =~ IMAGE_URL_WITH_CAPTION
|
||||
@url = $1
|
||||
@caption = $5
|
||||
elsif markup =~ IMAGE_URL_WITH_CLASS
|
||||
@class = $1
|
||||
@url = $3
|
||||
elsif markup =~ IMAGE_URL
|
||||
@url = $1
|
||||
end
|
||||
end
|
||||
def render(context)
|
||||
if @class
|
||||
source = "<figure class='#{@class}'>"
|
||||
else
|
||||
source = "<figure>"
|
||||
end
|
||||
if @link
|
||||
source += "<a href=\"#{@link}\">"
|
||||
end
|
||||
source += "<img src=\"#{@url}\">"
|
||||
if @link
|
||||
source += "</a>"
|
||||
end
|
||||
source += "<figcaption>#{@caption}</figcaption>" if @caption
|
||||
source += "</figure>"
|
||||
source
|
||||
end
|
||||
end
|
||||
end
|
||||
Liquid::Template.register_tag('image', Jekyll::ImageTag)
|
||||
|
||||
is written as this Hugo shortcode:
|
||||
|
||||
<!-- image -->
|
||||
<figure {{ with .Get "class" }}class="{{.}}"{{ end }}>
|
||||
{{ with .Get "link"}}<a href="{{.}}">{{ end }}
|
||||
<img src="{{ .Get "src" }}" {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt"}}{{.}}{{else}}{{ .Get "caption" }}{{ end }}"{{ end }} />
|
||||
{{ if .Get "link"}}</a>{{ end }}
|
||||
{{ if or (or (.Get "title") (.Get "caption")) (.Get "attr")}}
|
||||
<figcaption>{{ if isset .Params "title" }}
|
||||
{{ .Get "title" }}{{ end }}
|
||||
{{ if or (.Get "caption") (.Get "attr")}}<p>
|
||||
{{ .Get "caption" }}
|
||||
{{ with .Get "attrlink"}}<a href="{{.}}"> {{ end }}
|
||||
{{ .Get "attr" }}
|
||||
{{ if .Get "attrlink"}}</a> {{ end }}
|
||||
</p> {{ end }}
|
||||
</figcaption>
|
||||
{{ end }}
|
||||
</figure>
|
||||
<!-- image -->
|
||||
|
||||
### Usage
|
||||
I simply changed:
|
||||
|
||||
{% image full http://farm5.staticflickr.com/4136/4829260124_57712e570a_o_d.jpg "One of my favorite touristy-type photos. I secretly waited for the good light while we were "having fun" and took this. Only regret: a stupid pole in the top-left corner of the frame I had to clumsily get rid of at post-processing." ->http://www.flickr.com/photos/alexnormand/4829260124/in/set-72157624547713078/ %}
|
||||
|
||||
to this (this example uses a slightly extended version named `fig`, different than the built-in `figure`):
|
||||
|
||||
{{% fig class="full" src="http://farm5.staticflickr.com/4136/4829260124_57712e570a_o_d.jpg" title="One of my favorite touristy-type photos. I secretly waited for the good light while we were having fun and took this. Only regret: a stupid pole in the top-left corner of the frame I had to clumsily get rid of at post-processing." link="http://www.flickr.com/photos/alexnormand/4829260124/in/set-72157624547713078/" %}}
|
||||
|
||||
As a bonus, the shortcode named parameters are, arguably, more readable.
|
||||
|
||||
## Finishing touches
|
||||
### Fix content
|
||||
Depending on the amount of customization that was done with each post with Jekyll, this step will require more or less effort. There are no hard and fast rules here except that `hugo server --watch` is your friend. Test your changes and fix errors as needed.
|
||||
|
||||
### Clean up
|
||||
You'll want to remove the Jekyll configuration at this point. If you have anything else that isn't used, delete it.
|
||||
|
||||
## A pratical example in a diff
|
||||
[Hey, it's alex](http://heyitsalex.net) was migrated in less than a _father-with-kids day_ from Jekyll to Hugo. You can see all the changes (and screw-ups) by looking at this [diff](https://github.com/alexandre-normand/alexandre-normand/compare/869d69435bd2665c3fbf5b5c78d4c22759d7613a...b7f6605b1265e83b4b81495423294208cc74d610).
|
||||
@@ -0,0 +1,3 @@
|
||||
{{ template "partials/header.html" . }}
|
||||
{{ .Content }}
|
||||
{{ template "partials/footer.html" . }}
|
||||
@@ -1,12 +0,0 @@
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<footer id="footer">
|
||||
<p class="pull-right"><a href="#top">Back to top</a></p>
|
||||
Made by <a href="http://spf13.com">Steve Francia</a>.<br>
|
||||
Code licensed under the <a href="https://github.com/spf13/hugo/blob/master/LICENSE.md">Simple Public License 2.0</a>.<br>
|
||||
</footer>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,20 +0,0 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ .Title }}</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
|
||||
{{ template "chrome/includes.html" . }}
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar"></div>
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<div class="span3">
|
||||
<div class="well" style="background-color: #222; color: #ccc;">
|
||||
<h1>Hugo</h1>
|
||||
<p>A Fast and Flexible Static Site Generator built with love by <a href="http://spf13.com">spf13</a> in GO</p>
|
||||
</div>
|
||||
{{ template "chrome/menu.html" . }}
|
||||
</div>
|
||||
<div class="span9">
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user