mirror of
https://github.com/gohugoio/hugo.git
synced 2026-08-30 18:22:37 +00:00
Compare commits
821 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e797a94d97 | |||
| 21cf464c1f | |||
| fb5cac704e | |||
| 63311a14d2 | |||
| 0f8f51414d | |||
| 39408925fd | |||
| 00d632153a | |||
| f1da5a15a3 | |||
| d5ab7f087d | |||
| 55dd533bf7 | |||
| b82cd82f11 | |||
| 204c3a9e32 | |||
| fe901b8119 | |||
| b39689393c | |||
| bef5048580 | |||
| 49a104309d | |||
| 5be0448635 | |||
| 1f55cb767d | |||
| 8aaec644a9 | |||
| 55c53ae9be | |||
| e28d9aa42c | |||
| 46b4607828 | |||
| 2c2ce33a39 | |||
| adc0572d29 | |||
| 0907a5c1c2 | |||
| 3d9c4f513b | |||
| 250ebc1db5 | |||
| b37d959408 | |||
| 4e00bb7fdd | |||
| fdcfccedcb | |||
| 213ea74929 | |||
| 08a10e5d14 | |||
| 9fa71c945e | |||
| d25d89e653 | |||
| 8969701967 | |||
| 69d92dc49c | |||
| d74452cfe8 | |||
| 978951cf52 | |||
| 4aff2b6e74 | |||
| 2342df4d2d | |||
| 828427ef52 | |||
| ce624cc7d3 | |||
| 8930e259d7 | |||
| 710300cb76 | |||
| 93cab620d7 | |||
| 19de4476d8 | |||
| 37e378773f | |||
| b5b41c4468 | |||
| bde807bd1e | |||
| 612f6e3afe | |||
| 50d11138f3 | |||
| e0c2e79820 | |||
| 87203139c3 | |||
| a91c2705c7 | |||
| 99412bfe45 | |||
| 421a46947a | |||
| 0a40cb43ea | |||
| d460159a5f | |||
| 8b49c3a175 | |||
| bcd32f1086 | |||
| 62fe640d09 | |||
| fbb78b89df | |||
| 6c560288a6 | |||
| 89b85aede1 | |||
| 4113693ac1 | |||
| f41f728222 | |||
| 8ddc7a5cde | |||
| f63ee6567d | |||
| 1a965e5d2f | |||
| baa414ae41 | |||
| cdf32f08c7 | |||
| 98e333b35c | |||
| a00962134a | |||
| a119ef693f | |||
| 1f9e8dcc60 | |||
| ebd636e4d5 | |||
| 4d1989d59c | |||
| a59525b05b | |||
| 3954160a21 | |||
| 93c5774dd7 | |||
| 77d2fe7866 | |||
| 405c2f6899 | |||
| 58d4c25e50 | |||
| 38661c17bb | |||
| 42fbded105 | |||
| 10287263f5 | |||
| 27e88154af | |||
| f1c29b017b | |||
| 93b3b13867 | |||
| e92ce83d5e | |||
| 4c427f6aaa | |||
| e682fcc622 | |||
| b6ea492b7a | |||
| 6e2f2dd8d3 | |||
| 94b5be67fc | |||
| c7646551be | |||
| af72db806f | |||
| e951d65771 | |||
| 2bcbf10400 | |||
| 1e4d082cf5 | |||
| 1d70aa9826 | |||
| 6fc7337aac | |||
| ddaf694183 | |||
| a28fbca6dc | |||
| 544f0a6394 | |||
| 5794a265b4 | |||
| ebf677a583 | |||
| 58d9cbd31b | |||
| 7d39990497 | |||
| 9b2028626e | |||
| c99761555c | |||
| 9b080dc625 | |||
| 231c0a7e09 | |||
| 5575ed4469 | |||
| 42f4ce15a9 | |||
| cff2f31334 | |||
| f9e41f6497 | |||
| 8f2ab5f498 | |||
| cce49997a4 | |||
| 3dd949d956 | |||
| a40d1f6ed2 | |||
| 635b3bb4eb | |||
| 08c0de5cc3 | |||
| 1cf2f3dc4f | |||
| 5f095c27ea | |||
| f604076de1 | |||
| f69df916df | |||
| 690b0f8ff5 | |||
| e2b067f050 | |||
| 0e2260421e | |||
| 4714085a10 | |||
| 55f90a3a0d | |||
| ee5aa84f2a | |||
| 4a3463463f | |||
| b958c0c109 | |||
| fc77b6303c | |||
| a432c90aee | |||
| 9aee8ace4e | |||
| 744dccbea4 | |||
| 8a49c0b3b8 | |||
| a3bf118eaa | |||
| 6561557367 | |||
| 0ab23eb5a8 | |||
| eefa0703cb | |||
| c5373efcf0 | |||
| 8f95172c7a | |||
| 4b637ac041 | |||
| de7c32a1a8 | |||
| 154e18ddb9 | |||
| 565a78b110 | |||
| 355736ec35 | |||
| 93a447c5dd | |||
| eaf75a18ec | |||
| 8d0917af0a | |||
| 718c0e1414 | |||
| d6957c192d | |||
| a695202ff5 | |||
| fea4fd86a3 | |||
| 656f818867 | |||
| f0f69d03c5 | |||
| 8fbec59930 | |||
| e55399f50b | |||
| 5ad2f17693 | |||
| 162d3a586d | |||
| fd5109b6d8 | |||
| 88d8111093 | |||
| 4ac60e4ca2 | |||
| b332d93e39 | |||
| b096a10fe9 | |||
| 24be139cb7 | |||
| 3e0f1ad7f5 | |||
| 0bd0593a77 | |||
| c6e4aff1ce | |||
| c0f491ab6c | |||
| 67746f36dd | |||
| 7f6430d84d | |||
| 0e87b18b66 | |||
| e98f885b8a | |||
| 6498d73c08 | |||
| b5b6e81c02 | |||
| 90d3fbf1da | |||
| 5f3ad1c319 | |||
| 8cd3ea565a | |||
| 7935541087 | |||
| d6818f2381 | |||
| 592e055f12 | |||
| ab692e73de | |||
| 7cdc244a72 | |||
| b5e32eb609 | |||
| 66ec6305f6 | |||
| 1cf29200b4 | |||
| 8ccee6717c | |||
| 86a97dbd18 | |||
| 5e2e62d97f | |||
| 8ac1fcd0ce | |||
| 0ed3beec80 | |||
| 077005e514 | |||
| efc0e05c4e | |||
| 6d2ea0f7d7 | |||
| 45c7452668 | |||
| e765b43e2b | |||
| 3b67759495 | |||
| 5fad8a9d06 | |||
| 9ec00725b7 | |||
| cfd3af8e69 | |||
| 4c6fec56f1 | |||
| dac0d4a69d | |||
| 03ec2b3397 | |||
| 18f5f3c14c | |||
| 308678aa7f | |||
| e73a35dea5 | |||
| c9731b2c2a | |||
| 9ebbf1b054 | |||
| 2874fc75ce | |||
| 9e69a92e85 | |||
| 9a8b65d8d7 | |||
| 7b2e1b0be9 | |||
| e975a07fb0 | |||
| 7ad721fd78 | |||
| 5714531f34 | |||
| 3c405f5172 | |||
| 9580872459 | |||
| af99a59021 | |||
| 260b55ea56 | |||
| 8f09e5f6bc | |||
| c4a1165587 | |||
| e77bb13c20 | |||
| e6e1aca3f4 | |||
| f3b4a0e99e | |||
| 0dd6890ed5 | |||
| 6650fae7ad | |||
| b31da911b5 | |||
| 1425587193 | |||
| a883948c4f | |||
| bc36d468ab | |||
| 7da1b65968 | |||
| 868f89d5c6 | |||
| 04d80e6e87 | |||
| 0802f79e66 | |||
| 10ff2f31a6 | |||
| f8d555cca5 | |||
| c9aee467d3 | |||
| d6e8b86f66 | |||
| a098081c4a | |||
| 5d7eeeadf0 | |||
| 8b5b558bb5 | |||
| 27610ddd01 | |||
| 6b29bccfee | |||
| 28fdd71c29 | |||
| fe8462b205 | |||
| d122260de7 | |||
| a037b855dd | |||
| 7eb71ee064 | |||
| c97dae40d9 | |||
| 0aeadfd02d | |||
| 5c5efa03d2 | |||
| 73c1c7b69d | |||
| f911b107ef | |||
| 05949c9038 | |||
| d5036c3ab5 | |||
| af1f9ecf91 | |||
| 42a4f6f9cb | |||
| 79b34c2f1e | |||
| 3c6b16d5a2 | |||
| 87b3cd4655 | |||
| 5989c4d464 | |||
| af55ec7661 | |||
| f2fbf0b2ea | |||
| 4923273688 | |||
| 930a3df1b7 | |||
| e49a2b83ad | |||
| 9a0aa5fdbe | |||
| 0aaf3c56a5 | |||
| ee4a33b14f | |||
| 09c88e84d1 | |||
| 24c1770288 | |||
| b7ed67d425 | |||
| 3cd97951f1 | |||
| ee75e2999b | |||
| 15b64d51da | |||
| 148fedd227 | |||
| ec01c3a7f0 | |||
| 5761b93c96 | |||
| 87188496fb | |||
| 0c4701f0ef | |||
| d851d6b98f | |||
| 8bcc08e3b0 | |||
| dbb83f925a | |||
| 4aaed87dd9 | |||
| c7dbee2321 | |||
| 29d3778ba1 | |||
| 1b2be5e878 | |||
| baa29f6534 | |||
| c7c6b47ba8 | |||
| 08fa2b1124 | |||
| 6178238a0b | |||
| df95383914 | |||
| a49bf8707b | |||
| d76e5f36b4 | |||
| ad8cea87f3 | |||
| 4c2abe0015 | |||
| 6bf010fed4 | |||
| c8fff9501d | |||
| 3ec5fc3504 | |||
| f091fc23ed | |||
| 03122e51fa | |||
| e5200ddaa4 | |||
| a8244658f7 | |||
| 50c64415aa | |||
| 348834d017 | |||
| 254cd89c8e | |||
| 10de077164 | |||
| 3bb52bf7bf | |||
| d3d2c63dd9 | |||
| c4989c39f1 | |||
| 9262c5b32f | |||
| 2bea9d0ca1 | |||
| 1b92c8b713 | |||
| 17b21e0af1 | |||
| 7f68e3199e | |||
| 2ed75f3462 | |||
| 9d9ec1ddd9 | |||
| 9f0b02b898 | |||
| a159feffb2 | |||
| d07ff9d221 | |||
| f1b1df5058 | |||
| 559b4007f7 | |||
| 5e191ccf4c | |||
| d3cd68e656 | |||
| 68f4cd829e | |||
| 3fa7bc9c53 | |||
| 3518de1057 | |||
| 7c48ad57a9 | |||
| 0e75f6e7b1 | |||
| 6eddb3e587 | |||
| 6e03c96a20 | |||
| 4382a8a6a0 | |||
| 9dfb9c1445 | |||
| c2ffdfab63 | |||
| a99661031a | |||
| 491d406881 | |||
| d8923eb676 | |||
| d6093aba4d | |||
| 638cc806d6 | |||
| ec3dc32511 | |||
| b156ef2712 | |||
| 042f8fca03 | |||
| 431d597442 | |||
| ede452d34e | |||
| 62efcdfed4 | |||
| 4b9493cb03 | |||
| 5d0748ce51 | |||
| 63e2a46f63 | |||
| 2f2ea42c09 | |||
| 5f443bd45b | |||
| f039e3be9e | |||
| ddc8cc0082 | |||
| 0e44f75ebd | |||
| 690961ba02 | |||
| fe41bd61bb | |||
| 48120ccfd2 | |||
| 560ed6e686 | |||
| 45b9d7223a | |||
| a2a8a651f7 | |||
| 4bfa189031 | |||
| a2ec372a03 | |||
| c950699907 | |||
| 6c5ef71368 | |||
| c7b8c45d12 | |||
| e52e2a70e5 | |||
| ea165bf9e7 | |||
| 22c89dcb6c | |||
| d0e2a1fa14 | |||
| 5a94e4cfb9 | |||
| f4779b25bc | |||
| 8203fc5923 | |||
| 7acec3c639 | |||
| 74ea81b885 | |||
| 577522bd45 | |||
| 23f5b9ac4e | |||
| 1279ca201a | |||
| 9671162a22 | |||
| 3669015f56 | |||
| a0e3ff1645 | |||
| cc15864744 | |||
| b7a672fd22 | |||
| 972649c684 | |||
| afb3334ed8 | |||
| c266cd2d86 | |||
| 0b91053c9f | |||
| 396276aafa | |||
| 072cd00305 | |||
| 0a99168220 | |||
| 28198ce982 | |||
| a1741f192c | |||
| c9c889c198 | |||
| eb572c8a18 | |||
| 8d5132229f | |||
| 0eb76b0863 | |||
| a8a8249f67 | |||
| 3631fd2f0e | |||
| e37e3dcc04 | |||
| 6dd57f7a11 | |||
| eaabecf586 | |||
| e21fdbae8d | |||
| e9921ae4b2 | |||
| 950d1aa1b3 | |||
| c1425a166d | |||
| 831bfd36aa | |||
| 4d679627ec | |||
| e117b1b2c7 | |||
| 9e6b5eb98e | |||
| 0f109faefb | |||
| 6278393540 | |||
| 87acf292e5 | |||
| 13972d6c83 | |||
| 91968f3b1f | |||
| 7934db9169 | |||
| 9e52477d94 | |||
| c7535b9c25 | |||
| eb27c47fc5 | |||
| df1ff57d1a | |||
| 2cbdd65330 | |||
| 4e77c8717b | |||
| d3fb196067 | |||
| 2320c5682c | |||
| 41857d036d | |||
| 75d855c086 | |||
| 86e8dd62f0 | |||
| a3af4fe46e | |||
| 2a6b26a7a5 | |||
| fe9fd0acf4 | |||
| 7e0fa13faa | |||
| 3d4e99ed50 | |||
| 02b120d1bd | |||
| 6809ea1e7c | |||
| a0b3d9db16 | |||
| 2ea242d5fe | |||
| 99fbc75e7a | |||
| 9416fdd334 | |||
| b2e3748a4e | |||
| 6d2281c8ea | |||
| e096917f87 | |||
| 13ca0b4c95 | |||
| 3dade5de09 | |||
| b360f9b30e | |||
| bdc02edfa8 | |||
| 4493e8ed9f | |||
| 07ab7ae3d2 | |||
| ed847ed93d | |||
| 10c13f5d79 | |||
| ade207635e | |||
| 0946630715 | |||
| 9421690281 | |||
| d3abb93cc7 | |||
| b7aa230458 | |||
| edfb9d5565 | |||
| 53d07fb409 | |||
| 04a4a193a9 | |||
| 4b3ca38b2e | |||
| 77cbe4d60b | |||
| c507e2717d | |||
| 93ca7c9e95 | |||
| e34af6ee30 | |||
| 691156c5ba | |||
| a988d3cf36 | |||
| 2ded3bf30f | |||
| 234273a5b5 | |||
| 5cc8b58907 | |||
| 298ebc37c2 | |||
| 2618cfbeaa | |||
| 25bfa7e12f | |||
| 7a5cc3cfd7 | |||
| 962443ade8 | |||
| a89fb86cdf | |||
| f404603340 | |||
| d11f37d97c | |||
| 3e5ad4aeeb | |||
| 9c97949513 | |||
| 7fd88fb199 | |||
| faba90ab96 | |||
| 2af2ff3c1f | |||
| dae6a4539f | |||
| 19aff029b1 | |||
| c71e1b106e | |||
| 0ada405912 | |||
| c2f692266d | |||
| 24512fa82b | |||
| 7241253c22 | |||
| 1e79900860 | |||
| 72cffed89b | |||
| feeb93d4f1 | |||
| 95ad3ad2fa | |||
| 91c569c7e5 | |||
| 99fd7c684f | |||
| d949c34af1 | |||
| 7dc9458167 | |||
| 940c5d8bae | |||
| 3ac1b9fe33 | |||
| dc61d3b6b3 | |||
| 3818d6967a | |||
| 85c7578313 | |||
| 92ba7219dc | |||
| 1d7b960614 | |||
| db33a33e61 | |||
| d6000a208c | |||
| 4ea4359ac1 | |||
| bc06135c96 | |||
| 45e3ed517a | |||
| 24a286791f | |||
| 56c5eadc38 | |||
| 3d058a936f | |||
| 3286b24fce | |||
| 2989c38245 | |||
| 9c19ef0f87 | |||
| 9f20e648b9 | |||
| c60c41e051 | |||
| 01ee525f47 | |||
| 1b46d2cfee | |||
| fff6617c69 | |||
| 0dad69325d | |||
| 001dd01ee2 | |||
| e856f24129 | |||
| 49a840be83 | |||
| e3e5600b81 | |||
| 19b6fdf2b1 | |||
| b8057b4989 | |||
| 2127203ae3 | |||
| cb63e87f8d | |||
| c344b1901f | |||
| 2ac9817eae | |||
| 4352156a27 | |||
| 52976da0ec | |||
| 6fb4f048e1 | |||
| be39ae5e11 | |||
| 2ece1b325b | |||
| 433c03616b | |||
| 0d330b0d5d | |||
| 6a51216c6a | |||
| 5834efd5fd | |||
| f79877cbb7 | |||
| a60ec06383 | |||
| 09a0af94f5 | |||
| 6e0f326b9d | |||
| 695be00c07 | |||
| cabc6b3186 | |||
| 707d3cf137 | |||
| 7d072fbbe6 | |||
| 02d6f5320f | |||
| 73c1e271f7 | |||
| 6374d82b82 | |||
| e9e4fd90e4 | |||
| a18b9e72c4 | |||
| 95a473e7ec | |||
| 211d20a3c7 | |||
| 164d0fb6a7 | |||
| 8a63e092fa | |||
| 83b4c40566 | |||
| c22b7ff8d9 | |||
| 8489608012 | |||
| bcb3ef7413 | |||
| 862f09babe | |||
| 6affd31b3e | |||
| 88b5bbd532 | |||
| d1b89f5c7c | |||
| 17f851780c | |||
| e78dd3cd48 | |||
| 7d991ed89c | |||
| 3e4fbbaae4 | |||
| 99e5fc63c2 | |||
| 63d3c4ce25 | |||
| bc060ee1c9 | |||
| b0e86dcde0 | |||
| d055862a41 | |||
| 8b0c3b9b27 | |||
| 34c87421b8 | |||
| 29caaddce6 | |||
| 661d64c46a | |||
| 4e5b4ac504 | |||
| 6b8422bb35 | |||
| f25f837339 | |||
| 441476b6c5 | |||
| ec34ed0520 | |||
| a4fc20a12b | |||
| e7ff094d63 | |||
| b2687ab1f7 | |||
| 4845a13c9e | |||
| 1881f60a16 | |||
| 1eb079543f | |||
| 1e313ced3f | |||
| 8b410347a6 | |||
| 09cc7915ed | |||
| 3d6fdb8ed3 | |||
| 4de808ae7c | |||
| 018813caf6 | |||
| 71aa797b27 | |||
| 6fd4bfcae3 | |||
| 79b2725ac4 | |||
| a3a67163f9 | |||
| 596bbea815 | |||
| 26084ad198 | |||
| fa09e20d9a | |||
| 2f0e81989a | |||
| 9c2ea3691a | |||
| d332aa1606 | |||
| f8190777f2 | |||
| aecabfcd4f | |||
| ef03c6f954 | |||
| e4ebe0d5bf | |||
| 7862de91de | |||
| 83c6806576 | |||
| c7f67dd63c | |||
| b4404a9554 | |||
| b4cbccaaf4 | |||
| e3d48760c9 | |||
| d4b9fa96f9 | |||
| 5b1eee44c6 | |||
| 2236056672 | |||
| 0f6c73cf2e | |||
| 01b8bc1b26 | |||
| 0ba9fb9631 | |||
| ba8a00a6f9 | |||
| 15622c80ee | |||
| 2f026ab3f3 | |||
| 971d1baf13 | |||
| a4b9abf0b3 | |||
| 529574e6f9 | |||
| c87331ae84 | |||
| b2eadd93d3 | |||
| 96018ab98c | |||
| 65d4d96e7f | |||
| b7e800454f | |||
| 20d82a7a1b | |||
| 046320d3f4 | |||
| c38bfda43b | |||
| 1f6e0de361 | |||
| dbb0c1cfc9 | |||
| 001e2bbe8a | |||
| 2c7cbca8b1 | |||
| 68ebf61613 | |||
| 4c72eb12dc | |||
| 65e5959bad | |||
| 139585f84a | |||
| a721fbed1d | |||
| 3739871f1e | |||
| 4360452001 | |||
| f1ed89fec4 | |||
| 0a0db9cd25 | |||
| ff2498ee89 | |||
| a6d584bfb6 | |||
| 1156be3b13 | |||
| e0b278205a | |||
| c06c3234eb | |||
| c8d4114171 | |||
| c33eb93548 | |||
| 174f97a9dd | |||
| 7665dd239e | |||
| 581291dc3b | |||
| 32336e9ec6 | |||
| 75e55cd06f | |||
| e81c06c3f0 | |||
| 647540d0ef | |||
| 700d531a2c | |||
| 713f577a27 | |||
| dec1706ae0 | |||
| 1f130fd692 | |||
| 120f6b0cf2 | |||
| e1da7cb320 | |||
| a5b3b07657 | |||
| 382582fcda | |||
| 6c0ecc2d28 | |||
| e29f6fe527 | |||
| 0eb5f54d30 | |||
| 976f8f84bf | |||
| aafbd3b4bf | |||
| ae1de7abb1 | |||
| 7e81971b46 | |||
| f776af6c9b | |||
| 0bbdcf24fe | |||
| 32fb1e6fac | |||
| 28031b0897 | |||
| a843d5d3bb | |||
| 99d11386a7 | |||
| 62e9e7e6ba | |||
| 524eb16686 | |||
| c8d3124dde | |||
| 9347084d61 | |||
| 9fba2a30a9 | |||
| 96f71141bd | |||
| 487b210fb8 | |||
| c80308e6b3 | |||
| 063b78d2ec | |||
| 88972b0d5b | |||
| 640b8bed21 | |||
| 2d91b17c04 | |||
| 7cb0e34dce | |||
| ecedc85cb7 | |||
| d3d3863c05 | |||
| 7cc637e97a | |||
| 503fb29953 | |||
| 80e453f114 | |||
| 94ea12ebcf | |||
| bde1bfd34a | |||
| ec2d502b4f | |||
| 698b994f71 | |||
| c175407fa4 | |||
| 3ff25b37a3 | |||
| 75c38071d8 | |||
| f8bda16e15 | |||
| 3737c9bcb3 | |||
| c2f3cb2d7a | |||
| 734b6508a1 | |||
| e371ac0b6f | |||
| e7d0bc8a74 | |||
| 239c75c7f8 | |||
| 1eb3c4a8e7 | |||
| 3031793431 | |||
| 3b42640e3f | |||
| 65f803e1fa | |||
| 29fda0e683 | |||
| 7b8a09d5f9 | |||
| ce5f41ffb6 | |||
| a49f838cd0 | |||
| 950034db5c | |||
| bb36d57be5 | |||
| 4d4c7791ac | |||
| 85a2d81e3c | |||
| 4b4ab47553 | |||
| 52e2fd27f8 | |||
| b619eb5ad1 | |||
| 07eb3a50c7 | |||
| d4830fc4fd | |||
| 72156e403c | |||
| 8dace9ad6d | |||
| f4afd13386 | |||
| ec44ad5c0b | |||
| 774f13bd5d | |||
| 0cd0adda20 | |||
| 3a86aba517 | |||
| c9be931ebe | |||
| e8380e612f | |||
| 186db7cd7a | |||
| cda3b36fe2 | |||
| b5bc74ca46 | |||
| 01cfcce6c0 | |||
| 6a3d1037b3 | |||
| 342b6fe8a5 | |||
| 4ad39445ef | |||
| f5b2645566 | |||
| 301e4c7e78 | |||
| 0406be3d54 | |||
| 89e3125664 | |||
| c936b6c89a | |||
| c859810b37 | |||
| a2cc2e75a6 | |||
| 333bb05512 | |||
| 5859c691ec | |||
| f21e2f25c9 | |||
| d9f54a13c1 | |||
| 165edc7f0a | |||
| a10b2cd372 | |||
| dffd7da07c | |||
| 6427fba90b | |||
| db86f48082 | |||
| 1992b356b0 | |||
| d0d24b4337 | |||
| f0af80753c | |||
| ddf2a3407a | |||
| 67df33d83f | |||
| 58f31d2769 | |||
| faa64abdc2 | |||
| e6f2426ef0 | |||
| 3a5b702712 | |||
| 6a7f989d7b | |||
| 7f4d90250f | |||
| df943595a7 | |||
| 40b1b8f703 | |||
| 4d6cd3cb2a | |||
| 2ea22a422c | |||
| 0456f950a3 | |||
| 35dda2d938 | |||
| 9ee2538e0b | |||
| 2e0e77bed1 | |||
| 10a773cde7 | |||
| 886754738b | |||
| 8b43d39ef3 | |||
| 3ce904669a | |||
| 588256776e | |||
| 794589fbfd | |||
| 4e0c71a6eb | |||
| 8fa871a05f | |||
| 766c82a6bb | |||
| 9f9b93af2c | |||
| 998034faad | |||
| eb00c621e0 | |||
| 8ddd95e361 | |||
| 474eb454df | |||
| d2bc64bee3 | |||
| 5355ddf621 | |||
| bfe9b8708a | |||
| 8a63ebcb3d | |||
| 9d0b1320e0 | |||
| 71422a7dee | |||
| df7b8b5c38 | |||
| b3bcd78f4f | |||
| 8d50925820 | |||
| 8b8a1e0a4c | |||
| 0206be0275 | |||
| 7b0f92db0b | |||
| 1f0877947e | |||
| a7e2a04d5b | |||
| c2bf748ec5 | |||
| 56512e816f | |||
| 3616fb629b | |||
| cf5d2e2753 | |||
| 1c214fcb7c | |||
| 7cdd230e16 | |||
| a22294aa7c | |||
| 6195d8f79b | |||
| 1adfaf4972 | |||
| d54d6633ad |
@@ -11,3 +11,8 @@ cover.out
|
||||
.DS_Store
|
||||
*~
|
||||
vendor/*/
|
||||
*.bench
|
||||
coverage*.out
|
||||
|
||||
GoBuilds
|
||||
dist
|
||||
|
||||
+6
-7
@@ -1,8 +1,8 @@
|
||||
language: go
|
||||
sudo: required
|
||||
go:
|
||||
- 1.6.3
|
||||
- 1.7.1
|
||||
- 1.7.6
|
||||
- 1.8.3
|
||||
- tip
|
||||
os:
|
||||
- linux
|
||||
@@ -12,13 +12,12 @@ matrix:
|
||||
- go: tip
|
||||
fast_finish: true
|
||||
install:
|
||||
- make govendor
|
||||
- make vendor
|
||||
script:
|
||||
- make check
|
||||
- go build -race
|
||||
- make hugo-race check
|
||||
- ./hugo -s docs/
|
||||
- ./hugo --renderToMemory -s docs/
|
||||
before_install:
|
||||
# gem install must be run with sudo on OSX
|
||||
- sudo gem install asciidoctor | gem install asciidoctor
|
||||
# gem install must be run with sudo on OSX
|
||||
- sudo gem install asciidoctor | gem install asciidoctor
|
||||
- sudo pip install docutils
|
||||
|
||||
+39
-26
@@ -5,9 +5,7 @@ organization, tutorials, blog posts, bug reports, issues, feature requests,
|
||||
feature implementations, pull requests, answering questions on the forum,
|
||||
helping to manage issues, etc.
|
||||
|
||||
The Hugo community and maintainers are very active and helpful, and the project benefits greatly from this activity. We created a [step by step guide](https://gohugo.io/tutorials/how-to-contribute-to-hugo/) if you're unfamiliar with GitHub or contributing to open source projects in general.
|
||||
|
||||
[](https://waffle.io/spf13/hugo/metrics)
|
||||
The Hugo community and maintainers are [very active](https://github.com/spf13/hugo/pulse/monthly) and helpful, and the project benefits greatly from this activity. We created a [step by step guide](https://gohugo.io/tutorials/how-to-contribute-to-hugo/) if you're unfamiliar with GitHub or contributing to open source projects in general.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
@@ -16,19 +14,21 @@ The Hugo community and maintainers are very active and helpful, and the project
|
||||
* [Submitting Patches](#submitting-patches)
|
||||
* [Code Contribution Guidelines](#code-contribution-guidelines)
|
||||
* [Git Commit Message Guidelines](#git-commit-message-guidelines)
|
||||
* [Vendored Dependencies](#vendored-dependencies)
|
||||
* [Fetching the Sources From GitHub](#fetching-the-sources-from-github)
|
||||
* [Using Git Remotes](#using-git-remotes)
|
||||
* [Build Hugo with Your Changes](#build-hugo-with-your-changes)
|
||||
* [Add Compile Information to Hugo](#add-compile-information-to-hugo)
|
||||
* [Updating the Hugo Sources](#updating-the-hugo-sources)
|
||||
|
||||
## Asking Support Questions
|
||||
|
||||
We have an active [discussion forum](http://discuss.gohugo.io) where users and developers can ask questions.
|
||||
Please don't use the Github issue tracker to ask questions.
|
||||
Please don't use the GitHub issue tracker to ask questions.
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
If you believe you have found a defect in Hugo or its documentation, use
|
||||
the Github [issue tracker](https://github.com/spf13/hugo/issues) to report the problem to the Hugo maintainers.
|
||||
the GitHub [issue tracker](https://github.com/spf13/hugo/issues) to report the problem to the Hugo maintainers.
|
||||
If you're not sure if it's a bug or not, start by asking in the [discussion forum](http://discuss.gohugo.io).
|
||||
When reporting the issue, please provide the version of Hugo in use (`hugo version`) and your operating system.
|
||||
|
||||
@@ -53,7 +53,7 @@ To make the contribution process as seamless as possible, we ask for the followi
|
||||
* Run `go fmt`.
|
||||
* Add documentation if you are adding new features or changing functionality. The docs site lives in `/docs`.
|
||||
* Squash your commits into a single commit. `git rebase -i`. It’s okay to force update your pull request with `git push -f`.
|
||||
* Make sure `go test ./...` passes, and `go build` completes. [Travis CI](https://travis-ci.org/spf13/hugo) (Linux and OS X) and [AppVeyor](https://ci.appveyor.com/project/spf13/hugo/branch/master) (Windows) will catch most things that are missing.
|
||||
* Ensure that `make check` succeeds. [Travis CI](https://travis-ci.org/spf13/hugo) (Linux and macOS) and [AppVeyor](https://ci.appveyor.com/project/spf13/hugo/branch/master) (Windows) will fail the build if `make check` fails.
|
||||
* Follow the **Git Commit Message Guidelines** below.
|
||||
|
||||
### Git Commit Message Guidelines
|
||||
@@ -61,12 +61,16 @@ To make the contribution process as seamless as possible, we ask for the followi
|
||||
This [blog article](http://chris.beams.io/posts/git-commit/) is a good resource for learning how to write good commit messages,
|
||||
the most important part being that each commit message should have a title/subject in imperative mood starting with a capital letter and no trailing period:
|
||||
*"Return error on wrong use of the Paginator"*, **NOT** *"returning some error."*
|
||||
|
||||
Also, if your commit references one or more GitHub issues, always end your commit message body with *See #1234* or *Fixes #1234*.
|
||||
Replace *1234* with the GitHub issue ID. The last example will close the issue when the commit is merged into *master*.
|
||||
|
||||
Sometimes it makes sense to prefix the commit message with the packagename (or docs folder) all lowercased ending with a colon.
|
||||
That is fine, but the rest of the rules above apply.
|
||||
So it is "tpl: Add emojify template func", not "tpl: add emojify template func.", and "docs: Document emoji", not "doc: document emoji."
|
||||
|
||||
Please consider to use a short and descriptive branch name, e.g. **NOT** "patch-1". It's very common but creates a naming conflict each time when a submission is pulled for a review.
|
||||
|
||||
An example:
|
||||
|
||||
```text
|
||||
@@ -80,22 +84,31 @@ new default function more useful for Hugo users.
|
||||
Fixes #1949
|
||||
```
|
||||
|
||||
### Vendored Dependencies
|
||||
|
||||
Hugo uses [govendor](https://github.com/kardianos/govendor) to vendor dependencies, but we don't commit the vendored packages themselves to the Hugo git repository.
|
||||
Therefore, a simple `go get` is not supported since `go get` is not vendor-aware.
|
||||
You **must use govendor** to fetch and manage Hugo's dependencies.
|
||||
|
||||
### Fetch the Sources From GitHub
|
||||
|
||||
```
|
||||
go get github.com/kardianos/govendor
|
||||
govendor get github.com/spf13/hugo
|
||||
```
|
||||
|
||||
### Using Git Remotes
|
||||
|
||||
Due to the way Go handles package imports, the best approach for working on a
|
||||
Hugo fork is to use Git Remotes. Here's a simple walk-through for getting
|
||||
started:
|
||||
|
||||
1. Get the latest Hugo sources:
|
||||
|
||||
```
|
||||
go get -u -t github.com/spf13/hugo/...
|
||||
```
|
||||
1. Fetch the Hugo sources as described above.
|
||||
|
||||
1. Change to the Hugo source directory:
|
||||
|
||||
```
|
||||
cd $GOPATH/src/github.com/spf13/hugo
|
||||
cd $HOME/go/src/github.com/spf13/hugo
|
||||
```
|
||||
|
||||
1. Create a new branch for your changes (the branch name is arbitrary):
|
||||
@@ -110,7 +123,7 @@ started:
|
||||
git commit -a -v
|
||||
```
|
||||
|
||||
1. Fork Hugo in Github.
|
||||
1. Fork Hugo in GitHub.
|
||||
|
||||
1. Add your fork as a new remote (the remote name, "fork" in this example, is arbitrary):
|
||||
|
||||
@@ -129,20 +142,20 @@ started:
|
||||
### Build Hugo with Your Changes
|
||||
|
||||
```bash
|
||||
cd $GOPATH/src/github.com/spf13/hugo
|
||||
go build
|
||||
mv hugo /usr/local/bin/
|
||||
cd $HOME/go/src/github.com/spf13/hugo
|
||||
make hugo
|
||||
# or to install in $HOME/go/bin:
|
||||
make install
|
||||
```
|
||||
|
||||
### Add Compile Information to Hugo
|
||||
### Updating the Hugo Sources
|
||||
|
||||
To add compile information to Hugo, replace the `go build` command with the following *(replace `/path/to/hugo` with the actual path)*:
|
||||
If you want to stay in sync with the Hugo repository, you can easily pull down
|
||||
the source changes, but you'll need to keep the vendored packages up-to-date as
|
||||
well.
|
||||
|
||||
go build -ldflags "-X /path/to/hugo/hugolib.CommitHash=`git rev-parse --short HEAD 2>/dev/null` -X github.com/spf13/hugo/hugolib.BuildDate=`date +%FT%T%z`"
|
||||
|
||||
This will result in `hugo version` output that looks similar to:
|
||||
|
||||
Hugo Static Site Generator v0.13-DEV-8042E77 buildDate: 2014-12-25T03:25:57-07:00
|
||||
|
||||
Alternatively, just run `make` — all the “magic” above is already in the `Makefile`. :wink:
|
||||
```
|
||||
git pull
|
||||
make vendor
|
||||
```
|
||||
|
||||
|
||||
+8
-42
@@ -1,49 +1,15 @@
|
||||
FROM golang:1.6.2
|
||||
MAINTAINER Sven Dowideit <SvenDowideit@home.org.au>
|
||||
FROM golang:1.8-alpine
|
||||
|
||||
ENV GOPATH /go
|
||||
ENV USER root
|
||||
|
||||
RUN apk update && apk add git make
|
||||
|
||||
# pre-install known dependencies before the source, so we don't redownload them whenever the source changes
|
||||
RUN go get github.com/stretchr/testify/assert \
|
||||
&& go get github.com/kyokomi/emoji \
|
||||
&& go get github.com/bep/inflect \
|
||||
&& go get github.com/BurntSushi/toml \
|
||||
&& go get github.com/PuerkitoBio/purell \
|
||||
&& go get github.com/PuerkitoBio/urlesc \
|
||||
&& go get github.com/dchest/cssmin \
|
||||
&& go get github.com/eknkc/amber \
|
||||
&& go get github.com/gorilla/websocket \
|
||||
&& go get github.com/kardianos/osext \
|
||||
&& go get github.com/miekg/mmark \
|
||||
&& go get github.com/mitchellh/mapstructure \
|
||||
&& go get github.com/russross/blackfriday \
|
||||
&& go get github.com/shurcooL/sanitized_anchor_name \
|
||||
&& go get github.com/spf13/afero \
|
||||
&& go get github.com/spf13/cast \
|
||||
&& go get github.com/spf13/jwalterweatherman \
|
||||
&& go get github.com/spf13/cobra \
|
||||
&& go get github.com/cpuguy83/go-md2man \
|
||||
&& go get github.com/inconshreveable/mousetrap \
|
||||
&& go get github.com/spf13/pflag \
|
||||
&& go get github.com/spf13/fsync \
|
||||
&& go get github.com/spf13/viper \
|
||||
&& go get github.com/kr/pretty \
|
||||
&& go get github.com/kr/text \
|
||||
&& go get github.com/magiconair/properties \
|
||||
&& go get golang.org/x/text/transform \
|
||||
&& go get golang.org/x/text/unicode/norm \
|
||||
&& go get github.com/yosssi/ace \
|
||||
&& go get github.com/spf13/nitro \
|
||||
&& go get github.com/fortytw2/leaktest \
|
||||
&& go get github.com/fsnotify/fsnotify
|
||||
RUN go get github.com/kardianos/govendor \
|
||||
&& govendor get github.com/spf13/hugo
|
||||
|
||||
COPY . /go/src/github.com/spf13/hugo
|
||||
RUN go get -d -v github.com/spf13/hugo
|
||||
RUN go install github.com/spf13/hugo
|
||||
|
||||
WORKDIR /go/src/github.com/spf13/hugo
|
||||
RUN go get -d -v
|
||||
RUN go build -o hugo main.go
|
||||
RUN go test github.com/spf13/hugo/...
|
||||
COPY . $GOPATH/src/github.com/spf13/hugo
|
||||
|
||||
RUN cd $GOPATH/src/github.com/spf13/hugo \
|
||||
&& make install test
|
||||
|
||||
@@ -1,76 +1,83 @@
|
||||
# A Self-Documenting Makefile: http://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
|
||||
|
||||
# Adds build information from git repo
|
||||
#
|
||||
# as suggested by tatsushid in
|
||||
# https://github.com/spf13/hugo/issues/540
|
||||
PACKAGE = github.com/spf13/hugo
|
||||
COMMIT_HASH = `git rev-parse --short HEAD 2>/dev/null`
|
||||
BUILD_DATE = `date +%FT%T%z`
|
||||
LDFLAGS = -ldflags "-X ${PACKAGE}/hugolib.CommitHash=${COMMIT_HASH} -X ${PACKAGE}/hugolib.BuildDate=${BUILD_DATE}"
|
||||
NOGI_LDFLAGS = -ldflags "-X ${PACKAGE}/hugolib.BuildDate=${BUILD_DATE}"
|
||||
|
||||
COMMIT_HASH=`git rev-parse --short HEAD 2>/dev/null`
|
||||
BUILD_DATE=`date +%FT%T%z`
|
||||
LDFLAGS=-ldflags "-X github.com/spf13/hugo/hugolib.CommitHash=${COMMIT_HASH} -X github.com/spf13/hugo/hugolib.BuildDate=${BUILD_DATE}"
|
||||
.PHONY: vendor docker check fmt lint test test-race vet test-cover-html help
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
all: gitinfo
|
||||
vendor: ## Install govendor and sync Hugo's vendored dependencies
|
||||
go get github.com/kardianos/govendor
|
||||
govendor sync ${PACKAGE}
|
||||
|
||||
install: install-gitinfo
|
||||
hugo: vendor ## Build hugo binary
|
||||
go build ${LDFLAGS} ${PACKAGE}
|
||||
|
||||
help:
|
||||
echo ${COMMIT_HASH}
|
||||
echo ${BUILD_DATE}
|
||||
hugo-race: vendor ## Build hugo binary with race detector enabled
|
||||
go build -race ${LDFLAGS} ${PACKAGE}
|
||||
|
||||
gitinfo:
|
||||
go build ${LDFLAGS} -o hugo main.go
|
||||
install: vendor ## Install hugo binary
|
||||
go install ${LDFLAGS} ${PACKAGE}
|
||||
|
||||
install-gitinfo:
|
||||
go install ${LDFLAGS} ./...
|
||||
hugo-no-gitinfo: LDFLAGS = ${NOGI_LDFLAGS}
|
||||
hugo-no-gitinfo: vendor hugo ## Build hugo without git info
|
||||
|
||||
no-git-info:
|
||||
go build -o hugo main.go
|
||||
|
||||
docker:
|
||||
docker: ## Build hugo Docker container
|
||||
docker build -t hugo .
|
||||
docker rm -f hugo-build || true
|
||||
docker run --name hugo-build hugo ls /go/bin
|
||||
docker cp hugo-build:/go/bin/hugo .
|
||||
docker rm hugo-build
|
||||
|
||||
govendor:
|
||||
go get -u github.com/kardianos/govendor
|
||||
go install github.com/kardianos/govendor
|
||||
govendor get github.com/spf13/hugo
|
||||
govendor: vendor # Deprecated: use "vendor" target
|
||||
get: vendor # Deprecated: use "vendor"
|
||||
gitinfo: hugo # Deprecated: use "hugo" target
|
||||
install-gitinfo: install # Deprecated: use "install" target
|
||||
no-git-info: hugo-no-gitinfo # Deprecated: use "hugo-no-gitinfo" target
|
||||
|
||||
check: fmt vet test test-race
|
||||
check: test-race test386 fmt vet ## Run tests and linters
|
||||
|
||||
cyclo:
|
||||
@for d in `govendor list -no-status +local | sed 's/github.com.spf13.hugo/./'` ; do \
|
||||
if [ "`gocyclo -over 20 $$d | tee /dev/stderr`" ]; then \
|
||||
echo "^ cyclomatic complexity exceeds 20, refactor the code!" && echo && exit 1; \
|
||||
fi \
|
||||
done
|
||||
test386: ## Run tests in 32-bit mode
|
||||
GOARCH=386 govendor test +local
|
||||
|
||||
fmt:
|
||||
test: ## Run tests
|
||||
govendor test +local
|
||||
|
||||
test-race: ## Run tests with race detector
|
||||
govendor test -race +local
|
||||
|
||||
fmt: ## Run gofmt linter
|
||||
@for d in `govendor list -no-status +local | sed 's/github.com.spf13.hugo/./'` ; do \
|
||||
if [ "`gofmt -l $$d/*.go | tee /dev/stderr`" ]; then \
|
||||
echo "^ improperly formatted go files" && echo && exit 1; \
|
||||
fi \
|
||||
done
|
||||
|
||||
lint:
|
||||
lint: ## Run golint linter
|
||||
@for d in `govendor list -no-status +local | sed 's/github.com.spf13.hugo/./'` ; do \
|
||||
if [ "`golint $$d | tee /dev/stderr`" ]; then \
|
||||
echo "^ golint errors!" && echo && exit 1; \
|
||||
fi \
|
||||
done
|
||||
|
||||
get:
|
||||
go get -v -t ./...
|
||||
|
||||
test:
|
||||
govendor test +local
|
||||
|
||||
test-race:
|
||||
govendor test -race +local
|
||||
|
||||
vet:
|
||||
vet: ## Run go vet linter
|
||||
@if [ "`govendor vet +local | tee /dev/stderr`" ]; then \
|
||||
echo "^ go vet errors!" && echo && exit 1; \
|
||||
fi
|
||||
|
||||
test-cover-html: PACKAGES = $(shell govendor list -no-status +local | sed 's/github.com.spf13.hugo/./')
|
||||
test-cover-html: ## Generate test coverage report
|
||||
echo "mode: count" > coverage-all.out
|
||||
$(foreach pkg,$(PACKAGES),\
|
||||
govendor test -coverprofile=coverage.out -covermode=count $(pkg);\
|
||||
tail -n +2 coverage.out >> coverage-all.out;)
|
||||
go tool cover -html=coverage-all.out
|
||||
|
||||
check-vendor: ## Verify that vendored packages match git HEAD
|
||||
@git diff-index --quiet HEAD vendor/ || (echo "check-vendor target failed: vendored packages out of sync" && echo && git diff vendor/ && exit 1)
|
||||
|
||||
help:
|
||||
@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
|
||||
|
||||
@@ -8,10 +8,10 @@ A Fast and Flexible Static Site Generator built with love by [spf13](http://spf1
|
||||
[Documentation](https://gohugo.io/overview/introduction/) |
|
||||
[Installation Guide](https://gohugo.io/overview/installing/) |
|
||||
[Contribution Guide](CONTRIBUTING.md) |
|
||||
[Twitter](http://twitter.com/spf13)
|
||||
[Twitter](http://twitter.com/gohugoio)
|
||||
|
||||
[](https://godoc.org/github.com/spf13/hugo)
|
||||
[](https://travis-ci.org/spf13/hugo)
|
||||
[](https://travis-ci.org/spf13/hugo)
|
||||
[](https://ci.appveyor.com/project/spf13/hugo/branch/master)
|
||||
[](https://gitter.im/spf13/hugo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://goreportcard.com/report/github.com/spf13/hugo)
|
||||
@@ -33,7 +33,7 @@ Hugo is designed to work well for any kind of website including blogs, tumbles a
|
||||
|
||||
#### Supported Architectures
|
||||
|
||||
Currently, we provide pre-built Hugo binaries for Windows, Linux, FreeBSD, NetBSD and OS X (Darwin) for x64, i386 and ARM architectures.
|
||||
Currently, we provide pre-built Hugo binaries for Windows, Linux, FreeBSD, NetBSD and macOS (Darwin) and [Android](https://gist.github.com/bep/a0d8a26cf6b4f8bc992729b8e50b480b) for x64, i386 and ARM architectures.
|
||||
|
||||
Hugo may also be compiled from source wherever the Go compiler tool chain can run, e.g. for other operating systems including DragonFly BSD, OpenBSD, Plan 9 and Solaris.
|
||||
|
||||
@@ -74,19 +74,17 @@ organization, tutorials, blog posts, bug reports, issues, feature requests,
|
||||
feature implementations, pull requests, answering questions on the forum,
|
||||
helping to manage issues, etc.
|
||||
|
||||
The Hugo community and maintainers are very active and helpful, and the project benefits greatly from this activity.
|
||||
|
||||
[](https://waffle.io/spf13/hugo/metrics)
|
||||
The Hugo community and maintainers are [very active](https://github.com/spf13/hugo/pulse/monthly) and helpful, and the project benefits greatly from this activity.
|
||||
|
||||
### Asking Support Questions
|
||||
|
||||
We have an active [discussion forum](http://discuss.gohugo.io) where users and developers can ask questions.
|
||||
Please don't use the Github issue tracker to ask questions.
|
||||
Please don't use the GitHub issue tracker to ask questions.
|
||||
|
||||
### Reporting Issues
|
||||
|
||||
If you believe you have found a defect in Hugo or its documentation, use
|
||||
the Github issue tracker to report the problem to the Hugo maintainers.
|
||||
the GitHub issue tracker to report the problem to the Hugo maintainers.
|
||||
If you're not sure if it's a bug or not, start by asking in the [discussion forum](http://discuss.gohugo.io).
|
||||
When reporting the issue, please provide the version of Hugo in use (`hugo version`).
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
init:
|
||||
- copy c:\MinGW\bin\mingw32-make.exe c:\MinGW\bin\make.exe
|
||||
- set PATH=%PATH%;C:\MinGW\bin;%GOPATH%\bin
|
||||
- go version
|
||||
- go env
|
||||
|
||||
# clones and cd's to path
|
||||
clone_folder: C:\GOPATH\src\github.com\spf13\hugo
|
||||
|
||||
install:
|
||||
- gem install asciidoctor
|
||||
- pip install docutils
|
||||
|
||||
build_script:
|
||||
- make hugo-race check
|
||||
- hugo -s docs/
|
||||
- hugo --renderToMemory -s docs/
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Send in a regexp mathing the benchmarks you want to run, i.e. './benchSite.sh "YAML"'.
|
||||
# Note the quotes, which will be needed for more complex expressions.
|
||||
# The above will run all variations, but only for front matter YAML.
|
||||
|
||||
echo "Running with BenchmarkSiteBuilding/${1}"
|
||||
|
||||
go test -run="NONE" -bench="BenchmarkSiteBuilding/${1}$" -test.benchmem=true ./hugolib -memprofile mem.prof -cpuprofile cpu.prof
|
||||
Vendored
+80
@@ -0,0 +1,80 @@
|
||||
// Copyright 2017-present The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Partition represents a cache partition where Load is the callback
|
||||
// for when the partition is needed.
|
||||
type Partition struct {
|
||||
Key string
|
||||
Load func() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
type lazyPartition struct {
|
||||
initSync sync.Once
|
||||
cache map[string]interface{}
|
||||
load func() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
func (l *lazyPartition) init() error {
|
||||
var err error
|
||||
l.initSync.Do(func() {
|
||||
var c map[string]interface{}
|
||||
c, err = l.load()
|
||||
l.cache = c
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// PartitionedLazyCache is a lazily loaded cache paritioned by a supplied string key.
|
||||
type PartitionedLazyCache struct {
|
||||
partitions map[string]*lazyPartition
|
||||
}
|
||||
|
||||
// NewPartitionedLazyCache creates a new NewPartitionedLazyCache with the supplied
|
||||
// partitions.
|
||||
func NewPartitionedLazyCache(partitions ...Partition) *PartitionedLazyCache {
|
||||
lazyPartitions := make(map[string]*lazyPartition, len(partitions))
|
||||
for _, partition := range partitions {
|
||||
lazyPartitions[partition.Key] = &lazyPartition{load: partition.Load}
|
||||
}
|
||||
cache := &PartitionedLazyCache{partitions: lazyPartitions}
|
||||
|
||||
return cache
|
||||
}
|
||||
|
||||
// Get initializes the partition if not already done so, then looks up the given
|
||||
// key in the given partition, returns nil if no value found.
|
||||
func (c *PartitionedLazyCache) Get(partition, key string) (interface{}, error) {
|
||||
p, found := c.partitions[partition]
|
||||
|
||||
if !found {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
if err := p.init(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if v, found := p.cache[key]; found {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
|
||||
}
|
||||
Vendored
+92
@@ -0,0 +1,92 @@
|
||||
// Copyright 2017-present The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package cache
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewPartitionedLazyCache(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
assert := require.New(t)
|
||||
|
||||
p1 := Partition{
|
||||
Key: "p1",
|
||||
Load: func() (map[string]interface{}, error) {
|
||||
return map[string]interface{}{
|
||||
"p1_1": "p1v1",
|
||||
"p1_2": "p1v2",
|
||||
"p1_nil": nil,
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
p2 := Partition{
|
||||
Key: "p2",
|
||||
Load: func() (map[string]interface{}, error) {
|
||||
return map[string]interface{}{
|
||||
"p2_1": "p2v1",
|
||||
"p2_2": "p2v2",
|
||||
"p2_3": "p2v3",
|
||||
}, nil
|
||||
},
|
||||
}
|
||||
|
||||
cache := NewPartitionedLazyCache(p1, p2)
|
||||
|
||||
v, err := cache.Get("p1", "p1_1")
|
||||
assert.NoError(err)
|
||||
assert.Equal("p1v1", v)
|
||||
|
||||
v, err = cache.Get("p1", "p2_1")
|
||||
assert.NoError(err)
|
||||
assert.Nil(v)
|
||||
|
||||
v, err = cache.Get("p1", "p1_nil")
|
||||
assert.NoError(err)
|
||||
assert.Nil(v)
|
||||
|
||||
v, err = cache.Get("p2", "p2_3")
|
||||
assert.NoError(err)
|
||||
assert.Equal("p2v3", v)
|
||||
|
||||
v, err = cache.Get("doesnotexist", "p1_1")
|
||||
assert.NoError(err)
|
||||
assert.Nil(v)
|
||||
|
||||
v, err = cache.Get("p1", "doesnotexist")
|
||||
assert.NoError(err)
|
||||
assert.Nil(v)
|
||||
|
||||
errorP := Partition{
|
||||
Key: "p3",
|
||||
Load: func() (map[string]interface{}, error) {
|
||||
return nil, errors.New("Failed")
|
||||
},
|
||||
}
|
||||
|
||||
cache = NewPartitionedLazyCache(errorP)
|
||||
|
||||
v, err = cache.Get("p1", "doesnotexist")
|
||||
assert.NoError(err)
|
||||
assert.Nil(v)
|
||||
|
||||
_, err = cache.Get("p3", "doesnotexist")
|
||||
assert.Error(err)
|
||||
|
||||
}
|
||||
+58
-30
@@ -15,15 +15,18 @@ package commands
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/pprof"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
|
||||
var (
|
||||
benchmarkTimes int
|
||||
cpuProfilefile string
|
||||
memProfilefile string
|
||||
cpuProfileFile string
|
||||
memProfileFile string
|
||||
)
|
||||
|
||||
var benchmarkCmd = &cobra.Command{
|
||||
@@ -37,48 +40,73 @@ func init() {
|
||||
initHugoBuilderFlags(benchmarkCmd)
|
||||
initBenchmarkBuildingFlags(benchmarkCmd)
|
||||
|
||||
benchmarkCmd.Flags().StringVar(&cpuProfilefile, "cpuprofile", "", "path/filename for the CPU profile file")
|
||||
benchmarkCmd.Flags().StringVar(&memProfilefile, "memprofile", "", "path/filename for the memory profile file")
|
||||
|
||||
benchmarkCmd.Flags().StringVar(&cpuProfileFile, "cpuprofile", "", "path/filename for the CPU profile file")
|
||||
benchmarkCmd.Flags().StringVar(&memProfileFile, "memprofile", "", "path/filename for the memory profile file")
|
||||
benchmarkCmd.Flags().IntVarP(&benchmarkTimes, "count", "n", 13, "number of times to build the site")
|
||||
|
||||
benchmarkCmd.RunE = benchmark
|
||||
}
|
||||
|
||||
func benchmark(cmd *cobra.Command, args []string) error {
|
||||
if err := InitializeConfig(benchmarkCmd); err != nil {
|
||||
cfg, err := InitializeConfig(benchmarkCmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if memProfilefile != "" {
|
||||
f, err := os.Create(memProfilefile)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var memProf *os.File
|
||||
if memProfileFile != "" {
|
||||
memProf, err = os.Create(memProfileFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 0; i < benchmarkTimes; i++ {
|
||||
_ = resetAndbuildSites(false)
|
||||
}
|
||||
pprof.WriteHeapProfile(f)
|
||||
f.Close()
|
||||
|
||||
} else {
|
||||
if cpuProfilefile == "" {
|
||||
cpuProfilefile = "/tmp/hugo-cpuprofile"
|
||||
}
|
||||
f, err := os.Create(cpuProfilefile)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pprof.StartCPUProfile(f)
|
||||
defer pprof.StopCPUProfile()
|
||||
for i := 0; i < benchmarkTimes; i++ {
|
||||
_ = resetAndbuildSites(false)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
var cpuProf *os.File
|
||||
if cpuProfileFile != "" {
|
||||
cpuProf, err = os.Create(cpuProfileFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
var memStats runtime.MemStats
|
||||
runtime.ReadMemStats(&memStats)
|
||||
memAllocated := memStats.TotalAlloc
|
||||
mallocs := memStats.Mallocs
|
||||
if cpuProf != nil {
|
||||
pprof.StartCPUProfile(cpuProf)
|
||||
}
|
||||
|
||||
t := time.Now()
|
||||
for i := 0; i < benchmarkTimes; i++ {
|
||||
if err = c.resetAndBuildSites(false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
totalTime := time.Since(t)
|
||||
|
||||
if memProf != nil {
|
||||
pprof.WriteHeapProfile(memProf)
|
||||
memProf.Close()
|
||||
}
|
||||
if cpuProf != nil {
|
||||
pprof.StopCPUProfile()
|
||||
cpuProf.Close()
|
||||
}
|
||||
|
||||
runtime.ReadMemStats(&memStats)
|
||||
totalMemAllocated := memStats.TotalAlloc - memAllocated
|
||||
totalMallocs := memStats.Mallocs - mallocs
|
||||
|
||||
jww.FEEDBACK.Println()
|
||||
jww.FEEDBACK.Printf("Average time per operation: %vms\n", int(1000*totalTime.Seconds()/float64(benchmarkTimes)))
|
||||
jww.FEEDBACK.Printf("Average memory allocated per operation: %vkB\n", totalMemAllocated/uint64(benchmarkTimes)/1024)
|
||||
jww.FEEDBACK.Printf("Average allocations per operation: %v\n", totalMallocs/uint64(benchmarkTimes))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+1
-20
@@ -19,24 +19,5 @@ import (
|
||||
|
||||
var checkCmd = &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.`,
|
||||
}
|
||||
|
||||
func init() {
|
||||
initHugoBuilderFlags(checkCmd)
|
||||
checkCmd.RunE = check
|
||||
}
|
||||
|
||||
func check(cmd *cobra.Command, args []string) error {
|
||||
if err := InitializeConfig(checkCmd); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := initSites(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return Hugo.Analyze()
|
||||
Short: "Contains some verification checks",
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright 2017 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/spf13/hugo/deps"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"github.com/spf13/hugo/hugofs"
|
||||
)
|
||||
|
||||
type commandeer struct {
|
||||
*deps.DepsCfg
|
||||
pathSpec *helpers.PathSpec
|
||||
configured bool
|
||||
}
|
||||
|
||||
func (c *commandeer) Set(key string, value interface{}) {
|
||||
if c.configured {
|
||||
panic("commandeer cannot be changed")
|
||||
}
|
||||
c.Cfg.Set(key, value)
|
||||
}
|
||||
|
||||
// PathSpec lazily creates a new PathSpec, as all the paths must
|
||||
// be configured before it is created.
|
||||
func (c *commandeer) PathSpec() *helpers.PathSpec {
|
||||
c.configured = true
|
||||
return c.pathSpec
|
||||
}
|
||||
|
||||
func (c *commandeer) initFs(fs *hugofs.Fs) error {
|
||||
c.DepsCfg.Fs = fs
|
||||
ps, err := helpers.NewPathSpec(fs, c.Cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.pathSpec = ps
|
||||
return nil
|
||||
}
|
||||
|
||||
func newCommandeer(cfg *deps.DepsCfg) (*commandeer, error) {
|
||||
l := cfg.Language
|
||||
if l == nil {
|
||||
l = helpers.NewDefaultLanguage(cfg.Cfg)
|
||||
}
|
||||
ps, err := helpers.NewPathSpec(cfg.Fs, l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &commandeer{DepsCfg: cfg, pathSpec: ps}, nil
|
||||
}
|
||||
+21
-22
@@ -14,17 +14,15 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cast"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"github.com/spf13/hugo/hugolib"
|
||||
"github.com/spf13/hugo/parser"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var outputDir string
|
||||
@@ -79,13 +77,13 @@ func init() {
|
||||
convertCmd.PersistentFlags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{})
|
||||
}
|
||||
|
||||
func convertContents(mark rune) (err error) {
|
||||
if err := InitializeConfig(); err != nil {
|
||||
func convertContents(mark rune) error {
|
||||
cfg, err := InitializeConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h, err := hugolib.NewHugoSitesFromConfiguration()
|
||||
|
||||
h, err := hugolib.NewHugoSites(*cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -97,47 +95,48 @@ func convertContents(mark rune) (err error) {
|
||||
}
|
||||
|
||||
if site.Source == nil {
|
||||
panic(fmt.Sprintf("site.Source not set"))
|
||||
panic("site.Source not set")
|
||||
}
|
||||
if len(site.Source.Files()) < 1 {
|
||||
return fmt.Errorf("No source files found")
|
||||
return errors.New("No source files found")
|
||||
}
|
||||
|
||||
jww.FEEDBACK.Println("processing", len(site.Source.Files()), "content files")
|
||||
contentDir := site.PathSpec.AbsPathify(site.Cfg.GetString("contentDir"))
|
||||
site.Log.FEEDBACK.Println("processing", len(site.Source.Files()), "content files")
|
||||
for _, file := range site.Source.Files() {
|
||||
jww.INFO.Println("Attempting to convert", file.LogicalName())
|
||||
page, err := hugolib.NewPage(file.LogicalName())
|
||||
site.Log.INFO.Println("Attempting to convert", file.LogicalName())
|
||||
page, err := site.NewPage(file.LogicalName())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
psr, err := parser.ReadFrom(file.Contents)
|
||||
if err != nil {
|
||||
jww.ERROR.Println("Error processing file:", file.Path())
|
||||
site.Log.ERROR.Println("Error processing file:", file.Path())
|
||||
return err
|
||||
}
|
||||
metadata, err := psr.Metadata()
|
||||
if err != nil {
|
||||
jww.ERROR.Println("Error processing file:", file.Path())
|
||||
site.Log.ERROR.Println("Error processing file:", file.Path())
|
||||
return err
|
||||
}
|
||||
|
||||
// better handling of dates in formats that don't have support for them
|
||||
if mark == parser.FormatToLeadRune("json") || mark == parser.FormatToLeadRune("yaml") || mark == parser.FormatToLeadRune("toml") {
|
||||
newmetadata := cast.ToStringMap(metadata)
|
||||
for k, v := range newmetadata {
|
||||
newMetadata := cast.ToStringMap(metadata)
|
||||
for k, v := range newMetadata {
|
||||
switch vv := v.(type) {
|
||||
case time.Time:
|
||||
newmetadata[k] = vv.Format(time.RFC3339)
|
||||
newMetadata[k] = vv.Format(time.RFC3339)
|
||||
}
|
||||
}
|
||||
metadata = newmetadata
|
||||
metadata = newMetadata
|
||||
}
|
||||
|
||||
page.SetDir(filepath.Join(helpers.AbsPathify(viper.GetString("ContentDir")), file.Dir()))
|
||||
page.SetDir(filepath.Join(contentDir, file.Dir()))
|
||||
page.SetSourceContent(psr.Content())
|
||||
if err = page.SetSourceMetaData(metadata, mark); err != nil {
|
||||
jww.ERROR.Printf("Failed to set source metadata for file %q: %s. For more info see For more info see https://github.com/spf13/hugo/issues/2458", page.FullFilePath(), err)
|
||||
site.Log.ERROR.Printf("Failed to set source metadata for file %q: %s. For more info see For more info see https://github.com/spf13/hugo/issues/2458", page.FullFilePath(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -151,9 +150,9 @@ func convertContents(mark rune) (err error) {
|
||||
return fmt.Errorf("Failed to save file %q: %s", page.FullFilePath(), err)
|
||||
}
|
||||
} else {
|
||||
jww.FEEDBACK.Println("Unsafe operation not allowed, use --unsafe or set a different output path")
|
||||
site.Log.FEEDBACK.Println("Unsafe operation not allowed, use --unsafe or set a different output path")
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
+4
-4
@@ -14,10 +14,10 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
|
||||
var envCmd = &cobra.Command{
|
||||
@@ -26,9 +26,9 @@ var envCmd = &cobra.Command{
|
||||
Long: `Print Hugo version and environment info. This is useful in Hugo bug reports.`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
printHugoVersion()
|
||||
fmt.Printf("GOOS=%q\n", runtime.GOOS)
|
||||
fmt.Printf("GOARCH=%q\n", runtime.GOARCH)
|
||||
fmt.Printf("GOVERSION=%q\n", runtime.Version())
|
||||
jww.FEEDBACK.Printf("GOOS=%q\n", runtime.GOOS)
|
||||
jww.FEEDBACK.Printf("GOARCH=%q\n", runtime.GOARCH)
|
||||
jww.FEEDBACK.Printf("GOVERSION=%q\n", runtime.Version())
|
||||
|
||||
return nil
|
||||
},
|
||||
|
||||
@@ -62,8 +62,8 @@ or just source them in directly:
|
||||
}
|
||||
|
||||
func init() {
|
||||
genautocompleteCmd.PersistentFlags().StringVarP(&autocompleteTarget, "completionfile", "", "/etc/bash_completion.d/hugo.sh", "Autocompletion file")
|
||||
genautocompleteCmd.PersistentFlags().StringVarP(&autocompleteType, "type", "", "bash", "Autocompletion type (currently only bash supported)")
|
||||
genautocompleteCmd.PersistentFlags().StringVarP(&autocompleteTarget, "completionfile", "", "/etc/bash_completion.d/hugo.sh", "autocompletion file")
|
||||
genautocompleteCmd.PersistentFlags().StringVarP(&autocompleteType, "type", "", "bash", "autocompletion type (currently only bash supported)")
|
||||
|
||||
// For bash-completion
|
||||
genautocompleteCmd.PersistentFlags().SetAnnotation("completionfile", cobra.BashCompFilenameExt, []string{})
|
||||
|
||||
+4
-2
@@ -51,9 +51,11 @@ for rendering in Hugo.`,
|
||||
if !strings.HasSuffix(gendocdir, helpers.FilePathSeparator) {
|
||||
gendocdir += helpers.FilePathSeparator
|
||||
}
|
||||
if found, _ := helpers.Exists(gendocdir, hugofs.Os()); !found {
|
||||
if found, _ := helpers.Exists(gendocdir, hugofs.Os); !found {
|
||||
jww.FEEDBACK.Println("Directory", gendocdir, "does not exist, creating...")
|
||||
hugofs.Os().MkdirAll(gendocdir, 0777)
|
||||
if err := hugofs.Os.MkdirAll(gendocdir, 0777); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
now := time.Now().Format(time.RFC3339)
|
||||
prepender := func(filename string) string {
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
// Copyright 2017-present The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/docshelper"
|
||||
)
|
||||
|
||||
type genDocsHelper struct {
|
||||
target string
|
||||
cmd *cobra.Command
|
||||
}
|
||||
|
||||
func createGenDocsHelper() *genDocsHelper {
|
||||
g := &genDocsHelper{
|
||||
cmd: &cobra.Command{
|
||||
Use: "docshelper",
|
||||
Short: "Generate some data files for the Hugo docs.",
|
||||
Hidden: true,
|
||||
},
|
||||
}
|
||||
|
||||
g.cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
return g.generate()
|
||||
}
|
||||
|
||||
g.cmd.PersistentFlags().StringVarP(&g.target, "dir", "", "docs/data", "data dir")
|
||||
|
||||
return g
|
||||
}
|
||||
|
||||
func (g *genDocsHelper) generate() error {
|
||||
fmt.Println("Generate docs data to", g.target)
|
||||
|
||||
targetFile := filepath.Join(g.target, "docs.json")
|
||||
|
||||
f, err := os.Create(targetFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
enc := json.NewEncoder(f)
|
||||
enc.SetIndent("", " ")
|
||||
|
||||
if err := enc.Encode(docshelper.DocProviders); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Done!")
|
||||
return nil
|
||||
|
||||
}
|
||||
+5
-3
@@ -36,14 +36,16 @@ in the "man" directory under the current directory.`,
|
||||
header := &doc.GenManHeader{
|
||||
Section: "1",
|
||||
Manual: "Hugo Manual",
|
||||
Source: fmt.Sprintf("Hugo %s", helpers.HugoVersion()),
|
||||
Source: fmt.Sprintf("Hugo %s", helpers.CurrentHugoVersion),
|
||||
}
|
||||
if !strings.HasSuffix(genmandir, helpers.FilePathSeparator) {
|
||||
genmandir += helpers.FilePathSeparator
|
||||
}
|
||||
if found, _ := helpers.Exists(genmandir, hugofs.Os()); !found {
|
||||
if found, _ := helpers.Exists(genmandir, hugofs.Os); !found {
|
||||
jww.FEEDBACK.Println("Directory", genmandir, "does not exist, creating...")
|
||||
hugofs.Os().MkdirAll(genmandir, 0777)
|
||||
if err := hugofs.Os.MkdirAll(genmandir, 0777); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
cmd.Root().DisableAutoGenTag = true
|
||||
|
||||
|
||||
+394
-312
File diff suppressed because it is too large
Load Diff
+82
-37
@@ -16,7 +16,6 @@ package commands
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -26,6 +25,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cast"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
@@ -58,12 +58,10 @@ Import from Jekyll requires two paths, e.g. ` + "`hugo import jekyll jekyll_root
|
||||
}
|
||||
|
||||
func init() {
|
||||
importJekyllCmd.Flags().Bool("force", false, "Allow import into non-empty target directory")
|
||||
importJekyllCmd.Flags().Bool("force", false, "allow import into non-empty target directory")
|
||||
}
|
||||
|
||||
func importFromJekyll(cmd *cobra.Command, args []string) error {
|
||||
jww.SetLogThreshold(jww.LevelTrace)
|
||||
jww.SetStdoutThreshold(jww.LevelWarn)
|
||||
|
||||
if len(args) < 2 {
|
||||
return newUserError(`Import from Jekyll requires two paths, e.g. ` + "`hugo import jekyll jekyll_root_path target_path`.")
|
||||
@@ -86,11 +84,12 @@ func importFromJekyll(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
forceImport, _ := cmd.Flags().GetBool("force")
|
||||
if err := createSiteFromJekyll(jekyllRoot, targetDir, forceImport); err != nil {
|
||||
return newUserError(err)
|
||||
site, err := createSiteFromJekyll(jekyllRoot, targetDir, forceImport)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Importing...")
|
||||
jww.FEEDBACK.Println("Importing...")
|
||||
|
||||
fileCount := 0
|
||||
callback := func(path string, fi os.FileInfo, err error) error {
|
||||
@@ -121,38 +120,44 @@ func importFromJekyll(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
fileCount++
|
||||
return convertJekyllPost(path, relPath, targetDir, draft)
|
||||
return convertJekyllPost(site, path, relPath, targetDir, draft)
|
||||
}
|
||||
|
||||
err = helpers.SymbolicWalk(hugofs.Os(), jekyllRoot, callback)
|
||||
err = helpers.SymbolicWalk(hugofs.Os, jekyllRoot, callback)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Congratulations!", fileCount, "post(s) imported!")
|
||||
fmt.Println("Now, start Hugo by yourself:\n" +
|
||||
jww.FEEDBACK.Println("Congratulations!", fileCount, "post(s) imported!")
|
||||
jww.FEEDBACK.Println("Now, start Hugo by yourself:\n" +
|
||||
"$ git clone https://github.com/spf13/herring-cove.git " + args[1] + "/themes/herring-cove")
|
||||
fmt.Println("$ cd " + args[1] + "\n$ hugo server --theme=herring-cove")
|
||||
jww.FEEDBACK.Println("$ cd " + args[1] + "\n$ hugo server --theme=herring-cove")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: Consider calling doNewSite() instead?
|
||||
func createSiteFromJekyll(jekyllRoot, targetDir string, force bool) error {
|
||||
fs := hugofs.Source()
|
||||
func createSiteFromJekyll(jekyllRoot, targetDir string, force bool) (*hugolib.Site, error) {
|
||||
s, err := hugolib.NewSiteDefaultLang()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fs := s.Fs.Source
|
||||
|
||||
if exists, _ := helpers.Exists(targetDir, fs); exists {
|
||||
if isDir, _ := helpers.IsDir(targetDir, fs); !isDir {
|
||||
return errors.New("Target path \"" + targetDir + "\" already exists but not a directory")
|
||||
return nil, errors.New("Target path \"" + targetDir + "\" already exists but not a directory")
|
||||
}
|
||||
|
||||
isEmpty, _ := helpers.IsEmpty(targetDir, fs)
|
||||
|
||||
if !isEmpty && !force {
|
||||
return errors.New("Target path \"" + targetDir + "\" already exists and is not empty")
|
||||
return nil, errors.New("Target path \"" + targetDir + "\" already exists and is not empty")
|
||||
}
|
||||
}
|
||||
|
||||
jekyllConfig := loadJekyllConfig(jekyllRoot)
|
||||
jekyllConfig := loadJekyllConfig(fs, jekyllRoot)
|
||||
|
||||
// Crude test to make sure at least one of _drafts/ and _posts/ exists
|
||||
// and is not empty.
|
||||
@@ -169,7 +174,7 @@ func createSiteFromJekyll(jekyllRoot, targetDir string, force bool) error {
|
||||
}
|
||||
}
|
||||
if !hasPostsOrDrafts {
|
||||
return errors.New("Your Jekyll root contains neither posts nor drafts, aborting.")
|
||||
return nil, errors.New("Your Jekyll root contains neither posts nor drafts, aborting.")
|
||||
}
|
||||
|
||||
mkdir(targetDir, "layouts")
|
||||
@@ -179,15 +184,14 @@ func createSiteFromJekyll(jekyllRoot, targetDir string, force bool) error {
|
||||
mkdir(targetDir, "data")
|
||||
mkdir(targetDir, "themes")
|
||||
|
||||
createConfigFromJekyll(targetDir, "yaml", jekyllConfig)
|
||||
createConfigFromJekyll(fs, targetDir, "yaml", jekyllConfig)
|
||||
|
||||
copyJekyllFilesAndFolders(jekyllRoot, filepath.Join(targetDir, "static"))
|
||||
|
||||
return nil
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func loadJekyllConfig(jekyllRoot string) map[string]interface{} {
|
||||
fs := hugofs.Source()
|
||||
func loadJekyllConfig(fs afero.Fs, jekyllRoot string) map[string]interface{} {
|
||||
path := filepath.Join(jekyllRoot, "_config.yml")
|
||||
|
||||
exists, err := helpers.Exists(path, fs)
|
||||
@@ -219,9 +223,9 @@ func loadJekyllConfig(jekyllRoot string) map[string]interface{} {
|
||||
return c.(map[string]interface{})
|
||||
}
|
||||
|
||||
func createConfigFromJekyll(inpath string, kind string, jekyllConfig map[string]interface{}) (err error) {
|
||||
func createConfigFromJekyll(fs afero.Fs, inpath string, kind string, jekyllConfig map[string]interface{}) (err error) {
|
||||
title := "My New Hugo Site"
|
||||
baseurl := "http://replace-this-with-your-hugo-site.com/"
|
||||
baseURL := "http://example.org/"
|
||||
|
||||
for key, value := range jekyllConfig {
|
||||
lowerKey := strings.ToLower(key)
|
||||
@@ -234,30 +238,26 @@ func createConfigFromJekyll(inpath string, kind string, jekyllConfig map[string]
|
||||
|
||||
case "url":
|
||||
if str, ok := value.(string); ok {
|
||||
baseurl = str
|
||||
baseURL = str
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
in := map[string]interface{}{
|
||||
"baseurl": baseurl,
|
||||
"baseURL": baseURL,
|
||||
"title": title,
|
||||
"languageCode": "en-us",
|
||||
"disablePathToLower": true,
|
||||
}
|
||||
kind = parser.FormatSanitize(kind)
|
||||
|
||||
by, err := parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind))
|
||||
var buf bytes.Buffer
|
||||
err = parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind), &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = helpers.WriteToDisk(filepath.Join(inpath, "config."+kind), bytes.NewReader(by), hugofs.Source())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
return helpers.WriteToDisk(filepath.Join(inpath, "config."+kind), &buf, fs)
|
||||
}
|
||||
|
||||
func copyFile(source string, dest string) error {
|
||||
@@ -372,7 +372,7 @@ func parseJekyllFilename(filename string) (time.Time, string, error) {
|
||||
return time.Now(), "", errors.New("filename not match")
|
||||
}
|
||||
|
||||
postDate, err := time.Parse("2006-01-02", r[0][1])
|
||||
postDate, err := time.Parse("2006-1-2", r[0][1])
|
||||
if err != nil {
|
||||
return time.Now(), "", err
|
||||
}
|
||||
@@ -382,7 +382,7 @@ func parseJekyllFilename(filename string) (time.Time, string, error) {
|
||||
return postDate, postName, nil
|
||||
}
|
||||
|
||||
func convertJekyllPost(path, relPath, targetDir string, draft bool) error {
|
||||
func convertJekyllPost(s *hugolib.Site, path, relPath, targetDir string, draft bool) error {
|
||||
jww.TRACE.Println("Converting", path)
|
||||
|
||||
filename := filepath.Base(path)
|
||||
@@ -425,7 +425,7 @@ func convertJekyllPost(path, relPath, targetDir string, draft bool) error {
|
||||
jww.TRACE.Println(newmetadata)
|
||||
content := convertJekyllContent(newmetadata, string(psr.Content()))
|
||||
|
||||
page, err := hugolib.NewPage(filename)
|
||||
page, err := s.NewPage(filename)
|
||||
if err != nil {
|
||||
jww.ERROR.Println("New page error", filename)
|
||||
return err
|
||||
@@ -518,7 +518,7 @@ func convertJekyllContent(m interface{}, content string) string {
|
||||
re *regexp.Regexp
|
||||
replace string
|
||||
}{
|
||||
{regexp.MustCompile("<!-- more -->"), "<!--more-->"},
|
||||
{regexp.MustCompile("(?i)<!-- more -->"), "<!--more-->"},
|
||||
{regexp.MustCompile(`\{%\s*raw\s*%\}\s*(.*?)\s*\{%\s*endraw\s*%\}`), "$1"},
|
||||
{regexp.MustCompile(`{%\s*highlight\s*(.*?)\s*%}`), "{{< highlight $1 >}}"},
|
||||
{regexp.MustCompile(`{%\s*endhighlight\s*%}`), "{{< / highlight >}}"},
|
||||
@@ -528,5 +528,50 @@ func convertJekyllContent(m interface{}, content string) string {
|
||||
content = replace.re.ReplaceAllString(content, replace.replace)
|
||||
}
|
||||
|
||||
replaceListFunc := []struct {
|
||||
re *regexp.Regexp
|
||||
replace func(string) string
|
||||
}{
|
||||
// Octopress image tag: http://octopress.org/docs/plugins/image-tag/
|
||||
{regexp.MustCompile(`{%\s+img\s*(.*?)\s*%}`), replaceImageTag},
|
||||
}
|
||||
|
||||
for _, replace := range replaceListFunc {
|
||||
content = replace.re.ReplaceAllStringFunc(content, replace.replace)
|
||||
}
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
func replaceImageTag(match string) string {
|
||||
r := regexp.MustCompile(`{%\s+img\s*(\p{L}*)\s+([\S]*/[\S]+)\s+(\d*)\s*(\d*)\s*(.*?)\s*%}`)
|
||||
result := bytes.NewBufferString("{{< figure ")
|
||||
parts := r.FindStringSubmatch(match)
|
||||
// Index 0 is the entire string, ignore
|
||||
replaceOptionalPart(result, "class", parts[1])
|
||||
replaceOptionalPart(result, "src", parts[2])
|
||||
replaceOptionalPart(result, "width", parts[3])
|
||||
replaceOptionalPart(result, "height", parts[4])
|
||||
// title + alt
|
||||
part := parts[5]
|
||||
if len(part) > 0 {
|
||||
splits := strings.Split(part, "'")
|
||||
lenSplits := len(splits)
|
||||
if lenSplits == 1 {
|
||||
replaceOptionalPart(result, "title", splits[0])
|
||||
} else if lenSplits == 3 {
|
||||
replaceOptionalPart(result, "title", splits[1])
|
||||
} else if lenSplits == 5 {
|
||||
replaceOptionalPart(result, "title", splits[1])
|
||||
replaceOptionalPart(result, "alt", splits[3])
|
||||
}
|
||||
}
|
||||
result.WriteString(">}}")
|
||||
return result.String()
|
||||
|
||||
}
|
||||
func replaceOptionalPart(buffer *bytes.Buffer, partName string, part string) {
|
||||
if len(part) > 0 {
|
||||
buffer.WriteString(partName + "=\"" + part + "\" ")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +88,8 @@ func TestConvertJekyllContent(t *testing.T) {
|
||||
}{
|
||||
{map[interface{}]interface{}{},
|
||||
`Test content\n<!-- more -->\npart2 content`, `Test content\n<!--more-->\npart2 content`},
|
||||
{map[interface{}]interface{}{},
|
||||
`Test content\n<!-- More -->\npart2 content`, `Test content\n<!--more-->\npart2 content`},
|
||||
{map[interface{}]interface{}{"excerpt_separator": "<!--sep-->"},
|
||||
`Test content\n<!--sep-->\npart2 content`, `Test content\n<!--more-->\npart2 content`},
|
||||
{map[interface{}]interface{}{}, "{% raw %}text{% endraw %}", "text"},
|
||||
@@ -95,6 +97,26 @@ func TestConvertJekyllContent(t *testing.T) {
|
||||
{map[interface{}]interface{}{},
|
||||
"{% highlight go %}\nvar s int\n{% endhighlight %}",
|
||||
"{{< highlight go >}}\nvar s int\n{{< / highlight >}}"},
|
||||
|
||||
// Octopress image tag
|
||||
{map[interface{}]interface{}{},
|
||||
"{% img http://placekitten.com/890/280 %}",
|
||||
"{{< figure src=\"http://placekitten.com/890/280\" >}}"},
|
||||
{map[interface{}]interface{}{},
|
||||
"{% img left http://placekitten.com/320/250 Place Kitten #2 %}",
|
||||
"{{< figure class=\"left\" src=\"http://placekitten.com/320/250\" title=\"Place Kitten #2\" >}}"},
|
||||
{map[interface{}]interface{}{},
|
||||
"{% img right http://placekitten.com/300/500 150 250 'Place Kitten #3' %}",
|
||||
"{{< figure class=\"right\" src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #3\" >}}"},
|
||||
{map[interface{}]interface{}{},
|
||||
"{% img right http://placekitten.com/300/500 150 250 'Place Kitten #4' 'An image of a very cute kitten' %}",
|
||||
"{{< figure class=\"right\" src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}"},
|
||||
{map[interface{}]interface{}{},
|
||||
"{% img http://placekitten.com/300/500 150 250 'Place Kitten #4' 'An image of a very cute kitten' %}",
|
||||
"{{< figure src=\"http://placekitten.com/300/500\" width=\"150\" height=\"250\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}"},
|
||||
{map[interface{}]interface{}{},
|
||||
"{% img right /placekitten/300/500 'Place Kitten #4' 'An image of a very cute kitten' %}",
|
||||
"{{< figure class=\"right\" src=\"/placekitten/300/500\" title=\"Place Kitten #4\" alt=\"An image of a very cute kitten\" >}}"},
|
||||
}
|
||||
|
||||
for _, data := range testDataList {
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
// Copyright 2015 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build darwin
|
||||
// Copyright 2015 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
|
||||
func init() {
|
||||
checkCmd.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`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
var rLimit syscall.Rlimit
|
||||
err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)
|
||||
if err != nil {
|
||||
return newSystemError("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 {
|
||||
return newSystemError("Error Setting rLimit ", err)
|
||||
}
|
||||
err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)
|
||||
if err != nil {
|
||||
return newSystemError("Error Getting rLimit ", err)
|
||||
}
|
||||
jww.FEEDBACK.Println("rLimit after change:", rLimit)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright 2015 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// +build !darwin
|
||||
// Copyright 2015 The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
func tweakLimit() {
|
||||
// nothing to do
|
||||
}
|
||||
+31
-14
@@ -14,12 +14,11 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/hugolib"
|
||||
"github.com/spf13/viper"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -45,13 +44,19 @@ var listDraftsCmd = &cobra.Command{
|
||||
Long: `List all of the drafts in your content directory.`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
if err := InitializeConfig(); err != nil {
|
||||
cfg, err := InitializeConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
viper.Set("BuildDrafts", true)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sites, err := hugolib.NewHugoSitesFromConfiguration()
|
||||
c.Set("buildDrafts", true)
|
||||
|
||||
sites, err := hugolib.NewHugoSites(*cfg)
|
||||
|
||||
if err != nil {
|
||||
return newSystemError("Error creating sites", err)
|
||||
@@ -63,7 +68,7 @@ var listDraftsCmd = &cobra.Command{
|
||||
|
||||
for _, p := range sites.Pages() {
|
||||
if p.IsDraft() {
|
||||
fmt.Println(filepath.Join(p.File.Dir(), p.File.LogicalName()))
|
||||
jww.FEEDBACK.Println(filepath.Join(p.File.Dir(), p.File.LogicalName()))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -80,13 +85,19 @@ var listFutureCmd = &cobra.Command{
|
||||
posted in the future.`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
if err := InitializeConfig(); err != nil {
|
||||
cfg, err := InitializeConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
viper.Set("BuildFuture", true)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sites, err := hugolib.NewHugoSitesFromConfiguration()
|
||||
c.Set("buildFuture", true)
|
||||
|
||||
sites, err := hugolib.NewHugoSites(*cfg)
|
||||
|
||||
if err != nil {
|
||||
return newSystemError("Error creating sites", err)
|
||||
@@ -98,7 +109,7 @@ posted in the future.`,
|
||||
|
||||
for _, p := range sites.Pages() {
|
||||
if p.IsFuture() {
|
||||
fmt.Println(filepath.Join(p.File.Dir(), p.File.LogicalName()))
|
||||
jww.FEEDBACK.Println(filepath.Join(p.File.Dir(), p.File.LogicalName()))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -115,13 +126,19 @@ var listExpiredCmd = &cobra.Command{
|
||||
expired.`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
if err := InitializeConfig(); err != nil {
|
||||
cfg, err := InitializeConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
viper.Set("BuildExpired", true)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sites, err := hugolib.NewHugoSitesFromConfiguration()
|
||||
c.Set("buildExpired", true)
|
||||
|
||||
sites, err := hugolib.NewHugoSites(*cfg)
|
||||
|
||||
if err != nil {
|
||||
return newSystemError("Error creating sites", err)
|
||||
@@ -133,7 +150,7 @@ expired.`,
|
||||
|
||||
for _, p := range sites.Pages() {
|
||||
if p.IsExpired() {
|
||||
fmt.Println(filepath.Join(p.File.Dir(), p.File.LogicalName()))
|
||||
jww.FEEDBACK.Println(filepath.Join(p.File.Dir(), p.File.LogicalName()))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
@@ -29,15 +29,17 @@ var configCmd = &cobra.Command{
|
||||
}
|
||||
|
||||
func init() {
|
||||
configCmd.RunE = config
|
||||
configCmd.RunE = printConfig
|
||||
}
|
||||
|
||||
func config(cmd *cobra.Command, args []string) error {
|
||||
if err := InitializeConfig(configCmd); err != nil {
|
||||
func printConfig(cmd *cobra.Command, args []string) error {
|
||||
cfg, err := InitializeConfig(configCmd)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
allSettings := viper.AllSettings()
|
||||
allSettings := cfg.Cfg.(*viper.Viper).AllSettings()
|
||||
|
||||
var separator string
|
||||
if allSettings["metadataformat"] == "toml" {
|
||||
@@ -54,9 +56,9 @@ func config(cmd *cobra.Command, args []string) error {
|
||||
for _, k := range keys {
|
||||
kv := reflect.ValueOf(allSettings[k])
|
||||
if kv.Kind() == reflect.String {
|
||||
fmt.Printf("%s%s\"%+v\"\n", k, separator, allSettings[k])
|
||||
jww.FEEDBACK.Printf("%s%s\"%+v\"\n", k, separator, allSettings[k])
|
||||
} else {
|
||||
fmt.Printf("%s%s%+v\n", k, separator, allSettings[k])
|
||||
jww.FEEDBACK.Printf("%s%s%+v\n", k, separator, allSettings[k])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+85
-53
@@ -16,15 +16,18 @@ package commands
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/create"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"github.com/spf13/hugo/hugofs"
|
||||
"github.com/spf13/hugo/hugolib"
|
||||
"github.com/spf13/hugo/parser"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
"github.com/spf13/viper"
|
||||
@@ -38,9 +41,9 @@ var (
|
||||
|
||||
func init() {
|
||||
newSiteCmd.Flags().StringVarP(&configFormat, "format", "f", "toml", "config & frontmatter format")
|
||||
newSiteCmd.Flags().Bool("force", false, "Init inside non-empty directory")
|
||||
newSiteCmd.Flags().Bool("force", false, "init inside non-empty directory")
|
||||
newCmd.Flags().StringVarP(&configFormat, "format", "f", "toml", "frontmatter format")
|
||||
newCmd.Flags().StringVarP(&contentType, "kind", "k", "", "Content type to create")
|
||||
newCmd.Flags().StringVarP(&contentType, "kind", "k", "", "content type to create")
|
||||
newCmd.PersistentFlags().StringVarP(&source, "source", "s", "", "filesystem path to read files relative from")
|
||||
newCmd.PersistentFlags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{})
|
||||
newCmd.Flags().StringVar(&contentEditor, "editor", "", "edit new content with this editor, if provided")
|
||||
@@ -84,36 +87,49 @@ as you see fit.`,
|
||||
|
||||
// NewContent adds new content to a Hugo site.
|
||||
func NewContent(cmd *cobra.Command, args []string) error {
|
||||
if err := InitializeConfig(); err != nil {
|
||||
cfg, err := InitializeConfig()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if flagChanged(cmd.Flags(), "format") {
|
||||
viper.Set("MetaDataFormat", configFormat)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if flagChanged(cmd.Flags(), "editor") {
|
||||
viper.Set("NewContentEditor", contentEditor)
|
||||
if cmd.Flags().Changed("format") {
|
||||
c.Set("metaDataFormat", configFormat)
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("editor") {
|
||||
c.Set("newContentEditor", contentEditor)
|
||||
}
|
||||
|
||||
if len(args) < 1 {
|
||||
return newUserError("path needs to be provided")
|
||||
}
|
||||
|
||||
createpath := args[0]
|
||||
createPath := args[0]
|
||||
|
||||
var kind string
|
||||
|
||||
createpath, kind = newContentPathSection(createpath)
|
||||
createPath, kind = newContentPathSection(createPath)
|
||||
|
||||
if contentType != "" {
|
||||
kind = contentType
|
||||
}
|
||||
|
||||
return create.NewContent(hugofs.Source(), kind, createpath)
|
||||
s, err := hugolib.NewSite(*cfg)
|
||||
|
||||
if err != nil {
|
||||
return newSystemError(err)
|
||||
}
|
||||
|
||||
return create.NewContent(s, kind, createPath)
|
||||
}
|
||||
|
||||
func doNewSite(basepath string, force bool) error {
|
||||
func doNewSite(fs *hugofs.Fs, basepath string, force bool) error {
|
||||
dirs := []string{
|
||||
filepath.Join(basepath, "layouts"),
|
||||
filepath.Join(basepath, "content"),
|
||||
@@ -123,12 +139,12 @@ func doNewSite(basepath string, force bool) error {
|
||||
filepath.Join(basepath, "themes"),
|
||||
}
|
||||
|
||||
if exists, _ := helpers.Exists(basepath, hugofs.Source()); exists {
|
||||
if isDir, _ := helpers.IsDir(basepath, hugofs.Source()); !isDir {
|
||||
if exists, _ := helpers.Exists(basepath, fs.Source); exists {
|
||||
if isDir, _ := helpers.IsDir(basepath, fs.Source); !isDir {
|
||||
return errors.New(basepath + " already exists but not a directory")
|
||||
}
|
||||
|
||||
isEmpty, _ := helpers.IsEmpty(basepath, hugofs.Source())
|
||||
isEmpty, _ := helpers.IsEmpty(basepath, fs.Source)
|
||||
|
||||
switch {
|
||||
case !isEmpty && !force:
|
||||
@@ -137,7 +153,7 @@ func doNewSite(basepath string, force bool) error {
|
||||
case !isEmpty && force:
|
||||
all := append(dirs, filepath.Join(basepath, "config."+configFormat))
|
||||
for _, path := range all {
|
||||
if exists, _ := helpers.Exists(path, hugofs.Source()); exists {
|
||||
if exists, _ := helpers.Exists(path, fs.Source); exists {
|
||||
return errors.New(path + " already exists")
|
||||
}
|
||||
}
|
||||
@@ -145,24 +161,38 @@ func doNewSite(basepath string, force bool) error {
|
||||
}
|
||||
|
||||
for _, dir := range dirs {
|
||||
hugofs.Source().MkdirAll(dir, 0777)
|
||||
if err := fs.Source.MkdirAll(dir, 0777); err != nil {
|
||||
return fmt.Errorf("Failed to create dir: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
createConfig(basepath, configFormat)
|
||||
createConfig(fs, basepath, configFormat)
|
||||
|
||||
jww.FEEDBACK.Printf("Congratulations! Your new Hugo site is created in %q.\n\n", basepath)
|
||||
jww.FEEDBACK.Println(`Just a few more steps and you're ready to go:
|
||||
jww.FEEDBACK.Printf("Congratulations! Your new Hugo site is created in %s.\n\n", basepath)
|
||||
jww.FEEDBACK.Println(nextStepsText())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func nextStepsText() string {
|
||||
var nextStepsText bytes.Buffer
|
||||
|
||||
nextStepsText.WriteString(`Just a few more steps and you're ready to go:
|
||||
|
||||
1. Download a theme into the same-named folder.
|
||||
Choose a theme from https://themes.gohugo.io/, or
|
||||
create your own with the "hugo new theme <THEMENAME>" command.
|
||||
2. Perhaps you want to add some content. You can add single files
|
||||
with "hugo new <SECTIONNAME>/<FILENAME>.<FORMAT>".
|
||||
with "hugo new `)
|
||||
|
||||
nextStepsText.WriteString(filepath.Join("<SECTIONNAME>", "<FILENAME>.<FORMAT>"))
|
||||
|
||||
nextStepsText.WriteString(`".
|
||||
3. Start the built-in live server via "hugo server".
|
||||
|
||||
Visit https://gohugo.io/ for quickstart guide and full documentation.`)
|
||||
|
||||
return nil
|
||||
return nextStepsText.String()
|
||||
}
|
||||
|
||||
// NewSite creates a new Hugo site and initializes a structured Hugo directory.
|
||||
@@ -178,43 +208,49 @@ func NewSite(cmd *cobra.Command, args []string) error {
|
||||
|
||||
forceNew, _ := cmd.Flags().GetBool("force")
|
||||
|
||||
return doNewSite(createpath, forceNew)
|
||||
return doNewSite(hugofs.NewDefault(viper.New()), createpath, forceNew)
|
||||
}
|
||||
|
||||
// NewTheme creates a new Hugo theme.
|
||||
func NewTheme(cmd *cobra.Command, args []string) error {
|
||||
if err := InitializeConfig(); err != nil {
|
||||
cfg, err := InitializeConfig()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(args) < 1 {
|
||||
|
||||
return newUserError("theme name needs to be provided")
|
||||
}
|
||||
|
||||
createpath := helpers.AbsPathify(filepath.Join(viper.GetString("themesDir"), args[0]))
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
createpath := c.PathSpec().AbsPathify(filepath.Join(c.Cfg.GetString("themesDir"), args[0]))
|
||||
jww.INFO.Println("creating theme at", createpath)
|
||||
|
||||
if x, _ := helpers.Exists(createpath, hugofs.Source()); x {
|
||||
if x, _ := helpers.Exists(createpath, cfg.Fs.Source); x {
|
||||
return newUserError(createpath, "already exists")
|
||||
}
|
||||
|
||||
mkdir(createpath, "layouts", "_default")
|
||||
mkdir(createpath, "layouts", "partials")
|
||||
|
||||
touchFile(createpath, "layouts", "index.html")
|
||||
touchFile(createpath, "layouts", "404.html")
|
||||
touchFile(createpath, "layouts", "_default", "list.html")
|
||||
touchFile(createpath, "layouts", "_default", "single.html")
|
||||
touchFile(cfg.Fs.Source, createpath, "layouts", "index.html")
|
||||
touchFile(cfg.Fs.Source, createpath, "layouts", "404.html")
|
||||
touchFile(cfg.Fs.Source, createpath, "layouts", "_default", "list.html")
|
||||
touchFile(cfg.Fs.Source, createpath, "layouts", "_default", "single.html")
|
||||
|
||||
touchFile(createpath, "layouts", "partials", "header.html")
|
||||
touchFile(createpath, "layouts", "partials", "footer.html")
|
||||
touchFile(cfg.Fs.Source, createpath, "layouts", "partials", "header.html")
|
||||
touchFile(cfg.Fs.Source, createpath, "layouts", "partials", "footer.html")
|
||||
|
||||
mkdir(createpath, "archetypes")
|
||||
|
||||
archDefault := []byte("+++\n+++\n")
|
||||
|
||||
err := helpers.WriteToDisk(filepath.Join(createpath, "archetypes", "default.md"), bytes.NewReader(archDefault), hugofs.Source())
|
||||
err = helpers.WriteToDisk(filepath.Join(createpath, "archetypes", "default.md"), bytes.NewReader(archDefault), cfg.Fs.Source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -244,12 +280,12 @@ 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(filepath.Join(createpath, "LICENSE.md"), bytes.NewReader(by), hugofs.Source())
|
||||
err = helpers.WriteToDisk(filepath.Join(createpath, "LICENSE.md"), bytes.NewReader(by), cfg.Fs.Source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
createThemeMD(createpath)
|
||||
createThemeMD(cfg.Fs, createpath)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -263,16 +299,16 @@ func mkdir(x ...string) {
|
||||
}
|
||||
}
|
||||
|
||||
func touchFile(x ...string) {
|
||||
func touchFile(fs afero.Fs, x ...string) {
|
||||
inpath := filepath.Join(x...)
|
||||
mkdir(filepath.Dir(inpath))
|
||||
err := helpers.WriteToDisk(inpath, bytes.NewReader([]byte{}), hugofs.Source())
|
||||
err := helpers.WriteToDisk(inpath, bytes.NewReader([]byte{}), fs)
|
||||
if err != nil {
|
||||
jww.FATAL.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func createThemeMD(inpath string) (err error) {
|
||||
func createThemeMD(fs *hugofs.Fs, inpath string) (err error) {
|
||||
|
||||
by := []byte(`# theme.toml template for a Hugo theme
|
||||
# See https://github.com/spf13/hugoThemes#themetoml for an example
|
||||
@@ -282,9 +318,9 @@ license = "MIT"
|
||||
licenselink = "https://github.com/yourname/yourtheme/blob/master/LICENSE.md"
|
||||
description = ""
|
||||
homepage = "http://siteforthistheme.com/"
|
||||
tags = ["", ""]
|
||||
features = ["", ""]
|
||||
min_version = 0.17
|
||||
tags = []
|
||||
features = []
|
||||
min_version = "0.22"
|
||||
|
||||
[author]
|
||||
name = ""
|
||||
@@ -297,7 +333,7 @@ min_version = 0.17
|
||||
repo = ""
|
||||
`)
|
||||
|
||||
err = helpers.WriteToDisk(filepath.Join(inpath, "theme.toml"), bytes.NewReader(by), hugofs.Source())
|
||||
err = helpers.WriteToDisk(filepath.Join(inpath, "theme.toml"), bytes.NewReader(by), fs.Source)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -308,7 +344,7 @@ min_version = 0.17
|
||||
func newContentPathSection(path string) (string, string) {
|
||||
// Forward slashes is used in all examples. Convert if needed.
|
||||
// Issue #1133
|
||||
createpath := strings.Replace(path, "/", helpers.FilePathSeparator, -1)
|
||||
createpath := filepath.FromSlash(path)
|
||||
var section string
|
||||
// assume the first directory is the section (kind)
|
||||
if strings.Contains(createpath[1:], helpers.FilePathSeparator) {
|
||||
@@ -318,23 +354,19 @@ func newContentPathSection(path string) (string, string) {
|
||||
return createpath, section
|
||||
}
|
||||
|
||||
func createConfig(inpath string, kind string) (err error) {
|
||||
in := map[string]interface{}{
|
||||
"baseurl": "http://replace-this-with-your-hugo-site.com/",
|
||||
func createConfig(fs *hugofs.Fs, inpath string, kind string) (err error) {
|
||||
in := map[string]string{
|
||||
"baseURL": "http://example.org/",
|
||||
"title": "My New Hugo Site",
|
||||
"languageCode": "en-us",
|
||||
}
|
||||
kind = parser.FormatSanitize(kind)
|
||||
|
||||
by, err := parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind))
|
||||
var buf bytes.Buffer
|
||||
err = parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind), &buf)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = helpers.WriteToDisk(filepath.Join(inpath, "config."+kind), bytes.NewReader(by), hugofs.Source())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return nil
|
||||
return helpers.WriteToDisk(filepath.Join(inpath, "config."+kind), &buf, fs.Source)
|
||||
}
|
||||
|
||||
+57
-37
@@ -14,12 +14,13 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/hugo/hugofs"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// Issue #1133
|
||||
@@ -29,7 +30,8 @@ func TestNewContentPathSectionWithForwardSlashes(t *testing.T) {
|
||||
assert.Equal(t, "post", s)
|
||||
}
|
||||
|
||||
func checkNewSiteInited(basepath string, t *testing.T) {
|
||||
func checkNewSiteInited(fs *hugofs.Fs, basepath string, t *testing.T) {
|
||||
|
||||
paths := []string{
|
||||
filepath.Join(basepath, "layouts"),
|
||||
filepath.Join(basepath, "content"),
|
||||
@@ -40,63 +42,81 @@ func checkNewSiteInited(basepath string, t *testing.T) {
|
||||
}
|
||||
|
||||
for _, path := range paths {
|
||||
_, err := hugofs.Source().Stat(path)
|
||||
assert.Nil(t, err)
|
||||
_, err := fs.Source.Stat(path)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDoNewSite(t *testing.T) {
|
||||
basepath := filepath.Join(os.TempDir(), "blog")
|
||||
hugofs.InitMemFs()
|
||||
err := doNewSite(basepath, false)
|
||||
assert.Nil(t, err)
|
||||
basepath := filepath.Join("base", "blog")
|
||||
_, fs := newTestCfg()
|
||||
|
||||
checkNewSiteInited(basepath, t)
|
||||
require.NoError(t, doNewSite(fs, basepath, false))
|
||||
|
||||
checkNewSiteInited(fs, basepath, t)
|
||||
}
|
||||
|
||||
func TestDoNewSite_noerror_base_exists_but_empty(t *testing.T) {
|
||||
basepath := filepath.Join(os.TempDir(), "blog")
|
||||
hugofs.InitMemFs()
|
||||
hugofs.Source().MkdirAll(basepath, 777)
|
||||
err := doNewSite(basepath, false)
|
||||
assert.Nil(t, err)
|
||||
basepath := filepath.Join("base", "blog")
|
||||
_, fs := newTestCfg()
|
||||
|
||||
require.NoError(t, fs.Source.MkdirAll(basepath, 777))
|
||||
|
||||
require.NoError(t, doNewSite(fs, basepath, false))
|
||||
}
|
||||
|
||||
func TestDoNewSite_error_base_exists(t *testing.T) {
|
||||
basepath := filepath.Join(os.TempDir(), "blog")
|
||||
hugofs.InitMemFs()
|
||||
hugofs.Source().MkdirAll(basepath, 777)
|
||||
hugofs.Source().Create(filepath.Join(basepath, "foo"))
|
||||
basepath := filepath.Join("base", "blog")
|
||||
_, fs := newTestCfg()
|
||||
|
||||
require.NoError(t, fs.Source.MkdirAll(basepath, 777))
|
||||
_, err := fs.Source.Create(filepath.Join(basepath, "foo"))
|
||||
require.NoError(t, err)
|
||||
// Since the directory already exists and isn't empty, expect an error
|
||||
err := doNewSite(basepath, false)
|
||||
assert.NotNil(t, err)
|
||||
require.Error(t, doNewSite(fs, basepath, false))
|
||||
|
||||
}
|
||||
|
||||
func TestDoNewSite_force_empty_dir(t *testing.T) {
|
||||
basepath := filepath.Join(os.TempDir(), "blog")
|
||||
hugofs.InitMemFs()
|
||||
hugofs.Source().MkdirAll(basepath, 777)
|
||||
err := doNewSite(basepath, true)
|
||||
assert.Nil(t, err)
|
||||
basepath := filepath.Join("base", "blog")
|
||||
_, fs := newTestCfg()
|
||||
|
||||
checkNewSiteInited(basepath, t)
|
||||
require.NoError(t, fs.Source.MkdirAll(basepath, 777))
|
||||
|
||||
require.NoError(t, doNewSite(fs, basepath, true))
|
||||
|
||||
checkNewSiteInited(fs, basepath, t)
|
||||
}
|
||||
|
||||
func TestDoNewSite_error_force_dir_inside_exists(t *testing.T) {
|
||||
basepath := filepath.Join(os.TempDir(), "blog")
|
||||
basepath := filepath.Join("base", "blog")
|
||||
_, fs := newTestCfg()
|
||||
|
||||
contentPath := filepath.Join(basepath, "content")
|
||||
hugofs.InitMemFs()
|
||||
hugofs.Source().MkdirAll(contentPath, 777)
|
||||
err := doNewSite(basepath, true)
|
||||
assert.NotNil(t, err)
|
||||
|
||||
require.NoError(t, fs.Source.MkdirAll(contentPath, 777))
|
||||
require.Error(t, doNewSite(fs, basepath, true))
|
||||
}
|
||||
|
||||
func TestDoNewSite_error_force_config_inside_exists(t *testing.T) {
|
||||
basepath := filepath.Join(os.TempDir(), "blog")
|
||||
basepath := filepath.Join("base", "blog")
|
||||
_, fs := newTestCfg()
|
||||
|
||||
configPath := filepath.Join(basepath, "config.toml")
|
||||
hugofs.InitMemFs()
|
||||
hugofs.Source().MkdirAll(basepath, 777)
|
||||
hugofs.Source().Create(configPath)
|
||||
err := doNewSite(basepath, true)
|
||||
assert.NotNil(t, err)
|
||||
require.NoError(t, fs.Source.MkdirAll(basepath, 777))
|
||||
_, err := fs.Source.Create(configPath)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Error(t, doNewSite(fs, basepath, true))
|
||||
}
|
||||
|
||||
func newTestCfg() (*viper.Viper, *hugofs.Fs) {
|
||||
|
||||
v := viper.New()
|
||||
fs := hugofs.NewMem(v)
|
||||
|
||||
v.SetFs(fs.Source)
|
||||
|
||||
return v, fs
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// +build release
|
||||
|
||||
// Copyright 2017-present The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package commands
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/releaser"
|
||||
)
|
||||
|
||||
func init() {
|
||||
HugoCmd.AddCommand(createReleaser().cmd)
|
||||
}
|
||||
|
||||
type releaseCommandeer struct {
|
||||
cmd *cobra.Command
|
||||
|
||||
// Will be zero for main releases.
|
||||
patchLevel int
|
||||
|
||||
skipPublish bool
|
||||
|
||||
step int
|
||||
}
|
||||
|
||||
func createReleaser() *releaseCommandeer {
|
||||
// Note: This is a command only meant for internal use and must be run
|
||||
// via "go run -tags release main.go release" on the actual code base that is in the release.
|
||||
r := &releaseCommandeer{
|
||||
cmd: &cobra.Command{
|
||||
Use: "release",
|
||||
Short: "Release a new version of Hugo.",
|
||||
Hidden: true,
|
||||
},
|
||||
}
|
||||
|
||||
r.cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||
return r.release()
|
||||
}
|
||||
|
||||
r.cmd.PersistentFlags().IntVarP(&r.patchLevel, "patch", "p", 0, "patch level, defaults to 0 for main releases")
|
||||
r.cmd.PersistentFlags().IntVarP(&r.step, "step", "s", -1, "release step, defaults to -1 for all steps.")
|
||||
r.cmd.PersistentFlags().BoolVarP(&r.skipPublish, "skip-publish", "", false, "skip all publishing pipes of the release")
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *releaseCommandeer) release() error {
|
||||
return releaser.New(r.patchLevel, r.step, r.skipPublish).Run()
|
||||
}
|
||||
+40
-38
@@ -24,14 +24,11 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"mime"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/config"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"github.com/spf13/hugo/hugofs"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -43,8 +40,6 @@ var (
|
||||
serverWatch bool
|
||||
)
|
||||
|
||||
//var serverCmdV *cobra.Command
|
||||
|
||||
var serverCmd = &cobra.Command{
|
||||
Use: "server",
|
||||
Aliases: []string{"serve"},
|
||||
@@ -90,7 +85,7 @@ func init() {
|
||||
serverCmd.Flags().IntVarP(&serverPort, "port", "p", 1313, "port on which the server will listen")
|
||||
serverCmd.Flags().StringVarP(&serverInterface, "bind", "", "127.0.0.1", "interface to which the server will bind")
|
||||
serverCmd.Flags().BoolVarP(&serverWatch, "watch", "w", true, "watch filesystem for changes and recreate as needed")
|
||||
serverCmd.Flags().BoolVarP(&serverAppend, "appendPort", "", true, "append port to baseurl")
|
||||
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.Flags().BoolVar(&renderToDisk, "renderToDisk", false, "render to Destination path (default is render to memory & serve from there)")
|
||||
serverCmd.Flags().String("memstats", "", "log memory usage to this file")
|
||||
@@ -98,34 +93,37 @@ func init() {
|
||||
|
||||
serverCmd.RunE = server
|
||||
|
||||
mime.AddExtensionType(".json", "application/json; charset=utf-8")
|
||||
mime.AddExtensionType(".css", "text/css; charset=utf-8")
|
||||
|
||||
}
|
||||
|
||||
func server(cmd *cobra.Command, args []string) error {
|
||||
if err := InitializeConfig(serverCmd); err != nil {
|
||||
cfg, err := InitializeConfig(serverCmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if flagChanged(cmd.Flags(), "disableLiveReload") {
|
||||
viper.Set("DisableLiveReload", disableLiveReload)
|
||||
c, err := newCommandeer(cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if cmd.Flags().Changed("disableLiveReload") {
|
||||
c.Set("disableLiveReload", disableLiveReload)
|
||||
}
|
||||
|
||||
if serverWatch {
|
||||
viper.Set("Watch", true)
|
||||
c.Set("watch", true)
|
||||
}
|
||||
|
||||
if viper.GetBool("watch") {
|
||||
if c.Cfg.GetBool("watch") {
|
||||
serverWatch = true
|
||||
watchConfig()
|
||||
c.watchConfig()
|
||||
}
|
||||
|
||||
l, err := net.Listen("tcp", net.JoinHostPort(serverInterface, strconv.Itoa(serverPort)))
|
||||
if err == nil {
|
||||
l.Close()
|
||||
} else {
|
||||
if flagChanged(serverCmd.Flags(), "port") {
|
||||
if serverCmd.Flags().Changed("port") {
|
||||
// port set explicitly by user -- he/she probably meant it!
|
||||
return newSystemErrorF("Server startup failed: %s", err)
|
||||
}
|
||||
@@ -137,13 +135,13 @@ func server(cmd *cobra.Command, args []string) error {
|
||||
serverPort = sp.Port
|
||||
}
|
||||
|
||||
viper.Set("port", serverPort)
|
||||
c.Set("port", serverPort)
|
||||
|
||||
BaseURL, err := fixURL(baseURL)
|
||||
baseURL, err = fixURL(c.Cfg, baseURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
viper.Set("BaseURL", BaseURL)
|
||||
c.Set("baseURL", baseURL)
|
||||
|
||||
if err := memStats(); err != nil {
|
||||
jww.ERROR.Println("memstats error:", err)
|
||||
@@ -156,19 +154,23 @@ func server(cmd *cobra.Command, args []string) error {
|
||||
|
||||
// Hugo writes the output to memory instead of the disk
|
||||
if !renderToDisk {
|
||||
hugofs.SetDestination(new(afero.MemMapFs))
|
||||
cfg.Fs.Destination = new(afero.MemMapFs)
|
||||
// Rendering to memoryFS, publish to Root regardless of publishDir.
|
||||
viper.Set("PublishDir", "/")
|
||||
c.Set("publishDir", "/")
|
||||
}
|
||||
|
||||
if err := build(serverWatch); err != nil {
|
||||
if err := c.build(serverWatch); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, s := range Hugo.Sites {
|
||||
s.RegisterMediaTypes()
|
||||
}
|
||||
|
||||
// Watch runs its own server as part of the routine
|
||||
if serverWatch {
|
||||
watchDirs := getDirList()
|
||||
baseWatchDir := viper.GetString("WorkingDir")
|
||||
watchDirs := c.getDirList()
|
||||
baseWatchDir := c.Cfg.GetString("workingDir")
|
||||
for i, dir := range watchDirs {
|
||||
watchDirs[i], _ = helpers.GetRelativePath(dir, baseWatchDir)
|
||||
}
|
||||
@@ -176,33 +178,33 @@ func server(cmd *cobra.Command, args []string) error {
|
||||
rootWatchDirs := strings.Join(helpers.UniqueStrings(helpers.ExtractRootPaths(watchDirs)), ",")
|
||||
|
||||
jww.FEEDBACK.Printf("Watching for changes in %s%s{%s}\n", baseWatchDir, helpers.FilePathSeparator, rootWatchDirs)
|
||||
err := NewWatcher(serverPort)
|
||||
err := c.newWatcher(serverPort)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
serve(serverPort)
|
||||
c.serve(serverPort)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func serve(port int) {
|
||||
func (c *commandeer) serve(port int) {
|
||||
if renderToDisk {
|
||||
jww.FEEDBACK.Println("Serving pages from " + helpers.AbsPathify(viper.GetString("PublishDir")))
|
||||
jww.FEEDBACK.Println("Serving pages from " + c.PathSpec().AbsPathify(c.Cfg.GetString("publishDir")))
|
||||
} else {
|
||||
jww.FEEDBACK.Println("Serving pages from memory")
|
||||
}
|
||||
|
||||
httpFs := afero.NewHttpFs(hugofs.Destination())
|
||||
fs := filesOnlyFs{httpFs.Dir(helpers.AbsPathify(viper.GetString("PublishDir")))}
|
||||
httpFs := afero.NewHttpFs(c.Fs.Destination)
|
||||
fs := filesOnlyFs{httpFs.Dir(c.PathSpec().AbsPathify(c.Cfg.GetString("publishDir")))}
|
||||
fileserver := http.FileServer(fs)
|
||||
|
||||
// We're only interested in the path
|
||||
u, err := url.Parse(viper.GetString("BaseURL"))
|
||||
u, err := url.Parse(c.Cfg.GetString("baseURL"))
|
||||
if err != nil {
|
||||
jww.ERROR.Fatalf("Invalid BaseURL: %s", err)
|
||||
jww.ERROR.Fatalf("Invalid baseURL: %s", err)
|
||||
}
|
||||
if u.Path == "" || u.Path == "/" {
|
||||
http.Handle("/", fileserver)
|
||||
@@ -211,7 +213,7 @@ func serve(port int) {
|
||||
}
|
||||
|
||||
jww.FEEDBACK.Printf("Web Server is available at %s (bind address %s)\n", u.String(), serverInterface)
|
||||
fmt.Println("Press Ctrl+C to stop")
|
||||
jww.FEEDBACK.Println("Press Ctrl+C to stop")
|
||||
|
||||
endpoint := net.JoinHostPort(serverInterface, strconv.Itoa(port))
|
||||
err = http.ListenAndServe(endpoint, nil)
|
||||
@@ -221,12 +223,12 @@ func serve(port int) {
|
||||
}
|
||||
}
|
||||
|
||||
// fixURL massages the BaseURL into a form needed for serving
|
||||
// fixURL massages the baseURL into a form needed for serving
|
||||
// all pages correctly.
|
||||
func fixURL(s string) (string, error) {
|
||||
func fixURL(cfg config.Provider, s string) (string, error) {
|
||||
useLocalhost := false
|
||||
if s == "" {
|
||||
s = viper.GetString("BaseURL")
|
||||
s = cfg.GetString("baseURL")
|
||||
useLocalhost = true
|
||||
}
|
||||
|
||||
@@ -262,7 +264,7 @@ func fixURL(s string) (string, error) {
|
||||
if strings.Contains(u.Host, ":") {
|
||||
u.Host, _, err = net.SplitHostPort(u.Host)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Failed to split BaseURL hostpost: %s", err)
|
||||
return "", fmt.Errorf("Failed to split baseURL hostpost: %s", err)
|
||||
}
|
||||
}
|
||||
u.Host += fmt.Sprintf(":%d", serverPort)
|
||||
|
||||
@@ -20,8 +20,6 @@ import (
|
||||
)
|
||||
|
||||
func TestFixURL(t *testing.T) {
|
||||
defer viper.Reset()
|
||||
|
||||
type data struct {
|
||||
TestName string
|
||||
CLIBaseURL string
|
||||
@@ -44,12 +42,12 @@ func TestFixURL(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
viper.Reset()
|
||||
v := viper.New()
|
||||
baseURL = test.CLIBaseURL
|
||||
viper.Set("BaseURL", test.CfgBaseURL)
|
||||
v.Set("baseURL", test.CfgBaseURL)
|
||||
serverAppend = test.AppendPort
|
||||
serverPort = test.Port
|
||||
result, err := fixURL(baseURL)
|
||||
result, err := fixURL(v, baseURL)
|
||||
if err != nil {
|
||||
t.Errorf("Test #%d %s: unexpected error %s", i, test.TestName, err)
|
||||
}
|
||||
|
||||
+10
-10
@@ -15,12 +15,11 @@ package commands
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"errors"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/hugofs"
|
||||
"github.com/spf13/hugo/parser"
|
||||
)
|
||||
|
||||
@@ -37,7 +36,9 @@ If the content's draft status is 'False', nothing is done.`,
|
||||
// to false and setting its publish date to now. If the specified content is
|
||||
// not a draft, it will log an error.
|
||||
func Undraft(cmd *cobra.Command, args []string) error {
|
||||
if err := InitializeConfig(); err != nil {
|
||||
cfg, err := InitializeConfig()
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -47,7 +48,7 @@ func Undraft(cmd *cobra.Command, args []string) error {
|
||||
|
||||
location := args[0]
|
||||
// open the file
|
||||
f, err := hugofs.Source().Open(location)
|
||||
f, err := cfg.Fs.Source.Open(location)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -64,7 +65,7 @@ func Undraft(cmd *cobra.Command, args []string) error {
|
||||
return newSystemErrorF("an error occurred while undrafting %q: %s", location, err)
|
||||
}
|
||||
|
||||
f, err = hugofs.Source().OpenFile(location, os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
f, err = cfg.Fs.Source.OpenFile(location, os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
if err != nil {
|
||||
return newSystemErrorF("%q not be undrafted due to error opening file to save changes: %q\n", location, err)
|
||||
}
|
||||
@@ -90,8 +91,7 @@ func undraftContent(p parser.Page) (bytes.Buffer, error) {
|
||||
// Front Matter
|
||||
fm := p.FrontMatter()
|
||||
if fm == nil {
|
||||
err := fmt.Errorf("Front Matter was found, nothing was finalized")
|
||||
return buff, err
|
||||
return buff, errors.New("Front Matter was found, nothing was finalized")
|
||||
}
|
||||
|
||||
var isDraft, gotDate bool
|
||||
@@ -101,7 +101,7 @@ L:
|
||||
switch k {
|
||||
case "draft":
|
||||
if !v.(bool) {
|
||||
return buff, fmt.Errorf("not a Draft: nothing was done")
|
||||
return buff, errors.New("not a Draft: nothing was done")
|
||||
}
|
||||
isDraft = true
|
||||
if gotDate {
|
||||
@@ -118,7 +118,7 @@ L:
|
||||
|
||||
// if draft wasn't found in FrontMatter, it isn't a draft.
|
||||
if !isDraft {
|
||||
return buff, fmt.Errorf("not a Draft: nothing was done")
|
||||
return buff, errors.New("not a Draft: nothing was done")
|
||||
}
|
||||
|
||||
// get the front matter as bytes and split it into lines
|
||||
@@ -127,7 +127,7 @@ L:
|
||||
if len(fmLines) == 1 { // if the result is only 1 element, try to split on dos line endings
|
||||
fmLines = bytes.Split(fm, []byte("\r\n"))
|
||||
if len(fmLines) == 1 {
|
||||
return buff, fmt.Errorf("unable to split FrontMatter into lines")
|
||||
return buff, errors.New("unable to split FrontMatter into lines")
|
||||
}
|
||||
lineEnding = append(lineEnding, []byte("\r\n")...)
|
||||
} else {
|
||||
|
||||
@@ -46,17 +46,17 @@ func TestUndraftContent(t *testing.T) {
|
||||
{yamlDraftFM, ""},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
for i, test := range tests {
|
||||
r := bytes.NewReader([]byte(test.fm))
|
||||
p, _ := parser.ReadFrom(r)
|
||||
res, err := undraftContent(p)
|
||||
if test.expectedErr != "" {
|
||||
if err == nil {
|
||||
t.Error("Expected error, got none")
|
||||
t.Errorf("[%d] Expected error, got none", i)
|
||||
continue
|
||||
}
|
||||
if err.Error() != test.expectedErr {
|
||||
t.Errorf("Expected %q, got %q", test.expectedErr, err)
|
||||
t.Errorf("[%d] Expected %q, got %q", i, test.expectedErr, err)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
@@ -64,19 +64,19 @@ func TestUndraftContent(t *testing.T) {
|
||||
p, _ = parser.ReadFrom(r)
|
||||
meta, err := p.Metadata()
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error %q", err)
|
||||
t.Errorf("[%d] unexpected error %q", i, err)
|
||||
continue
|
||||
}
|
||||
for k, v := range meta.(map[string]interface{}) {
|
||||
if k == "draft" {
|
||||
if v.(bool) {
|
||||
t.Errorf("Expected %q to be \"false\", got \"true\"", k)
|
||||
t.Errorf("[%d] Expected %q to be \"false\", got \"true\"", i, k)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if k == "date" {
|
||||
if !strings.HasPrefix(v.(string), time.Now().Format("2006-01-02")) {
|
||||
t.Errorf("Expected %v to start with %v", v.(string), time.Now().Format("2006-01-02"))
|
||||
t.Errorf("[%d] Expected %v to start with %v", i, v.(string), time.Now().Format("2006-01-02"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -14,9 +14,9 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"github.com/spf13/hugo/hugolib"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
|
||||
var versionCmd = &cobra.Command{
|
||||
@@ -32,7 +33,6 @@ var versionCmd = &cobra.Command{
|
||||
Long: `All software has versions. This is Hugo's.`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
printHugoVersion()
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
@@ -44,9 +44,9 @@ func printHugoVersion() {
|
||||
formatBuildDate() // format the compile time
|
||||
}
|
||||
if hugolib.CommitHash == "" {
|
||||
fmt.Printf("Hugo Static Site Generator v%s BuildDate: %s\n", helpers.HugoVersion(), hugolib.BuildDate)
|
||||
jww.FEEDBACK.Printf("Hugo Static Site Generator v%s %s/%s BuildDate: %s\n", helpers.CurrentHugoVersion, runtime.GOOS, runtime.GOARCH, hugolib.BuildDate)
|
||||
} else {
|
||||
fmt.Printf("Hugo Static Site Generator v%s-%s BuildDate: %s\n", helpers.HugoVersion(), strings.ToUpper(hugolib.CommitHash), hugolib.BuildDate)
|
||||
jww.FEEDBACK.Printf("Hugo Static Site Generator v%s-%s %s/%s BuildDate: %s\n", helpers.CurrentHugoVersion, strings.ToUpper(hugolib.CommitHash), runtime.GOOS, runtime.GOARCH, hugolib.BuildDate)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,12 +60,12 @@ func setBuildDate() {
|
||||
fname, _ := osext.Executable()
|
||||
dir, err := filepath.Abs(filepath.Dir(fname))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
jww.ERROR.Println(err)
|
||||
return
|
||||
}
|
||||
fi, err := os.Lstat(filepath.Join(dir, filepath.Base(fname)))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
jww.ERROR.Println(err)
|
||||
return
|
||||
}
|
||||
t := fi.ModTime()
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright 2017-present The Hugo Authors. All rights reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package config
|
||||
|
||||
// Provider provides the configuration settings for Hugo.
|
||||
type Provider interface {
|
||||
GetString(key string) string
|
||||
GetInt(key string) int
|
||||
GetBool(key string) bool
|
||||
GetStringMap(key string) map[string]interface{}
|
||||
GetStringMapString(key string) map[string]string
|
||||
Get(key string) interface{}
|
||||
Set(key string, value interface{})
|
||||
IsSet(key string) bool
|
||||
}
|
||||
+38
-40
@@ -18,7 +18,6 @@ import (
|
||||
"bytes"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -29,26 +28,25 @@ import (
|
||||
"github.com/spf13/hugo/hugolib"
|
||||
"github.com/spf13/hugo/parser"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// NewContent creates a new content file in the content directory based upon the
|
||||
// given kind, which is used to lookup an archetype.
|
||||
func NewContent(fs afero.Fs, kind, name string) (err error) {
|
||||
func NewContent(s *hugolib.Site, kind, name string) (err error) {
|
||||
jww.INFO.Println("attempting to create ", name, "of", kind)
|
||||
|
||||
location := FindArchetype(fs, kind)
|
||||
location := FindArchetype(s, kind)
|
||||
|
||||
var by []byte
|
||||
|
||||
if location != "" {
|
||||
by, err = afero.ReadFile(fs, location)
|
||||
by, err = afero.ReadFile(s.Fs.Source, location)
|
||||
if err != nil {
|
||||
jww.ERROR.Println(err)
|
||||
}
|
||||
}
|
||||
if location == "" || err != nil {
|
||||
by = []byte("+++\n title = \"title\"\n draft = true \n+++\n")
|
||||
by = []byte("+++\ndraft = true \n+++\n")
|
||||
}
|
||||
|
||||
psr, err := parser.ReadFrom(bytes.NewReader(by))
|
||||
@@ -62,28 +60,29 @@ func NewContent(fs afero.Fs, kind, name string) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
page, err := hugolib.NewPage(name)
|
||||
page, err := s.NewPage(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = page.SetSourceMetaData(metadata, parser.FormatToLeadRune(viper.GetString("MetaDataFormat"))); err != nil {
|
||||
if err = page.SetSourceMetaData(metadata, parser.FormatToLeadRune(s.Cfg.GetString("metaDataFormat"))); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
page.SetSourceContent(psr.Content())
|
||||
|
||||
if err = page.SafeSaveSourceAs(filepath.Join(viper.GetString("contentDir"), name)); err != nil {
|
||||
contentPath := s.PathSpec.AbsPathify(filepath.Join(s.Cfg.GetString("contentDir"), name))
|
||||
|
||||
if err = page.SafeSaveSourceAs(contentPath); err != nil {
|
||||
return
|
||||
}
|
||||
jww.FEEDBACK.Println(helpers.AbsPathify(filepath.Join(viper.GetString("contentDir"), name)), "created")
|
||||
|
||||
editor := viper.GetString("NewContentEditor")
|
||||
jww.FEEDBACK.Println(contentPath, "created")
|
||||
|
||||
editor := s.Cfg.GetString("newContentEditor")
|
||||
if editor != "" {
|
||||
jww.FEEDBACK.Printf("Editing %s with %q ...\n", name, editor)
|
||||
|
||||
cmd := exec.Command(editor, helpers.AbsPathify(path.Join(viper.GetString("contentDir"), name)))
|
||||
cmd := exec.Command(editor, contentPath)
|
||||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
@@ -107,39 +106,38 @@ func createMetadata(archetype parser.Page, name string) (map[string]interface{},
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for k := range metadata {
|
||||
switch strings.ToLower(k) {
|
||||
case "date":
|
||||
metadata[k] = time.Now()
|
||||
case "title":
|
||||
metadata[k] = helpers.MakeTitle(helpers.Filename(name))
|
||||
}
|
||||
}
|
||||
var date time.Time
|
||||
|
||||
caseimatch := func(m map[string]interface{}, key string) bool {
|
||||
for k := range m {
|
||||
if strings.ToLower(k) == strings.ToLower(key) {
|
||||
return true
|
||||
}
|
||||
for k, v := range metadata {
|
||||
if v == "" {
|
||||
continue
|
||||
}
|
||||
lk := strings.ToLower(k)
|
||||
switch lk {
|
||||
case "date":
|
||||
date, err = cast.ToTimeE(v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case "title":
|
||||
// Use the archetype title as is
|
||||
metadata[lk] = v
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
if metadata == nil {
|
||||
metadata = make(map[string]interface{})
|
||||
}
|
||||
|
||||
if !caseimatch(metadata, "date") {
|
||||
metadata["date"] = time.Now()
|
||||
if date.IsZero() {
|
||||
date = time.Now()
|
||||
}
|
||||
|
||||
if !caseimatch(metadata, "title") {
|
||||
if _, ok := metadata["title"]; !ok {
|
||||
metadata["title"] = helpers.MakeTitle(helpers.Filename(name))
|
||||
}
|
||||
|
||||
if x := parser.FormatSanitize(viper.GetString("MetaDataFormat")); x == "json" || x == "yaml" || x == "toml" {
|
||||
metadata["date"] = time.Now().Format(time.RFC3339)
|
||||
}
|
||||
metadata["date"] = date.Format(time.RFC3339)
|
||||
|
||||
return metadata, nil
|
||||
}
|
||||
@@ -147,13 +145,13 @@ func createMetadata(archetype parser.Page, name string) (map[string]interface{},
|
||||
// FindArchetype takes a given kind/archetype of content and returns an output
|
||||
// path for that archetype. If no archetype is found, an empty string is
|
||||
// returned.
|
||||
func FindArchetype(fs afero.Fs, kind string) (outpath string) {
|
||||
search := []string{helpers.AbsPathify(viper.GetString("archetypeDir"))}
|
||||
func FindArchetype(s *hugolib.Site, kind string) (outpath string) {
|
||||
search := []string{s.PathSpec.AbsPathify(s.Cfg.GetString("archetypeDir"))}
|
||||
|
||||
if viper.GetString("theme") != "" {
|
||||
themeDir := filepath.Join(helpers.AbsPathify(viper.GetString("themesDir")+"/"+viper.GetString("theme")), "/archetypes/")
|
||||
if _, err := fs.Stat(themeDir); os.IsNotExist(err) {
|
||||
jww.ERROR.Printf("Unable to find archetypes directory for theme %q at %q", viper.GetString("theme"), themeDir)
|
||||
if s.Cfg.GetString("theme") != "" {
|
||||
themeDir := filepath.Join(s.PathSpec.AbsPathify(s.Cfg.GetString("themesDir")+"/"+s.Cfg.GetString("theme")), "/archetypes/")
|
||||
if _, err := s.Fs.Source.Stat(themeDir); os.IsNotExist(err) {
|
||||
jww.ERROR.Printf("Unable to find archetypes directory for theme %q at %q", s.Cfg.GetString("theme"), themeDir)
|
||||
} else {
|
||||
search = append(search, themeDir)
|
||||
}
|
||||
@@ -173,7 +171,7 @@ func FindArchetype(fs afero.Fs, kind string) (outpath string) {
|
||||
for _, p := range pathsToCheck {
|
||||
curpath := filepath.Join(x, p)
|
||||
jww.DEBUG.Println("checking", curpath, "for archetypes")
|
||||
if exists, _ := helpers.Exists(curpath, fs); exists {
|
||||
if exists, _ := helpers.Exists(curpath, s.Fs.Source); exists {
|
||||
jww.INFO.Println("curpath: " + curpath)
|
||||
return curpath
|
||||
}
|
||||
|
||||
+81
-42
@@ -16,68 +16,72 @@ package create_test
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/hugo/deps"
|
||||
|
||||
"github.com/spf13/hugo/hugolib"
|
||||
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/hugo/hugofs"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/hugo/create"
|
||||
"github.com/spf13/hugo/hugofs"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestNewContent(t *testing.T) {
|
||||
initViper()
|
||||
|
||||
err := initFs()
|
||||
if err != nil {
|
||||
t.Fatalf("initialization error: %s", err)
|
||||
}
|
||||
v := viper.New()
|
||||
initViper(v)
|
||||
|
||||
cases := []struct {
|
||||
kind string
|
||||
path string
|
||||
resultStrings []string
|
||||
kind string
|
||||
path string
|
||||
expected []string
|
||||
}{
|
||||
{"post", "post/sample-1.md", []string{`title = "sample 1"`, `test = "test1"`}},
|
||||
{"post", "post/sample-1.md", []string{`title = "Post Arch title"`, `test = "test1"`, "date = \"2015-01-12T19:20:04-07:00\""}},
|
||||
{"emptydate", "post/sample-ed.md", []string{`title = "Empty Date Arch title"`, `test = "test1"`}},
|
||||
{"stump", "stump/sample-2.md", []string{`title = "sample 2"`}}, // no archetype file
|
||||
{"", "sample-3.md", []string{`title = "sample 3"`}}, // no archetype
|
||||
{"product", "product/sample-4.md", []string{`title = "sample 4"`}}, // empty archetype front matter
|
||||
}
|
||||
|
||||
for i, c := range cases {
|
||||
err = create.NewContent(hugofs.Source(), c.kind, c.path)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] NewContent: %s", i, err)
|
||||
}
|
||||
for _, c := range cases {
|
||||
cfg, fs := newTestCfg()
|
||||
h, err := hugolib.NewHugoSites(deps.DepsCfg{Cfg: cfg, Fs: fs})
|
||||
require.NoError(t, err)
|
||||
require.NoError(t, initFs(fs))
|
||||
|
||||
fname := filepath.Join(os.TempDir(), "content", filepath.FromSlash(c.path))
|
||||
_, err = hugofs.Source().Stat(fname)
|
||||
if err != nil {
|
||||
t.Errorf("[%d] Stat: %s", i, err)
|
||||
}
|
||||
s := h.Sites[0]
|
||||
|
||||
for _, v := range c.resultStrings {
|
||||
found, err := afero.FileContainsBytes(hugofs.Source(), fname, []byte(v))
|
||||
if err != nil {
|
||||
t.Errorf("[%d] FileContainsBytes: %s", i, err)
|
||||
}
|
||||
require.NoError(t, create.NewContent(s, c.kind, c.path))
|
||||
|
||||
fname := filepath.Join("content", filepath.FromSlash(c.path))
|
||||
content := readFileFromFs(t, fs.Source, fname)
|
||||
for i, v := range c.expected {
|
||||
found := strings.Contains(content, v)
|
||||
if !found {
|
||||
t.Errorf("content missing from output: %q", v)
|
||||
t.Errorf("[%d] %q missing from output:\n%q", i, v, content)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func initViper() {
|
||||
viper.Reset()
|
||||
viper.Set("MetaDataFormat", "toml")
|
||||
viper.Set("archetypeDir", filepath.Join(os.TempDir(), "archetypes"))
|
||||
viper.Set("contentDir", filepath.Join(os.TempDir(), "content"))
|
||||
viper.Set("themesDir", filepath.Join(os.TempDir(), "themes"))
|
||||
viper.Set("theme", "sample")
|
||||
func initViper(v *viper.Viper) {
|
||||
v.Set("metaDataFormat", "toml")
|
||||
v.Set("archetypeDir", "archetypes")
|
||||
v.Set("contentDir", "content")
|
||||
v.Set("themesDir", "themes")
|
||||
v.Set("layoutDir", "layouts")
|
||||
v.Set("i18nDir", "i18n")
|
||||
v.Set("theme", "sample")
|
||||
}
|
||||
|
||||
func initFs() error {
|
||||
hugofs.SetSource(new(afero.MemMapFs))
|
||||
func initFs(fs *hugofs.Fs) error {
|
||||
perm := os.FileMode(0755)
|
||||
var err error
|
||||
|
||||
@@ -88,8 +92,7 @@ func initFs() error {
|
||||
filepath.Join("themes", "sample", "archetypes"),
|
||||
}
|
||||
for _, dir := range dirs {
|
||||
dir = filepath.Join(os.TempDir(), dir)
|
||||
err = hugofs.Source().Mkdir(dir, perm)
|
||||
err = fs.Source.Mkdir(dir, perm)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -101,15 +104,19 @@ func initFs() error {
|
||||
content string
|
||||
}{
|
||||
{
|
||||
path: filepath.Join(os.TempDir(), "archetypes", "post.md"),
|
||||
content: "+++\ndate = \"2015-01-12T19:20:04-07:00\"\ntitle = \"post arch\"\ntest = \"test1\"\n+++\n",
|
||||
path: filepath.Join("archetypes", "post.md"),
|
||||
content: "+++\ndate = \"2015-01-12T19:20:04-07:00\"\ntitle = \"Post Arch title\"\ntest = \"test1\"\n+++\n",
|
||||
},
|
||||
{
|
||||
path: filepath.Join(os.TempDir(), "archetypes", "product.md"),
|
||||
path: filepath.Join("archetypes", "product.md"),
|
||||
content: "+++\n+++\n",
|
||||
},
|
||||
{
|
||||
path: filepath.Join("archetypes", "emptydate.md"),
|
||||
content: "+++\ndate =\"\"\ntitle = \"Empty Date Arch title\"\ntest = \"test1\"\n+++\n",
|
||||
},
|
||||
} {
|
||||
f, err := hugofs.Source().Create(v.path)
|
||||
f, err := fs.Source.Create(v.path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -123,3 +130,35 @@ func initFs() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO(bep) extract common testing package with this and some others
|
||||
func readFileFromFs(t *testing.T, fs afero.Fs, filename string) string {
|
||||
filename = filepath.FromSlash(filename)
|
||||
b, err := afero.ReadFile(fs, filename)
|
||||
if err != nil {
|
||||
// Print some debug info
|
||||
root := strings.Split(filename, helpers.FilePathSeparator)[0]
|
||||
afero.Walk(fs, root, func(path string, info os.FileInfo, err error) error {
|
||||
if info != nil && !info.IsDir() {
|
||||
fmt.Println(" ", path)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
t.Fatalf("Failed to read file: %s", err)
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func newTestCfg() (*viper.Viper, *hugofs.Fs) {
|
||||
|
||||
v := viper.New()
|
||||
fs := hugofs.NewMem(v)
|
||||
|
||||
v.SetFs(fs.Source)
|
||||
|
||||
initViper(v)
|
||||
|
||||
return v, fs
|
||||
|
||||
}
|
||||
|
||||
Vendored
+176
@@ -0,0 +1,176 @@
|
||||
package deps
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/hugo/config"
|
||||
"github.com/spf13/hugo/helpers"
|
||||
"github.com/spf13/hugo/hugofs"
|
||||
"github.com/spf13/hugo/output"
|
||||
"github.com/spf13/hugo/tpl"
|
||||
jww "github.com/spf13/jwalterweatherman"
|
||||
)
|
||||
|
||||
// Deps holds dependencies used by many.
|
||||
// There will be normally be only one instance of deps in play
|
||||
// at a given time, i.e. one per Site built.
|
||||
type Deps struct {
|
||||
// The logger to use.
|
||||
Log *jww.Notepad `json:"-"`
|
||||
|
||||
// The templates to use. This will usually implement the full tpl.TemplateHandler.
|
||||
Tmpl tpl.TemplateFinder `json:"-"`
|
||||
|
||||
// The file systems to use.
|
||||
Fs *hugofs.Fs `json:"-"`
|
||||
|
||||
// The PathSpec to use
|
||||
*helpers.PathSpec `json:"-"`
|
||||
|
||||
// The ContentSpec to use
|
||||
*helpers.ContentSpec `json:"-"`
|
||||
|
||||
// The configuration to use
|
||||
Cfg config.Provider `json:"-"`
|
||||
|
||||
// The translation func to use
|
||||
Translate func(translationID string, args ...interface{}) string `json:"-"`
|
||||
|
||||
Language *helpers.Language
|
||||
|
||||
// All the output formats available for the current site.
|
||||
OutputFormatsConfig output.Formats
|
||||
|
||||
templateProvider ResourceProvider
|
||||
WithTemplate func(templ tpl.TemplateHandler) error `json:"-"`
|
||||
|
||||
translationProvider ResourceProvider
|
||||
}
|
||||
|
||||
// ResourceProvider is used to create and refresh, and clone resources needed.
|
||||
type ResourceProvider interface {
|
||||
Update(deps *Deps) error
|
||||
Clone(deps *Deps) error
|
||||
}
|
||||
|
||||
func (d *Deps) TemplateHandler() tpl.TemplateHandler {
|
||||
return d.Tmpl.(tpl.TemplateHandler)
|
||||
}
|
||||
|
||||
func (d *Deps) LoadResources() error {
|
||||
// Note that the translations need to be loaded before the templates.
|
||||
if err := d.translationProvider.Update(d); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := d.templateProvider.Update(d); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if th, ok := d.Tmpl.(tpl.TemplateHandler); ok {
|
||||
th.PrintErrors()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func New(cfg DepsCfg) (*Deps, error) {
|
||||
var (
|
||||
logger = cfg.Logger
|
||||
fs = cfg.Fs
|
||||
)
|
||||
|
||||
if cfg.TemplateProvider == nil {
|
||||
panic("Must have a TemplateProvider")
|
||||
}
|
||||
|
||||
if cfg.TranslationProvider == nil {
|
||||
panic("Must have a TranslationProvider")
|
||||
}
|
||||
|
||||
if cfg.Language == nil {
|
||||
panic("Must have a Language")
|
||||
}
|
||||
|
||||
if logger == nil {
|
||||
logger = jww.NewNotepad(jww.LevelError, jww.LevelError, os.Stdout, ioutil.Discard, "", log.Ldate|log.Ltime)
|
||||
}
|
||||
|
||||
if fs == nil {
|
||||
// Default to the production file system.
|
||||
fs = hugofs.NewDefault(cfg.Language)
|
||||
}
|
||||
|
||||
ps, err := helpers.NewPathSpec(fs, cfg.Language)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d := &Deps{
|
||||
Fs: fs,
|
||||
Log: logger,
|
||||
templateProvider: cfg.TemplateProvider,
|
||||
translationProvider: cfg.TranslationProvider,
|
||||
WithTemplate: cfg.WithTemplate,
|
||||
PathSpec: ps,
|
||||
ContentSpec: helpers.NewContentSpec(cfg.Language),
|
||||
Cfg: cfg.Language,
|
||||
Language: cfg.Language,
|
||||
}
|
||||
|
||||
return d, nil
|
||||
}
|
||||
|
||||
// ForLanguage creates a copy of the Deps with the language dependent
|
||||
// parts switched out.
|
||||
func (d Deps) ForLanguage(l *helpers.Language) (*Deps, error) {
|
||||
var err error
|
||||
|
||||
d.PathSpec, err = helpers.NewPathSpec(d.Fs, l)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
d.ContentSpec = helpers.NewContentSpec(l)
|
||||
d.Cfg = l
|
||||
d.Language = l
|
||||
|
||||
if err := d.translationProvider.Clone(&d); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := d.templateProvider.Clone(&d); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &d, nil
|
||||
|
||||
}
|
||||
|
||||
// DepsCfg contains configuration options that can be used to configure Hugo
|
||||
// on a global level, i.e. logging etc.
|
||||
// Nil values will be given default values.
|
||||
type DepsCfg struct {
|
||||
|
||||
// The Logger to use.
|
||||
Logger *jww.Notepad
|
||||
|
||||
// The file systems to use
|
||||
Fs *hugofs.Fs
|
||||
|
||||
// The language to use.
|
||||
Language *helpers.Language
|
||||
|
||||
// The configuration to use.
|
||||
Cfg config.Provider
|
||||
|
||||
// Template handling.
|
||||
TemplateProvider ResourceProvider
|
||||
WithTemplate func(templ tpl.TemplateHandler) error
|
||||
|
||||
// i18n handling.
|
||||
TranslationProvider ResourceProvider
|
||||
}
|
||||
@@ -9,6 +9,7 @@ pluralizeListTitles = false
|
||||
[params]
|
||||
description = "Documentation of Hugo, a fast and flexible static site generator built with love by spf13, bep and friends in Go"
|
||||
author = "Steve Francia (spf13) and friends"
|
||||
release = "0.22"
|
||||
|
||||
[taxonomies]
|
||||
tag = "tags"
|
||||
@@ -44,6 +45,11 @@ pluralizeListTitles = false
|
||||
identifier = "about"
|
||||
pre = "<i class='fa fa-heart'></i>"
|
||||
weight = -110
|
||||
[[menu.main]]
|
||||
name = "Release Notes"
|
||||
url = "/release-notes/"
|
||||
pre = "<i class='fa fa-newspaper-o'></i>"
|
||||
weight = -111
|
||||
[[menu.main]]
|
||||
name = "Getting Started"
|
||||
identifier = "getting started"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo"
|
||||
slug: hugo
|
||||
url: /commands/hugo/
|
||||
@@ -19,47 +19,52 @@ built with love by spf13 and friends in Go.
|
||||
Complete documentation is available at http://gohugo.io/.
|
||||
|
||||
```
|
||||
hugo
|
||||
hugo [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. http://spf13.com/
|
||||
-D, --buildDrafts include content marked as draft
|
||||
-E, --buildExpired include expired content
|
||||
-F, --buildFuture include content with publishdate in the future
|
||||
--cacheDir string filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir Remove files from destination not found in static directories
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 Do not render 404 page
|
||||
--disableRSS Do not build RSS files
|
||||
--disableSitemap Do not build Sitemap file
|
||||
--forceSyncStatic Copy all files when static is changed.
|
||||
--i18n-warnings Print missing translations
|
||||
--ignoreCache Ignores the cache directory
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--noTimes Don't sync modification time of files
|
||||
--pluralizeListTitles Pluralize titles in lists using inflect (default true)
|
||||
--preserveTaxonomyNames Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--renderToMemory render to memory (only useful for benchmark testing)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
-w, --watch watch filesystem for changes and recreate as needed
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. http://spf13.com/
|
||||
-D, --buildDrafts include content marked as draft
|
||||
-E, --buildExpired include expired content
|
||||
-F, --buildFuture include content with publishdate in the future
|
||||
--cacheDir string filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir remove files from destination not found in static directories
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 do not render 404 page
|
||||
--disableKinds stringSlice disable different kind of pages (home, RSS etc.)
|
||||
--disableRSS do not build RSS files
|
||||
--disableSitemap do not build Sitemap file
|
||||
--enableGitInfo add Git revision, date and author info to the pages
|
||||
--forceSyncStatic copy all files when static is changed.
|
||||
-h, --help help for hugo
|
||||
--i18n-warnings print missing translations
|
||||
--ignoreCache ignores the cache directory
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--noChmod don't sync permission mode of files
|
||||
--noTimes don't sync modification time of files
|
||||
--pluralizeListTitles pluralize titles in lists using inflect (default true)
|
||||
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--quiet build in quiet mode
|
||||
--renderToMemory render to memory (only useful for benchmark testing)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--themesDir string filesystem path to themes directory
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
-w, --watch watch filesystem for changes and recreate as needed
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
* [hugo benchmark](/commands/hugo_benchmark/) - Benchmark Hugo by building a site a number of times.
|
||||
* [hugo check](/commands/hugo_check/) - Check content in the source directory
|
||||
* [hugo config](/commands/hugo_config/) - Print the site configuration
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
* [hugo env](/commands/hugo_env/) - Print Hugo version and environment info
|
||||
@@ -71,4 +76,4 @@ hugo
|
||||
* [hugo undraft](/commands/hugo_undraft/) - Undraft changes the content's draft status from 'True' to 'False'
|
||||
* [hugo version](/commands/hugo_version/) - Print the version number of Hugo
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo benchmark"
|
||||
slug: hugo_benchmark
|
||||
url: /commands/hugo_benchmark/
|
||||
@@ -15,47 +15,53 @@ Hugo can build a site many times over and analyze the running process
|
||||
creating a benchmark.
|
||||
|
||||
```
|
||||
hugo benchmark
|
||||
hugo benchmark [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. http://spf13.com/
|
||||
-D, --buildDrafts include content marked as draft
|
||||
-E, --buildExpired include expired content
|
||||
-F, --buildFuture include content with publishdate in the future
|
||||
--cacheDir string filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir Remove files from destination not found in static directories
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
-n, --count int number of times to build the site (default 13)
|
||||
--cpuprofile string path/filename for the CPU profile file
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 Do not render 404 page
|
||||
--disableRSS Do not build RSS files
|
||||
--disableSitemap Do not build Sitemap file
|
||||
--forceSyncStatic Copy all files when static is changed.
|
||||
--i18n-warnings Print missing translations
|
||||
--ignoreCache Ignores the cache directory
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--memprofile string path/filename for the memory profile file
|
||||
--noTimes Don't sync modification time of files
|
||||
--pluralizeListTitles Pluralize titles in lists using inflect (default true)
|
||||
--preserveTaxonomyNames Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--renderToMemory render to memory (only useful for benchmark testing)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. http://spf13.com/
|
||||
-D, --buildDrafts include content marked as draft
|
||||
-E, --buildExpired include expired content
|
||||
-F, --buildFuture include content with publishdate in the future
|
||||
--cacheDir string filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir remove files from destination not found in static directories
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
-n, --count int number of times to build the site (default 13)
|
||||
--cpuprofile string path/filename for the CPU profile file
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 do not render 404 page
|
||||
--disableKinds stringSlice disable different kind of pages (home, RSS etc.)
|
||||
--disableRSS do not build RSS files
|
||||
--disableSitemap do not build Sitemap file
|
||||
--enableGitInfo add Git revision, date and author info to the pages
|
||||
--forceSyncStatic copy all files when static is changed.
|
||||
-h, --help help for benchmark
|
||||
--i18n-warnings print missing translations
|
||||
--ignoreCache ignores the cache directory
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--memprofile string path/filename for the memory profile file
|
||||
--noChmod don't sync permission mode of files
|
||||
--noTimes don't sync modification time of files
|
||||
--pluralizeListTitles pluralize titles in lists using inflect (default true)
|
||||
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--renderToMemory render to memory (only useful for benchmark testing)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--themesDir string filesystem path to themes directory
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -63,4 +69,4 @@ hugo benchmark
|
||||
### SEE ALSO
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,57 +1,25 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-04-26T22:40:07+02:00
|
||||
title: "hugo check"
|
||||
slug: hugo_check
|
||||
url: /commands/hugo_check/
|
||||
---
|
||||
## hugo check
|
||||
|
||||
Check content in the source directory
|
||||
Contains some verification checks
|
||||
|
||||
### Synopsis
|
||||
|
||||
|
||||
Hugo will perform some basic analysis on the content provided
|
||||
and will give feedback.
|
||||
|
||||
```
|
||||
hugo check
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. http://spf13.com/
|
||||
-D, --buildDrafts include content marked as draft
|
||||
-E, --buildExpired include expired content
|
||||
-F, --buildFuture include content with publishdate in the future
|
||||
--cacheDir string filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir Remove files from destination not found in static directories
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 Do not render 404 page
|
||||
--disableRSS Do not build RSS files
|
||||
--disableSitemap Do not build Sitemap file
|
||||
--forceSyncStatic Copy all files when static is changed.
|
||||
--i18n-warnings Print missing translations
|
||||
--ignoreCache Ignores the cache directory
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--noTimes Don't sync modification time of files
|
||||
--pluralizeListTitles Pluralize titles in lists using inflect (default true)
|
||||
--preserveTaxonomyNames Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
```
|
||||
Contains some verification checks
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -60,4 +28,4 @@ hugo check
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo check ulimit](/commands/hugo_check_ulimit/) - Check system ulimit settings
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 26-Apr-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-04-26T22:40:07+02:00
|
||||
title: "hugo check ulimit"
|
||||
slug: hugo_check_ulimit
|
||||
url: /commands/hugo_check_ulimit/
|
||||
@@ -22,13 +22,14 @@ hugo check ulimit
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
* [hugo check](/commands/hugo_check/) - Check content in the source directory
|
||||
* [hugo check](/commands/hugo_check/) - Contains some verification checks
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 26-Apr-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo config"
|
||||
slug: hugo_config
|
||||
url: /commands/hugo_config/
|
||||
@@ -14,15 +14,22 @@ Print the site configuration
|
||||
Print the site configuration, both default and custom settings.
|
||||
|
||||
```
|
||||
hugo config
|
||||
hugo config [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for config
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -30,4 +37,4 @@ hugo config
|
||||
### SEE ALSO
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo convert"
|
||||
slug: hugo_convert
|
||||
url: /commands/hugo_convert/
|
||||
@@ -18,6 +18,7 @@ See convert's subcommands toJSON, toTOML and toYAML for more information.
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for convert
|
||||
-o, --output string filesystem path to write files to
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--unsafe enable less safe operations, please backup first
|
||||
@@ -27,8 +28,9 @@ See convert's subcommands toJSON, toTOML and toYAML for more information.
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -39,4 +41,4 @@ See convert's subcommands toJSON, toTOML and toYAML for more information.
|
||||
* [hugo convert toTOML](/commands/hugo_convert_totoml/) - Convert front matter to TOML
|
||||
* [hugo convert toYAML](/commands/hugo_convert_toyaml/) - Convert front matter to YAML
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo convert toJSON"
|
||||
slug: hugo_convert_toJSON
|
||||
url: /commands/hugo_convert_tojson/
|
||||
@@ -15,16 +15,23 @@ toJSON converts all front matter in the content directory
|
||||
to use JSON for the front matter.
|
||||
|
||||
```
|
||||
hugo convert toJSON
|
||||
hugo convert toJSON [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for toJSON
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
-o, --output string filesystem path to write files to
|
||||
--quiet build in quiet mode
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--unsafe enable less safe operations, please backup first
|
||||
-v, --verbose verbose output
|
||||
@@ -34,4 +41,4 @@ hugo convert toJSON
|
||||
### SEE ALSO
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo convert toTOML"
|
||||
slug: hugo_convert_toTOML
|
||||
url: /commands/hugo_convert_totoml/
|
||||
@@ -15,16 +15,23 @@ toTOML converts all front matter in the content directory
|
||||
to use TOML for the front matter.
|
||||
|
||||
```
|
||||
hugo convert toTOML
|
||||
hugo convert toTOML [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for toTOML
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
-o, --output string filesystem path to write files to
|
||||
--quiet build in quiet mode
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--unsafe enable less safe operations, please backup first
|
||||
-v, --verbose verbose output
|
||||
@@ -34,4 +41,4 @@ hugo convert toTOML
|
||||
### SEE ALSO
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo convert toYAML"
|
||||
slug: hugo_convert_toYAML
|
||||
url: /commands/hugo_convert_toyaml/
|
||||
@@ -15,16 +15,23 @@ toYAML converts all front matter in the content directory
|
||||
to use YAML for the front matter.
|
||||
|
||||
```
|
||||
hugo convert toYAML
|
||||
hugo convert toYAML [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for toYAML
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
-o, --output string filesystem path to write files to
|
||||
--quiet build in quiet mode
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--unsafe enable less safe operations, please backup first
|
||||
-v, --verbose verbose output
|
||||
@@ -34,4 +41,4 @@ hugo convert toYAML
|
||||
### SEE ALSO
|
||||
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo env"
|
||||
slug: hugo_env
|
||||
url: /commands/hugo_env/
|
||||
@@ -14,15 +14,22 @@ Print Hugo version and environment info
|
||||
Print Hugo version and environment info. This is useful in Hugo bug reports.
|
||||
|
||||
```
|
||||
hugo env
|
||||
hugo env [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for env
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -30,4 +37,4 @@ hugo env
|
||||
### SEE ALSO
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo gen"
|
||||
slug: hugo_gen
|
||||
url: /commands/hugo_gen/
|
||||
@@ -13,12 +13,19 @@ A collection of several useful generators.
|
||||
|
||||
A collection of several useful generators.
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for gen
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -29,4 +36,4 @@ A collection of several useful generators.
|
||||
* [hugo gen doc](/commands/hugo_gen_doc/) - Generate Markdown documentation for the Hugo CLI.
|
||||
* [hugo gen man](/commands/hugo_gen_man/) - Generate man pages for the Hugo CLI
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo gen autocomplete"
|
||||
slug: hugo_gen_autocomplete
|
||||
url: /commands/hugo_gen_autocomplete/
|
||||
@@ -30,22 +30,24 @@ or just source them in directly:
|
||||
$ . /etc/bash_completion
|
||||
|
||||
```
|
||||
hugo gen autocomplete
|
||||
hugo gen autocomplete [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--completionfile string Autocompletion file (default "/etc/bash_completion.d/hugo.sh")
|
||||
--type string Autocompletion type (currently only bash supported) (default "bash")
|
||||
--completionfile string autocompletion file (default "/etc/bash_completion.d/hugo.sh")
|
||||
-h, --help help for autocomplete
|
||||
--type string autocompletion type (currently only bash supported) (default "bash")
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -53,4 +55,4 @@ hugo gen autocomplete
|
||||
### SEE ALSO
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo gen doc"
|
||||
slug: hugo_gen_doc
|
||||
url: /commands/hugo_gen_doc/
|
||||
@@ -20,21 +20,23 @@ It creates one Markdown file per command with front matter suitable
|
||||
for rendering in Hugo.
|
||||
|
||||
```
|
||||
hugo gen doc
|
||||
hugo gen doc [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--dir string the directory to write the doc. (default "/tmp/hugodoc/")
|
||||
-h, --help help for doc
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -42,4 +44,4 @@ hugo gen doc
|
||||
### SEE ALSO
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo gen man"
|
||||
slug: hugo_gen_man
|
||||
url: /commands/hugo_gen_man/
|
||||
@@ -16,21 +16,23 @@ command-line interface. By default, it creates the man page files
|
||||
in the "man" directory under the current directory.
|
||||
|
||||
```
|
||||
hugo gen man
|
||||
hugo gen man [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--dir string the directory to write the man pages. (default "man/")
|
||||
-h, --help help for man
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -38,4 +40,4 @@ hugo gen man
|
||||
### SEE ALSO
|
||||
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo import"
|
||||
slug: hugo_import
|
||||
url: /commands/hugo_import/
|
||||
@@ -15,12 +15,19 @@ Import your site from other web site generators like Jekyll.
|
||||
|
||||
Import requires a subcommand, e.g. `hugo import jekyll jekyll_root_path target_path`.
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for import
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -29,4 +36,4 @@ Import requires a subcommand, e.g. `hugo import jekyll jekyll_root_path target_p
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
* [hugo import jekyll](/commands/hugo_import_jekyll/) - hugo import from Jekyll
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo import jekyll"
|
||||
slug: hugo_import_jekyll
|
||||
url: /commands/hugo_import_jekyll/
|
||||
@@ -16,21 +16,23 @@ hugo import from Jekyll.
|
||||
Import from Jekyll requires two paths, e.g. `hugo import jekyll jekyll_root_path target_path`.
|
||||
|
||||
```
|
||||
hugo import jekyll
|
||||
hugo import jekyll [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--force Allow import into non-empty target directory
|
||||
--force allow import into non-empty target directory
|
||||
-h, --help help for jekyll
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -38,4 +40,4 @@ hugo import jekyll
|
||||
### SEE ALSO
|
||||
* [hugo import](/commands/hugo_import/) - Import your site from others.
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo list"
|
||||
slug: hugo_list
|
||||
url: /commands/hugo_list/
|
||||
@@ -18,6 +18,7 @@ List requires a subcommand, e.g. `hugo list drafts`.
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for list
|
||||
-s, --source string filesystem path to read files relative from
|
||||
```
|
||||
|
||||
@@ -25,8 +26,9 @@ List requires a subcommand, e.g. `hugo list drafts`.
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -37,4 +39,4 @@ List requires a subcommand, e.g. `hugo list drafts`.
|
||||
* [hugo list expired](/commands/hugo_list_expired/) - List all posts already expired
|
||||
* [hugo list future](/commands/hugo_list_future/) - List all posts dated in the future
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo list drafts"
|
||||
slug: hugo_list_drafts
|
||||
url: /commands/hugo_list_drafts/
|
||||
@@ -14,15 +14,22 @@ List all drafts
|
||||
List all of the drafts in your content directory.
|
||||
|
||||
```
|
||||
hugo list drafts
|
||||
hugo list drafts [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for drafts
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-s, --source string filesystem path to read files relative from
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
@@ -31,4 +38,4 @@ hugo list drafts
|
||||
### SEE ALSO
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo list expired"
|
||||
slug: hugo_list_expired
|
||||
url: /commands/hugo_list_expired/
|
||||
@@ -15,15 +15,22 @@ List all of the posts in your content directory which has already
|
||||
expired.
|
||||
|
||||
```
|
||||
hugo list expired
|
||||
hugo list expired [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for expired
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-s, --source string filesystem path to read files relative from
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
@@ -32,4 +39,4 @@ hugo list expired
|
||||
### SEE ALSO
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo list future"
|
||||
slug: hugo_list_future
|
||||
url: /commands/hugo_list_future/
|
||||
@@ -15,15 +15,22 @@ List all of the posts in your content directory which will be
|
||||
posted in the future.
|
||||
|
||||
```
|
||||
hugo list future
|
||||
hugo list future [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for future
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-s, --source string filesystem path to read files relative from
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
@@ -32,4 +39,4 @@ hugo list future
|
||||
### SEE ALSO
|
||||
* [hugo list](/commands/hugo_list/) - Listing out various types of content
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo new"
|
||||
slug: hugo_new
|
||||
url: /commands/hugo_new/
|
||||
@@ -19,7 +19,7 @@ You can also specify the kind with `-k KIND`.
|
||||
If archetypes are provided in your theme or site, they will be used.
|
||||
|
||||
```
|
||||
hugo new [path]
|
||||
hugo new [path] [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
@@ -27,7 +27,8 @@ hugo new [path]
|
||||
```
|
||||
--editor string edit new content with this editor, if provided
|
||||
-f, --format string frontmatter format (default "toml")
|
||||
-k, --kind string Content type to create
|
||||
-h, --help help for new
|
||||
-k, --kind string content type to create
|
||||
-s, --source string filesystem path to read files relative from
|
||||
```
|
||||
|
||||
@@ -35,8 +36,9 @@ hugo new [path]
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -46,4 +48,4 @@ hugo new [path]
|
||||
* [hugo new site](/commands/hugo_new_site/) - Create a new site (skeleton)
|
||||
* [hugo new theme](/commands/hugo_new_theme/) - Create a new theme
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo new site"
|
||||
slug: hugo_new_site
|
||||
url: /commands/hugo_new_site/
|
||||
@@ -16,22 +16,24 @@ The new site will have the correct structure, but no content or theme yet.
|
||||
Use `hugo new [contentPath]` to create new content.
|
||||
|
||||
```
|
||||
hugo new site [path]
|
||||
hugo new site [path] [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--force Init inside non-empty directory
|
||||
--force init inside non-empty directory
|
||||
-f, --format string config & frontmatter format (default "toml")
|
||||
-h, --help help for site
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-s, --source string filesystem path to read files relative from
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
@@ -40,4 +42,4 @@ hugo new site [path]
|
||||
### SEE ALSO
|
||||
* [hugo new](/commands/hugo_new/) - Create new content for your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo new theme"
|
||||
slug: hugo_new_theme
|
||||
url: /commands/hugo_new_theme/
|
||||
@@ -17,15 +17,22 @@ name to the copyright line in the license and adjust the theme.toml file
|
||||
as you see fit.
|
||||
|
||||
```
|
||||
hugo new theme [name]
|
||||
hugo new theme [name] [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for theme
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-s, --source string filesystem path to read files relative from
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
@@ -34,4 +41,4 @@ hugo new theme [name]
|
||||
### SEE ALSO
|
||||
* [hugo new](/commands/hugo_new/) - Create new content for your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo server"
|
||||
slug: hugo_server
|
||||
url: /commands/hugo_server/
|
||||
@@ -25,51 +25,57 @@ and push the latest content to them. As most Hugo sites are built in a fraction
|
||||
of a second, you will be able to save and see your changes nearly instantly.
|
||||
|
||||
```
|
||||
hugo server
|
||||
hugo server [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
--appendPort append port to baseurl (default true)
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. http://spf13.com/
|
||||
--bind string interface to which the server will bind (default "127.0.0.1")
|
||||
-D, --buildDrafts include content marked as draft
|
||||
-E, --buildExpired include expired content
|
||||
-F, --buildFuture include content with publishdate in the future
|
||||
--cacheDir string filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir Remove files from destination not found in static directories
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 Do not render 404 page
|
||||
--disableLiveReload watch without enabling live browser reload on rebuild
|
||||
--disableRSS Do not build RSS files
|
||||
--disableSitemap Do not build Sitemap file
|
||||
--forceSyncStatic Copy all files when static is changed.
|
||||
--i18n-warnings Print missing translations
|
||||
--ignoreCache Ignores the cache directory
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--meminterval string interval to poll memory usage (requires --memstats), valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". (default "100ms")
|
||||
--memstats string log memory usage to this file
|
||||
--noTimes Don't sync modification time of files
|
||||
--pluralizeListTitles Pluralize titles in lists using inflect (default true)
|
||||
-p, --port int port on which the server will listen (default 1313)
|
||||
--preserveTaxonomyNames Preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--renderToDisk render to Destination path (default is render to memory & serve from there)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
-w, --watch watch filesystem for changes and recreate as needed (default true)
|
||||
--appendPort append port to baseURL (default true)
|
||||
-b, --baseURL string hostname (and path) to the root, e.g. http://spf13.com/
|
||||
--bind string interface to which the server will bind (default "127.0.0.1")
|
||||
-D, --buildDrafts include content marked as draft
|
||||
-E, --buildExpired include expired content
|
||||
-F, --buildFuture include content with publishdate in the future
|
||||
--cacheDir string filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
|
||||
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
|
||||
--cleanDestinationDir remove files from destination not found in static directories
|
||||
-c, --contentDir string filesystem path to content directory
|
||||
-d, --destination string filesystem path to write files to
|
||||
--disable404 do not render 404 page
|
||||
--disableKinds stringSlice disable different kind of pages (home, RSS etc.)
|
||||
--disableLiveReload watch without enabling live browser reload on rebuild
|
||||
--disableRSS do not build RSS files
|
||||
--disableSitemap do not build Sitemap file
|
||||
--enableGitInfo add Git revision, date and author info to the pages
|
||||
--forceSyncStatic copy all files when static is changed.
|
||||
-h, --help help for server
|
||||
--i18n-warnings print missing translations
|
||||
--ignoreCache ignores the cache directory
|
||||
-l, --layoutDir string filesystem path to layout directory
|
||||
--meminterval string interval to poll memory usage (requires --memstats), valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". (default "100ms")
|
||||
--memstats string log memory usage to this file
|
||||
--noChmod don't sync permission mode of files
|
||||
--noTimes don't sync modification time of files
|
||||
--pluralizeListTitles pluralize titles in lists using inflect (default true)
|
||||
-p, --port int port on which the server will listen (default 1313)
|
||||
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
|
||||
--renderToDisk render to Destination path (default is render to memory & serve from there)
|
||||
-s, --source string filesystem path to read files relative from
|
||||
--stepAnalysis display memory and timing of different steps of the program
|
||||
-t, --theme string theme to use (located in /themes/THEMENAME/)
|
||||
--themesDir string filesystem path to themes directory
|
||||
--uglyURLs if true, use /filename.html instead of /filename/
|
||||
-w, --watch watch filesystem for changes and recreate as needed (default true)
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -77,4 +83,4 @@ hugo server
|
||||
### SEE ALSO
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo undraft"
|
||||
slug: hugo_undraft
|
||||
url: /commands/hugo_undraft/
|
||||
@@ -16,15 +16,22 @@ and updates the date to the current date and time.
|
||||
If the content's draft status is 'False', nothing is done.
|
||||
|
||||
```
|
||||
hugo undraft path/to/content
|
||||
hugo undraft path/to/content [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for undraft
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -32,4 +39,4 @@ hugo undraft path/to/content
|
||||
### SEE ALSO
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
date: 2016-10-05T10:21:48+02:00
|
||||
date: 2017-05-23T20:59:46+03:00
|
||||
title: "hugo version"
|
||||
slug: hugo_version
|
||||
url: /commands/hugo_version/
|
||||
@@ -14,15 +14,22 @@ Print the version number of Hugo
|
||||
All software has versions. This is Hugo's.
|
||||
|
||||
```
|
||||
hugo version
|
||||
hugo version [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for version
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string config file (default is path/config.yaml|json|toml)
|
||||
--log Enable Logging
|
||||
--logFile string Log File path (if set, logging enabled automatically)
|
||||
--log enable Logging
|
||||
--logFile string log File path (if set, logging enabled automatically)
|
||||
--quiet build in quiet mode
|
||||
-v, --verbose verbose output
|
||||
--verboseLog verbose logging
|
||||
```
|
||||
@@ -30,4 +37,4 @@ hugo version
|
||||
### SEE ALSO
|
||||
* [hugo](/commands/hugo/) - hugo builds your site
|
||||
|
||||
###### Auto generated by spf13/cobra on 5-Oct-2016
|
||||
###### Auto generated by spf13/cobra on 23-May-2017
|
||||
|
||||
@@ -13,7 +13,7 @@ title: Contributing to Hugo
|
||||
weight: 30
|
||||
---
|
||||
|
||||
All contributions to Hugo are welcome. Whether you want to scratch an itch, or simply contribute to the project, feel free to pick something from the [roadmap]({{< relref "meta/roadmap.md" >}}) or contact [spf13](http://spf13.com/) about what may make sense to do next.
|
||||
All contributions to Hugo are welcome. Whether you want to scratch an itch or simply contribute to the project, feel free to pick something from the [roadmap]({{< relref "meta/roadmap.md" >}}) or contact the dev team via the [Forums](https://discuss.gohugo.io/) or [Gitter](https://gitter.im/spf13/hugo) about what may make sense to do next.
|
||||
|
||||
You should fork the project and make your changes. *We encourage pull requests to discuss code changes.*
|
||||
|
||||
@@ -21,47 +21,46 @@ You should fork the project and make your changes. *We encourage pull requests
|
||||
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`
|
||||
* Run `go fmt`.
|
||||
* Squash your commits into a single commit. `git rebase -i`. It's okay to force update your pull request.
|
||||
* Make sure `go test ./...` passes, and `go build` completes. Our [Travis CI loop](https://travis-ci.org/spf13/hugo) will catch most things that are missing. The exception: Windows. We run on Windows from time to time, but if you have access, please check on a Windows machine too.
|
||||
* Run `make check` and ensure it succeeds. [Travis CI](https://travis-ci.org/spf13/hugo) and [Appveyor](https://ci.appveyor.com/project/spf13/hugo) will runs these checks and fail the build if `make check` fails.
|
||||
|
||||
## Contribution Overview
|
||||
|
||||
We wrote a [detailed guide]({{< relref "tutorials/how-to-contribute-to-hugo.md" >}}) for newcomers that guides you step by step to your first contribution. If you are more experienced read on. You probably know what to do.
|
||||
We wrote a [detailed guide]({{< relref "tutorials/how-to-contribute-to-hugo.md" >}}) for newcomers that guides you step by step to your first contribution. If you are more experienced, follow the guide below.
|
||||
|
||||
|
||||
# Building from source
|
||||
|
||||
## Clone locally (for contributors):
|
||||
## Vendored Dependencies
|
||||
|
||||
git clone https://github.com/spf13/hugo
|
||||
cd hugo
|
||||
go get
|
||||
Hugo uses [govendor][] to vendor dependencies, but we don't commit the vendored packages themselves to the Hugo git repository.
|
||||
Therefore, a simple `go get` is not supported since `go get` is not vendor-aware.
|
||||
You **must use govendor** to fetch Hugo's dependencies.
|
||||
|
||||
Because Go expects all of your libraries to be found in either
|
||||
`$GOROOT` or `$GOPATH`, it's helpful to symlink the project to one
|
||||
of the following paths:
|
||||
## Fetch the Sources
|
||||
|
||||
* `ln -s /path/to/your/hugo $GOPATH/src/github.com/spf13/hugo`
|
||||
* `ln -s /path/to/your/hugo $GOROOT/src/pkg/github.com/spf13/hugo`
|
||||
go get github.com/kardianos/govendor
|
||||
govendor get github.com/spf13/hugo
|
||||
|
||||
## Running Hugo
|
||||
|
||||
cd /path/to/hugo
|
||||
go install github.com/spf13/hugo/hugo
|
||||
cd $HOME/go/src/github.com/spf13/hugo
|
||||
go run main.go
|
||||
|
||||
## Building Hugo
|
||||
|
||||
cd /path/to/hugo
|
||||
go build -o hugo main.go
|
||||
mv hugo /usr/local/bin/
|
||||
cd $HOME/go/src/github.com/spf13/hugo
|
||||
make build
|
||||
# or to install to $HOME/go/bin:
|
||||
make install
|
||||
|
||||
|
||||
# Showcase additions
|
||||
|
||||
You got your new website running and it's powered by Hugo? Great. You can add your website with a few steps to the [showcase](/showcase/).
|
||||
|
||||
First, make sure that you created a [fork](https://help.github.com/articles/fork-a-repo/) of Hugo on Github and cloned your fork on your local computer. Next, create a separate branch for your additions:
|
||||
First, make sure that you created a [fork](https://help.github.com/articles/fork-a-repo/) of Hugo on GitHub and cloned your fork on your local computer. Next, create a separate branch for your additions:
|
||||
|
||||
```
|
||||
# You can choose a different descriptive branch name if you like
|
||||
@@ -108,3 +107,5 @@ If everything looks fine, we are ready to commit your additions. For the sake of
|
||||
Last but not least, we're ready to create a [pull request](https://github.com/spf13/hugo/compare).
|
||||
|
||||
Don't forget to accept the contributor license agreement. Click on the yellow badge in the automatically added comment in the pull request.
|
||||
|
||||
[govendor]: https://github.com/kardianos/govendor
|
||||
|
||||
@@ -16,6 +16,10 @@ Hugo has its own [discussion forum](http://discuss.gohugo.io/) powered by [Disco
|
||||
|
||||
Please use this for all discussions, questions, etc.
|
||||
|
||||
### Twitter
|
||||
|
||||
Get the latest bite-sized news and themes from the Hugo community on Twitter by following [@gohugoio](http://twitter.com/gohugoio).
|
||||
|
||||
## Mailing List
|
||||
|
||||
Hugo has two mailing lists:
|
||||
@@ -45,7 +49,3 @@ https://groups.google.com/forum/#!forum/golang-nuts
|
||||
### GitHub Issues
|
||||
|
||||
https://github.com/spf13/hugo/issues
|
||||
|
||||
### Twitter
|
||||
|
||||
Hugo doesn't have its own Twitter handle, but feel free to tweet [@spf13](http://twitter.com/spf13).
|
||||
|
||||
+123
-115
@@ -1,5 +1,5 @@
|
||||
---
|
||||
lastmod: 2016-08-17
|
||||
lastmod: 2017-03-02
|
||||
date: 2014-03-24T20:00:00Z
|
||||
linktitle: Press
|
||||
notoc: true
|
||||
@@ -16,117 +16,125 @@ Know of a post, article or tutorial on Hugo? [Add it to this list](https://githu
|
||||
Hugo has been featured in the following Blog Posts, Press and Media.
|
||||
|
||||
|
||||
| Title | Author | Date |
|
||||
| ------ | ------ | -----: |
|
||||
| [Building our site: From Django & Wordpress to a static generator (Part I)](https://tryolabs.com/blog/2016/09/20/building-our-site-django-wordpress-to-static-part-i/) | Alan Descoins | 20 Sep 2016 |
|
||||
| [Webseitenmaschine - Statische Websites mit Hugo erzeugen](http://www.heise.de/ct/ausgabe/2016-12-Statische-Websites-mit-Hugo-erzeugen-3211704.html) <small>(German, $)</small> | Christian Helmbold | 27 May 2016 |
|
||||
| [Cómo hacer sitios web estáticos con Hugo y Go - Platzi](https://www.youtube.com/watch?v=qaXXpdiCHXE) <small>(Video tutorial)</small> | Verónica López | 6 Apr 2016 |
|
||||
| [CDNOverview: A CDN comparison site made with Hugo](https://www.cloakfusion.com/cdnoverview-cdn-comparison-site-made-hugo/) | Thijs de Zoete | 23 Feb 2016 |
|
||||
| [Hugo: A Modern WebSite Engine That Just Works](https://github.com/shekhargulati/52-technologies-in-2016/blob/master/07-hugo/README.md) | Shekhar Gulati | 14 Feb 2016 |
|
||||
| [Minify Hugo Generated HTML](http://ratson.name/blog/minify-hugo-generated-html/) | Ratson | 2 Feb 2016 |
|
||||
| [Static site generators: el futuro de las webs estáticas<br>(Hugo, Jekyll, Flask y otros)](http://sitelabs.es/static-site-generators-futuro-las-webs-estaticas/) | Eneko Sarasola | 9 Jan 2016 |
|
||||
| [Writing a Lambda Function for Hugo](https://blog.jolexa.net/post/writing-a-lambda-function-for-hugo/) | Jeremy Olexa | 1 Jan 2016 |
|
||||
| [Ein Blog mit Hugo erstellen - Tutorial](http://privat.albicker.org/blog/tags/hugo/) <small>(Deutsch/German)</small> | Bernhard Albicker | 30 Dec 2015 |
|
||||
| [How to host Hugo static website generator on AWS Lambda](http://bezdelev.com/post/hugo-aws-lambda-static-website/) | Ilya Bezdelev | 15 Dec 2015 |
|
||||
| [Migrating from Pelican to Hugo](http://www.softinio.com/post/migrating-from-pelican-to-hugo/) | Salar Rahmanian | 29 Nov 2015 |
|
||||
| [Hugo + Uberspace + Git = Hubergit — eine Anleitung (German)](https://harms-ensink.name/post/hubergit/) | Christoph Harms-Ensink | 24 Nov 2015 |
|
||||
| [Static Website Generators Reviewed: Jekyll, Middleman, Roots, Hugo](http://www.smashingmagazine.com/2015/11/static-website-generators-jekyll-middleman-roots-hugo-review/) | <div style="line-height: 100%">Mathias Biilmann Christensen</div> | 16 Nov 2015 |
|
||||
| [How To Deploy a Hugo Site to Production with Git Hooks on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-hugo-site-to-production-with-git-hooks-on-ubuntu-14-04) | Justin Ellingwood | 12 Nov 2015 |
|
||||
| [How To Install and Use Hugo, a Static Site Generator, on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-hugo-a-static-site-generator-on-ubuntu-14-04) | Justin Ellingwood | 9 Nov 2015 |
|
||||
| [Switching from Wordpress to Hugo](http://justinfx.com/2015/11/08/switching-from-wordpress-to-hugo/) | Justin Israel | 8 Nov 2015 |
|
||||
| [Hands-on Experience with Hugo as a Static Site Generator](http://usersnap.com/blog/hands-on-experience-with-hugo-static-site-generator/) | Thomas Peham | 15 Oct 2015 |
|
||||
| [Statische Webseites mit Hugo erstellen/Vortrag mit Foliensatz (deutsch)](http://sfd.koelnerlinuxtreffen.de/2015/HaraldWeidner/) | Harald Weidner | 19 Sep 2015 |
|
||||
| [Moving from WordPress to Hugo](http://abhipandey.com/2015/09/moving-to-hugo/) | Abhishek Pandey | 15 Sep 2015 |
|
||||
| [<span lang="zh-CN">通过webhook将Hugo自动部署至GitHub Pages和GitCafe Pages</span> <small>(Automated deployment)</small>](http://blog.coderzh.com/2015/09/13/use-webhook-automated-deploy-hugo/) | CoderZh | 13 Sep 2015 |
|
||||
| [<span lang="zh-CN">使用hugo搭建个人博客站点</span> <small>(Using Hugo to build a personal blog site)</small>](http://blog.coderzh.com/2015/08/29/hugo/) | CoderZh | 29 Aug 2015 |
|
||||
| [Good-Bye Wordpress, Hello Hugo!](http://blog.arminhanisch.de/2015/08/blog-migration-zu-hugo/) <small>(German)</small> | Armin Hanisch | 18 Aug 2015 |
|
||||
| [Static Site E-Commerce: Integrating Snipcart with Hugo](https://snipcart.com/blog/snipcart-hugo-integration) | Francis Tremblay | 13 Aug 2015 |
|
||||
| [Hugo on Netlify — Insanely Fast Deploys](https://www.netlify.com/blog/2015/07/30/hugo-on-netlify-insanely-fast-deploys.html) | Mathias Biilmann | 30 July 2015 |
|
||||
| [Générer votre site web statique avec Hugo <small>(Generate your static site with Hugo)<small>](http://www.linux-pratique.com/?p=191) | Benoît Benedetti | 26 June 2015 |
|
||||
| [<span lang="ja">Hugo向けの新しいテーマを作った</span> <small>(I created a new theme for Hugo)<small>](http://yet.unresolved.xyz/blog/2015/06/20/making-new-theme-robust-for-hugo/) | Daisuke Tsuji | 20 June 2015 |
|
||||
| [Hugo - Gerando um site com conteúdo estático. (Portuguese Brazil)](http://blog.ffrizzo.com/posts/hugo/) | Fabiano Frizzo | 2 Jun 2015 |
|
||||
| [An Introduction to Static Site Generators](http://davidwalsh.name/introduction-static-site-generators) | Eduardo Bouças | 20 May 2015 |
|
||||
| [Hugo Still Rules](http://cheekycoder.com/2015/05/hugo-still-rules/) | Cheeky Coder | 18 May 2015 |
|
||||
| [hugo - Static Site Generator](http://gscacco.github.io/post/hugo/) | G Scaccoio | 4 May 2015 |
|
||||
| [<span lang="ja">WindowsでHugoを使う</span>](http://ureta.net/2015/05/hugo-on-windows/) | <span lang="ja">うれ太郎</span> | 1 May 2015 |
|
||||
| [<span lang="ja">Hugoのshortcodesを用いてサイトにスライドなどを埋め込む</span>](http://blog.yucchiy.com/2015/04/29/hugo-shortcode/) | Yucchiy | 29 Apr 2015 |
|
||||
| [<span lang="ja">HugoとCircleCIでGitHub PagesにBlogを公開してみたら超簡単だった</span>](http://hori-ryota.github.io/blog/create-blog-with-hugo-and-circleci/) | Hori Ryota | 17 Apr 2015 |
|
||||
| [How to build a mobile friendly website Part 2 - Ok to Go](http://jbrodriguez.io/mobile-friendly-website-2/) | Juan B. Rodriguez | 13 Apr 2015 |
|
||||
| [10 Best Static Site Generators](http://beebom.com/2015/04/best-static-site-generators) | Aniruddha Mysore | 6 Apr 2015 |
|
||||
| [Goodbye WordPress; Hello Hugo](http://willwarren.com/2015/04/05/goodbye-wordpress-hello-hugo/) | Will Warren | 5 Apr 2015 |
|
||||
| [Static Websites with Hugo on Google Cloud Storage](http://www.moxie.io/post/static-websites-with-hugo-on-google-cloud-storage/) | Moxie Input/Output | 2 Apr 2015 |
|
||||
| [De nuevo iniciando un blog](http://alvarolizama.net/blog/denuevo-iniciando-un-blog/) | Alvaro Lizama | 29 Mar 2015 |
|
||||
| [We moved our blog from Posthaven to Hugo after only three posts. Why?](http://blog.hypriot.com/post/moved-from-posthaven-to-hugo/) | Hypriot | 27 Mar 2015 |
|
||||
| [Hugo is cool](http://tnt.wicast.tk/2015/03/23/hugo-is-cool/) <small>(<span lang="zh-CN">中文</span> Chinese)</small> | wicast | 23 Mar 2015 |
|
||||
| [Top Static Site Generators in 2015](http://superdevresources.com/static-site-generators-2015/) | Kanishk Kunal | 12 Mar 2015 |
|
||||
| [Moving to Hugo](http://abiosoft.com/moving-to-hugo/) | Abiola Ibrahim | 8 Mar 2015 |
|
||||
| [<span lang="ja">Hugoで試行錯誤する</span> - log](http://deprode.net/log/logs/first/) | Deprode | 28 Feb 2015 |
|
||||
| [Migrating a blog (yes, this one!) from Wordpress to Hugo](http://justindunham.net/migrating-from-wordpress-to-hugo/) | Justin Dunham | 13 Feb 2015 |
|
||||
| [<span lang="ja">blogをoctopressからHugoに乗り換えたメモ</span>](http://blog.jigyakkuma.org/2015/02/11/hugo/) | jigyakkuma | 11 Feb 2015 |
|
||||
| [<span lang="ja">Hugoでブログをつくった</span>](http://porgy13.github.io/post/new-hugo-blog/) | porgy13 | 7 Feb 2015 |
|
||||
| [<span lang="ja">Hugoにブログを移行した</span>](http://keichi.net/post/first/) | Keichi Takahashi | 4 Feb 2015 |
|
||||
| [<span lang="zh-CN">Hugo静态网站生成器中文教程</span>](http://nanshu.wang/post/2015-01-31/) | Nanshu Wang | 31 Jan 2015 |
|
||||
| [<span lang="ja">Hugo + Github Pages + Wercker CI = ¥0(無料)<br>でコマンド 1 発(自動化)でサイト<br>・ブログを公開・運営・分析・収益化</span>](http://qiita.com/yoheimuta/items/8a619cac356bed89a4c9) | Yohei Yoshimuta | 31 Jan 2015 |
|
||||
| [Running Hugo websites on anynines](http://blog.anynines.com/running-hugo-websites-on-anynines/) | Julian Weber | 30 Jan 2015 |
|
||||
| [MiddlemanからHugoへ移行した](http://re-dzine.net/2015/01/hugo/) | Haruki Konishi | 21 Jan 2015 |
|
||||
| [WordPress から Hugo に乗り換えました](http://rakuishi.com/archives/wordpress-to-hugo/) | rakuishi | 20 Jan 2015 |
|
||||
| [HUGOを使ってサイトを立ち上げる方法](http://qiita.com/syui/items/869538099551f24acbbf) | Syui | 17 Jan 2015 |
|
||||
| [<span lang="ja">Jekyllが許されるのは小学生までだよね</span>](http://t32k.me/mol/log/hugo/) | Ishimoto Koji | 16 Jan 2015 |
|
||||
| [Getting started with Hugo](http://anthonyfok.org/post/getting-started-with-hugo/) | Anthony Fok | 12 Jan 2015 |
|
||||
| [<span lang="zh-CN">把这个博客静态化了</span> <small>(Migrate to Hugo)</small>](http://lich-eng.com/2015/01/03/migrate-to-hugo/) | Li Cheng | 3 Jan 2015 |
|
||||
| [My Hugo Experiment](http://tilde.club/~jbaty/2014/12/2014-12-31-my-hugo-experiment/) | Jack Baty | 31 Dec 2014 |
|
||||
| [Porting my blog with Hugo](http://blog.srackham.com/posts/porting-my-blog-with-hugo/) | Stuart Rackham | 30 Dec 2014 |
|
||||
| [Hugoを使ってみたときのメモ](http://machortz.github.io/posts/usinghugo/) | Machortz | 29 Dec 2014 |
|
||||
| [OctopressからHugoへ移行した](http://deeeet.com/writing/2014/12/25/hugo/) | Taichi Nakashima | 25 Dec 2014 |
|
||||
| [Hugo로 Github에 블로그 호스팅하기](http://cdpython.github.io/post/go/hugo/hugo-github/) | CD Python | 25 Dec 2014 |
|
||||
| [Migrating to Hugo From Octopress](http://nathanleclaire.com/blog/2014/12/22/migrating-to-hugo-from-octopress/) | Nathan LeClaire | 22 Dec 2014 |
|
||||
| [Dynamic Pages with GoHugo.io](http://cyrillschumacher.com/2014/12/21/dynamic-pages-with-gohugo.io/) | Cyrill Schumacher | 21 Dec 2014 |
|
||||
| [6 Static Blog Generators That Aren’t Jekyll](http://www.sitepoint.com/6-static-blog-generators-arent-jekyll/) | David Turnbull | 8 Dec 2014 |
|
||||
| [Travel Blogging Setup](http://www.stou.dk/2014/11/travel-blogging-setup/) | Rasmus Stougaard | 23 Nov 2014 |
|
||||
| [Hosting A Hugo Website Behind Nginx](http://www.bigbeeconsultants.co.uk/blog/hosting-hugo-website-behind-nginx) | Rick Beton | 20 Nov 2014 |
|
||||
| [<span lang="zh-CN">使用Hugo搭建免费个人Blog</span> <small>(How to use Hugo)</small>](http://ulricqin.com/post/how-to-use-hugo/) | Ulric Qin <span lang="zh-CN">秦晓辉</span> | 11 Nov 2014 |
|
||||
| [Built in Speed and Built for Speed by Hugo](http://cheekycoder.com/2014/10/built-for-speed-by-hugo/) | Cheeky Coder | 30 Oct 2014 |
|
||||
| [hugo, syncthing](http://fredix.ovh/2014/10/hugo-syncthing/) | Frédéric Logier | 13 Oct 2014 |
|
||||
| [Hugo para crear sitios web estáticos](http://www.webbizarro.com/noticias/1076/hugo-para-crear-sitios-web-estaticos/) | Web Bizarro | 19 Aug 2014 |
|
||||
| [Going with hugo](http://www.markuseliasson.se/article/going-with-hugo/) | Markus Eliasson | 18 Aug 2014 |
|
||||
| [Benchmarking Jekyll, Hugo and Wintersmith](http://fredrikloch.me/post/2014-08-12-Jekyll-and-its-alternatives-from-a-site-generation-point-of-view/) | Fredrik Loch | 12 Aug 2014 |
|
||||
| [Goodbye Octopress, Hello Hugo!](http://andreimihu.com/blog/2014/08/11/goodbye-octopress-hello-hugo/) | Andrei Mihu | 11 Aug 2014 |
|
||||
| [Beautiful sites for Open Source projects](http://beautifulopen.com/2014/08/09/hugo/) | Beautiful Open | 9 Aug 2014 |
|
||||
| [Hugo: Beyond the Defaults](http://npf.io/2014/08/hugo-beyond-the-defaults/) | Nate Finch | 8 Aug 2014 |
|
||||
| [First Impressions of Hugo](https://peteraba.com/blog/first-impressions-of-hugo/) | Peter Aba | 6 Aug 2014 |
|
||||
| [New Site Workflow](http://vurt.co.uk/post/new_website/) | Giles Paterson | 5 Aug 2014 |
|
||||
| [How I Learned to Stop Worrying and Love the (Static) Web](http://cognition.ca/post/about-hugo/) | Joshua McKenty | 4 Aug 2014 |
|
||||
| [Hugo - Static Site Generator](http://kenwoo.io/blog/hugo---static-site-generator/) | Kenny Woo | 3 Aug 2014 |
|
||||
| [Hugo Is Friggin' Awesome](http://npf.io/2014/08/hugo-is-awesome/) | Nate Finch | 1 Aug 2014 |
|
||||
| [<span lang="zh-CN">再次搬家</span> <small>(Move from WordPress to Hugo)</small>](http://www.chingli.com/misc/move-from-wordpress-to-hugo/) | <span lang="zh-CN">青砾</span> (chingli) | 12 July 2014 |
|
||||
| [Embedding Gists in Hugo](http://danmux.com/posts/embedded_gists/) | Dan Mull | 5 July 2014 |
|
||||
| [An Introduction To Hugo](http://www.cirrushosting.com/web-hosting-blog/an-introduction-to-hugo/) | Dan Silber | 1 July 2014 |
|
||||
| [Moving to Hugo](http://danmux.com/posts/hugo_based_blog/) | Dan Mull | 29 May 2014 |
|
||||
| [<span lang="zh-CN">开源之静态站点生成器排行榜</span><br><small>(Leaderboard of open-source static website generators)</small>](http://code.csdn.net/news/2819909) | CSDN.net | 23 May 2014 |
|
||||
| [How I deploy this site using Fabric](http://carlorat.me/quote/fabric/) | Carlo Ratam | 21 May 2014 |
|
||||
| [Finally, a satisfying and effective blog setup](http://michaelwhatcott.com/now-powered-by-hugo/) | Michael Whatcott | 20 May 2014 |
|
||||
| [Hugo from scratch](http://zackofalltrades.com/notes/2014/05/hugo-from-scratch/) | Zack Williams | 18 May 2014 |
|
||||
| [Why I switched away from Jekyll](http://www.jakejanuzelli.com/why-I-switched-away-from-jekyll/) | Jake Januzelli | 10 May 2014 |
|
||||
| [Welcome our new blog](http://blog.ninya.io/posts/welcome-our-new-blog/) | Ninya.io | 11 Apr 2014 |
|
||||
| [Mission Not Accomplished](http://johnsto.co.uk/blog/mission-not-accomplished/) | Dave Johnston | 3 Apr 2014 |
|
||||
| [Hugo - A Static Site Builder in Go](http://deepfriedcode.com/post/hugo/) | Deep Fried Code | 30 Mar 2014 |
|
||||
| [Adventures in Angular Podcast](http://devchat.tv/adventures-in-angular/003-aia-gdes) | Matias Niemela | 28 Mar 2014 |
|
||||
| [Hugo](http://bra.am/post/hugo/) | bra.am | 23 Mar 2014 |
|
||||
| [Converting Blogger To Markdown](http://trishagee.github.io/project/atom-to-hugo/) | Trisha Gee | 20 Mar 2014 |
|
||||
| [Moving to Hugo Static Web Pages](http://tepid.org/tech/hugo-web/) | Tobias Weingartner | 16 Mar 2014 |
|
||||
| [Hugo and GitHub Pages](http://spencerlyon.com/blog/2014/creating-the-site/) | Spencer Lyon | 15 Mar 2014 |
|
||||
| [New Blog Engine: Hugo](https://blog.afoolishmanifesto.com/posts/hugo/) | fREW Schmidt | 15 Mar 2014 |
|
||||
| [Hugo + gulp.js = Huggle](http://ktmud.github.io/huggle/en/intro/) ([English](http://ktmud.github.io/huggle/en/intro/), [<span lang="zh-CN">中文</span>](http://ktmud.github.io/huggle/zh/intro/)) | Jesse Yang <span lang="zh-CN">杨建超</span> | 8 Mar 2014 |
|
||||
| [Powered by Hugo](http://kieranhealy.org/blog/archives/2014/02/24/powered-by-hugo/) | Kieran Healy | 24 Feb 2014 |
|
||||
| [<span lang="ja">静的サイトを素早く構築するために<br>GoLangで作られたジェネレータHugo</span>](http://hamasyou.com/blog/2014/02/21/hugo/) | <div lang="ja" style="line-height: 1.1;">Shogo Hamada<br>濱田章吾</div> | 21 Feb 2014 |
|
||||
| [Latest Roundup of Useful Tools For Developers](http://codegeekz.com/latest-roundup-of-useful-tools-for-developers/) | CodeGeekz | 13 Feb 2014 |
|
||||
| [Hugo: Static Site Generator written in Go](http://www.braveterry.com/2014/02/06/hugo-static-site-generator-written-in-go/) | Brave Terry | 6 Feb 2014 |
|
||||
| [10 Useful HTML5 Tools for Web Designers and Developers](http://designdizzy.com/10-useful-html5-tools-for-web-designers-and-developers/) | Design Dizzy | 4 Feb 2014 |
|
||||
| [Hugo – Fast, Flexible Static Site Generator](http://cube3x.com/hugo-fast-flexible-static-site-generator/) | Joby Joseph | 18 Jan 2014 |
|
||||
| [Hugo: A new way to build static website](http://www.w3update.com/opensource/hugo-a-new-way-to-build-static-website.html) | w3update | 17 Jan 2014 |
|
||||
| [Xaprb now uses Hugo](http://xaprb.com/blog/2014/01/15/using-hugo/) | Baron Schwartz | 15 Jan 2014 |
|
||||
| [New jQuery Plugins And Resources That Web Designers Need](http://www.designyourway.net/blog/resources/new-jquery-plugins-and-resources-that-web-designers-need/) | Design Your Way | 2014 |
|
||||
| [On Blog Construction](http://alexla.sh/post/on-blog-construction/) | Alexander Lash | 27 Dec 2013 |
|
||||
| [Hugo](http://onethingwell.org/post/69070926608/hugo) | One Thing Well | 5 Dec 2013 |
|
||||
| [In Praise Of Hugo](http://sound-guru.com/blog/post/hello-world/) | sound-guru.com | 19 Oct 2013 |
|
||||
| [Hosting a blog on S3 and Cloudfront](http://www.danesparza.net/2013/07/hosting-a-blog-on-s3-and-cloudfront/) | Dan Esparza | 24 July 2013 |
|
||||
| Title | Author | Date |
|
||||
| ------ | ------ | -----: |
|
||||
| [Hugo Easy Gallery - Automagical PhotoSwipe image gallery with a one-line shortcode](https://www.liwen.id.au/heg/)| Li-Wen Yip | 2017-03-25 |
|
||||
| [Hugo Tutorial: How to Build & Host a (Very Fast) Static E-Commerce Site](https://snipcart.com/blog/hugo-tutorial-static-site-ecommerce) | Snipcart | 2017-03-12 |
|
||||
| [Automagical image gallery in Hugo with PhotoSwipe and jQuery](https://www.liwen.id.au/photoswipe/)| Li-Wen Yip | 2017-03-04 |
|
||||
| [Adding Isso Comments to Hugo](https://stiobhart.net/2017-02-24-isso-comments/) | Stíobhart Matulevicz | 2017-02-24 |
|
||||
| [Zero to HTTP/2 with AWS and Hugo](https://habd.as/zero-to-http-2-aws-hugo/) | Josh Habdas | 2017-02-16 |
|
||||
| [How to Password Protect a Hugo Site](https://www.aerobatic.com/blog/password-protect-a-hugo-site/) | Aerobatic | 2017-02-19 |
|
||||
| [Switching from Wordpress to Hugo](http://schnuddelhuddel.de/switching-from-wordpress-to-hugo/) | Mario Martelli | 2017-02-19 | ]
|
||||
| [Deploy a Hugo site to Aerobatic with CircleCI ](https://www.aerobatic.com/blog/hugo-github-circleci/) | Aerobatic | 2017-02-14 |
|
||||
| [NPM scripts for building and deploying Hugo site](https://www.aerobatic.com/blog/hugo-npm-buildtool-setup/) | Aerobatic | 2017-02-12 |
|
||||
| [Getting started with Hugo and the plain-blog theme, on NearlyFreeSpeech.Net](https://www.penwatch.net/cms/get_started_plain_blog/) | Li-aung “Lewis” Yip | 2017-02-12 |
|
||||
| [Build a Hugo site using Cloud9 IDE and host on App Engine](https://loyall.ch/lab/2017/01/build-a-static-website-with-cloud9-hugo-and-app-engine/)| Pascal Aubort | 2017-02-05 |
|
||||
| [Hugo Continuous Deployment with Bitbucket Pipelines and Aerobatic](https://www.aerobatic.com/blog/hugo-bitbucket-pipelines/) | Aerobatic | 2017-02-04 |
|
||||
| [How to use Firebase to host a Hugo site](https://www.m0d3rnc0ad.com/post/static-site-firebase/) | Andrew Cuga | 2017-02-04 |
|
||||
| [A publishing workflow for teams using static site generators](https://www.keybits.net/post/publishing-workflow-for-teams-using-static-site-generators/) | Tom Atkins | 2017-01-02 |
|
||||
| [How To Dynamically Use Google Fonts In A Hugo Website](https://stoned.io/web-development/hugo/How-To-Dynamically-Use-Google-Fonts-In-A-Hugo-Website/) | Hash Borgir | 2016-10-27 |
|
||||
| [Embedding Facebook In A Hugo Template](https://stoned.io/web-development/hugo/Embedding-Facebook-In-A-Hugo-Template/) | Hash Borgir | 2016-10-22 |
|
||||
| [通过 Gitlab-cl 将 Hugo blog 自动部署至 GitHub](https://zetaoyang.github.io/post/2016/10/17/gitlab-cl.html) <small>(Chinese, Continious integration)</small> | Zetao Yang | 2016-10-17 |
|
||||
| [A Step-by-Step Guide: Hugo on Netlify](https://www.netlify.com/blog/2016/09/21/a-step-by-step-guide-hugo-on-netlify/) | Eli Williamson | 2016-09-21 |
|
||||
| [Building our site: From Django & Wordpress to a static generator (Part I)](https://tryolabs.com/blog/2016/09/20/building-our-site-django-wordpress-to-static-part-i/) | Alan Descoins | 2016-09-20 |
|
||||
| [Webseitenmaschine - Statische Websites mit Hugo erzeugen](http://www.heise.de/ct/ausgabe/2016-12-Statische-Websites-mit-Hugo-erzeugen-3211704.html) <small>(German, $)</small> | Christian Helmbold | 2016-05-27 |
|
||||
| [Cómo hacer sitios web estáticos con Hugo y Go - Platzi](https://www.youtube.com/watch?v=qaXXpdiCHXE) <small>(Video tutorial)</small> | Verónica López | 2016-04-06 |
|
||||
| [CDNOverview: A CDN comparison site made with Hugo](https://www.cloakfusion.com/cdnoverview-cdn-comparison-site-made-hugo/) | Thijs de Zoete | 2016-02-23 |
|
||||
| [Hugo: A Modern WebSite Engine That Just Works](https://github.com/shekhargulati/52-technologies-in-2016/blob/master/07-hugo/README.md) | Shekhar Gulati | 2016-02-14 |
|
||||
| [Minify Hugo Generated HTML](http://ratson.name/blog/minify-hugo-generated-html/) | Ratson | 2016-02-02 |
|
||||
| [<span lang="ja">HugoのデプロイをWerckerからCircle CIに変更した</span> - log](http://log.deprode.net/logs/2016-01-17/) | Deprode | 2016-01-17 |
|
||||
| [Static site generators: el futuro de las webs estáticas<br>(Hugo, Jekyll, Flask y otros)](http://sitelabs.es/static-site-generators-futuro-las-webs-estaticas/) | Eneko Sarasola | 2016-01-09 |
|
||||
| [Writing a Lambda Function for Hugo](https://blog.jolexa.net/post/writing-a-lambda-function-for-hugo/) | Jeremy Olexa | 2016-01-01 |
|
||||
| [Ein Blog mit Hugo erstellen - Tutorial](http://privat.albicker.org/tags/hugo.html) <small>(Deutsch/German)</small> | Bernhard Albicker | 2015-12-30 |
|
||||
| [How to host Hugo static website generator on AWS Lambda](http://bezdelev.com/post/hugo-aws-lambda-static-website/) | Ilya Bezdelev | 2015-12-15 |
|
||||
| [Migrating from Pelican to Hugo](http://www.softinio.com/post/migrating-from-pelican-to-hugo/) | Salar Rahmanian | 2015-11-29 |
|
||||
| [Static Website Generators Reviewed: Jekyll, Middleman, Roots, Hugo](http://www.smashingmagazine.com/2015/11/static-website-generators-jekyll-middleman-roots-hugo-review/) | Mathias Biilmann Christensen | 2015-11-16 |
|
||||
| [How To Deploy a Hugo Site to Production with Git Hooks on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-deploy-a-hugo-site-to-production-with-git-hooks-on-ubuntu-14-04) | Justin Ellingwood | 2015-11-12 |
|
||||
| [How To Install and Use Hugo, a Static Site Generator, on Ubuntu 14.04](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-hugo-a-static-site-generator-on-ubuntu-14-04) | Justin Ellingwood | 2015-11-09 |
|
||||
| [Switching from Wordpress to Hugo](http://justinfx.com/2015/11/08/switching-from-wordpress-to-hugo/) | Justin Israel | 2015-11-08 |
|
||||
| [Hands-on Experience with Hugo as a Static Site Generator](http://usersnap.com/blog/hands-on-experience-with-hugo-static-site-generator/) | Thomas Peham | 2015 -10-15 |
|
||||
| [Statische Webseites mit Hugo erstellen/Vortrag mit Foliensatz (deutsch)](http://sfd.koelnerlinuxtreffen.de/2015/HaraldWeidner/) | Harald Weidner | 2015-09-19 |
|
||||
| [Moving from WordPress to Hugo](http://abhipandey.com/2015/09/moving-to-hugo/) | Abhishek Pandey | 2015-09-15 |
|
||||
| [<span lang="zh-CN">通过webhook将Hugo自动部署至GitHub Pages和GitCafe Pages</span> <small>(Automated deployment)</small>](http://blog.coderzh.com/2015/09/13/use-webhook-automated-deploy-hugo/) | CoderZh | 2015-09-13 |
|
||||
| [<span lang="zh-CN">使用hugo搭建个人博客站点</span> <small>(Using Hugo to build a personal blog site)</small>](http://blog.coderzh.com/2015/08/29/hugo/) | CoderZh | 2015-08-29 |
|
||||
| [Good-Bye Wordpress, Hello Hugo!](http://blog.arminhanisch.de/2015/08/blog-migration-zu-hugo/) <small>(German)</small> | Armin Hanisch | 2015-08-18 |
|
||||
| [Générer votre site web statique avec Hugo <small>(Generate your static site with Hugo)<small>](http://www.linux-pratique.com/?p=191) | Benoît Benedetti | 2015-06-26 |
|
||||
| [<span lang="ja">Hugo向けの新しいテーマを作った</span> <small>(I created a new theme for Hugo)<small>](https://yet.unresolved.xyz/blog/2016/10/03/how-to-make-of-hugo-theme/) | Daisuke Tsuji | 2015-06-20 |
|
||||
| [Hugo - Gerando um site com conteúdo estático. (Portuguese Brazil)](http://blog.ffrizzo.com/posts/hugo/) | Fabiano Frizzo | 2015-06-02 |
|
||||
| [An Introduction to Static Site Generators](http://davidwalsh.name/introduction-static-site-generators) | Eduardo Bouças | 2015-05-20 |
|
||||
| [Hugo Still Rules](http://cheekycoder.com/2015/05/hugo-still-rules/) | Cheeky Coder | 2015-05-18 |
|
||||
| [hugo - Static Site Generator](http://gscacco.github.io/post/hugo/) | G Scaccoio | 2015-05-04 |
|
||||
| [<span lang="ja">WindowsでHugoを使う</span>](http://ureta.net/2015/05/hugo-on-windows/) | <span lang="ja">うれ太郎</span> | 2015-05-01 |
|
||||
| [<span lang="ja">Hugoのshortcodesを用いてサイトにスライドなどを埋め込む</span>](http://blog.yucchiy.com/2015/04/29/hugo-shortcode/) | Yucchiy | 2015-04-29 |
|
||||
| [<span lang="ja">HugoとCircleCIでGitHub PagesにBlogを公開してみたら超簡単だった</span>](http://hori-ryota.github.io/blog/create-blog-with-hugo-and-circleci/) | Hori Ryota | 2015-04-17 |
|
||||
| [10 Best Static Site Generators](http://beebom.com/2015/04/best-static-site-generators) | Aniruddha Mysore | 2015-04-06 |
|
||||
| [Goodbye WordPress; Hello Hugo](http://willwarren.com/2015/04/05/goodbye-wordpress-hello-hugo/) | Will Warren | 2015-04-05 |
|
||||
| [Static Websites with Hugo on Google Cloud Storage](http://www.moxie.io/post/static-websites-with-hugo-on-google-cloud-storage/) | Moxie Input/Output | 2015-04-02 |
|
||||
| [De nuevo iniciando un blog](https://alvarolizama.net/) | Alvaro Lizama | 2015-03-29 |
|
||||
| [We moved our blog from Posthaven to Hugo after only three posts. Why?](http://blog.hypriot.com/post/moved-from-posthaven-to-hugo/) | Hypriot | 2015-03-27 |
|
||||
| [Top Static Site Generators in 2015](http://superdevresources.com/static-site-generators-2015/) | Kanishk Kunal | 2015-03-12 |
|
||||
| [Moving to Hugo](http://abiosoft.com/moving-to-hugo/) | Abiola Ibrahim | 2015-03-08 |
|
||||
| [Migrating a blog (yes, this one!) from Wordpress to Hugo](http://justindunham.net/migrating-from-wordpress-to-hugo/) | Justin Dunham | 2015-02-13 |
|
||||
| [<span lang="ja">blogをoctopressからHugoに乗り換えたメモ</span>](http://blog.jigyakkuma.org/2015/02/11/hugo/) | jigyakkuma | 2015-02-11 |
|
||||
| [<span lang="ja">Hugoでブログをつくった</span>](http://porgy13.github.io/post/new-hugo-blog/) | porgy13 | 2015-02-07 |
|
||||
| [<span lang="ja">Hugoにブログを移行した</span>](http://keichi.net/post/first/) | Keichi Takahashi | 2015-02-04 |
|
||||
| [<span lang="zh-CN">Hugo静态网站生成器中文教程</span>](http://nanshu.wang/post/2015-01-31/) | Nanshu Wang | 2015-01-31 |
|
||||
| [<span lang="ja">Hugo + GitHub Pages + Wercker CI = ¥0(無料)<br>でコマンド 1 発(自動化)でサイト<br>・ブログを公開・運営・分析・収益化</span>](http://qiita.com/yoheimuta/items/8a619cac356bed89a4c9) | Yohei Yoshimuta | 2015-01-31 |
|
||||
| [Running Hugo websites on anynines](http://blog.anynines.com/running-hugo-websites-on-anynines/) | Julian Weber | 2015-01-30 |
|
||||
| [MiddlemanからHugoへ移行した](http://re-dzine.net/2015/01/hugo/) | Haruki Konishi | 2015-01-21 |
|
||||
| [WordPress から Hugo に乗り換えました](http://rakuishi.com/archives/wordpress-to-hugo/) | rakuishi | 2015-01-20 |
|
||||
| [HUGOを使ってサイトを立ち上げる方法](http://qiita.com/syui/items/869538099551f24acbbf) | Syui | 2015-01-17 |
|
||||
| [<span lang="ja">Jekyllが許されるのは小学生までだよね</span>](http://t32k.me/mol/log/hugo/) | Ishimoto Koji | 2015-01-16 |
|
||||
| [Getting started with Hugo](http://anthonyfok.org/post/getting-started-with-hugo/) | Anthony Fok | 2015-01-12 |
|
||||
| [<span lang="zh-CN">把这个博客静态化了</span> <small>(Migrate to Hugo)</small>](http://lich-eng.com/2015/01/03/migrate-to-hugo/)| Li Cheng | 2015-01-03 |
|
||||
| [Porting my blog with Hugo](http://blog.srackham.com/posts/porting-my-blog-with-hugo/) | Stuart Rackham | 2014-12-30 |
|
||||
| [Hugoを使ってみたときのメモ](http://machortz.github.io/posts/usinghugo/) | Machortz | 2014-12-29 |
|
||||
| [OctopressからHugoへ移行した](http://deeeet.com/writing/2014/12/25/hugo/) | Taichi Nakashima | 2014-12-25 |
|
||||
| [Migrating to Hugo From Octopress](http://nathanleclaire.com/blog/2014/12/22/migrating-to-hugo-from-octopress/) | Nathan LeClaire | 2014-12-22 |
|
||||
| [Dynamic Pages with GoHugo.io](http://cyrillschumacher.com/2014/12/21/dynamic-pages-with-gohugo.io/) | Cyrill Schumacher | 2014-12-21 |
|
||||
| [6 Static Blog Generators That Aren’t Jekyll](http://www.sitepoint.com/6-static-blog-generators-arent-jekyll/) | David Turnbull | 2014-12-08 |
|
||||
| [Travel Blogging Setup](http://www.stou.dk/2014/11/travel-blogging-setup/) | Rasmus Stougaard | 2014-11-23 |
|
||||
| [Hosting A Hugo Website Behind Nginx](http://www.bigbeeconsultants.co.uk/blog/hosting-hugo-website-behind-nginx) | Rick Beton | 2014-11-20 |
|
||||
| [<span lang="zh-CN">使用Hugo搭建免费个人Blog</span> <small>(How to use Hugo)</small>](http://ulricqin.com/post/how-to-use-hugo/) | Ulric Qin <span lang="zh-CN">秦晓辉</span> | 2014-11-11 |
|
||||
| [Built in Speed and Built for Speed by Hugo](http://cheekycoder.com/2014/10/built-for-speed-by-hugo/) | Cheeky Coder | 2014-10-30 |
|
||||
| [Hugo para crear sitios web estáticos](http://www.webbizarro.com/noticias/1076/hugo-para-crear-sitios-web-estaticos/) | Web Bizarro | 2014-08-19 |
|
||||
| [Going with hugo](http://www.markuseliasson.se/article/going-with-hugo/) | Markus Eliasson | 2014-08-18 |
|
||||
| [Benchmarking Jekyll, Hugo and Wintersmith](http://fredrikloch.me/post/2014-08-12-Jekyll-and-its-alternatives-from-a-site-generation-point-of-view/) | Fredrik Loch | 2014-08-12 |
|
||||
| [Goodbye Octopress, Hello Hugo!](http://andreimihu.com/blog/2014/08/11/goodbye-octopress-hello-hugo/) | Andrei Mihu | 2014-08-11 |
|
||||
| [Beautiful sites for Open Source projects](http://beautifulopen.com/2014/08/09/hugo/) | Beautiful Open | 2014-08-09 |
|
||||
| [Hugo: Beyond the Defaults](http://npf.io/2014/08/hugo-beyond-the-defaults/) | Nate Finch | 2014-08-08 |
|
||||
| [First Impressions of Hugo](https://peteraba.com/blog/first-impressions-of-hugo/) | Peter Aba | 2014-06-06 |
|
||||
| [New Site Workflow](http://vurt.co.uk/post/new_website/) | Giles Paterson | 2014-08-05 |
|
||||
| [How I Learned to Stop Worrying and Love the (Static) Web](http://cognition.ca/post/about-hugo/) | Joshua McKenty | 2014-08-04 |
|
||||
| [Hugo - Static Site Generator](http://kenwoo.io/blog/hugo---static-site-generator/) | Kenny Woo | 2014-08-03 |
|
||||
| [Hugo Is Friggin' Awesome](http://npf.io/2014/08/hugo-is-awesome/) | Nate Finch | 2014-08-01 |
|
||||
| [<span lang="zh-CN">再次搬家</span> <small>(Move from WordPress to Hugo)</small>](http://www.chingli.com/misc/move-from-wordpress-to-hugo/) | <span lang="zh-CN">青砾</span> (chingli) | 2014-07-12 |
|
||||
| [Embedding Gists in Hugo](http://danmux.com/posts/embedded_gists/) | Dan Mull | 2014-07-05 |
|
||||
| [An Introduction To Hugo](http://www.cirrushosting.com/web-hosting-blog/an-introduction-to-hugo/) | Dan Silber | 2014-07-01 |
|
||||
| [Moving to Hugo](http://danmux.com/posts/hugo_based_blog/) | Dan Mull | 2014-05-29 |
|
||||
| [<span lang="zh-CN">开源之静态站点生成器排行榜</span><br><small>(Leaderboard of open-source static website generators)</small>](http://code.csdn.net/news/2819909) | CSDN.net | 2014-05-23 |
|
||||
| [Finally, a satisfying and effective blog setup](http://michaelwhatcott.com/now-powered-by-hugo/) | Michael Whatcott | 2014-05-20 |
|
||||
| [Hugo from scratch](http://zackofalltrades.com/notes/2014/05/hugo-from-scratch/) | Zack Williams | 2014-05-18 |
|
||||
| [Why I switched away from Jekyll](http://www.jakejanuzelli.com/why-I-switched-away-from-jekyll/) | Jake Januzelli | 2014-05-10 |
|
||||
| [Welcome our new blog](http://blog.ninya.io/posts/welcome-our-new-blog/) | Ninya.io | 2014-04-11 |
|
||||
| [Mission Not Accomplished](http://johnsto.co.uk/blog/mission-not-accomplished/) | Dave Johnston | 2014-04-03 |
|
||||
| [Hugo - A Static Site Builder in Go](http://deepfriedcode.com/post/hugo/) | Deep Fried Code | 2014-03-30 |
|
||||
| [Adventures in Angular Podcast](http://devchat.tv/adventures-in-angular/003-aia-gdes) | Matias Niemela | 2014-03-28 |
|
||||
| [Hugo](http://bra.am/post/hugo/) | bra.am | 2014-03-23 |
|
||||
| [Converting Blogger To Markdown](http://trishagee.github.io/project/atom-to-hugo/) | Trisha Gee | 2014-03-20 |
|
||||
| [Moving to Hugo Static Web Pages](http://tepid.org/tech/hugo-web/) | Tobias Weingartner | 2014-03-16 |
|
||||
| [New Blog Engine: Hugo](https://blog.afoolishmanifesto.com/posts/hugo/) | fREW Schmidt | 2014-03-15 |
|
||||
| [Hugo + gulp.js = Huggle](http://ktmud.github.io/huggle/en/intro/) ([English](http://ktmud.github.io/huggle/en/intro/), [<span lang="zh-CN">中文</span>](http://ktmud.github.io/huggle/zh/intro/)) | Jesse Yang <span lang="zh-CN">杨建超</span> | 2014-03-08 |
|
||||
| [Powered by Hugo](http://kieranhealy.org/blog/archives/2014/02/24/powered-by-hugo/) | Kieran Healy | 2014-02-24 |
|
||||
| [<span lang="ja">静的サイトを素早く構築するために<br>GoLangで作られたジェネレータHugo</span>](http://hamasyou.com/blog/2014/02/21/hugo/)| <div lang="ja" style="line-height: 1.1;">Shogo Hamada<br>濱田章吾</div> | 2014-02-21 |
|
||||
| [Latest Roundup of Useful Tools For Developers](http://codegeekz.com/latest-roundup-of-useful-tools-for-developers/) | CodeGeekz | 2014-02-13 |
|
||||
| [Hugo: Static Site Generator written in Go](http://www.braveterry.com/2014/02/06/hugo-static-site-generator-written-in-go/) | Brave Terry | 2014-02-06 |
|
||||
| [10 Useful HTML5 Tools for Web Designers and Developers](http://designdizzy.com/10-useful-html5-tools-for-web-designers-and-developers/) | Design Dizzy | 2014-02-04 |
|
||||
| [Hugo – Fast, Flexible Static Site Generator](http://cube3x.com/hugo-fast-flexible-static-site-generator/) | Joby Joseph | 2014-01-18 |
|
||||
| [Hugo: A new way to build static website](http://www.w3update.com/opensource/hugo-a-new-way-to-build-static-website.html) | w3update | 2014-01-17 |
|
||||
| [Xaprb now uses Hugo](http://xaprb.com/blog/2014/01/15/using-hugo/) | Baron Schwartz | 2014-01-15 |
|
||||
| [New jQuery Plugins And Resources That Web Designers Need](http://www.designyourway.net/blog/resources/new-jquery-plugins-and-resources-that-web-designers-need/) | Design Your Way | 2014-01-01 |
|
||||
| [On Blog Construction](http://alexla.sh/post/on-blog-construction/) | Alexander Lash | 2013-12-27 |
|
||||
| [Hugo](http://onethingwell.org/post/69070926608/hugo) | One Thing Well | 2013-12-05 |
|
||||
| [In Praise Of Hugo](http://sound-guru.com/blog/post/hello-world/) | sound-guru.com | 2013-10-19 |
|
||||
| [Hosting a blog on S3 and Cloudfront](http://www.danesparza.net/2013/07/hosting-a-blog-on-s3-and-cloudfront/) | Dan Esparza | 2013-07-24 |
|
||||
|
||||
@@ -11,138 +11,320 @@ weight: 50
|
||||
toc: true
|
||||
---
|
||||
|
||||
In Hugo v0.11, we introduced the concept of a content builder. Using the CLI
|
||||
command <code>hugo new <em>[path/to/my/content]</em></code>, an author could
|
||||
create an empty content file, with the date and title automatically defined in
|
||||
the front matter of the post. While this was a welcome feature, active writers
|
||||
need more flexibility.
|
||||
|
||||
When defining a custom content type, you can use an **archetype** as a way to
|
||||
define the default metadata for a new post of that type.
|
||||
|
||||
**Archetypes** are quite literally archetypal content files with pre-configured
|
||||
[front matter](/content/front-matter). An archetype will populate each new
|
||||
content file of a given type with any default metadata you've defined whenever
|
||||
you run the `hugo new` command.
|
||||
|
||||
## Example
|
||||
|
||||
### Step 1. Creating an archetype
|
||||
|
||||
In the following example scenario, suppose we have a blog with a single content
|
||||
type (blog post). Our imaginary blog will use ‘tags’ and ‘categories’ for its
|
||||
taxonomies, so let's create an archetype file with ‘tags’ and ‘categories’
|
||||
pre-defined:
|
||||
|
||||
#### archetypes/default.md
|
||||
Typically, each piece of content you create within a Hugo project will have [front matter](/content/front-matter/) that follows a consistent structure. If you write blog posts, for instance, you might use the following front matter for the vast majority of those posts:
|
||||
|
||||
```toml
|
||||
+++
|
||||
tags = ["x", "y"]
|
||||
categories = ["x", "y"]
|
||||
title = ""
|
||||
date = ""
|
||||
slug = ""
|
||||
tags = [
|
||||
""
|
||||
]
|
||||
categories = [
|
||||
""
|
||||
]
|
||||
draft = true
|
||||
+++
|
||||
```
|
||||
|
||||
> __CAVEAT:__ Some editors (e.g. Sublime, Emacs) do not insert an EOL (end-of-line) character at the end of the file (i.e. EOF). If you get a [strange EOF error](/troubleshooting/strange-eof-error/) when using `hugo new`, please open each archetype file (i.e. `archetypes/*.md`) and press <kbd>Enter</kbd> to type a carriage return after the closing `+++` or `---` as necessary.
|
||||
You can always add non-typical front matter to any piece of content, but since it takes extra work to develop a theme that handles unique metadata, consistency is simpler.
|
||||
|
||||
With this in mind, Hugo has a convenient feature known as *archetypes* that allows users to define default front matter for new pieces of content.
|
||||
|
||||
### Step 2. Using the archetype
|
||||
By using archetypes, we can:
|
||||
|
||||
Now, with `archetypes/default.md` in place, let's create a new post in the `post`
|
||||
section with the `hugo new` command:
|
||||
1. **Save time**. Stop writing the same front matter over and over again.
|
||||
2. **Avoid errors**. Reduce the odds of typos, improperly formatted syntax, and other simple mistakes.
|
||||
3. **Focus on more important things**. Avoid having to remember all of the fields that need to be associated with each piece of content. (This is particularly important for larger projects with complex front matter and a variety of content types.)
|
||||
|
||||
$ hugo new post/my-new-post.md
|
||||
Let's explore how they work.
|
||||
|
||||
Hugo will now create the file with the following contents:
|
||||
## Built-in Archetypes
|
||||
|
||||
#### content/post/my-new-post.md
|
||||
If you've been using Hugo for a while, there's a decent chance you've come across archetypes without even realizing it. This is because Hugo includes a basic, built-in archetype that is used by default whenever it generates a content file.
|
||||
|
||||
To see this in action, open the command line, navigate into your project's directory, and run the following command:
|
||||
|
||||
```bash
|
||||
hugo new hello-world.md
|
||||
```
|
||||
|
||||
This `hugo new` command creates a new content file inside the project's `content` directory — in this case, a file named `hello-world.md` — and if you open this file, you'll notice it contains the following front matter:
|
||||
|
||||
```toml
|
||||
+++
|
||||
title = "my new post"
|
||||
date = "2015-01-12T19:20:04-07:00"
|
||||
tags = ["x", "y"]
|
||||
categories = ["x", "y"]
|
||||
date = "2017-05-31T15:18:11+10:00"
|
||||
draft = true
|
||||
title = "hello world"
|
||||
+++
|
||||
```
|
||||
|
||||
We see that the `title` and `date` variables have been added, in addition to the
|
||||
`tags` and `categories` variables which were carried over from `archetype/default.md`.
|
||||
Here, we can see that three fields have been added to the document: a `title` field that is based on the file name we defined, a `draft` field that ensures this content won't be published by default, and a `date` field that is auto-populated with the current date and time in the [RFC 3339](https://stackoverflow.com/questions/522251/whats-the-difference-between-iso-8601-and-rfc-3339-date-formats) format.
|
||||
|
||||
Congratulations! We have successfully created an archetype and used it to
|
||||
quickly scaffold out a new post. But wait, what if we want to create some content
|
||||
that isn't exactly a blog post, like a profile for a musician? Let's see how
|
||||
using **archetypes** can help us out.
|
||||
This, in its most basic form, is an example of an archetype. To understand how useful they can be though, it's best if we create our own.
|
||||
|
||||
### Creating custom archetypes
|
||||
## Creating Archetypes
|
||||
|
||||
Previously, we had created a new content type by adding a new subfolder to the
|
||||
content directory. In this case, its name would be `content/musician`. To begin
|
||||
using a `musician` archetype for each new `musician` post, we simply need to
|
||||
create a file named after the content type called `musician.md`, and put it in
|
||||
the `archetypes` directory, similar to the one below.
|
||||
In this section, we're going to create an archetype that will override the built-in archetype, allowing us to define custom front matter that will be included in any content files that we generate with the `hugo new` command.
|
||||
|
||||
#### archetypes/musician.md
|
||||
To achieve this, create a file named `default.md` inside the `archetypes` folder of a Hugo project. (If the folder doesn't exist, create it.)
|
||||
|
||||
Then, inside this file, define the following front matter:
|
||||
|
||||
```toml
|
||||
+++
|
||||
name = ""
|
||||
bio = ""
|
||||
genre = ""
|
||||
slug = ""
|
||||
tags = []
|
||||
categories = []
|
||||
draft = true
|
||||
+++
|
||||
```
|
||||
|
||||
Now, let's create a new musician.
|
||||
You'll notice that we haven't defined a `title` or `date` field. This is because Hugo will automatically add these fields to the beginning of the front matter. We do, however, need to define the `draft` field if we want it to exist in our front matter.
|
||||
|
||||
$ hugo new musician/mozart.md
|
||||
You'll also notice that we're writing the front matter in the TOML format. It's possible to define archetype front matter in other formats, but a setting needs to be changed in the configuration file for this to be possible. See the "[Archetype Formats](#archetype-formats)" section of this article for more details.
|
||||
|
||||
This time, Hugo recognizes our custom `musician` archetype and uses it instead of
|
||||
the default one. Take a look at the new `musician/mozart.md` post. You should see
|
||||
that the generated file's front matter now includes the variables `name`, `bio`,
|
||||
and `genre`.
|
||||
Next, run the following command:
|
||||
|
||||
#### content/musician/mozart.md
|
||||
```bash
|
||||
hugo new my-archetype-example.md
|
||||
```
|
||||
|
||||
This command will generate a file named `my-archetype-example.md` inside the `content` directory, and this file will contain the following output:
|
||||
|
||||
```toml
|
||||
+++
|
||||
title = "mozart"
|
||||
date = "2015-08-24T13:04:37+02:00"
|
||||
name = ""
|
||||
bio = ""
|
||||
genre = ""
|
||||
categories = []
|
||||
date = "2017-05-31T15:21:13+10:00"
|
||||
draft = true
|
||||
slug = ""
|
||||
tags = []
|
||||
title = "my archetype example"
|
||||
+++
|
||||
```
|
||||
|
||||
## Using a different front matter format
|
||||
As we can see, the file contains the `title` and `date` property that Hugo created for us, along with the front matter that we defined in the `archetypes/default.md` file.
|
||||
|
||||
By default, the front matter will be created in the TOML format
|
||||
regardless of what format the archetype is using.
|
||||
You'll also notice that the fields have been sorted into alphabetical order. This is an unintentional side-effect that stems from the underlying code libraries that Hugo relies upon. It is, however, [a known issue that is actively being discussed](https://github.com/spf13/hugo/issues/452).
|
||||
|
||||
You can specify a different default format in your site-wide config file
|
||||
(e.g. `config.toml`) using the `MetaDataFormat` directive.
|
||||
Possible values are `"toml"`, `"yaml"` and `"json"`.
|
||||
## Section Archetypes
|
||||
|
||||
## Which archetype is being used
|
||||
By creating the `archetypes/default.md` file, we've created a default archetype that is more useful than the built-in archetype, but since Hugo encourages us to [organize our content into sections](/content/sections/), each of which will likely have different front matter requirements, a "one-size-fits-all" archetype isn't necessarily the best approach.
|
||||
|
||||
The following rules apply when creating new content:
|
||||
To accommodate for this, Hugo allows us to create archetypes for each section of our project. This means, whenever we generate content for a certain section, the appropriate front matter for that section will be automatically included in the generated file.
|
||||
|
||||
* If an archetype with a filename matching the new post's [content type](/content/type) exists, it will be used.
|
||||
* If no match is found, `archetypes/default.md` will be used.
|
||||
* If neither is 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.
|
||||
To see this in action, create a "photo" section by creating a directory named "photo" inside the `content` directory.
|
||||
|
||||
Hugo provides a simple archetype which sets the `title` (based on the
|
||||
file name) and the `date` in RFC 3339 format based on
|
||||
[`now()`](http://golang.org/pkg/time/#Now), which returns the current time.
|
||||
Then create a file named `photo.md` inside the `archetypes` directory and include the following front matter inside this file:
|
||||
|
||||
> *Note: `hugo new` does not automatically add `draft = true` when the user
|
||||
> provides an archetype. This is by design, rationale being that
|
||||
> the archetype should set its own value for all fields.
|
||||
> `title` and `date`, which are dynamic and unique for each piece of content,
|
||||
> are the sole exceptions.*
|
||||
```toml
|
||||
+++
|
||||
image_url = ""
|
||||
camera = ""
|
||||
lens = ""
|
||||
aperture = ""
|
||||
iso = ""
|
||||
draft = true
|
||||
+++
|
||||
```
|
||||
|
||||
The content type is automatically detected based on the file path passed to the
|
||||
Hugo CLI command <code>hugo new <em>[my-content-type/post-name]</em></code>. To
|
||||
override the content type for a new post, include the `--kind` flag during creation.
|
||||
Here, the critical detail is that the `photo.md` file in the `archetypes` directory is named after the `photo` section that we just created. By sharing a name, Hugo can understand that there's a relationship between them.
|
||||
|
||||
Next, run the following command:
|
||||
|
||||
```bash
|
||||
hugo new photo/my-pretty-cat.md
|
||||
```
|
||||
|
||||
This command will generate a file named `my-pretty-cat.md` inside the `content/photo` directory, and this file will contain the following output:
|
||||
|
||||
```toml
|
||||
+++
|
||||
aperture = ""
|
||||
camera = ""
|
||||
date = "2017-05-31T15:25:18+10:00"
|
||||
draft = true
|
||||
image_url = ""
|
||||
iso = ""
|
||||
lens = ""
|
||||
title = "my pretty cat"
|
||||
+++
|
||||
```
|
||||
|
||||
As we can see, the `title` and `date` fields are still included by Hugo, but the rest of the front matter is being generated from the `photo.md` archetype instead of the `default.md` archetype.
|
||||
|
||||
### Tip: Default Values
|
||||
|
||||
To make archetypes more useful, define default values for any fields that will always be set to a range of limited options. In the case of the `photo.md` archetype, for instance, you could include lists of the various cameras and lenses that you own:
|
||||
|
||||
```toml
|
||||
+++
|
||||
image_url = ""
|
||||
camera = [
|
||||
"Sony RX100 Mark IV",
|
||||
"Canon 5D Mark III",
|
||||
"iPhone 6S"
|
||||
]
|
||||
lens = [
|
||||
"Canon EF 50mm f/1.8",
|
||||
"Rokinon 14mm f/2.8"
|
||||
]
|
||||
aperture = ""
|
||||
iso = ""
|
||||
draft = true
|
||||
+++
|
||||
```
|
||||
|
||||
Then, after generating a content file, simply remove the values that aren't relevant. This saves you from typing out the same options over and over again while ensuring consistency in how they're written.
|
||||
|
||||
## Scaffolding Content
|
||||
|
||||
Archetypes aren't limited to defining default front matter. They can also be used to define a default structure for the body of Markdown documents.
|
||||
|
||||
For example, imagine creating a `review.md` archetype for the purpose of writing camera reviews. This is what the front matter for such an archetype might look like:
|
||||
|
||||
```toml
|
||||
+++
|
||||
manufacturer = ""
|
||||
model = ""
|
||||
price = ""
|
||||
releaseDate = ""
|
||||
rating = ""
|
||||
+++
|
||||
```
|
||||
|
||||
But reviews tend to follow strict formats and need to answer specific questions, and it's with these expectations of precise structure that archetypes can prove to be even more useful.
|
||||
|
||||
For the sake of writing reviews, for instance, we could define the structure of a review beneath the front matter of the `review.md` file:
|
||||
|
||||
```markdown
|
||||
+++
|
||||
manufacturer = ""
|
||||
model = ""
|
||||
price = ""
|
||||
releaseDate = ""
|
||||
rating = ""
|
||||
+++
|
||||
|
||||
## Introduction
|
||||
|
||||
## Sample Photos
|
||||
|
||||
## Conclusion
|
||||
```
|
||||
|
||||
Then, whenever we use the `hugo new` command to create a new review, not only will the default front matter be copied into the newly created Markdown document, but the body of the `review.md` archetype will also be copied.
|
||||
|
||||
To take this further though — and to ensure authors on multi-author websites are on the same page about how content should be written — we could include notes and reminders within the archetype:
|
||||
|
||||
```markdown
|
||||
+++
|
||||
manufacturer = ""
|
||||
model = ""
|
||||
price = ""
|
||||
releaseDate = ""
|
||||
rating = ""
|
||||
+++
|
||||
|
||||
## Introduction
|
||||
|
||||
<!--
|
||||
What is the selling point of the camera?
|
||||
What has changed since last year's model?
|
||||
Include a bullet-point list of key features.
|
||||
-->
|
||||
|
||||
## Sample Photos
|
||||
|
||||
<!-- TODO: Take at least 12 photos in a variety of situations. -->
|
||||
|
||||
## Conclusion
|
||||
|
||||
<!--
|
||||
Is this camera worth the money?
|
||||
Does it accomplish what it set out to achieve?
|
||||
Are there any specific groups of people who should/shouldn't buy it?
|
||||
Would you recommend it to a friend?
|
||||
Are there alternatives on the horizon?
|
||||
-->
|
||||
|
||||
```
|
||||
|
||||
That way, each time we generate a new content file, we have a series of handy notes to push us closer to a piece of writing that's suitable for publishing.
|
||||
|
||||
(If you're wondering why the notes are wrapped in the HTML comment syntax, it's to ensure they won't appear inside the preview window of whatever Markdown editor the author happens to be using. They're not strictly necessary though.)
|
||||
|
||||
This is still a fairly simple example, but if your content usually contains a variety of components — headings, bullet-points, images, [short-codes](/extras/shortcodes/), etc — it's not hard to see the time-saving benefits of placing these components in the body of an archetype file.
|
||||
|
||||
## Theme Archetypes
|
||||
|
||||
Whenever you generate a content file with the `hugo new` command, Hugo will start by searching for archetypes in the `archetypes` directory, initially looking for an archetype that matches the content's section and falling-back on the `default.md` archetype (if one is present). If no archetypes are found in this directory, Hugo will continue its search in the `archetypes` directory of the currently active theme. In other words, it's possible for themes to come packaged with their own archetypes, ensuring that users of that theme format their content files with correctly structured front matter.
|
||||
|
||||
To allow Hugo to use archetypes from a theme, [that theme must be activated via the project's configuration file](/themes/usage/):
|
||||
|
||||
```toml
|
||||
theme = "ThemeNameGoesHere"
|
||||
```
|
||||
|
||||
If an archetype doesn't exist in the `archetypes` directory at the top-level of a project or inside the `archetypes` directory of an active theme, the built-in archetype will be used.
|
||||
|
||||
{{< figure src="/img/content/archetypes/archetype-hierarchy.png" alt="How Hugo Decides Which Archetype To Use" >}}
|
||||
|
||||
## Archetype Formats
|
||||
|
||||
By default, the `hugo new` command will generate front matter in the TOML format. This means, even if we define the front matter in our archetype files as YAML or JSON, it will be converted to the TOML format before it ends up in our content files.
|
||||
|
||||
Fortunately, this functionality can be overwritten.
|
||||
|
||||
Inside the project's configuration file, simply define a `metaDataFormat` property:
|
||||
|
||||
```toml
|
||||
metaDataFormat = ""
|
||||
```
|
||||
|
||||
Then set this property to any of the following values:
|
||||
|
||||
* toml
|
||||
* yaml
|
||||
* json
|
||||
|
||||
By defining this option, any front matter will be generated in your preferred format.
|
||||
|
||||
It's worth noting, however, that when generating front matter in the TOML format, you might encounter the following error:
|
||||
|
||||
```bash
|
||||
Error: cannot convert type <nil> to TomlTree
|
||||
```
|
||||
|
||||
This is because, to generate TOML, all of the fields in the front matter need to have a default value, even if that default value is just an empty string.
|
||||
|
||||
For example, this YAML would *not* successfully compile into the TOML format:
|
||||
|
||||
```yaml
|
||||
---
|
||||
slug:
|
||||
tags:
|
||||
categories:
|
||||
draft:
|
||||
---
|
||||
```
|
||||
|
||||
But this YAML *would* successfully compile:
|
||||
|
||||
```yaml
|
||||
---
|
||||
slug: ""
|
||||
tags:
|
||||
-
|
||||
categories:
|
||||
-
|
||||
draft: true
|
||||
---
|
||||
```
|
||||
|
||||
It's a subtle yet important detail to remember.
|
||||
|
||||
## Notes
|
||||
|
||||
* Prior to Hugo v0.13, some users received [an "EOF" error when using archetypes](https://github.com/spf13/hugo/issues/776), related to what text editor they used to create the archetype. As of Hugo v0.13, this error has been [resolved](https://github.com/spf13/hugo/pull/785).
|
||||
|
||||
@@ -7,8 +7,8 @@ linktitle: Example
|
||||
menu:
|
||||
main:
|
||||
parent: content
|
||||
prev: /content/summaries
|
||||
next: /themes/overview
|
||||
prev: /content/multilingual
|
||||
next: /content/using-index-md
|
||||
notoc: true
|
||||
title: Example Content File
|
||||
weight: 70
|
||||
|
||||
@@ -21,7 +21,7 @@ Supported formats:
|
||||
|
||||
* **[TOML][]**, identified by '`+++`'.
|
||||
* **[YAML][]**, identified by '`---`'.
|
||||
* **[JSON][]**, a single JSON object which is surrounded by '`{`' and '`}`', each on their own line.
|
||||
* **[JSON][]**, a single JSON object which is surrounded by '`{`' and '`}`', followed by a newline.
|
||||
|
||||
[TOML]: https://github.com/toml-lang/toml "Tom's Obvious, Minimal Language"
|
||||
[YAML]: http://www.yaml.org/ "YAML Ain't Markup Language"
|
||||
@@ -82,7 +82,7 @@ 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.
|
||||
any variable they want. These will be placed into the `.Params` variable available to the templates.
|
||||
Field names are always normalized to lowercase (e.g. `camelCase: true` is available as `.Params.camelcase`).
|
||||
|
||||
### Required variables
|
||||
@@ -113,7 +113,7 @@ Field names are always normalized to lowercase (e.g. `camelCase: true` is availa
|
||||
|
||||
## Configure Blackfriday rendering
|
||||
|
||||
It's possible to set some options for Markdown rendering in the page's front matter, as an override to the site wide configuration.
|
||||
It's possible to set some options for Markdown rendering in the page's front matter as an override to the site wide configuration.
|
||||
|
||||
See [Configuration]({{< ref "overview/configuration.md#configure-blackfriday-rendering" >}}) for more.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ menu:
|
||||
main:
|
||||
parent: content
|
||||
prev: /content/summaries
|
||||
next: /content/example
|
||||
next: /content/multilingual
|
||||
title: Markdown Extras
|
||||
weight: 66
|
||||
toc: false
|
||||
|
||||
@@ -3,8 +3,8 @@ date: 2016-01-02T21:21:00Z
|
||||
menu:
|
||||
main:
|
||||
parent: content
|
||||
prev: /content/markdown-extras
|
||||
next: /content/example
|
||||
prev: /content/summaries
|
||||
title: Multilingual Mode
|
||||
weight: 68
|
||||
toc: true
|
||||
@@ -15,30 +15,38 @@ Example:
|
||||
|
||||
```
|
||||
DefaultContentLanguage = "en"
|
||||
copyright = "Everything is mine"
|
||||
|
||||
Languages:
|
||||
en:
|
||||
weight: 1
|
||||
title: "My blog"
|
||||
params:
|
||||
linkedin: "english-link"
|
||||
fr:
|
||||
weight: 2
|
||||
title: "Mon blog"
|
||||
params:
|
||||
linkedin: "lien-francais"
|
||||
copyright: "Tout est à moi"
|
||||
[params.navigation]
|
||||
help = "Help"
|
||||
|
||||
[Languages]
|
||||
[Languages.en]
|
||||
title = "My blog"
|
||||
weight = 1
|
||||
[Languages.en.params]
|
||||
linkedin = "english-link"
|
||||
|
||||
[Languages.fr]
|
||||
copyright = "Tout est à moi"
|
||||
title = "Mon blog"
|
||||
weight = 2
|
||||
[Languages.fr.params]
|
||||
linkedin = "lien-francais"
|
||||
[Languages.fr.navigation]
|
||||
help = "Aide"
|
||||
|
||||
copyright: "Everything is mine"
|
||||
```
|
||||
|
||||
Anything not defined in a `[lang]:` block will fall back to the global
|
||||
Anything not defined in a `[Languages]` block will fall back to the global
|
||||
value for that key (like `copyright` for the English (`en`) language in this example).
|
||||
|
||||
With the config above, all content, sitemap, RSS feeds, paginations
|
||||
and taxonomy pages will be rendered below `/` in English (your default content language), and below `/fr` in French.
|
||||
|
||||
If you want all of the languages to be put below their respective language code, enable `DefaultContentLanguageInSubdir: true` in your configuration.
|
||||
When working with params in frontmatter pages, omit the `params` in the key for the translation.
|
||||
|
||||
If you want all of the languages to be put below their respective language code, enable `defaultContentLanguageInSubdir: true` in your configuration.
|
||||
|
||||
Only the obvious non-global options can be overridden per language. Examples of global options are `BaseURL`, `BuildDrafts`, etc.
|
||||
|
||||
@@ -81,13 +89,23 @@ You can also have:
|
||||
1. `/content/about.md`
|
||||
2. `/content/about.fr.md`
|
||||
|
||||
In which case the config variable `DefaultContentLanguage` will be used to affect the default language `about.md`. This way, you can
|
||||
In which case the config variable `defaultContentLanguage` will be used to affect the default language `about.md`. This way, you can
|
||||
slowly start to translate your current content without having to rename everything.
|
||||
|
||||
If left unspecified, the value for `DefaultContentLanguage` defaults to `en`.
|
||||
If left unspecified, the value for `defaultContentLanguage` defaults to `en`.
|
||||
|
||||
By having the same _base file name_, the content pieces are linked together as translated pieces.
|
||||
|
||||
If you need distinct URLs per language you can set the slug in the non-default language file. Just define the custom slug for the french translation in your `/content/about.fr.md` file:
|
||||
|
||||
```
|
||||
---
|
||||
slug: "a-propos"
|
||||
---
|
||||
```
|
||||
|
||||
You will get both `/about/` and `/a-propos/` URLs in your build, properly linked as translated pieces.
|
||||
|
||||
### Link to translated content
|
||||
|
||||
To create a list of links to translated content, use a template similar to this:
|
||||
@@ -110,9 +128,9 @@ The above also uses the `i18n` func, see [Translation of strings](#translation-o
|
||||
|
||||
### Translation of strings
|
||||
|
||||
Hugo uses [go-i18n](https://github.com/nicksnyder/go-i18n) to support string translations. Follow the link to find tools to manage your translation workflows.
|
||||
Hugo uses [go-i18n](https://github.com/nicksnyder/go-i18n) to support string translations. Follow the link to find tools to manage your translation workflows.
|
||||
|
||||
Translations are collected from the `themes/[name]/i18n/` folder (built into the theme), as well as translations present in `i18n/` at the root of your project. In the `i18n`, the translations will be merged and take precedence over what is in the theme folder. Language files should be named according to RFC 5646 with names such as `en-US.yaml`, `fr.yaml`, etc.
|
||||
Translations are collected from the `themes/[name]/i18n/` folder (built into the theme), as well as translations present in `i18n/` at the root of your project. In the `i18n`, the translations will be merged and take precedence over what is in the theme folder. Language files should be named according to RFC 5646 with names such as `en-US.toml`, `fr.toml`, etc.
|
||||
|
||||
From within your templates, use the `i18n` function like this:
|
||||
|
||||
@@ -120,11 +138,11 @@ From within your templates, use the `i18n` function like this:
|
||||
{{ i18n "home" }}
|
||||
```
|
||||
|
||||
This uses a definition like this one in `i18n/en-US.yaml`:
|
||||
This uses a definition like this one in `i18n/en-US.toml`:
|
||||
|
||||
```
|
||||
- id: home
|
||||
translation: "Home"
|
||||
[home]
|
||||
other = "Home"
|
||||
```
|
||||
|
||||
Often you will want to use to the page variables in the translations strings. To do that, pass on the "." context when calling `i18n`:
|
||||
@@ -133,13 +151,24 @@ Often you will want to use to the page variables in the translations strings. To
|
||||
{{ i18n "wordCount" . }}
|
||||
```
|
||||
|
||||
This uses a definition like this one in `i18n/en-US.yaml`:
|
||||
This uses a definition like this one in `i18n/en-US.toml`:
|
||||
|
||||
```
|
||||
- id: wordCount
|
||||
translation: "This article has {{ .WordCount }} words."
|
||||
[wordCount]
|
||||
other = "This article has {{ .WordCount }} words."
|
||||
```
|
||||
An example of singular and plural form:
|
||||
|
||||
```
|
||||
[readingTime]
|
||||
one = "One minute read"
|
||||
other = "{{.Count}} minutes read"
|
||||
```
|
||||
And then in the template:
|
||||
|
||||
```
|
||||
{{ i18n "readingTime" .ReadingTime }}
|
||||
```
|
||||
To track down missing translation strings, run Hugo with the `--i18n-warnings` flag:
|
||||
|
||||
```bash
|
||||
@@ -147,14 +176,12 @@ To track down missing translation strings, run Hugo with the `--i18n-warnings` f
|
||||
i18n|MISSING_TRANSLATION|en|wordCount
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Menus
|
||||
|
||||
You can define your menus for each language independently. The [creation of a menu]({{< relref "extras/menus.md" >}}) works analogous to earlier versions of Hugo, except that they have to be defined in their language-specific block in the configuration file:
|
||||
|
||||
```toml
|
||||
DefaultContentLanguage = "en"
|
||||
defaultContentLanguage = "en"
|
||||
|
||||
[languages.en]
|
||||
weight = 0
|
||||
@@ -180,9 +207,9 @@ The rendering of the main navigation works as usual. `.Site.Menus` will just con
|
||||
|
||||
```html
|
||||
<ul>
|
||||
{{- $currentNode := . -}}
|
||||
{{- $currentPage := . -}}
|
||||
{{ range .Site.Menus.main -}}
|
||||
<li class="{{ if $currentNode.IsMenuCurrent "main" . }}active{{ end }}">
|
||||
<li class="{{ if $currentPage.IsMenuCurrent "main" . }}active{{ end }}">
|
||||
<a href="{{ .URL | absLangURL }}">{{ .Name }}</a>
|
||||
</li>
|
||||
{{- end }}
|
||||
|
||||
@@ -29,7 +29,7 @@ in Hugo and is used as the [section](/content/sections/).
|
||||
.
|
||||
└── content
|
||||
└── about
|
||||
| └── index.md // <- http://1.com/about/
|
||||
| └── _index.md // <- http://1.com/about/
|
||||
├── post
|
||||
| ├── firstpost.md // <- http://1.com/post/firstpost/
|
||||
| ├── happy
|
||||
@@ -44,7 +44,7 @@ in Hugo and is used as the [section](/content/sections/).
|
||||
.
|
||||
└── content
|
||||
└── about
|
||||
| └── index.md // <- http://1.com/about/
|
||||
| └── _index.md // <- http://1.com/about/
|
||||
├── post
|
||||
| ├── firstpost.md // <- http://1.com/post/firstpost.html
|
||||
| ├── happy
|
||||
@@ -62,13 +62,13 @@ site. As displayed above, the organization of the source content will be
|
||||
mirrored in the destination.
|
||||
|
||||
Notice that the first level `about/` page URL was created using a directory
|
||||
named "about" with a single `index.md` file inside.
|
||||
named "about" with a single `_index.md` file inside. Find out more about `_index.md` specifically in [content for the homepage and other list pages](https://gohugo.io/overview/source-directory#content-for-home-page-and-other-list-pages).
|
||||
|
||||
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
|
||||
The following items are defined in order; latter items in the list will override
|
||||
earlier settings.
|
||||
|
||||
### filename
|
||||
@@ -84,7 +84,7 @@ The actual path to the file on disk. Destination will create the destination
|
||||
with the same path. Includes [section](/content/sections/).
|
||||
|
||||
### section
|
||||
`section` is determined by its location on disk and can *not* be specified in the front matter. See [section](/content/sections/).
|
||||
`section` is determined by its location on disk and *cannot* be specified in the front matter. See [section](/content/sections/).
|
||||
|
||||
### type
|
||||
`type` is also determined by its location on disk but, unlike `section`, it *can* be specified in the front matter. See [type](/content/types/).
|
||||
|
||||
@@ -36,6 +36,8 @@ 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.
|
||||
|
||||
Section pages can also have a content file and frontmatter, see [Source Organization]({{< relref "overview/source-directory.md#content-for-home-page-and-other-list-pages" >}}).
|
||||
|
||||
## Sections and Types
|
||||
|
||||
By default everything created within a section will use the content type
|
||||
|
||||
@@ -11,7 +11,7 @@ title: Summaries
|
||||
weight: 65
|
||||
---
|
||||
|
||||
With the use of the `.Summary` [page variable](/templates/variables/), Hugo can generate summaries of content for easily showing snippets in summary views. The summary view snippets are automatically generated by Hugo. Where a piece of content is split for the content summary depends on whether the split is Hugo-defined or user-defined.
|
||||
With the use of the `.Summary` [page variable](/templates/variables/), Hugo can generate summaries of content to show snippets in summary views. The summary view snippets are automatically generated by Hugo. Where a piece of content is split for the content summary depends on whether the split is Hugo-defined or user-defined.
|
||||
|
||||
Content summaries may also provide links to the original content, usually in the form of a "Read More..." link, with the help of the `.RelPermalink` or `.Permalink` variable, as well as the `.Truncated` boolean variable to determine whether such "Read More..." link is necessary.
|
||||
|
||||
@@ -24,19 +24,20 @@ By default, Hugo automatically takes the first 70 words of your content as its s
|
||||
|
||||
## User-defined: manual summary split:
|
||||
|
||||
Alternatively, you may add the <code><!--more--></code> summary divider[^1] where you want to split the article. Content prior to the summary divider will be used as that content's summary, and stored into the `.Summary` variable with all HTML formatting intact.
|
||||
Alternatively, you may add the <code><!--more--></code> summary divider[^1] (for org content, use <code># more</code>) where you want to split the article. Content prior to the summary divider will be used as that content's summary, and stored into the `.Summary` variable with all HTML formatting intact.
|
||||
|
||||
[^1]: The **summary divider** is also called "more tag", "excerpt separator", etc. in other literature.
|
||||
|
||||
* Pros: Freedom, precision, and improved rendering. All formatting is preserved.
|
||||
* Cons: Need to remember to type <code><!--more--></code> in your content file. :-)
|
||||
* Cons: Need to remember to type <code><!--more--></code> (or <code># more</code> for org content) in your content file. :-)
|
||||
|
||||
Be careful to enter <code><!--more--></code> exactly, i.e. all lowercase with no whitespace, otherwise it would be treated as regular comment and ignored.
|
||||
Be careful to enter <code><!--more--></code> (or <code># more</code> for org content) exactly, i.e. all lowercase with no whitespace, otherwise it would be treated as regular comment and ignored.
|
||||
|
||||
If there is nothing but spaces and newlines after the summary divider then `.Truncated` will be false.
|
||||
|
||||
## Showing Summaries
|
||||
|
||||
You can show content summaries with the following code. You could do this, for example, on a [list](/templates/list/) node.
|
||||
You can show content summaries with the following code. You could do this, for example, on a [list](/templates/list/) page.
|
||||
|
||||
{{ range first 10 .Data.Pages }}
|
||||
<div class="summary">
|
||||
|
||||
@@ -13,7 +13,7 @@ weight: 15
|
||||
toc: true
|
||||
---
|
||||
|
||||
Since 0.14, Hugo has defined a new concept called _external helpers_. It means that you can write your content using Asciidoc[tor], or reStructuredText. If you have files with associated extensions ([details](https://github.com/spf13/hugo/blob/77c60a3440806067109347d04eb5368b65ea0fe8/helpers/general.go#L65)), then Hugo will call external commands to generate the content.
|
||||
Since 0.14, Hugo has defined a new concept called _external helpers_. It means that you can write your content using Asciidoc[tor], reStructuredText or Org-Mode. If you have files with associated extensions ([details](https://github.com/spf13/hugo/blob/77c60a3440806067109347d04eb5368b65ea0fe8/helpers/general.go#L65)), then Hugo will call external commands to generate the content (the exception being Org-Mode content, which is parsed natively).
|
||||
|
||||
This means that you will have to install the associated tool on your machine to be able to use those formats.
|
||||
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/using-index-md/
|
||||
lastmod: 2017-02-22
|
||||
date: 2017-02-22
|
||||
linktitle: Using _index.md
|
||||
menu:
|
||||
main:
|
||||
parent: content
|
||||
prev: /content/example
|
||||
next: /themes/overview
|
||||
notoc: true
|
||||
title: Using _index.md
|
||||
weight: 70
|
||||
---
|
||||
# \_index.md and 'Everything is a Page'
|
||||
|
||||
As of version v0.18 Hugo now treats '[everything as a page](http://bepsays.com/en/2016/12/19/hugo-018/)'. This allows you to add content and frontmatter to any page - including List pages like [Sections](/content/sections/), [Taxonomies](/taxonomies/overview/), [Taxonomy Terms pages](/templates/terms/) and even to potential 'special case' pages like the [Home page](/templates/homepage/).
|
||||
|
||||
In order to take advantage of this behaviour you need to do a few things.
|
||||
|
||||
1. Create an \_index.md file that contains the frontmatter and content you would like to apply.
|
||||
|
||||
2. Place the \_index.md file in the correct place in the directory structure.
|
||||
|
||||
3. Ensure that the respective template is configured to display `{{ .Content }}` if you wish for the content of the \_index.md file to be rendered on the respective page.
|
||||
|
||||
## How \_index.md pages work
|
||||
|
||||
Before continuing it's important to know that this page must reference certain templates to describe how the \_index.md page will be rendered. Hugo has a multitude of possible templates that can be used and placed in various places (think theme templates for instance). For simplicity/brevity the default/top level template location will be used to refer to the entire range of places the template can be placed.
|
||||
|
||||
If this is confusing or you are unfamiliar with Hugo's template hierarchy, visit the various template pages listed below. You may need to find the 'active' template responsible for any particular page on your own site by going through the template hierarchy and matching it to your particular setup/theme you are using.
|
||||
|
||||
- [Home page template](/templates/homepage/)
|
||||
- [Content List templates](/templates/list/)
|
||||
- [Single Content templates](/templates/content/)
|
||||
- [Taxonomy Terms templates](/templates/terms/)
|
||||
|
||||
Now that you've got a handle on templates lets recap some Hugo basics to understand how to use an \_index.md file with a List page.
|
||||
|
||||
1. Sections and Taxonomies are 'List' pages, NOT single pages.
|
||||
2. List pages are rendered using the template hierarchy found in the [Content - List Template](/templates/list/) docs.
|
||||
3. The Home page, though technically a List page, can have [its own template](/templates/homepage/) at layouts/index.html rather than \_default/list.html. Many themes exploit this behaviour so you are likely to encounter this specific use case.
|
||||
4. Taxonomy terms pages are 'lists of metadata' not lists of content, so [have their own templates](/templates/terms/).
|
||||
|
||||
Let's put all this information together:
|
||||
|
||||
> **\_index.md files used in List pages, Terms pages or the Home page are NOT rendered as single pages or with Single Content templates.**
|
||||
|
||||
> **All pages, including List pages, can have frontmatter and frontmatter can have markdown content - meaning \_index.md files are the way to _provide_ frontmatter and content to the respective List/Terms/Home page.**
|
||||
|
||||
Here are a couple of examples to make it clearer...
|
||||
|
||||
| \_index.md location | Page affected | Rendered by |
|
||||
| ------------------- | ------------ | ----------- |
|
||||
| /content/post/\_index.md | site.com/post/ | /layouts/section/post.html |
|
||||
| /content/categories/hugo/\_index.md | site.com/categories/hugo/ | /layouts/taxonomy/hugo.html |
|
||||
|
||||
## Why \_index.md files are used
|
||||
|
||||
With a Single page such as a post it's possible to add the frontmatter and content directly into the .md page itself. With List/Terms/Home pages this is not possible so \_index.md files can be used to provide that frontmatter/content to them.
|
||||
|
||||
## How to display content from \_index.md files
|
||||
|
||||
From the information above it should follow that content within an \_index.md file won't be rendered in its own Single Page, instead it'll be made available to the respective List/Terms/Home page.
|
||||
|
||||
To **_actually render that content_** you need to ensure that the relevant template responsible for rendering the List/Terms/Home page contains (at least) `{{ .Content }}`.
|
||||
|
||||
This is the way to actually display the content within the \_index.md file on the List/Terms/Home page.
|
||||
|
||||
A very simple/naive example of this would be:
|
||||
|
||||
```html
|
||||
{{ partial "header.html" . }}
|
||||
<main>
|
||||
{{ .Content }}
|
||||
{{ range .Paginator.Pages }}
|
||||
{{ partial "summary.html" . }}
|
||||
{{ end }}
|
||||
{{ partial "pagination.html" . }}
|
||||
</main>
|
||||
{{ partial "sidebar.html" . }}
|
||||
{{ partial "footer.html" . }}
|
||||
```
|
||||
|
||||
You can see `{{ .Content }}` just after the `<main>` element. For this particular example, the content of the \_index.md file will show before the main list of summaries.
|
||||
|
||||
## Where to organise an \_index.md file
|
||||
|
||||
To add content and frontmatter to the home page, a section, a taxonomy or a taxonomy terms listing, add a markdown file with the base name \_index on the relevant place on the file system.
|
||||
|
||||
```bash
|
||||
└── content
|
||||
├── _index.md
|
||||
├── categories
|
||||
│ ├── _index.md
|
||||
│ └── photo
|
||||
│ └── _index.md
|
||||
├── post
|
||||
│ ├── _index.md
|
||||
│ └── firstpost.md
|
||||
└── tags
|
||||
├── _index.md
|
||||
└── hugo
|
||||
└── _index.md
|
||||
```
|
||||
|
||||
In the above example \_index.md pages have been added to each section/taxonomy.
|
||||
|
||||
An \_index.md file has also been added in the top level 'content' directory.
|
||||
|
||||
### Where to place \_index.md for the Home page
|
||||
|
||||
Hugo themes are designed to use the 'content' directory as the root of the website, so adding an \_index.md file here (like has been done in the example above) is how you would add frontmatter/content to the home page.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,9 +9,8 @@ menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/analytics
|
||||
prev: /taxonomies/ordering
|
||||
prev: /taxonomies/methods
|
||||
title: Aliases
|
||||
weight: 10
|
||||
---
|
||||
|
||||
For people migrating existing published content to Hugo, there's a good chance you need a mechanism to handle redirecting old URLs.
|
||||
@@ -79,7 +78,7 @@ aliases:
|
||||
|
||||
When aliases are specified, Hugo creates a physical folder structure to match the alias entry, and, an html file specifying the canonical URL for the page, and a redirect target.
|
||||
|
||||
Assuming a baseurl of `mysite.tld`, the contents of the html file will look something like:
|
||||
Assuming a baseURL of `mysite.tld`, the contents of the html file will look something like:
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
@@ -94,3 +93,11 @@ Assuming a baseurl of `mysite.tld`, the contents of the html file will look some
|
||||
```
|
||||
|
||||
The `http-equiv="refresh"` line is what performs the redirect, in 0 seconds in this case.
|
||||
|
||||
## Customizing
|
||||
|
||||
You may customize this alias page by creating an alias.html template in the
|
||||
layouts folder of your site. In this case, the data passed to the template is
|
||||
|
||||
* Permalink - the link to the page being aliased
|
||||
* Page - the Page data for the page being aliased
|
||||
|
||||
@@ -7,7 +7,6 @@ menu:
|
||||
next: /extras/builders
|
||||
prev: /extras/aliases
|
||||
title: Analytics in Hugo
|
||||
weight: 15
|
||||
---
|
||||
|
||||
Hugo ships with prebuilt internal templates for Google Analytics tracking, including both synchronous and asynchronous tracking codes.
|
||||
|
||||
@@ -8,7 +8,6 @@ menu:
|
||||
next: /extras/comments
|
||||
prev: /extras/analytics
|
||||
title: Hugo Builders
|
||||
weight: 20
|
||||
---
|
||||
|
||||
Hugo provides the functionality to quickly get a site, theme or page
|
||||
|
||||
@@ -8,7 +8,6 @@ menu:
|
||||
next: /extras/crossreferences
|
||||
prev: /extras/builders
|
||||
title: Comments in Hugo
|
||||
weight: 30
|
||||
---
|
||||
|
||||
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.
|
||||
@@ -73,9 +72,10 @@ Now, reference the partial template from your page template:
|
||||
|
||||
A few alternatives exist to [Disqus](https://disqus.com/):
|
||||
|
||||
* [txtpen](https://txtpen.com)
|
||||
* [Discourse](http://www.discourse.org)
|
||||
* [IntenseDebate](http://intensedebate.com/)
|
||||
* [Livefyre](http://livefyre.com/)
|
||||
* [Livefyre](http://www.adobe.com/marketing-cloud/enterprise-content-management/ugc-content-platform.html)
|
||||
* [Muut](http://muut.com/)
|
||||
* [多说](http://duoshuo.com/) ([Duoshuo](http://duoshuo.com/), popular in China)
|
||||
* [isso](http://posativ.org/isso/) (Self-hosted, Python)
|
||||
@@ -89,6 +89,10 @@ Written using Go, Socket.io and MongoDB, it is very fast and easy to deploy.
|
||||
|
||||
It is in early development but shows promise. If you have interest, please help by contributing whether via a pull request, an issue or even just a tweet. Everything helps.
|
||||
|
||||
## txtpen
|
||||
|
||||
[txtpen](https://txtpen.com) adds highlighting an in-line commenting similar to Medium to your Hugo blog.
|
||||
|
||||
## Discourse
|
||||
|
||||
Additionally, you may recognize [Discourse](http://www.discourse.org) as the system that powers the [Hugo Discussion Forum](http://discuss.gohugo.io).
|
||||
|
||||
@@ -4,11 +4,10 @@ date: 2014-11-25
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/livereload
|
||||
next: /extras/robots-txt
|
||||
prev: /extras/comments
|
||||
title: Cross-References
|
||||
toc: true
|
||||
weight: 40
|
||||
---
|
||||
|
||||
Hugo makes it easy to link documents together with the `ref` and `relref` shortcodes. These shortcodes are also used to safely provide links to headings inside of your content, whether across documents or within a document. The only difference between `ref` and `relref` is whether the resulting URL is absolute (`http://1.com/about/`) or relative (`/about/`).
|
||||
|
||||
@@ -6,10 +6,9 @@ date: 2015-02-14
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/highlighting
|
||||
next: /extras/gitinfo
|
||||
prev: /extras/datafiles
|
||||
title: Data-driven Content
|
||||
weight: 91
|
||||
toc: true
|
||||
---
|
||||
|
||||
@@ -103,6 +102,8 @@ temporary directory.
|
||||
With the command-line flag `--cacheDir`, you can specify any folder on
|
||||
your system as a caching directory.
|
||||
|
||||
You can also set `cacheDir` in the main configuration file.
|
||||
|
||||
If you don't like caching at all, you can fully disable caching with the
|
||||
command line flag `--ignoreCache`.
|
||||
|
||||
|
||||
@@ -7,9 +7,8 @@ menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/datadrivencontent
|
||||
prev: /extras/scratch
|
||||
prev: /extras/robots-txt
|
||||
title: Data Files
|
||||
weight: 90
|
||||
---
|
||||
|
||||
In addition to the [built-in variables](/templates/variables/) available from Hugo, you can specify your own custom data that can be accessed via templates or shortcodes.
|
||||
@@ -22,7 +21,7 @@ Data Files can also be used in [themes](/themes/overview/), but note: If the sam
|
||||
|
||||
## The Data Folder
|
||||
|
||||
The `data` folder is where you can store additional data for Hugo to use when generating your site. Data files aren't used to generate standalone pages - rather they're meant supplemental to the content files. This feature can extend the content in case your frontmatter would grow immensely. Or perhaps your want to show a larger dataset in a template (see example below). In both cases it's a good idea to outsource the data in their own file.
|
||||
The `data` folder is where you can store additional data for Hugo to use when generating your site. Data files aren't used to generate standalone pages - rather they're meant to supplement the content files. This feature can extend the content in case your frontmatter would grow immensely. Or perhaps you want to show a larger dataset in a template (see example below). In both cases it's a good idea to outsource the data in their own file.
|
||||
|
||||
These files must be YAML, JSON or TOML files (using either the `.yml`, `.yaml`, `.json` or `toml` extension) and the data will be accessible as a `map` in `.Site.Data`.
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/gitinfo/
|
||||
lastmod: 2016-12-11
|
||||
date: 2016-12-11
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/livereload
|
||||
prev: /extras/datadrivencontent
|
||||
title: GitInfo
|
||||
---
|
||||
|
||||
Hugo provides a way to integrate Git data into your site.
|
||||
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. The Hugo site must be in a Git-enabled directory.
|
||||
1. The Git executable must be installed and in your system `PATH`.
|
||||
1. Enable the GitInfo feature in Hugo by using `--enableGitInfo` on the command
|
||||
line or by setting `enableGitInfo` to `true` in your site configuration.
|
||||
|
||||
## The GitInfo Object
|
||||
|
||||
The `GitInfo` object contains the following fields:
|
||||
|
||||
AbbreviatedHash
|
||||
: abbreviated commit hash, e.g. `866cbcc`
|
||||
|
||||
AuthorName
|
||||
: author name, respecting `.mailmap`
|
||||
|
||||
AuthorEmail
|
||||
: author email address, respecting `.mailmap`
|
||||
|
||||
AuthorDate
|
||||
: the author date
|
||||
|
||||
Hash
|
||||
: commit hash, e.g. `866cbccdab588b9908887ffd3b4f2667e94090c3`
|
||||
|
||||
Subject
|
||||
: commit message subject, e.g. `tpl: Add custom index function`
|
||||
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
The Git integrations should be fairly performant, but it does add some time to the build, which depends somewhat on the Git history size.
|
||||
|
||||
@@ -7,9 +7,8 @@ menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/toc
|
||||
prev: /extras/datadrivencontent
|
||||
prev: /extras/shortcodes
|
||||
title: Syntax Highlighting
|
||||
weight: 90
|
||||
toc: true
|
||||
---
|
||||
|
||||
|
||||
@@ -5,9 +5,8 @@ menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/menus
|
||||
prev: /extras/crossreferences
|
||||
prev: /extras/gitinfo
|
||||
title: LiveReload
|
||||
weight: 50
|
||||
---
|
||||
|
||||
Hugo may not be the first static site generator to utilize LiveReload
|
||||
|
||||
@@ -6,11 +6,10 @@ date: 2015-06-12
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /community/mailing-list
|
||||
next: /extras/urls
|
||||
notoc: true
|
||||
prev: /extras/urls
|
||||
prev: /extras/toc
|
||||
title: Traversing Local Files
|
||||
weight: 110
|
||||
---
|
||||
## Traversing Local Files
|
||||
|
||||
|
||||
+181
-23
@@ -5,10 +5,9 @@ toc: true
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/permalinks
|
||||
next: /extras/pagination
|
||||
prev: /extras/livereload
|
||||
title: Menus
|
||||
weight: 60
|
||||
---
|
||||
|
||||
Hugo has a simple yet powerful menu system that permits content to be
|
||||
@@ -34,25 +33,26 @@ If you make use of the [multilingual feature]({{< relref "content/multilingual.m
|
||||
|
||||
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
|
||||
* `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
|
||||
* `HasChildren() bool`
|
||||
|
||||
Additionally, there are some relevant functions available on the page:
|
||||
Additionally, the `Page` object has two functions, which can be used when rendering menus:
|
||||
|
||||
* **IsMenuCurrent** (menu string, menuEntry *MenuEntry ) bool
|
||||
* **HasMenuCurrent** (menu string, menuEntry *MenuEntry) bool
|
||||
* `IsMenuCurrent (menu string, menuEntry *MenuEntry ) bool`
|
||||
* `HasMenuCurrent** (menu string, menuEntry *MenuEntry) bool`
|
||||
|
||||
See [Menu Functions](#menu-functions) for explanations of these functions, and [Rendering Nested Menus](#rendering-nested-menus) for an example of their use.
|
||||
|
||||
## Adding content to menus
|
||||
|
||||
@@ -127,7 +127,7 @@ And the equivalent example `config.yaml`:
|
||||
---
|
||||
|
||||
|
||||
**NOTE:** The URLs must be relative to the context root. If the `BaseURL` is `http://example.com/mysite/`, then the URLs in the menu must not include the context root `mysite`. Using an absolute URL will overide the BaseURL. If the `URL` is `http://subdomain.example.com/`, the output will be `http://subdomain.example.com`.
|
||||
**NOTE:** The URLs must be relative to the context root. If the `baseURL` is `http://example.com/mysite/`, then the URLs in the menu must not include the context root `mysite`. Using an absolute URL will overide the baseURL. If the `URL` is `http://subdomain.example.com/`, the output will be `http://subdomain.example.com`.
|
||||
|
||||
## Nesting
|
||||
|
||||
@@ -136,9 +136,9 @@ 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 an Identifier:
|
||||
The following order is used to determine an Identifier:
|
||||
|
||||
> Name > LinkTitle > Title.
|
||||
> Name > LinkTitle > Title.
|
||||
|
||||
This means that the title will be used unless
|
||||
linktitle is present, etc. In practice Name and Identifier are never
|
||||
@@ -162,11 +162,11 @@ The following is an example:
|
||||
<div id="sidebar" class="nav-collapse">
|
||||
<!-- sidebar menu start-->
|
||||
<ul class="sidebar-menu">
|
||||
{{ $currentNode := . }}
|
||||
{{ $currentPage := . }}
|
||||
{{ range .Site.Menus.main }}
|
||||
{{ if .HasChildren }}
|
||||
|
||||
<li class="sub-menu{{if $currentNode.HasMenuCurrent "main" . }} active{{end}}">
|
||||
<li class="sub-menu{{if $currentPage.HasMenuCurrent "main" . }} active{{end}}">
|
||||
<a href="javascript:;" class="">
|
||||
{{ .Pre }}
|
||||
<span>{{ .Name }}</span>
|
||||
@@ -174,7 +174,7 @@ The following is an example:
|
||||
</a>
|
||||
<ul class="sub">
|
||||
{{ range .Children }}
|
||||
<li{{if $currentNode.IsMenuCurrent "main" . }} class="active"{{end}}><a href="{{.URL}}"> {{ .Name }} </a> </li>
|
||||
<li{{if $currentPage.IsMenuCurrent "main" . }} class="active"{{end}}><a href="{{.URL}}"> {{ .Name }} </a> </li>
|
||||
{{ end }}
|
||||
</ul>
|
||||
{{else}}
|
||||
@@ -210,9 +210,9 @@ This will create a menu with all the sections as menu items and all the sections
|
||||
|
||||
```
|
||||
<nav class="sidebar-nav">
|
||||
{{ $currentNode := . }}
|
||||
{{ $currentPage := . }}
|
||||
{{ range .Site.Menus.main }}
|
||||
<a class="sidebar-nav-item{{if or ($currentNode.IsMenuCurrent "main" .) ($currentNode.HasMenuCurrent "main" .) }} active{{end}}" href="{{.URL}}">{{ .Name }}</a>
|
||||
<a class="sidebar-nav-item{{if or ($currentPage.IsMenuCurrent "main" .) ($currentPage.HasMenuCurrent "main" .) }} active{{end}}" href="{{.URL}}">{{ .Name }}</a>
|
||||
{{ end }}
|
||||
</nav>
|
||||
|
||||
@@ -233,3 +233,161 @@ The above is all that's needed. But if you want custom menu items, e.g. changing
|
||||
|
||||
**Note** that the `identifier` must match the section name.
|
||||
|
||||
|
||||
|
||||
|
||||
## Menu Functions
|
||||
|
||||
Suppose you have the menu structure shown below.
|
||||
|
||||
```
|
||||
[menu.main]
|
||||
│
|
||||
├───colour
|
||||
│ │
|
||||
│ ├───warm
|
||||
│ │ ├───orange
|
||||
│ │ ├───red
|
||||
│ │ └───yellow
|
||||
│ │
|
||||
│ └───cool
|
||||
│ ├───blue
|
||||
│ ├───green
|
||||
│ └───purple
|
||||
│
|
||||
└───tool
|
||||
├───hammer
|
||||
├───shovel
|
||||
└───saw
|
||||
```
|
||||
|
||||
For each menu item, you can determine:
|
||||
|
||||
* If the menu item has any children: `.HasChildren()`
|
||||
* If the menu item is a parent of the page you are currently rendering: `.Page.HasMenuCurrent()`
|
||||
* If the menu item **is** the page you are currently rendering: `.Page.IsMenuCurrent()`
|
||||
|
||||
For example, if you are currently rendering the page `/colour/warm`, the values of `.HasChildren`, `HasMenuCurrent`, and `IsMenuCurrent` would be as shown below:
|
||||
|
||||
```
|
||||
|
||||
[menu.main] | | | |
|
||||
│ | | | |
|
||||
├───colour | HasMenuCurrent | | HasChildren |
|
||||
│ ├───<< WARM >> | | IsMenuCurrent | HasChildren |
|
||||
│ │ ├───orange | | | |
|
||||
│ │ ├───red | | | |
|
||||
│ │ └───yellow | | | |
|
||||
│ └───cool | | | HasChildren |
|
||||
│ ├───blue | | | |
|
||||
│ ├───green | | | |
|
||||
│ └───purple | | | |
|
||||
└───tool | | | HasChildren |
|
||||
├───hammer | | | |
|
||||
├───shovel | | | |
|
||||
└───saw | | | |
|
||||
```
|
||||
|
||||
## Rendering nested menus
|
||||
|
||||
Hugo supports nested menus with as many levels as you like.
|
||||
|
||||
Nested menus can be rendered using a recursive partial template, such as the example below.
|
||||
|
||||
```
|
||||
<!-- layouts/index.html, layouts/_default/single.html, ... -->
|
||||
<h1>{{ .Title }}</h1>
|
||||
<!-- Put this line in your main template, at the place where you want to
|
||||
render the menu. -->
|
||||
{{ partial "menu_include.html" . }}
|
||||
```
|
||||
|
||||
```
|
||||
<!-- layouts/partials/menu_include.html -->
|
||||
{{ partial "menu_recursive.html" (dict "menu" .Site.Menus.main "page" . "site" .Site) }}
|
||||
```
|
||||
|
||||
```
|
||||
<!-- layouts/partials/menu_recursive.html -->
|
||||
{{ $page := .page }}
|
||||
{{ $site := .site }}
|
||||
<ul>
|
||||
{{ range .menu }}
|
||||
{{ $is := $page.IsMenuCurrent "main" . }}
|
||||
{{ $has := $page.HasMenuCurrent "main" . }}
|
||||
{{ if .HasChildren }}
|
||||
<li>
|
||||
<a href="{{ .URL }}">
|
||||
{{ .Name }}
|
||||
{{ if $is }}[Is]{{ end }}
|
||||
{{ if $has }}[Has]{{ end }}
|
||||
{{ if .HasChildren }}[Children]{{ end }}
|
||||
</a>
|
||||
<!-- If the menu item has children, include this partial template again (recursively) -->
|
||||
{{ partial "menu_recursive.html" (dict "menu" .Children "page" $page "site" $site) }}
|
||||
</li>
|
||||
{{ else }}
|
||||
<li>
|
||||
<a href="{{ .URL }}">
|
||||
{{ .Name }}
|
||||
{{ if $is }}[Is]{{ end }}
|
||||
{{ if $has }}[Has]{{ end }}
|
||||
{{ if .HasChildren }}[Children]{{ end }}
|
||||
</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</ul>
|
||||
```
|
||||
|
||||
This example code renders the words `[Is]`, `[Has]`, and `[Children]` to demonstrate how the `IsMenuCurrent()`, `HasMenuCurrent()`, and `HasChildren()` functions work.
|
||||
|
||||
You can customise this example to implement features such as:
|
||||
|
||||
* Highlight the current item, by applying a CSS style:
|
||||
|
||||
<a href="{{ .URL }}"{{ if $is }} class="active"{{ end }}>
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* Highlight parents of the current item, by applying a CSS style:
|
||||
|
||||
<a href="{{ .URL }}"{{ if $has }} class="parent-active"{{ end }}>
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
* Only render sub-menus for parents of the current menu item, and the current menu item itself:
|
||||
|
||||
{{ if or $is $has }}
|
||||
{{ partial "menu_recursive.html" (dict "menu" .Children "page" $page "site" $site) }}
|
||||
{{ end }}
|
||||
|
||||
A working example, implementing these features, is shown below.
|
||||
|
||||
```
|
||||
<!-- layouts/partials/menu_recursive.html -->
|
||||
{{ $page := .page }}
|
||||
{{ $site := .site }}
|
||||
<ul>
|
||||
<!-- Menu items sorted alphabetically by name -->
|
||||
{{ range .menu.ByName }}
|
||||
{{ $is := $page.IsMenuCurrent "main" . }}
|
||||
{{ $has := $page.HasMenuCurrent "main" . }}
|
||||
{{ if .HasChildren }}
|
||||
<li>
|
||||
<a href="{{ .URL }}" class="{{ if $is }} active{{ end }}{{ if $has }} parent-active{{ end }}">
|
||||
{{ .Name }}
|
||||
<!-- Show a » symbol if there is a sub-menu we haven't rendered -->
|
||||
{{ if not (or $is $has) }}»{{ end }}
|
||||
</a>
|
||||
<!-- Only render sub-menu for parent items and the current item -->
|
||||
{{ if or $is $has }}
|
||||
{{ partial "menu_recursive.html" (dict "menu" .Children "page" $page "site" $site) }}
|
||||
{{ end }}
|
||||
</li>
|
||||
{{ else }}
|
||||
<li>
|
||||
<a href="{{ .URL }}" class="{{ if $is }}active{{end}}">{{ .Name }}</a>
|
||||
</li>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
</ul>
|
||||
```
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
---
|
||||
aliases:
|
||||
- /doc/output-formats/
|
||||
- /doc/custom-output/
|
||||
date: 2017-03-22T08:20:13+01:00
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
title: Output Formats
|
||||
weight: 5
|
||||
toc: true
|
||||
---
|
||||
|
||||
Hugo `0.20` introduced the powerful feature **Custom Output Formats**; Hugo isn't just that "static HTML with an added RSS feed" anymore. _Say hello_ to calendars, e-book formats, Google AMP, and JSON search indexes, to name a few.
|
||||
|
||||
This page describes how to properly configure your site with the media types and output formats you need.
|
||||
|
||||
## Media Types
|
||||
|
||||
A [media type](https://en.wikipedia.org/wiki/Media_type) (also known as MIME type and content type) is a two-part identifier for file formats and format contents transmitted on the Internet.
|
||||
|
||||
This is the full set of built-in media types in Hugo:
|
||||
|
||||
{{< datatable "media" "types" "Type" "Suffix" >}}
|
||||
|
||||
**Note:**
|
||||
|
||||
* It is possible to add custom media types or change the defaults (if you, say, want to change the suffix to `asp` for `text/html`).
|
||||
* The `Suffix` is the value that will be used for URLs and filenames for that media type in Hugo.
|
||||
* The `Type` is the identifier that must be used when defining new `Output Formats` (see below).
|
||||
* The full set of media types will be registered in Hugo's built-in development server to make sure they are recognized by the browser.
|
||||
|
||||
To add or modify a media type, define it in a `mediaTypes` section in your site config (either for all sites or for a given language).
|
||||
|
||||
Example in `config.toml`:
|
||||
|
||||
```toml
|
||||
[mediaTypes]
|
||||
[mediaTypes."text/enriched"]
|
||||
suffix = "enr"
|
||||
[mediaTypes."text/html"]
|
||||
suffix = "asp"
|
||||
```
|
||||
|
||||
The above example adds one new media type, `text/enriched`, and changes the suffix for the built-in `text/html` media type.
|
||||
|
||||
## Output Formats
|
||||
Given a media type and some additional configuration, you get an `Output Format`.
|
||||
|
||||
This is the full set of built-in output formats in Hugo:
|
||||
|
||||
{{< datatable "output" "formats" "Name" "MediaType" "Path" "BaseName" "Rel" "Protocol" "IsPlainText" "IsHTML" "NoUgly" "NotAlternative">}}
|
||||
|
||||
**Note:**
|
||||
|
||||
* A page can be output in as many output formats as you want, and you can have an infinite amount of output formats defined, as long as _they resolve to a unique path on the file system_. In the table above, the best example of this is `AMP` vs. `HTML`: We have given `AMP` a value for `Path` so it doesn't overwrite the `HTML` version, i.e. we can now have both `/index.html` and `/amp/index.html`.
|
||||
* The `MediaType` must match the `Type` of an already defined media type (see above).
|
||||
* You can define new or redefine built-in output formats (if you, as an example, want to put `AMP` pages in a different path).
|
||||
|
||||
To add or modify a media type, define it in a `outputFormats` section in your site config (either for all sites or for a given language).
|
||||
|
||||
Example in `config.toml`:
|
||||
|
||||
```toml
|
||||
[outputFormats.MyEnrichedFormat]
|
||||
mediaType = "text/enriched"
|
||||
baseName = "myindex"
|
||||
isPlainText = true
|
||||
protocol = "bep://"
|
||||
```
|
||||
|
||||
The above example is fictional, but if used for the home page on a site with `baseURL` `http://example.org`, it will produce a plain text home page with the URL `bep://example.org/myindex.enr`.
|
||||
|
||||
All the available configuration options for output formats and their default values:
|
||||
|
||||
Field | Description
|
||||
--- | ---
|
||||
**Name** | The output format identifier. This is used to define what output format(s) you want for your pages.
|
||||
**MediaType**|This must match the `Type` of a defined media type. |
|
||||
**Path** | Sub path to save the output files.
|
||||
**BaseName** | The base filename for the list filenames (home page etc.). **Default:** _index_.
|
||||
**Rel** | Can be used to create `rel` values in `link` tags. **Default:** _alternate_.
|
||||
**Protocol** | Will replace the "http://" or "https://" in your `baseURL` for this output format.
|
||||
**IsPlainText** | Use Go's plain text templates parser for the templates. **Default:** _false_.
|
||||
**IsHTML** | Used in situations only relevant for `HTML` type of formats, page aliases being one example.|
|
||||
**NoUgly** | If `uglyURLs` is enabled globally, this can be used to turn it off for a given output format. **Default:** _false_.
|
||||
**NotAlternative** | Enable if it doesn't make sense to include this format in an the `.AlternativeOutputFormats` format listing on `Page`, `CSS` being one good example. Note that we use the term "alternative" and not "alternate" here, as it does not necessarily replace the other format, it is an alternative representation. **Default:** _false_.
|
||||
|
||||
|
||||
## Output Formats for your pages
|
||||
|
||||
A `Page` in Hugo can be rendered to multiple representations on the file system: In its default configuration all will get an `HTML` page and some of them will get an `RSS` page (home page, sections etc.).
|
||||
|
||||
This can be changed by defining an `outputs` list of output formats in either the `Page` front matter or in the site configuration (either for all sites or per language).
|
||||
|
||||
Example from site config in `config.toml`:
|
||||
|
||||
```toml
|
||||
[outputs]
|
||||
home = [ "HTML", "AMP", "RSS"]
|
||||
page = [ "HTML"]
|
||||
```
|
||||
Note:
|
||||
|
||||
* The output definition is per `Page` `Kind`(`page`, `home`, `section`, `taxonomy`, `taxonomyTerm`).
|
||||
* The names used must match the `Name` of a defined `Output Format`.
|
||||
* Any `Kind` without a definition will get `HTML`.
|
||||
* These can be overriden per `Page` in front matter (see below).
|
||||
* When `outputs` is specified, only the formats defined in outputs will be rendered
|
||||
|
||||
A `Page` with `YAML` front matter defining some output formats for that `Page`:
|
||||
|
||||
```yaml
|
||||
---
|
||||
date: "2016-03-19"
|
||||
outputs:
|
||||
- html
|
||||
- amp
|
||||
- json
|
||||
---
|
||||
```
|
||||
Note:
|
||||
|
||||
* The names used for the output formats are case insensitive.
|
||||
* The first output format in the list will act as the default.
|
||||
* The default output format is used when generating links to other pages in menus, etc.
|
||||
|
||||
## Link to Output Formats
|
||||
|
||||
`Page` has both `.OutputFormats` (all formats including the current) and `.AlternativeOutputFormats`, the latter useful for creating a `link rel` list in your `head` section:
|
||||
|
||||
```
|
||||
{{ range .AlternativeOutputFormats -}}
|
||||
<link rel="{{ .Rel }}" type="{{ .MediaType.Type }}" href="{{ .Permalink | safeURL }}">
|
||||
{{ end -}}
|
||||
```
|
||||
|
||||
Note that `.Permalink` on `RelPermalink` on `Page` will return the first output format defined for that page (usually `HTML` if nothing else is defined).
|
||||
|
||||
This is how you link to a given output format:
|
||||
|
||||
```
|
||||
{{ with .OutputFormats.Get "json" -}}
|
||||
<a href="{{ .Permalink }}">{{ .Name }}</a>
|
||||
{{- end }}
|
||||
```
|
||||
From content files, you can use the `ref` or `relref` shortcodes:
|
||||
|
||||
```
|
||||
[Neat]({{</* ref "blog/neat.md" "amp" */>}})
|
||||
[Who]({{</* relref "about.md#who" "amp" */>}})
|
||||
```
|
||||
|
||||
## Templates for your Output Formats
|
||||
|
||||
Of course, for a new Output Format to render anything useful, we need a template for it.
|
||||
|
||||
**The fundamental thing to understand about this is that we in `Hugo 0.20` now also look at Output Format´s `Name` and MediaType´s `Suffix` when we choose the templates to use to render a given `Page`.**
|
||||
|
||||
And with so many possible variations, this is best explained with some examples:
|
||||
|
||||
|
||||
{{< datatable "output" "layouts" "Example" "OutputFormat" "Suffix" "Template Lookup Order" >}}
|
||||
|
||||
**Note:**
|
||||
|
||||
* All of the above examples can use a base template, see [Blocks]({{< relref "templates/blocks.md" >}}).
|
||||
* All of the above examples can also include partials.
|
||||
|
||||
Hugo will now also detect the media type and output format of partials, if possible, and use that information to decide if the partial should be parsed as a plain text template or not.
|
||||
|
||||
Hugo will look for the name given, so you can name it whatever you want. But if you want it treated as plain text, you should use the file suffix and, if needed, the name of the Output Format (`[partial name].[OutputFormat].[suffix])`.
|
||||
|
||||
The partial below is a plain text template (Outpuf Format is `CSV`, and since this is the only output format with the suffix `csv`, we don't need to include the Output Format's `Name`):
|
||||
|
||||
```
|
||||
{{ partial "mytextpartial.csv" . }}
|
||||
```
|
||||
|
||||
Also note that plain text partials can currently only be included in plain text templates, and vice versa. See [this issue](https://github.com/spf13/hugo/issues/3273) for some background.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,10 +6,9 @@ date: 2014-01-01
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/scratch
|
||||
prev: /extras/shortcodes
|
||||
next: /extras/permalinks
|
||||
prev: /extras/menus
|
||||
title: Pagination
|
||||
weight: 80
|
||||
---
|
||||
|
||||
Hugo supports pagination for the home page, sections and taxonomies. It's built to be easy use, but with loads of flexibility when needed. The real power shines when you combine it with [`where`](/templates/functions/), with its SQL-like operators, `first` and others --- you can even [order the content](/templates/list/) the way you've become used to with Hugo.
|
||||
@@ -27,14 +26,14 @@ Setting `Paginate` to a positive value will split the list pages for the home pa
|
||||
|
||||
## List the pages
|
||||
|
||||
**A `.Paginator` is provided to help building a pager menu. This is only relevant for the templates for the home page and the list pages (sections and taxonomies).**
|
||||
**A `.Paginator` is provided to help building a pager menu. This is currently only relevant for the templates for the home page and the list pages (sections and taxonomies).**
|
||||
|
||||
There are two ways to configure and use a `.Paginator`:
|
||||
|
||||
1. The simplest way is just to call `.Paginator.Pages` from a template. It will contain the pages for *that page* .
|
||||
2. Select a sub-set of the pages with the available template functions and ordering options, and pass the slice to `.Paginate`, e.g. `{{ range (.Paginate ( first 50 .Data.Pages.ByTitle )).Pages }}`.
|
||||
|
||||
For a given **Node**, it's one of the options above. The `.Paginator` is static and cannot change once created.
|
||||
For a given **Page**, it's one of the options above. The `.Paginator` is static and cannot change once created.
|
||||
|
||||
The global page size setting (`Paginate`) can be overridden by providing a positive integer as the last argument. The examples below will give five items per page:
|
||||
|
||||
|
||||
@@ -6,11 +6,10 @@ date: 2013-11-18
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/shortcodes
|
||||
next: /extras/scratch
|
||||
notoc: true
|
||||
prev: /extras/menus
|
||||
prev: /extras/pagination
|
||||
title: Permalinks
|
||||
weight: 70
|
||||
---
|
||||
|
||||
By default, content is laid out into the target `publishdir` (public)
|
||||
|
||||
@@ -4,10 +4,9 @@ date: 2015-12-08
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /community/mailing-list
|
||||
prev: /extras/urls
|
||||
next: /extras/datafiles
|
||||
prev: /extras/crossreferences
|
||||
title: Custom robots.txt
|
||||
weight: 120
|
||||
---
|
||||
|
||||
Hugo can generated a customized [robots.txt](http://www.robotstxt.org/) in the
|
||||
|
||||
@@ -6,28 +6,27 @@ date: 2015-01-22
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/datafiles
|
||||
prev: /extras/pagination
|
||||
next: /extras/shortcodes
|
||||
prev: /extras/permalinks
|
||||
title: Scratch
|
||||
weight: 80
|
||||
---
|
||||
|
||||
`Scratch` -- a "scratchpad" for your node- or page-scoped variables. In most cases you can do well without `Scratch`, but there are some use cases that aren't solvable with Go's templates without `Scratch`'s help, due to scoping issues.
|
||||
`Scratch` -- a "scratchpad" for your page-scoped variables. In most cases you can do well without `Scratch`, but there are some use cases that aren't solvable with Go's templates without `Scratch`'s help, due to scoping issues.
|
||||
|
||||
`Scratch` is added to both `Node` and `Page` and `Shortcode` -- with following methods:
|
||||
`Scratch` is added to both `Page` and `Shortcode` -- with following methods:
|
||||
|
||||
* `Set` and `Add` takes a `key` and the `value` to add.
|
||||
* `Get` returns the `value` for the `key` given.
|
||||
* `SetInMap` takes a `key`, `mapKey` and `value`
|
||||
* `GetSortedMapValues` returns array of values from `key` sorted by `mapKey`
|
||||
|
||||
`Set` and `SetInMap` can store values of any type.
|
||||
`Set` and `SetInMap` can store values of any type.
|
||||
|
||||
For single values, `Add` accepts values that support Go's `+` operator. If the first `Add` for a key is an array or slice, the follwing adds will be appended to that list.
|
||||
For single values, `Add` accepts values that support Go's `+` operator. If the first `Add` for a key is an array or slice, the following adds will be appended to that list.
|
||||
|
||||
The scope of the backing data is global for the given `Node`, `Page` or `Shortcode`, and spans partial and shortcode includes.
|
||||
The scope of the backing data is global for the given `Page` or `Shortcode`, and spans partial and shortcode includes.
|
||||
|
||||
Note that `.Scratch` from a shortcode will return the shortcode's `Scratch`, which in most casses is what you want. If you want to store it in the page scroped Scratch, then use `.Page.Scratch`.
|
||||
Note that `.Scratch` from a shortcode will return the shortcode's `Scratch`, which in most cases is what you want. If you want to store it in the page scroped Scratch, then use `.Page.Scratch`.
|
||||
|
||||
## Sample usage
|
||||
|
||||
|
||||
@@ -6,11 +6,10 @@ date: 2013-07-01
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/pagination
|
||||
prev: /extras/permalinks
|
||||
next: /extras/highlighting
|
||||
prev: /extras/scratch
|
||||
title: Shortcodes
|
||||
weight: 80
|
||||
toc: false
|
||||
toc: true
|
||||
---
|
||||
|
||||
Hugo uses Markdown for its simple content format. However, there are a lot
|
||||
@@ -41,7 +40,7 @@ can be quoted.
|
||||
|
||||
The first word is always the name of the shortcode. Parameters follow the name.
|
||||
Depending upon how the shortcode is defined, the parameters may be named,
|
||||
positional or both (although you can't mixed parameter types in a single call).
|
||||
positional or both (although you can't mix parameter types in a single call).
|
||||
The format for named parameters models that of HTML with the format
|
||||
`name="value"`.
|
||||
|
||||
@@ -158,6 +157,11 @@ Read more on [cross-references]({{% ref "extras/crossreferences.md" %}}).
|
||||
|
||||
[Neat]({{</* ref "blog/neat.md" */>}})
|
||||
[Who]({{</* relref "about.md#who" */>}})
|
||||
|
||||
If the page exists in multiple [output formats]({{< relref "extras/output-formats.md" >}}), `ref` or `relref` can be used with a output format name:
|
||||
|
||||
[Neat]({{</* ref "blog/neat.md" "amp" */>}})
|
||||
|
||||
|
||||
#### Example Output
|
||||
|
||||
@@ -186,7 +190,7 @@ Copy the ID from behind `v=` and pass it to the shortcode:
|
||||
|
||||
{{</* youtube w7Ft2ymGmfc */>}}
|
||||
|
||||
Furthermore, you can autostart the embedded video by setting the `autostart` parameter to true. Remember that you can't mix named an unamed parameters. Assign the yet unamed video id to the parameter `id` like below too.
|
||||
Furthermore, you can autoplay the embedded video by setting the `autoplay` parameter to true. Remember that you can't mix named an unamed parameters. Assign the yet unamed video id to the parameter `id` like below too.
|
||||
|
||||
{{</* youtube id="w7Ft2ymGmfc" autoplay="true" */>}}
|
||||
|
||||
@@ -225,6 +229,19 @@ Extract the value from the field `data-id` and pass it to the shortcode:
|
||||
|
||||
{{</* speakerdeck 4e8126e72d853c0060001f97 */>}}
|
||||
|
||||
### Instagram
|
||||
|
||||
If you'd like to embed photo from [Instagram](https://www.instagram.com/), all you need is photo ID from the URL, e. g.:
|
||||
|
||||
* https://www.instagram.com/p/BMokmydjG-M/
|
||||
|
||||
Pass it to the shortcode:
|
||||
|
||||
{{</* instagram BMokmydjG-M */>}}
|
||||
|
||||
Optionally, hide caption:
|
||||
|
||||
{{</* instagram BMokmydjG-M hidecaption */>}}
|
||||
|
||||
## Creating your own shortcodes
|
||||
|
||||
|
||||
@@ -4,10 +4,9 @@ date: 2013-07-09
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/urls
|
||||
next: /extras/localfiles
|
||||
prev: /extras/highlighting
|
||||
title: Table of Contents
|
||||
weight: 100
|
||||
---
|
||||
|
||||
Hugo will automatically parse the Markdown for your content and create
|
||||
|
||||
@@ -6,11 +6,10 @@ date: 2014-01-03
|
||||
menu:
|
||||
main:
|
||||
parent: extras
|
||||
next: /extras/robots-txt
|
||||
next: /community/mailing-list
|
||||
notoc: true
|
||||
prev: /extras/toc
|
||||
prev: /extras/localfiles
|
||||
title: URLs
|
||||
weight: 110
|
||||
---
|
||||
|
||||
## Pretty URLs
|
||||
@@ -35,11 +34,11 @@ Organization](/content/organization/) for more details.
|
||||
|
||||
By default, all relative URLs encountered in the input are left unmodified,
|
||||
e.g. `/css/foo.css` would stay as `/css/foo.css`,
|
||||
i.e. `canonifyurls` defaults to `false`.
|
||||
i.e. `canonifyURLs` defaults to `false`.
|
||||
|
||||
By setting `canonifyurls` to `true`, all relative URLs would instead
|
||||
be *canonicalized* using `baseurl`. For example, assuming you have
|
||||
`baseurl = http://yoursite.example.com/` defined in the site-wide
|
||||
By setting `canonifyURLs` to `true`, all relative URLs would instead
|
||||
be *canonicalized* using `baseURL`. For example, assuming you have
|
||||
`baseURL = http://yoursite.example.com/` defined in the site-wide
|
||||
`config.toml`, the relative URL `/css/foo.css` would be turned into
|
||||
the absolute URL `http://yoursite.example.com/css/foo.css`.
|
||||
|
||||
@@ -51,9 +50,9 @@ 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.
|
||||
|
||||
> Note: In the May 2014 release of Hugo v0.11, the default value of `canonifyurls` was switched from `true` to `false`, which we think is the better default and should continue to be the case going forward. So, please verify and adjust your website accordingly if you are upgrading from v0.10 or older versions.
|
||||
> Note: In the May 2014 release of Hugo v0.11, the default value of `canonifyURLs` was switched from `true` to `false`, which we think is the better default and should continue to be the case going forward. So, please verify and adjust your website accordingly if you are upgrading from v0.10 or older versions.
|
||||
|
||||
To find out the current value of `canonifyurls` for your website, you may use the handy `hugo config` command added in v0.13:
|
||||
To find out the current value of `canonifyURLs` for your website, you may use the handy `hugo config` command added in v0.13:
|
||||
|
||||
hugo config | grep -i canon
|
||||
|
||||
|
||||
@@ -14,24 +14,20 @@ 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
|
||||
* from Drupal (See https://bitbucket.org/rickb777/drupal2hugo by Rick Beton (@rickb777))
|
||||
* from WordPress (See [#100][], especially https://github.com/SchumacherFM/wordpress-to-hugo-exporter by Cyrill Schumacher (@SchumacherFM), but volunteers are needed to make it work with latest versions of WordPress.)
|
||||
* An interactive web based editor (See http://discuss.gohugo.io/t/web-based-editor/155)
|
||||
* Intelligently related posts ([#98][])
|
||||
* Even easier deployment to S3, SSH, GitHub, rsync. Give the [tools section](https://gohugo.io/tools/#deployment) a shot or read one of the related tutorials.
|
||||
* Import from other website systems. There are already existing [migration tools](https://gohugo.io/tools/#migration) but they don't cover all major platforms.
|
||||
* An interactive web based editor (See https://discuss.gohugo.io/t/web-based-editor/155)
|
||||
* Additional [themes](https://github.com/spf13/hugoThemes) (always on-going, contributions welcome!)
|
||||
* Dynamic image resizing via shortcodes
|
||||
* Support for additional formats (AsciiDoc ([#470][], [#826][]), reST [#472][])
|
||||
* Pagination (See [#96][], [#750][])
|
||||
* Dynamic image resizing via shortcodes ([#1014][])
|
||||
* Native support for additional content formats (AsciiDoc [#1435][], reST [#1436][])
|
||||
* And, last but not least, ***Your best ideas***!
|
||||
|
||||
[#100]: https://github.com/spf13/hugo/issues/100 "hugo import from wordpress · Issue #100 · spf13/hugo"
|
||||
[#101]: https://github.com/spf13/hugo/issues/101 "hugo import from jekyll · Issue #101 · spf13/hugo"
|
||||
[#96]: https://github.com/spf13/hugo/issues/96 "Support for pagination · Issue #96 · spf13/hugo"
|
||||
[#750]: https://github.com/spf13/hugo/pull/750 "Add pagination support for home page, sections and taxonomies by bep · Pull Request #750 · spf13/hugo"
|
||||
[#470]: https://github.com/spf13/hugo/issues/470 "Support for AsciiDoc · Issue #470 · spf13/hugo"
|
||||
[#826]: https://github.com/spf13/hugo/pull/826 "Experimental AsciiDoc support with external helpers by anthonyfok · Pull Request #826 · spf13/hugo"
|
||||
[#472]: https://github.com/spf13/hugo/issues/472 "support for using reST · Issue #472 · spf13/hugo"
|
||||
[#1435]: https://github.com/spf13/hugo/issues/1435 "Add support for native Go implementation of AsciiDoc · Issue #1435 · spf13/hugo"
|
||||
[#1436]: https://github.com/spf13/hugo/issues/1436 "Add support for native Go implementation of reStructuredText (reST) · Issue #1436 · spf13/hugo"
|
||||
[#1014]: https://github.com/spf13/hugo/issues/1014 "Image Resizing and Cropping · Issue #1014 · spf13/hugo"
|
||||
[#98]: https://github.com/spf13/hugo/issues/98 "Add support for related content · Issue #98 · spf13/hugo"
|
||||
|
||||
> Feel free to [contribute]({{< relref "tutorials/how-to-contribute-to-hugo.md" >}}) or open a [new issue](https://github.com/spf13/hugo/issues/new) if you have an idea for a new feature.)
|
||||
|
||||
@@ -49,7 +49,7 @@ Three periods end the document:
|
||||
|
||||
```yaml
|
||||
---
|
||||
baseurl: "http://yoursite.example.com/"
|
||||
baseURL: "http://yoursite.example.com/"
|
||||
...
|
||||
```
|
||||
Following is an example TOML configuration file with some default values.
|
||||
@@ -57,12 +57,12 @@ The values under `[params]` will populate the `.Site.Params` variable
|
||||
for use in templates:
|
||||
|
||||
```toml
|
||||
contentdir = "content"
|
||||
layoutdir = "layouts"
|
||||
publishdir = "public"
|
||||
builddrafts = false
|
||||
baseurl = "http://yoursite.example.com/"
|
||||
canonifyurls = true
|
||||
contentDir = "content"
|
||||
layoutDir = "layouts"
|
||||
publishDir = "public"
|
||||
buildDrafts = false
|
||||
baseURL = "http://yoursite.example.com/"
|
||||
canonifyURLs = true
|
||||
|
||||
[taxonomies]
|
||||
category = "categories"
|
||||
@@ -76,9 +76,9 @@ Here is a YAML configuration file which sets a few more options:
|
||||
|
||||
```yaml
|
||||
---
|
||||
baseurl: "http://yoursite.example.com/"
|
||||
baseURL: "http://yoursite.example.com/"
|
||||
title: "Yoyodyne Widget Blogging"
|
||||
footnotereturnlinkcontents: "↩"
|
||||
footnoteReturnLinkContents: "↩"
|
||||
permalinks:
|
||||
post: /:year/:month/:title/
|
||||
params:
|
||||
@@ -97,7 +97,7 @@ Following is a list of Hugo-defined variables you can configure,
|
||||
along with their current, default values:
|
||||
|
||||
---
|
||||
archetypedir: "archetype"
|
||||
archetypeDir: "archetypes"
|
||||
# hostname (and path) to the root, e.g. http://spf13.com/
|
||||
baseURL: ""
|
||||
# include content marked as draft
|
||||
@@ -111,27 +111,29 @@ along with their current, default values:
|
||||
canonifyURLs: false
|
||||
# config file (default is path/config.yaml|json|toml)
|
||||
config: "config.toml"
|
||||
contentdir: "content"
|
||||
contentDir: "content"
|
||||
dataDir: "data"
|
||||
defaultExtension: "html"
|
||||
defaultLayout: "post"
|
||||
# Missing translations will default to this content language
|
||||
DefaultContentLanguage: "en"
|
||||
defaultContentLanguage: "en"
|
||||
# Renders the default content language in subdir, e.g. /en/. The root directory / will redirect to /en/
|
||||
DefaultContentLanguageInSubdir: false
|
||||
defaultContentLanguageInSubdir: false
|
||||
# The below example will disable all page types and will render nothing.
|
||||
disableKinds = ["page", "home", "section", "taxonomy", "taxonomyTerm", "RSS", "sitemap", "robotsTXT", "404"]
|
||||
disableLiveReload: false
|
||||
# Do not build RSS files
|
||||
disableRSS: false
|
||||
# Do not build Sitemap file
|
||||
disableSitemap: false
|
||||
# Enable GitInfo feature
|
||||
enableGitInfo: false
|
||||
# Build robots.txt file
|
||||
enableRobotsTXT: false
|
||||
# Do not render 404 page
|
||||
disable404: false
|
||||
# Do not inject generator meta tag on homepage
|
||||
disableHugoGeneratorInject: false
|
||||
# edit new content with this editor, if provided
|
||||
editor: ""
|
||||
# Enable Emoji emoticons support for page content.
|
||||
# See www.emoji-cheat-sheet.com
|
||||
enableEmoji: false
|
||||
@@ -142,14 +144,17 @@ along with their current, default values:
|
||||
# google analytics tracking id
|
||||
googleAnalytics: ""
|
||||
languageCode: ""
|
||||
layoutdir: "layouts"
|
||||
layoutDir: "layouts"
|
||||
# Enable Logging
|
||||
log: false
|
||||
# Log File path (if set, logging enabled automatically)
|
||||
logFile: ""
|
||||
# "yaml", "toml", "json"
|
||||
metaDataFormat: "toml"
|
||||
# Edit new content with this editor, if provided
|
||||
newContentEditor: ""
|
||||
# Don't sync permission mode of files
|
||||
noChmod: false
|
||||
# Don't sync modification time of files
|
||||
noTimes: false
|
||||
paginate: 10
|
||||
@@ -160,22 +165,24 @@ along with their current, default values:
|
||||
# Preserve special characters in taxonomy names ("Gérard Depardieu" vs "Gerard Depardieu")
|
||||
preserveTaxonomyNames: false
|
||||
# filesystem path to write files to
|
||||
publishdir: "public"
|
||||
publishDir: "public"
|
||||
# enables syntax guessing for code fences without specified language
|
||||
pygmentsCodeFencesGuessSyntax: false
|
||||
# color-codes for highlighting derived from this style
|
||||
pygmentsStyle: "monokai"
|
||||
# true: use pygments-css or false: color-codes directly
|
||||
pygmentsUseClasses: false
|
||||
# maximum number of items in the RSS feed
|
||||
rssLimit: 15
|
||||
# default sitemap configuration map
|
||||
sitemap:
|
||||
# filesystem path to read files relative from
|
||||
source: ""
|
||||
staticdir: "static"
|
||||
staticDir: "static"
|
||||
# display memory and timing of different steps of the program
|
||||
stepAnalysis: false
|
||||
# theme to use (located by default in /themes/THEMENAME/)
|
||||
themesdir: "themes"
|
||||
themesDir: "themes"
|
||||
theme: ""
|
||||
title: ""
|
||||
# if true, use /filename.html instead of /filename/
|
||||
@@ -409,56 +416,7 @@ paired with the corresponding flags from Blackfriday's source code (for the latt
|
||||
</small>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><strong>sourceRelativeLinksEval</strong></code></td>
|
||||
<td><code>false</code></td>
|
||||
<td><code>none</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="purpose-description" colspan="3">
|
||||
<span class="purpose-title">Purpose:</span>
|
||||
<code>true</code> enables source file-based relative linking (à la Github).
|
||||
Relative links to Markdown and static files within a page
|
||||
will be evaluated relative to the location of that page,
|
||||
and then converted to HTML links during rendering.<br>
|
||||
<small>
|
||||
<strong>Example:</strong>
|
||||
<code>[some-reference-text](../other/page.md)</code> in
|
||||
<code>./content/total/overview.md</code> will link to
|
||||
<code>./content/other/overview.md</code> and render to
|
||||
<code>/other/overview/</code> in the HTML output.
|
||||
</small>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code><strong>sourceRelativeLinksProjectFolder</strong></code></td>
|
||||
<td><code>/docs/content</code></td>
|
||||
<td><code>none</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="purpose-description" colspan="3">
|
||||
<span class="purpose-title">Purpose:</span>
|
||||
Set a sub-folder for source file-based relative linking
|
||||
on a Hugo Project (i.e., a web site). When
|
||||
<code>sourceRelativeLinksEval</code> (see above) is enabled,
|
||||
some source level paths may contain absolute respository
|
||||
paths to Markdown or static files.
|
||||
The absolute portion of these paths should be removed
|
||||
before trying to match the intended links.<br />
|
||||
<small>
|
||||
<strong>Example:</strong>
|
||||
Assuming your documentation resides in
|
||||
<code>./docs/content</code>,
|
||||
then a reference within
|
||||
<code>./docs/content/total/overview.md</code> to
|
||||
<code>[some-reference-text](/docs/content/other/page.md)</code>
|
||||
will link to
|
||||
<code>./docs/content/other/overview.md</code> and render to
|
||||
<code>/other/overview/</code> in the HTML output.
|
||||
</small>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
**Notes**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user