Compare commits

...

341 Commits

Author SHA1 Message Date
hugoreleaser 933a16b109 releaser: Add release notes to /docs for release of 0.39
[ci skip]
2018-04-16 07:31:26 +00:00
hugoreleaser 60845a5a0e releaser: Bump versions for release of 0.39
[ci skip]
2018-04-16 07:31:26 +00:00
Bjørn Erik Pedersen 9a39146edf releaser: Fix LICENSE vs LICENSE.md
Fixes #4631
2018-04-16 09:27:39 +02:00
Bjørn Erik Pedersen 1a6a0fa6f2 Release 0.39 2018-04-16 09:08:36 +02:00
hugoreleaser 936fc76ad6 releaser: Add release notes draft for 0.39
Rename to *-ready.md to continue. [ci skip]
2018-04-16 06:27:26 +00:00
Bjørn Erik Pedersen f21b827f7b commands: Re-add the missing releaser command 2018-04-16 08:23:32 +02:00
Bjørn Erik Pedersen 7c597c7d75 Merge commit '047c4188dfc854f658d16f1e4a9501f9c97a31c7' 2018-04-16 07:45:38 +02:00
Bjørn Erik Pedersen 047c4188df Squashed 'docs/' changes from d9c8fc220..f9a5dc59b
f9a5dc59b Code Toggle block added to doc site final batch Templates  Variables 
4d4107968 Add eSolia as new sponsor
000fed94e Add missing closing tags for li in menu template example
f462b620f Clarify that local CSV files cannot be inside data dir
ae083641a Added hugo-search-index to list of search tools
e2b64d0b7 Remove extra link
2fb4c9af5 Release 0.38.2
59b1c9853 releaser: Prepare repository for 0.39-DEV
92f6a05ea releaser: Add release notes to /docs for release of 0.38.2
76244729e releaser: Bump versions for release of 0.38.2
0960c5fb3 Adjust gray color of tab vs pane in code-toggle.
8ae3aadd7 use code-toggle shortcode when relevant Content Management 
455b8b53b Update related.md
6e8d19090 Release 0.38.1
079ba044c releaser: Prepare repository for 0.39-DEV
6f23e6ec1 releaser: Add release notes to /docs for release of 0.38.1
c51692ceb releaser: Bump versions for release of 0.38.1
d37ea6a5e Update related.md
faa2707d0 Update index.md
9ce901dcb Add a forgotten language tag (go-html-template) for code
b05aaed14 Update where.md
4d4760819 Fix typo in code-toggle.md
c5a5250a1 Use the new go-html-template Chroma lexer
2de831f4b Add the full list of Chroma lexers
18114d4b4 Update Output Formats
b069d7f84 Release 0.38
caaa8355a releaser: Prepare repository for 0.39-DEV
e45b7cc9f releaser: Add release notes to /docs for release of 0.38
40f40906e releaser: Bump versions for release of 0.38
2d52e2e4e Merge commit 'ed8bf081fdbf336e026517b7e1b123c039014ab5'
1439f64a0 docs: Generate docshelper data
5b0edfd79 Add .Site.IsServer
fdb579ad1 Merge commit '0a23baa6a90901f772c234107c4f12c16c76f4aa'
7b71da1f8 hugolib: Add Reset method to delete key from Scratch
63a131664 docs: Add docs for lang.Merge
55cba056d Merge commit '3886fc1fef6ac19d58b9ba1bb642d0c6c9a54031'
6f301ebcc docs: Add docs on the new front matter configuration
7ba35ef56 Merge commit 'c0290655825e7bb36e13fb39f89d85b392cf1adc'
3d2cab754 releaser: Prepare repository for 0.38-DEV
095e888e1 releaser: Add release notes to /docs for release of 0.37.1
593fa0dcb releaser: Bump versions for release of 0.37.1
c18c1df54 releaser: Prepare repository for 0.38-DEV

git-subtree-dir: docs
git-subtree-split: f9a5dc59b7
2018-04-16 07:43:59 +02:00
Bjørn Erik Pedersen e136c26d0c Remove old LICENSE.md
Closes #4623
2018-04-16 00:03:56 +02:00
Bjørn Erik Pedersen dd48277497 Add a GitHub compatible Apache 2 license text 2018-04-16 00:03:30 +02:00
Bjørn Erik Pedersen 4dba6ce15a tpl/urls: Add anchorize template func 2018-04-15 23:17:50 +02:00
Bjørn Erik Pedersen 880ca19f20 tpl/path: Add path.Join 2018-04-15 22:19:12 +02:00
Bjørn Erik Pedersen 01b72eb592 tpl: Add path.Split template func 2018-04-15 22:19:12 +02:00
Bjørn Erik Pedersen 61d52f1462 hugolib: Do not reset .Page.Scratch on rebuilds
Fixes #4627
2018-04-15 19:31:42 +02:00
Bjørn Erik Pedersen 0e7716a424 resource: Implement Resource.Content
Fixes #4622
2018-04-15 18:08:06 +02:00
Bjørn Erik Pedersen 417c5e2b67 Make Page.Content a method that returns interface{}
To prepare for a `Resource.Content` method.

See #4622
2018-04-15 18:08:06 +02:00
Bjørn Erik Pedersen 94c8b29c39 source: Remove deprecated File.Bytes 2018-04-15 14:34:34 +02:00
Bjørn Erik Pedersen 1b4e0c4161 commands: Remove accidental and breaking space in baseURL flag
And added key-trimming to prevent future mishaps.

See #4607
2018-04-15 11:20:04 +02:00
Bjørn Erik Pedersen 27a524b090 commands: Properly handle CLI slice arguments
Like `--disableKinds` -- this handling was kind of broken when we recently moved this from global vars

See #4607
2018-04-14 11:32:25 +02:00
Bjørn Erik Pedersen bede93de00 commands: Correctly handle destination and i18n-warnings
And add some more CLI tests.

See #4607
2018-04-14 11:32:25 +02:00
Bjørn Erik Pedersen 2aab6dee85 commands: Fix handling of persistent CLI flags
See #4607
2018-04-13 09:08:49 +02:00
Bjørn Erik Pedersen f3775877c6 hugolib: Fix livereload of bundled pages
Fixes #4607
2018-04-12 12:19:46 +02:00
Bjørn Erik Pedersen 9c782d5147 commands: Fix failing Travis server test 2018-04-12 09:31:53 +02:00
Bjørn Erik Pedersen 14c35c8a56 Allow "*/" inside commented out shortcodes
Fixes #4608
2018-04-11 22:41:48 +02:00
Bjørn Erik Pedersen 96689a5c31 commands: Make commands.Execute return a Response object
We have no global `Hugo` object no more (yay!), and there are some external tools that depends on that value.

These tools need to use get that value from `Response.Result`.

Note that `commands.Execute` now also takes the arguments as a string slice. This should also make it easier to use, not having to modify `os.Args`.

This commit also wraps up this particular issue. Phew!

Test coverage in /commands before: 14.4%
Now:  53.5%

Still work to do, now it is at least possible.

Closes #4598
2018-04-11 20:37:08 +02:00
Bjørn Erik Pedersen e7010c1b62 commands: Remove some TODOs
See #4598
2018-04-11 10:16:30 +02:00
Bjørn Erik Pedersen f396cffa23 commands: Fix the config command
It now also accepts the `-s` (source) flag.

See #4598
2018-04-11 10:09:45 +02:00
Bjørn Erik Pedersen 24d5c21942 commands: Fix some flag diff
The CLI docs output is now identical with the master version.

See #4598
2018-04-11 09:57:43 +02:00
Bjørn Erik Pedersen a7d00fc39e commands: Add basic server test
See #4598
2018-04-11 09:51:07 +02:00
Bjørn Erik Pedersen 1e233b1c45 commands: Fix TestFixURL
See #4598
2018-04-11 09:50:19 +02:00
Bjørn Erik Pedersen b110d0ae04 commands: Remove the Hugo global
There are still some cleaning to do, but that felt good.

See #4598
2018-04-11 09:50:19 +02:00
Bjørn Erik Pedersen 73825cfc1c commands: Make the limit command work again
See #4598
2018-04-11 09:50:19 +02:00
Bjørn Erik Pedersen a8f7fbbb10 commands: Move the commands related logic to its own file
See #4598
2018-04-11 09:50:19 +02:00
Bjørn Erik Pedersen e8d6ca9531 commands: Add CLI tests
See #4598
2018-04-11 09:50:19 +02:00
Bjørn Erik Pedersen 4d32f2fa89 commands: Make the hugo command non-global
See #4598
2018-04-11 09:50:19 +02:00
Bjørn Erik Pedersen 018602c46d commands: Extract some common types into its own file
See #4598
2018-04-11 09:50:19 +02:00
Bjørn Erik Pedersen 2f0d98a19b commands: Make the server command non-global
See #4598
2018-04-11 09:50:18 +02:00
Bjørn Erik Pedersen e0621d207c commands: Make the gen commands non-global
See #4598
2018-04-11 09:50:18 +02:00
Bjørn Erik Pedersen e26a8b242a commands: Make the list commands non-global
See #4598
2018-04-11 09:48:56 +02:00
Bjørn Erik Pedersen 2a2c983867 commands: Make the import commands non-global
See #4598
2018-04-11 09:48:56 +02:00
Bjørn Erik Pedersen 15b1e269ad comands: Make the config command non-global
See #4598
2018-04-11 09:48:56 +02:00
Bjørn Erik Pedersen 56a1308044 commands: Make the new commands non-global
See #4598
2018-04-11 09:48:56 +02:00
Bjørn Erik Pedersen 4b780ca778 commands: Make convert command non-global
See #4598
2018-04-11 09:48:56 +02:00
Bjørn Erik Pedersen 7bc5e89fba commands: Make more commands non-global
See #4598
2018-04-11 09:48:56 +02:00
Bjørn Erik Pedersen fdf1d94ebc commands: Make benchmark non-global
See #4598
2018-04-11 09:48:56 +02:00
Bjørn Erik Pedersen 1157fef859 commands: Start of flag cleaning
See #4598
2018-04-11 09:48:55 +02:00
Bjørn Erik Pedersen e614d8a57c commands: Use short date format in CLI docs
To make it possible to compare the output.

See #4598
2018-04-11 09:48:34 +02:00
Hudson Muff fca49d6c60 Update README.md
I discovered an inconsistency between the website documentation (https://gohugo.io/getting-started/installing/#source) and this README, for installing from source. I checked them both and the website seems to be newer so I would like to propose updating this README to install Hugo using mage (unless it doesn't really matter).
2018-04-09 18:06:21 +02:00
Bjørn Erik Pedersen 0e8b3cbcd2 Sync dependencies 2018-04-09 11:12:05 +02:00
Bjørn Erik Pedersen 230f2b8c4f Bump Go versions
Fixes #4545
2018-04-09 11:01:01 +02:00
hugoreleaser d7f47b780c releaser: Prepare repository for 0.39-DEV
[ci skip]
2018-04-09 08:19:32 +00:00
hugoreleaser 712c0fdfe6 releaser: Add release notes to /docs for release of 0.38.2
[ci skip]
2018-04-09 08:17:15 +00:00
hugoreleaser 62e7588262 releaser: Bump versions for release of 0.38.2
[ci skip]
2018-04-09 08:17:14 +00:00
Bjørn Erik Pedersen 47da0dca52 Release 0.38.2 2018-04-09 10:08:33 +02:00
hugoreleaser 8d87bfd5ee releaser: Add release notes draft for 0.38.2
Rename to *-ready.md to continue. [ci skip]
2018-04-09 08:00:48 +00:00
Bjørn Erik Pedersen 719251c1af Bump the debouncer dependency
No practical difference.
2018-04-08 10:20:39 +02:00
Bjørn Erik Pedersen 8b2ef83bb1 Use a versioned debounce dependency 2018-04-07 18:09:31 +02:00
Bjørn Erik Pedersen 080302eb87 Fix handling of --contentDir etc. flag
We need to revisit the commands package re globals and tests, but this should fix the init order of flags and languages.

Fixes #4589
2018-04-07 16:40:45 +02:00
Anthony Fok 094ec17142 travis: Disable shallow clone to fix TestPageWithLastmodFromGitInfo
Fixes #4584
2018-04-07 06:54:24 -06:00
Anthony Fok e84b7ade65 Revert "Disable failing test on Travis"
This reverts commit 2170943ae6
and commit 623c9afa84.
2018-04-07 06:53:47 -06:00
Bjørn Erik Pedersen 2817e84240 Fix handling of content files with "." in them
As in, more dots than just to separate the extension and any language indicator.

Fixes #4559
2018-04-07 10:57:29 +02:00
Bjørn Erik Pedersen 623c9afa84 And now really disable failing test on Travis
See #4584
2018-04-06 18:14:11 +02:00
Bjørn Erik Pedersen 2170943ae6 Disable failing test on Travis
See #4584
2018-04-06 17:31:13 +02:00
Bjørn Erik Pedersen 9cd4d35977 Revert "Try an older GitMap version"
This reverts commit 3a3261a3b9.
2018-04-06 12:01:38 +02:00
Bjørn Erik Pedersen 3a3261a3b9 Try an older GitMap version
To test if the test failures goes away.
2018-04-06 10:59:47 +02:00
Bjørn Erik Pedersen 6792d86ad0 hugolib: Set .Parent in bundled pages to its owner
Fixes #4582
2018-04-06 10:41:28 +02:00
hugoreleaser e7d87e2410 releaser: Prepare repository for 0.39-DEV
[ci skip]
2018-04-05 16:39:05 +00:00
hugoreleaser c475eab474 releaser: Add release notes to /docs for release of 0.38.1
[ci skip]
2018-04-05 16:35:25 +00:00
hugoreleaser 3a96fa40bf releaser: Bump versions for release of 0.38.1
[ci skip]
2018-04-05 16:35:25 +00:00
Bjørn Erik Pedersen c356f1d417 Release 0.38.1 2018-04-05 18:31:17 +02:00
hugoreleaser 30c2c2f8ec releaser: Add release notes draft for 0.38.1
Rename to *-ready.md to continue. [ci skip]
2018-04-05 16:27:24 +00:00
Bjørn Erik Pedersen f87239e4ca Fix livereload for the home page bundle
Fixes #4576
2018-04-05 18:03:33 +02:00
Anthony Fok db0633c1a4 snap: Revert to "mage test" because "mage check" fails
"mage check", which runs "go test", gofmt, "go vet", and
"go test -race", fails one way or another especially on
on non-amd64 architectures, and sometimes even on amd64 too.

Partially reverting my undocumented change in commit 294c0f8.

Fixes #4578
2018-04-05 09:35:47 -06:00
Anthony Fok 874159b543 snap: Add bash completion 2018-04-05 15:51:11 +02:00
Anthony Fok 294c0f8001 snap: Fix empty BuildDate in "hugo version"
Previously, "snap run hugo version" returns an empty BuildDate like so:

    Hugo Static Site Generator v0.38 linux/amd64 BuildDate:

Fix by overriding the default build target of snapcraft's go plugin.
2018-04-05 15:51:11 +02:00
Bjørn Erik Pedersen a4deaeff0c Fix some livereload content regressions
Introduced in Hugo 0.38.

Fixes #4566
2018-04-05 14:28:45 +02:00
Anthony Fok 4d115c56fa Update github.com/bep/gitmap to fix snap build
Fixes #4538
2018-04-05 14:20:39 +02:00
Brian Fitzgerald 26f34fd59d Fix two tests that are broken on Windows
Put guards around TestPageBundlerCaptureSymlinks and
TestPageBundlerSiteWitSymbolicLinksInContent so that they aren't
run on Windows (they both use symbolic links and the Go library
implementation requires administrator mode on Windows).
2018-04-05 08:35:06 +02:00
Bjørn Erik Pedersen 730b66b652 commands: Handle mass content etc. edits in server mode
Fixes #4563
2018-04-04 09:29:59 +02:00
hugoreleaser 4f639d6bd5 releaser: Prepare repository for 0.39-DEV
[ci skip]
2018-04-02 11:06:04 +00:00
hugoreleaser f7bc28c529 releaser: Add release notes to /docs for release of 0.38
[ci skip]
2018-04-02 11:03:32 +00:00
hugoreleaser 20e9c08e1f releaser: Bump versions for release of 0.38
[ci skip]
2018-04-02 11:03:32 +00:00
Bjørn Erik Pedersen 37140a093b Release 0.38 2018-04-02 12:58:13 +02:00
hugoreleaser da80163c75 releaser: Add release notes draft for 0.38
Rename to *-ready.md to continue. [ci skip]
2018-04-02 12:58:13 +02:00
Anthony Fok 60e66d12ea travis: Clean up and increase verbosity 2018-04-02 09:20:58 +02:00
Bjørn Erik Pedersen ed8bf081fd Squashed 'docs/' changes from 3068989b9..d9c8fc220
d9c8fc220 Rebuild Chroma CSS
a9168b106 Adds missing word
ebaa172af Remove note about enabling custom GitLab domains
2ef3918b2 Add code toggler
41878b6ca Clarify the use of .GetPage with page bundles
ffcb26270 Fix broken link for configuration.md
1e72e2b3e Fixed typo in heading - Hightlighter
72b2db77c Change "on the form" to "of the form"
e15e6966f Fix example GitHub url

git-subtree-dir: docs
git-subtree-split: d9c8fc2207
2018-04-02 08:53:34 +02:00
Bjørn Erik Pedersen 558825cc20 Merge commit 'ed8bf081fdbf336e026517b7e1b123c039014ab5' 2018-04-02 08:53:34 +02:00
Bjørn Erik Pedersen 10c33c17cd docs: Generate docshelper data
And fix build ...
2018-04-02 08:52:42 +02:00
Bjørn Erik Pedersen 2c54f1ad48 docshelper: List Chroma lexers
Fixes #4554
2018-04-02 08:50:42 +02:00
Anthony Fok eb15ac37ef travis: Run "gem install" without sudo
Running "sudo gem install" was causing random errors like the following:

ERROR:  While executing gem ... (Errno::EACCES)
    Permission denied @ rb_sysopen - /home/travis/.rvm/gems/ruby-2.4.1/cache/asciidoctor-1.5.6.2.gem

Perhaps sudo is no longer necessary, even on OS X?  :-)
2018-04-02 08:15:35 +02:00
Bjørn Erik Pedersen eb42774e58 Add support for a content dir set per language
A sample config:

```toml
defaultContentLanguage = "en"
defaultContentLanguageInSubdir = true

[Languages]
[Languages.en]
weight = 10
title = "In English"
languageName = "English"
contentDir = "content/english"

[Languages.nn]
weight = 20
title = "På Norsk"
languageName = "Norsk"
contentDir = "content/norwegian"
```

The value of `contentDir` can be any valid path, even absolute path references. The only restriction is that the content dirs cannot overlap.

The content files will be assigned a language by

1. The placement: `content/norwegian/post/my-post.md` will be read as Norwegian content.
2. The filename: `content/english/post/my-post.nn.md` will be read as Norwegian even if it lives in the English content folder.

The content directories will be merged into a big virtual filesystem with one simple rule: The most specific language file will win.
This means that if both `content/norwegian/post/my-post.md` and `content/english/post/my-post.nn.md` exists, they will be considered duplicates and the version inside `content/norwegian` will win.

Note that translations will be automatically assigned by Hugo by the content file's relative placement, so `content/norwegian/post/my-post.md` will be a translation of `content/english/post/my-post.md`.

If this does not work for you, you can connect the translations together by setting a `translationKey` in the content files' front matter.

Fixes #4523
Fixes #4552
Fixes #4553
2018-04-02 08:06:21 +02:00
Bjørn Erik Pedersen f27977809c Update stale.yml 2018-04-01 21:36:00 +02:00
Bjørn Erik Pedersen 7a634898c3 Update Chroma
Fixes #4549
2018-03-31 10:51:01 +02:00
Ricardo N Feliciano 1823c053c8 Add .Site.IsServer
Fixes #4478
2018-03-30 20:15:22 +02:00
Anthony Fok 511d5d3b76 travis: Move to Ubuntu Trusty image 2018-03-26 09:09:58 -06:00
Anthony Fok 8299fa885c snap: Remove "make" from build-packages because we use mage now 2018-03-26 07:02:45 -06:00
Anthony Fok 06495f713b snapcraft.yaml: Call mage with "-v" for debugging
See #4538
2018-03-26 04:56:15 -06:00
Bjørn Erik Pedersen 93e24a03ce hugolib: Fix freeze in invalid front matter error case
Fixes #4526
2018-03-24 10:06:58 +01:00
Bjørn Erik Pedersen e9c7b6205f Allow themes to define output formats, media types and params
This allows a `config.toml` (or `yaml`, ´yml`, or `json`)  in the theme to set:

1) `params` (but cannot override params in project. Will also get its own "namespace", i.e. `{{ .Site.Params.mytheme.my_param }}` will be the same as `{{ .Site.Params.my_param }}` providing that the main project does not define a param with that key.
2) `menu` -- but cannot redefine/add menus in the project. Must create its own menus with its own identifiers.
3) `languages` -- only `params` and `menu`. Same rules as above.
4) **new** `outputFormats`
5) **new** `mediaTypes`

This should help with the "theme portability" issue and people having to copy and paste lots of setting into their projects.

Fixes #4490
2018-03-21 09:22:19 +01:00
Bjørn Erik Pedersen 3d1a6e109c hugolib: Add ConfigSourceDescriptor
To prepare for config in themes

See #4490
2018-03-20 21:30:43 +01:00
Bjørn Erik Pedersen b6798ee867 Bump some deprecations 2018-03-20 21:13:44 +01:00
Bjørn Erik Pedersen 0a23baa6a9 Squashed 'docs/' changes from 211a3c613..3068989b9
3068989b9 Merge commit '7ae9cf2ccb3eecc1ff50f686925249d01cf37c6c'
7ae9cf2cc Squashed 'themes/gohugoioTheme/' changes from d7a475e7..a1768ebb
b55157fae Revert "Anchorify headings up to h4"
b63dd5566 Anchorify headings up to h4
edfe36a19 Test out trac as highlighter style
98dc8d269 Update multilingual.md
a6e4d92c0 Update multilingual.md
86a90edf9 Fix typo 'If will' to 'It will' line 41
6b626fac6 Add a tip for testing custom 404.html on hugo server
6bfc17cfc Update few links to now point to gohugoio organization repos
f66bad971 Remove unintended alias
3bc56e9ec Fix shortcode name in example: image -> img
251142388 Fix broken link
27245af6a Fix the minimum required git version for GH Pages flow
aefc87b4d Fix link in Forestry showcase
489ec5ea0 Squashed 'themes/gohugoioTheme/' changes from 6f3a8bf5..d7a475e7
308a616fd Merge commit '489ec5ea03799fa092d891838c1655e60b34f337'
a80859814 Adjust showcase description

git-subtree-dir: docs
git-subtree-split: 3068989b9c
2018-03-20 21:11:45 +01:00
Bjørn Erik Pedersen 84f4b731d2 Merge commit '0a23baa6a90901f772c234107c4f12c16c76f4aa' 2018-03-20 21:11:45 +01:00
Bjørn Erik Pedersen 61f6e9f63b tpl/transform: Add a comments test for Remarshal
See #4521
2018-03-20 18:23:32 +01:00
Bjørn Erik Pedersen 904a3d9ddf Update Chroma to get Go template support
Fixes #4515
2018-03-19 09:19:47 +01:00
Bjørn Erik Pedersen f0052b6d0f commands: Recover from error in server
Issue introduced some days ago.

Fixes #4516
2018-03-18 12:54:06 +01:00
Bjørn Erik Pedersen da88015776 Spring test cleaning, take 2 2018-03-18 09:54:32 +01:00
Bjørn Erik Pedersen debd3663dd hugolib: Test cleaning #1 2018-03-17 18:59:07 +01:00
Bjørn Erik Pedersen af67ad8af1 hugolib: Trim some now superflous tests
These were written as a development aid in some kind of structural change at some point.

They served their purpose then, but these are tests covered elsewhere and is deleted to reduce maintainance.

The reported test covrage is not reduced because of this.
2018-03-17 18:59:07 +01:00
cmal e46ab29bd2 hugolib: Add Reset method to delete key from Scratch 2018-03-17 00:13:23 +01:00
Bjørn Erik Pedersen 10fef32de6 releaser: Adjust the "thank you" section 2018-03-16 20:56:28 +01:00
Bjørn Erik Pedersen 70005364a2 docs: Add docs for lang.Merge
See https://github.com/gohugoio/hugo/issues/4463
2018-03-16 10:10:01 +01:00
Bjørn Erik Pedersen ffaec4ca8c Add a way to merge pages by language
As an example:

```html
{{ $pages := .Site.RegularPages | lang.Merge $frSite.RegularPages | lang.Merge $enSite.RegularPages }}
```

Will "fill in the gaps" in the current site with, from left to right, content from the French site, and lastly the English.

Fixes #4463
2018-03-16 10:10:01 +01:00
Bjørn Erik Pedersen 3886fc1fef Squashed 'docs/' changes from 4e7e1815b..211a3c613
211a3c613 Prepare the forestry.io article for release
23995d6b4 Add forestry.io to showcase
3f177c94e Fix some typos (found by codespell)
dc26e0a5a Clarify the default for site config files and multiple config files
c87c9c62e Review and update the Site config documentation for consistency
a29edc50c Fix the default value of rssLimit site config
83f3c46b0 Minor style fix
4f860d1a2 Typo capitalization fixes
7851345c8 Add docs about comments within templates
d129b4a28 Make the recommendation to use partial over template consistent
6cd260a41 Update index.md
a2787e1a4 Add Let’s Encrypt showcase
7e664f69e Update configuration.md
8002120f1 Update multilingual.md
702b46a62 Add documentation for the disableLanguages setting
cb3d395de Fix content type reference
d33226924 Update Page Kinds documentation
8203f649d Fix misformed markdown link
19e99c957 Add Section definition

git-subtree-dir: docs
git-subtree-split: 211a3c6136
2018-03-16 09:44:54 +01:00
Bjørn Erik Pedersen 91fb8f1b59 Merge commit '3886fc1fef6ac19d58b9ba1bb642d0c6c9a54031' 2018-03-16 09:44:54 +01:00
Bjørn Erik Pedersen ac12d51e7e create: Remove archetype title/date warning
Closes #4504
2018-03-15 08:52:20 +01:00
Bjørn Erik Pedersen 3fbc75534d resource: Fix path duplication/flattening in processed images
Fixes #4502
Closes #4501
2018-03-14 17:04:14 +01:00
Bjørn Erik Pedersen e427ba4268 hugolib: Remove superflous debug file 2018-03-12 23:36:20 +01:00
Bjørn Erik Pedersen 79dd7cb31a hugolib: Simplify Prev/Next 2018-03-12 22:13:25 +01:00
Bjørn Erik Pedersen 0dbf79c2f8 docs: Add docs on the new front matter configuration
See #4495
2018-03-11 22:51:11 +01:00
Bjørn Erik Pedersen f12ad7d56a hugolib: Adjust GitInfo author date test
Now that we have a commit to assert against.

See #4495
2018-03-11 21:32:15 +01:00
Bjørn Erik Pedersen ce6e4310fe Refactor the GitInfo into the date handlers
Fixes #4495
2018-03-11 21:32:05 +01:00
Bjørn Erik Pedersen 95d62004a0 Merge commit 'c0290655825e7bb36e13fb39f89d85b392cf1adc' 2018-03-11 20:40:26 +01:00
Bjørn Erik Pedersen c029065582 Squashed 'docs/' changes from 715741f73..4e7e1815b
4e7e1815b Fix some typos
d23d8f5c4 Remove 'fundamentals' category from function pages
52fa65e15 Mention Chroma as the preferred syntax highlighter
64ca535db Merge commit '8762aee8afe30bec6f1fbc9560749983dc44d60b'
8762aee8a Squashed 'themes/gohugoioTheme/' changes from 396b859f..6f3a8bf5
03f0673a9 Move the gopher to the theme
320e268cd Spelling
e45b640f7 More layout lookup work
fe0ad9d9d Sync the YAML config menu example with TOML's
b9505fc70 Remove template reference to ordinal numbers
0fa2532d3 Remove deprecated Hugoidx, add native hugo solution
2152b907c Fix a link in the last commit
47614f416 Manually specifying heading anchors in Markdown content
9d6770d2a Release notes 0.37.1
e1eed8b27 Remove some unused images
e960046f5 releaser: Prepare repository for 0.38-DEV
4fa83a4ee releaser: Add release notes to /docs for release of 0.37.1
46c879995 releaser: Bump versions for release of 0.37.1
fb3ac5a3e releaser: Prepare repository for 0.38-DEV
4870c8e7b Update archetypes.md
232c0b578 Merge commit '2b18014fd0aa99e9f1a5610ba875101351a90de3'
2b18014fd Squashed 'themes/gohugoioTheme/' changes from fe71e360..396b859f
62567e9aa Add some "writing guidelines"
7cfd530d2 Revise the archetype docs
5d4c3c03c Update data-templates.md
e5fee3099 Update page-bundles.md
ca7f03c8d Update page-bundles.md
2a7fdc269 Fix typo 'vailable' to 'available' line 53
999b75201 LastMod should be Lastmod?
099f46ca5 Fix spacing in content-management/types.md
6bcdc58ef Word choice improvements
20e8a21f6 update rss linking docs
7ef44d262 Add some missing configuration entries
f1c7aa568 Sort config list
5cb8ceade Create a proper definition list for the configuration settings
25dffe4ac Send custom dimensions in GA
55df01a34 Fix broken gtag
6c8772aad Add site to GA config
e63acb894 Remove conflicting release note for 0.35
f30083a23 Add branch to GA config
99caedb96 Set the small-multiples to draft
4a33c70ab Polish the Small Multiples showcase
7b2f1ea2e Add small multiples showcase
e78e96bae Add new sponsor
c42943041 updated to new Forestry logo
e07eda273 Add OS env to faq
414f0dbc6 Release Hugo 0.37
85f0cc324 Merge branch 'temp37'
1e6da9497 Rebuild images
75e97adfc releaser: Add release notes to /docs for release of 0.37
50b887cb0 releaser: Bump versions for release of 0.37
7acf73ba3 Merge commit '900b5f6cfe5a377ef369d26cd700201be4cf6b06'
819d02c30 Merge commit '374d184e6747678364fd61f5faf328ec9205eb6b'
c7eacf018 Fix typos in development contribution doc

git-subtree-dir: docs
git-subtree-split: 4e7e1815b7
2018-03-11 20:39:20 +01:00
Bjørn Erik Pedersen 68bf1511f2 hugolib: Extract date and slug from filename
This commit makes it possible to extract the date from the content filename. Also, the filenames in these cases will make for very poor permalinks, so we will also use the remaining part as the page `slug` if that value is not set in front matter.

This should make it easier to move content from Jekyll to Hugo.

To enable, put this in your `config.toml`:

```toml
[frontmatter]
date  = [":filename", ":default"]
```

This commit is also a spring cleaning of how the different dates are configured in Hugo. Hugo will check for dates following the configuration from left to right, starting with `:filename` etc.

So, if you want to use the `file modification time`, this can be a good configuration:

 ```toml
[frontmatter]
date = [ "date",":fileModTime", ":default"]
lastmod = ["lastmod" ,":fileModTime", ":default"]
```

The current `:default` values for the different dates are

```toml
[frontmatter]
date = ["date","publishDate", "lastmod"]
lastmod = ["lastmod", "date","publishDate"]
publishDate = ["publishDate", "date"]
expiryDate = ["expiryDate"]
```

The above will now be the same as:

```toml
[frontmatter]
date = [":default"]
lastmod = [":default"]
publishDate = [":default"]
expiryDate = [":default"]
```

Note:

* We have some built-in aliases to the above: lastmod => modified, publishDate => pubdate, published and expiryDate => unpublishdate.
* If you want a new configuration for, say, `date`, you can provide only that line, and the rest will be preserved.
* All the keywords to the right that does not start with a ":" maps to front matter parameters, and can be any date param (e.g. `myCustomDateParam`).
* The keywords to the left are the **4 predefined dates in Hugo**, i.e. they are constant values.
* The current "special date handlers" are `:fileModTime` and `:filename`. We will soon add `:git` to that list.

Fixes #285
Closes #3310
Closes #3762
Closes #4340
2018-03-11 18:26:18 +01:00
Bjørn Erik Pedersen f8dc47eeff Allow partial redefinition of the ouputs config
Fixes #4487
2018-03-10 16:57:25 +01:00
Bjørn Erik Pedersen ae3fa349de output: Fix build
See #4484
2018-03-09 17:28:20 +01:00
Bjørn Erik Pedersen 64cec07293 outputs: Adjust the layout examples 2018-03-09 13:26:28 +01:00
hugoreleaser 9ac6206584 releaser: Prepare repository for 0.38-DEV
[ci skip]
2018-03-07 17:58:48 +00:00
hugoreleaser f414966b94 releaser: Add release notes to /docs for release of 0.37.1
[ci skip]
2018-03-07 17:56:23 +00:00
hugoreleaser c29a2ed2f5 releaser: Bump versions for release of 0.37.1
[ci skip]
2018-03-07 17:56:23 +00:00
Bjørn Erik Pedersen dfb6484a41 Release 0.37.1 2018-03-07 18:52:14 +01:00
hugoreleaser 8a02968393 releaser: Add release notes draft for 0.37.1
Rename to *-ready.md to continue. [ci skip]
2018-03-07 17:45:56 +00:00
Bjørn Erik Pedersen e7fda289b1 Remove defaultLayout config
Not in use.
2018-03-01 17:19:49 +01:00
Bjørn Erik Pedersen 50a03a5acc commands: Do not print build total when --quiet is set
Fixes #4456
2018-02-27 21:04:39 +01:00
Bjørn Erik Pedersen ba94abbf5d resource: Fix SVG and similar resource handling
The validation of if we could process the image (resize etc.) was moved up in Hugo 0.37, which meant SVG and other "non-processable" images would fail.

This commit fixes that by creating a regular resource for these image formats. They will not have `.Resize` or any of the other image methods.

Fixes #4455
2018-02-27 18:29:15 +01:00
Bjørn Erik Pedersen 55fb0eac20 releaser: Remove suplerflous release notes slug 2018-02-27 10:33:35 +01:00
hugoreleaser 06e5ee6526 releaser: Prepare repository for 0.38-DEV
[ci skip]
2018-02-27 09:17:53 +00:00
hugoreleaser 956a2dce8d releaser: Add release notes to /docs for release of 0.37
[ci skip]
2018-02-27 09:15:23 +00:00
hugoreleaser 1f1c562b9c releaser: Bump versions for release of 0.37
[ci skip]
2018-02-27 09:15:23 +00:00
Bjørn Erik Pedersen 3e1a6ebc11 Release 0.37 2018-02-27 10:06:15 +01:00
hugoreleaser 8915cb83f4 releaser: Add release notes draft for 0.37
Rename to *-ready.md to continue. [ci skip]
2018-02-27 08:43:18 +00:00
Bjørn Erik Pedersen 900b5f6cfe Squashed 'docs/' changes from 1dc05a16b..715741f73
715741f73 Add Netlify config for a split testin branch
4917f0636 Mention that math add/sub/mul/div functions can do float math too
31632beeb Document .Site.Params.mainSections
3416ba80d Update sectionvars.md
295ccb463 Update sections.md
15b5a0342 Fix duplicated paragraph
eb13db670 Fix text highlight
fa46cafdf Get 1password-support ready
979bb5698 Add 1password support showcase
ceb94d1e1 Fix readDir function links

git-subtree-dir: docs
git-subtree-split: 715741f739
2018-02-27 09:36:36 +01:00
Bjørn Erik Pedersen 57637d89ec Merge commit '900b5f6cfe5a377ef369d26cd700201be4cf6b06' 2018-02-27 09:36:36 +01:00
Bjørn Erik Pedersen 13ea1e7c35 resource: Use Floyd-Steinberg dithering for PNGs
Fixes #4453
2018-02-26 19:44:36 +01:00
Bjørn Erik Pedersen 9f740b37cf hugolib: Fix paginator URL for sections with URL in front matter
Fixes #4415
2018-02-26 17:45:51 +01:00
Bjørn Erik Pedersen e39797fa72 hugolib: Avoid scanning entire site to find the home
See #4447
2018-02-25 10:50:44 +01:00
Vas Sudanagunta 00868081f6 Fix bug in Site.assembleSections method
Site.assembleSections logic assumes that the the home page would always be the first in the Site's list of pages. This is not in fact guaranteed to be true. When it is not, the method can fail to set the parent for some or all root-level pages. 

Fixes #4447
2018-02-25 10:34:24 +01:00
Bjørn Erik Pedersen e9750d831f hugolib: Continue GitInfo lookup on error
The current logic stops looking after the first failure to connect a page with a Git commit. This implies a fatal error, but that may not be the case.
2018-02-22 17:21:09 +01:00
Bjørn Erik Pedersen 19d9a46f63 Properly handle -DEV suffix when comparing Hugo versions
See #4443
2018-02-22 17:16:42 +01:00
Bjørn Erik Pedersen 0602135fd4 Make ge, le etc. work with the Hugo Version number
This means that you can do something ala:

```html
{{ if ge .Hugo.Version "0.36" }}Reasonable new Hugo version!{{ end }}
```

The intented use is feature toggling, but please note that it will take some time and Hugo versions until this can be trusted. It does not work in older Hugo versions.

Fixes #4443
2018-02-22 09:15:12 +01:00
Bjørn Erik Pedersen 55bd46a633 commands: Remove ERROR on missing baseURL
That logic fails in multi-host mode when no baseURL is set on top level.

Fixes #4397
2018-02-21 10:30:00 +01:00
Bjørn Erik Pedersen 8dc77b84a5 releaser: Create bundles for the release notes
Fixes #4413
2018-02-21 10:22:08 +01:00
Bjørn Erik Pedersen 4560261b58 Merge commit '374d184e6747678364fd61f5faf328ec9205eb6b' 2018-02-21 10:02:51 +01:00
Bjørn Erik Pedersen 374d184e67 Squashed 'docs/' changes from f97826a17..1dc05a16b
1dc05a16b Update index.md
d73a9b3b4 Added StackImpact showcase
b0e82b3a5 Fix uglyURLs example
cf8a93728 GA track outgoing sponsor clikcs
aca59ac66 Move the sponsor banners up a little
5571673f0 Migrate from analytics.js to gtag.js
64a29b6cb Update faq.md
84704aa84 Use GOPATH variable if defined in installation from source
5f70e6ee2 Remove disableRSS etc. from the documentation
4945e7937 Remove superflous asterisks
39f6c9c28 showcase: Add 1password.com
fe0f82610 Add GitLab warning
9f26f21d2 Fix URL typo
83a91fc99 Remove duplicate release notes
133cdd313 Release 0.36.1
fbe2a2dc7 Clean images
1b02f9193 Merge branch 'temp361'
c430d2d58 Merge branch 'release-0.36.1'
dd7370fc4 releaser: Prepare repository for 0.37-DEV
72534f9ec releaser: Add release notes to /docs for release of 0.36.1
845b2cacb releaser: Bump versions for release of 0.36.1
78790fcb1 Add fluid type to showcase details box
4ef59e008 Adjust column widths to handle a wider variety of copy width
6d2e68521 Always show the latest showcase item on front page
665b1eb5e showcase: Shuffle the news items
5fef1f9b7 Escape quote
d680f0c16 Add some quotes
1722f0d5a showcase: Make the description more about Hugo
a9d43db0a Add Quiply Employee Communications App
7aaa464ec Add Quiply Employee Communications App
fad6a25dd maintenance: Show last 30
7afcfdced showcase: Set Linode date to today
0c31f481a New showcase for Linode
6c7687c2d Minor edits to the `apply` documentation
04bbff8b3 Update apply.md
f543032e3 Fix clunky sentence
218ba2a65 Some more Netlify improvements
0bd512125 Improve the Netlify versioning docs
7a708d60e Clarify Netlify's Hugo versions handling
8f86342cd Add some space
d68d4ff37 Remove now superflous warning
bf93a46ea maintenance: Add TODO list
3b5f27835 maintenance: Remove a superflous prefix
8f29ba2fb maintenance: Adjust order
105d53610 maintenance: Add TOC
29e86396b maintenance: Fix page list selection
ba51fe66d Finish the Maintenance  section
e9b0c710c Add latest changes in new spotlight section
8ccd79f61 Fix broken sentence
c77643c37 Spelling
919f2faef Remove some old troubleshooting articles
09e467f06 Add a new FAQ
ac2b25bb5 Hartwell showcase typos
5bf766993 Trim "www." from shocase URLs in title
a180cd5cb Make the inline showcase template names unique
6886982fd Merge commit '9cc9bab46288d8d5f9fda7009c5f746258cec1b4'
09728efbf Add "target" and "rel" parameters to figure shortcode

git-subtree-dir: docs
git-subtree-split: 1dc05a16bd
2018-02-21 10:00:31 +01:00
Bjørn Erik Pedersen 772128485a Run gofmt -s with Go 1.10
See #4434
2018-02-21 09:59:33 +01:00
Bjørn Erik Pedersen c2c4cb1f9f hugolib: Fix broken footnote test
See #4433
2018-02-21 09:25:32 +01:00
Bjørn Erik Pedersen 492fea7cd2 Update Blackfriday to fix footnote HTML5 validation error
Fixes #4433
2018-02-21 09:18:17 +01:00
Bjørn Erik Pedersen 5ed11edf5a releaser: Update to Go 1.10 2018-02-21 08:52:44 +01:00
Bjørn Erik Pedersen 799c654b0d resource: Preserve color palette for PNG images
This commit will force a reprocessing of PNG images with new names, so it is adviced to run a `hugo --gc` to remove stale files.

Fixes #4416
2018-02-19 20:15:58 +01:00
Curtis Timson faa3159e5e Fix typos in development contribution doc 2018-02-18 20:47:18 +01:00
Bjørn Erik Pedersen eaf573a277 Update dependencies
Closes #4418
2018-02-17 10:46:38 +01:00
Bjørn Erik Pedersen 3ced6f8d47 magefile: Disable Go 1.10 gofmt check for now 2018-02-17 01:24:07 +01:00
Bjørn Erik Pedersen a3f26e5636 Second try: Update to Go 1.10 (!) 2018-02-17 00:35:22 +01:00
Bjørn Erik Pedersen 0c452c6e7d Revert "Update to Go 1.10 (!)"
This reverts commit ff10c15a93.
2018-02-16 23:42:42 +01:00
Bjørn Erik Pedersen ff10c15a93 Update to Go 1.10 (!)
See https://blog.golang.org/go1.10
2018-02-16 23:29:51 +01:00
Bjørn Erik Pedersen efd506314a Merge branch 'release-0.36.1' 2018-02-15 10:13:09 +01:00
hugoreleaser 8de91da74f releaser: Prepare repository for 0.37-DEV
[ci skip]
2018-02-15 09:10:09 +00:00
hugoreleaser 25e88ccabe releaser: Add release notes to /docs for release of 0.36.1
[ci skip]
2018-02-15 09:07:43 +00:00
hugoreleaser 19228ed83c releaser: Bump versions for release of 0.36.1
[ci skip]
2018-02-15 09:07:43 +00:00
Bjørn Erik Pedersen a1f40084f9 Release 0.36.1 2018-02-15 10:03:24 +01:00
hugoreleaser d7bf9d4daa releaser: Add release notes draft for 0.36.1
Rename to *-ready.md to continue. [ci skip]
2018-02-15 08:51:22 +00:00
Bjørn Erik Pedersen 53e661e7c9 releaser: Update to Go 1.9.4 2018-02-15 09:43:03 +01:00
Bjørn Erik Pedersen fc23a80ffd Bump Travis/Snapcraft to Go 1.9.4 2018-02-15 09:43:03 +01:00
Bjørn Erik Pedersen d8fdffb552 resource: Fix multi-threaded image processing issue
When doing something like this with the same image from a partial used in, say, both the home page and the single page:

```bash
{{ with $img }}
{{ $big := .Fill "1024x512 top" }}
{{ $small := $big.Resize "512x" }}
{{ end }}
```

There would be timing issues making Hugo in some cases try to process the same image with the same instructions in parallel.

You would experience errors of type:

```bash
png: invalid format: not enough pixel data
```

This commit works around that by adding a mutex per image. This should also improve the performance, sligthly, as it avoids duplicate work.

The current workaround before this fix is to always operate on the original:

```bash
{{ with $img }}
{{ $big := .Fill "1024x512 top" }}
{{ $small := .Fill "512x256 top" }}
{{ end }}
```

Fixes #4404
2018-02-15 09:41:29 +01:00
Bjørn Erik Pedersen 2851af0225 resource: Improve error processing error message 2018-02-15 09:41:29 +01:00
Bjørn Erik Pedersen 08521dac83 hugolib: Improve error message in .Render 2018-02-15 09:41:29 +01:00
Bjørn Erik Pedersen 58382e9572 resource: Fix multi-threaded image processing issue
When doing something like this with the same image from a partial used in, say, both the home page and the single page:

```bash
{{ with $img }}
{{ $big := .Fill "1024x512 top" }}
{{ $small := $big.Resize "512x" }}
{{ end }}
```

There would be timing issues making Hugo in some cases try to process the same image with the same instructions in parallel.

You would experience errors of type:

```bash
png: invalid format: not enough pixel data
```

This commit works around that by adding a mutex per image. This should also improve the performance, sligthly, as it avoids duplicate work.

The current workaround before this fix is to always operate on the original:

```bash
{{ with $img }}
{{ $big := .Fill "1024x512 top" }}
{{ $small := .Fill "512x256 top" }}
{{ end }}
```

Fixes #4404
2018-02-14 20:59:02 +01:00
Bjørn Erik Pedersen 53dac9a506 resource: Improve error processing error message 2018-02-13 09:14:44 +01:00
Bjørn Erik Pedersen 4edb4bcc65 hugolib: Improve error message in .Render 2018-02-13 09:01:47 +01:00
Bjørn Erik Pedersen 0816a97a46 parser: Add WARNING for integer YAML keys
```bash
benchmark                                               old ns/op     new ns/op     delta
BenchmarkStringifyMapKeysStringsOnlyInterfaceMaps-4     3053          2015          -34.00%
BenchmarkStringifyMapKeysStringsOnlyStringMaps-4        5.23          5.18          -0.96%
BenchmarkStringifyMapKeysIntegers-4                     2320          5177          +123.15%

benchmark                                               old allocs     new allocs     delta
BenchmarkStringifyMapKeysStringsOnlyInterfaceMaps-4     6              6              +0.00%
BenchmarkStringifyMapKeysStringsOnlyStringMaps-4        0              0              +0.00%
BenchmarkStringifyMapKeysIntegers-4                     6              14             +133.33%

benchmark                                               old bytes     new bytes     delta
BenchmarkStringifyMapKeysStringsOnlyInterfaceMaps-4     1008          1008          +0.00%
BenchmarkStringifyMapKeysStringsOnlyStringMaps-4        0             0             +0.00%
BenchmarkStringifyMapKeysIntegers-4                     1008          1776          +76.19%
```
Closes #4393
2018-02-12 19:16:12 +01:00
Bjørn Erik Pedersen 10a917dfdc parser: Tune stringifyMapKeys
```bash
benchmark                                               old ns/op     new ns/op     delta
BenchmarkStringifyMapKeysStringsOnlyInterfaceMaps-4     3269          3053          -6.61%
BenchmarkStringifyMapKeysStringsOnlyStringMaps-4        4.79          5.23          +9.19%
BenchmarkStringifyMapKeysIntegers-4                     2707          2320          -14.30%

benchmark                                               old allocs     new allocs     delta
BenchmarkStringifyMapKeysStringsOnlyInterfaceMaps-4     16             6              -62.50%
BenchmarkStringifyMapKeysStringsOnlyStringMaps-4        0              0              +0.00%
BenchmarkStringifyMapKeysIntegers-4                     16             6              -62.50%

benchmark                                               old bytes     new bytes     delta
BenchmarkStringifyMapKeysStringsOnlyInterfaceMaps-4     1080          1008          -6.67%
BenchmarkStringifyMapKeysStringsOnlyStringMaps-4        0             0             +0.00%
BenchmarkStringifyMapKeysIntegers-4                     1080          1008          -6.67%
```
2018-02-12 19:14:02 +01:00
Bjørn Erik Pedersen d4beef0d2b parser: Rename stringifyYAMLMapKeys to stringifyMapKeys 2018-02-12 18:17:25 +01:00
Bjørn Erik Pedersen 51213e0be1 parser: Add benchmarks for stringifyYAMLMapKeys
```bash
BenchmarkStringifyMapKeysStringsOnlyInterfaceMaps-4       500000              3269 ns/op            1080 B/op         16 allocs/op
BenchmarkStringifyMapKeysStringsOnlyStringMaps-4        300000000                4.79 ns/op            0 B/op          0 allocs/op
BenchmarkStringifyMapKeysIntegers-4                       500000              2707 ns/op            1080 B/op         16 allocs/op
```
2018-02-12 18:16:48 +01:00
Vas Sudanagunta 1fa2417777 Add support for YAML array data files
* Unmarshaled YAML arrays indistinguishable from JSON arrays.
* Fixes #3890
2018-02-12 17:14:40 +01:00
Vas Sudanagunta bb549a0d57 Account for array type data in data dir merge/override logic
* Fixes #4366

* Error message to console for unsupported data types
2018-02-12 17:14:40 +01:00
Vas Sudanagunta 82eefded13 hugolib: Refactor tests for JSON, YAML and TOML equivalency, add coverage
The same code now cycles through equivalent JSON, YAML and TOML data sets,
verifying output both proper and identical. Coverage increased by applying
previous tests for one format to the others.

More DRY. Added tests for numeric and bool value types.
2018-02-12 17:14:40 +01:00
Vas Sudanagunta e172834993 hugolib: Re-enable YAML data tests disabled in f554503f
Also gave basic tests for JSON, YAML and TOML identical inputs and expected outputs, a step toward JSON, YAML and TOML equivalency (see https://github.com/gohugoio/hugo/issues/4393#issuecomment-364437785).
2018-02-12 17:14:40 +01:00
Bjørn Erik Pedersen b5cb8866e9 Merge commit '9cc9bab46288d8d5f9fda7009c5f746258cec1b4' 2018-02-10 12:52:31 +01:00
Bjørn Erik Pedersen 9cc9bab462 Squashed 'docs/' changes from 2fc775dec..f97826a17
f97826a17 Merge commit '12ecbf4a1b05c2794281f47909c836b1a005bc19'
12ecbf4a1 Squashed 'themes/gohugoioTheme/' changes from ecad8247..fe71e360
aaa7ac214 Ignore .DS_Store files
0e023ca12 Remove comments in showcase front matter
f3ba5ac87 Hartwell Insurance showcase
47aefdbda Remove unnecessary duplicated words
612693b4f Some minor language fixes
a833ba15b Spelling
5972e70a9 Revert "showcase: Even smaller file"
3479b975e showcase: Even smaller file
2272e0b83 showcase: Reduce image size
718c3c3e5 Spelling
0b954eccb showcase: Pace copy-edits
baded8064 showcase: Pace
842c1cedf Add a Showcase copyright notice
c5963edaa Update installing
4fa0b0d73 Add link to showcase template
d0f303916 Add some showcase guide content
c809789b1 Add srcset to the showcase screenshots
49d875904 Start of a template
1153de221 Clean resouerces
69f00df4c Remove the showcases
653ad5bcd Add a simple byline
c5342b5e5 Regenerate image after rebase
b80669b34 Bump version in config.toml
cd5c79c67 Fix an issue where whitespace wrap caused scrollbars on some browsers
f00547e98 Add section to the title element
aa10defed Iterating on Showcase (#330)
76a0bfbc3 Add some dummy content to some of the showcase pages
66f68964d Standardize showcase metadata
627ffa6d4 Adjust showcase image size on front page
cbc3efece Redo some showcase images
054b54cb6 Use .RelPermalink and not .URL
82ba5f1c6 Add resources
d1415795b Move showcase items in list view to a template in the layout
f34620e90 Tweak details box for mobile
df6a0bf24 Include images that changed from the column shift
02036581f Improve showcase single layout
5f7730c89 Improve styling of showcase prev/next buttons
a2b2f7731 Remove extra div that was breaking mobile layout of the showcase
b172fe5f4 Add block class to to images on mobile so they behave as expected
a4ebfec86 Add a proper RSS feed to home page
0524479e0 Move showcase images to proper Resources
0544b57df Convert showcase pages to bundles
8febaab2b Add Showcase to Home page and internal pages
26d1f4542 Fix baseURL in Netlify deploy previews
046497616 Revert "Try to fix the Netlify preview baseURL setup"
80dce17ca Revert "Add some temporary baseURL debug"
8617e8692 Add some temporary baseURL debug
371e56bce Try to fix the Netlify preview baseURL setup
1b70b3f18 Add Netlify CMS to Frontends list
d6184e71d Fix menu for "What is Hugo" page
1ae83ad3e Fix mobile menu display so it shows on mid-size displays
f60e1f750 Edited slight typo, added "of"
56b906667 Fix typo
c5bea5cbd Release 0.36
00539094e releaser: Prepare repository for 0.37-DEV
b222cbdf2 releaser: Add release notes to /docs for release of 0.36
e59d1d766 releaser: Bump versions for release of 0.36
9620aa002 docs: Add documentation for smart cropping etc.
91c3801f1 Merge commit 'c305e44f5f081e4436195923a4593e396f07cd49'
8e71ff60b releaser: Prepare repository for 0.36-DEV

git-subtree-dir: docs
git-subtree-split: f97826a172
2018-02-10 12:51:31 +01:00
Bjørn Erik Pedersen d382502d6d tpl/transform: Add template func for TOML/JSON/YAML docs examples conversion
Usage:

```html
{{ "title = \"Hello World\"" | transform.Remarshal "json" | safeHTML }}
```

Fixes #4389
2018-02-10 12:36:31 +01:00
Kaushal Modi 2e95ec6844 Add "target" and "rel" parameters to figure shortcode
Also:

- Remove unnecessary space from `figure` tag if no class is specified.
  - Update related tests.
- Add test cases for the changes made to the figure shortcode.
- Document the newly added target and rel parameters
- Add more detail to the documentation of all figure shortcode parameters.
2018-02-09 22:27:58 +01:00
Kaushal Modi 76d38d5e53 Use more canonical "twitter:image" property, not "twitter:image:src"
This change is made in the "twitter_cards" internal template.

References:

- https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/summary-card-with-large-image
- https://twittercommunity.com/t/twitter-image-src-or-twitter-image/16085/7
2018-02-09 20:27:09 +01:00
Bjørn Erik Pedersen f554503fef hugolib: Temp. disable some YAML data tests
They fail.

We will have to think about this.

See #4393
2018-02-09 12:32:45 +01:00
Dawid Gaweł 16a5c74519 parser: Fix YAML maps key type
Recurse through result of yaml package parsing and change all
maps from map[interface{}]interface{} to map[string]interface{}
making them jsonable and sortable.

Fixes #2441, #4083
2018-02-09 10:27:17 +01:00
Bjørn Erik Pedersen 49b98975be releaser: Update to Go 1.9.4 2018-02-08 19:25:02 +01:00
Bjørn Erik Pedersen 0de375a7e7 Bump Travis/Snapcraft to Go 1.9.4 2018-02-07 21:45:53 +01:00
hugoreleaser e02ee7d6ad releaser: Prepare repository for 0.37-DEV
[ci skip]
2018-02-05 15:24:52 +00:00
hugoreleaser 18e3657a2a releaser: Add release notes to /docs for release of 0.36
[ci skip]
2018-02-05 15:22:26 +00:00
hugoreleaser 4bc8727fc6 releaser: Bump versions for release of 0.36
[ci skip]
2018-02-05 15:22:26 +00:00
Bjørn Erik Pedersen a9a0190b13 Release 0.336 2018-02-05 16:16:46 +01:00
hugoreleaser 742deaa3d0 releaser: Add release notes draft for 0.36
Rename to *-ready.md to continue. [ci skip]
2018-02-05 14:56:39 +00:00
Bjørn Erik Pedersen 694c0fd763 docs: Add documentation for smart cropping etc. 2018-02-05 15:04:07 +01:00
Bjørn Erik Pedersen 15ff076572 Merge commit 'c305e44f5f081e4436195923a4593e396f07cd49' 2018-02-05 14:24:24 +01:00
Bjørn Erik Pedersen c305e44f5f Squashed 'docs/' changes from dce236ad1..2fc775dec
2fc775dec Fix allLanguages code
dc6bfbedb Fix header level
6d652458c Fixed typo in docs.
2da6518be Fix broken build in previous commit
eabe7a40b Move some release notes to bundles to test the resource setup
34f2a41f2 Add featured image to news articles
bba1104b8 Update index.md
62bb8d826 Bundless > bundles
afea67773 Release notes spelling
f66d13af2 Release Hugo 0.35
613c50cdd releaser: Add release notes to /docs for release of 0.35
c9f7fd637 releaser: Bump versions for release of 0.35
360296c34 docs: Regenerate CLI docs
0d688633f Merge commit '337d0c5f516ee085205e8abefdb7f87e6d33ca05'
8fc9e325b command: Remove undraft command
f8cc6d51f docs: Re-generate CLI docs
556ea887a releaser: Prepare repository for 0.35-DEV

git-subtree-dir: docs
git-subtree-split: 2fc775dece
2018-02-05 14:24:00 +01:00
Bjørn Erik Pedersen 722086b4ed resource: Add smart cropping
This commit `smart` as a new and default anchor in `Fill`.

So:

```html
{{ $image.Fill "200x200" }}
```

Is, with default configuration, the same as:

```html
{{ $image.Fill "200x200" "smart" }}
```

You can change this default in your `config.toml`:

```toml
[imaging]
[imaging]
resampleFilter = "box"

quality = 68

anchor = "Smart"
```

Fixes #4375
2018-02-05 13:59:15 +01:00
Cameron Moore 084cf4191b tpl: Ensure site templates can override theme templates
The tplimpl package was misusing the TemplateLookupDescriptor.WorkingDir
field from the output package. By incorrectly setting it to the theme
directory instead of the site root, the user is unable to override theme
templates in some situations.

Fixes #3505
2018-02-05 08:38:04 +01:00
Cameron Moore fc06d5c18b hugolib: Add additional test to TestTemplateLookupOrder
Add an additional test to "Variant 4, theme, use site base" to also test
for the index.html base (from by testing of #3505).  Also add a "name"
field to the test cases to make it easier to know which test is failing
versus just getting a slice index.
2018-02-05 08:38:04 +01:00
Cameron Moore 9a367d9d06 hugolib: Fix broken TestTemplateLookupOrder
It looks like we left some debugging code in place that caused all but
one test case to run.
2018-02-05 08:38:04 +01:00
Vas Sudanagunta 4402c07775 Fix JSON array-based data file handling regression
This bug was introduced in Hugo 0.35.

Fixes #4361
2018-02-02 09:14:37 +01:00
Vas Sudanagunta 4743de0d3c Increase data directory test coverage
*  Adds retro-coverage for #4361
*  Verifies open issues #4138, #3890, #4366, 4083
*  Removes test reliance on the very code it is testing (hugo/parser package).
   Expected results are now all built manually / are more precise.
   Tests can run against different versions (no linkage errs)
2018-02-02 09:14:37 +01:00
hugoreleaser 19e26cb4eb releaser: Prepare repository for 0.36-DEV
[ci skip]
2018-01-31 10:47:09 +00:00
hugoreleaser 0283db6c60 releaser: Add release notes to /docs for release of 0.35
[ci skip]
2018-01-31 10:44:41 +00:00
hugoreleaser 58188807aa releaser: Bump versions for release of 0.35
[ci skip]
2018-01-31 10:44:41 +00:00
Bjørn Erik Pedersen 51d5c5421e Release 0.35 2018-01-31 11:41:19 +01:00
Bjørn Erik Pedersen a9a5b1e094 docs: Regenerate CLI docs 2018-01-31 11:40:30 +01:00
hugoreleaser cf5c2df81c releaser: Add release notes draft for 0.35
Rename to *-ready.md to continue. [ci skip]
2018-01-31 11:40:03 +01:00
Bjørn Erik Pedersen 158e1151cd Merge commit '337d0c5f516ee085205e8abefdb7f87e6d33ca05' 2018-01-31 11:08:08 +01:00
Bjørn Erik Pedersen 337d0c5f51 Squashed 'docs/' changes from 56c34962c..dce236ad1
dce236ad1 Wrap up the bundle etc. edits for now
27d058566 Add the bundle tree to the organization bundle
a83f750dd Move organization.md to its own bundle
01ec4f462 Make the image docs a bundle
60de1e090 Some more resources copy-edits
05d763c0c Some resource copy-edits
6299d6dbb Update the imgproc shortcode
59e0fc209 Add headless bundle documentation
a3bbf60bf Link Page Resources page from Front Matter page
830576f86 Update order significance section, add counter section
3b1836509 Revert the recent change made to default list template
886ed0e10 Page Bundles draft rev 2
f530d1a7a image processing and page resources made into regular .md
ec47cecda Finalised Page Resources and Image Processing Moved Page Resources and Impage Processing out of the Bundle section and at the root of the Content Management section
253092335 Modified front matter metadata exemple. Added yaml version.
da5e4f476 Adding date in the front-matter; missed in previous commit
6bc3ced13 Add rough draft for page and section bundles
a0e44458f Image processing first draft, Resources second read/fix
2367f0b78 data: Remove duplicate layouts in table
c2f179839 First draft of bundles/resources (covers resources and metadata)
2a3f9a613 Add weights to pages in Bundles branch
9a0146cc0 Switch front-matter format of Bundles doc to yaml; add front-matter
1295fc083 First draft for Bundles documentation organization structure
5a2e52231 Fix archetype paths
9c2e5c063 Merge commit '22cced34fc608256f8271ad591a5ccca991bb164'
22cced34f Squashed 'themes/gohugoioTheme/' changes from 75da2f6b..ecad8247
55d16c9a1 Fix broken sentence in multilingual sections
a76895ad2 Replace the outdated Emacs package with new one
e6cf1dec0 Remove obsolete link to hugo roadmap
dd2fd145b Add GitLab Pages to mentioned hosters (#309)
a05ce6bf6 Add 0.34 release notes poster
5c0ebdfca Release 0.34
13c2f3dc8 Merge branch 'temp34'
e6b5ffa04 Add 0.34 poster
1e1960496 releaser: Add release notes to /docs for release of 0.34
ac3efe182 releaser: Bump versions for release of 0.34
8f91f62d8 Fixes #222
cca35dbe4 Fix example
eaaa21ca1 Add missing params key
00d0b0363 Adding new Blogger utility to tools/migrations
7d36d579e Updated the line number for Dockerfile pointer
852188f85 Update installing.md with Fedora instructions
4d151a3ab Update search.md
4c2750bfb Update deployment-with-nanobox.md
c3cc9cd49 configuration: Remove defaultExtension from docs
f7c96b4b5 Update GitHub Pages documentation
55787f09a Merge branch 'rmetzler-menu-link-title'
2abbd9bd9 Merge branch 'master' into menu-link-title
e1fd710b7 Bring archetypes in from theme.
daf6f51c0 Mention the significance of leading 0 in int fn string input
07f498755 Add documentation for `cond` function.
050ccd12b Add documentation for the .HasShortcode function
919af9071 Correct anchor under 'Add custom metadata to a Taxonomy Term'
55600b4ff More layouts work
201cf4f67 Add some more single page layout variants
d5e7c03e2 Rework the layouts doc
84622e67c Cleans up the code sample
c231c9bd5 Add a new note to 0.33 relnotes
328ec9930 Release 0.33
b108fcc7b Merge branch 'temp33' into next
ab9d9ee65 releaser: Prepare repository for 0.34-DEV
e20c75320 releaser: Add release notes to /docs for release of 0.33
49f24dcd1 releaser: Bump versions for release of 0.33
9c8e5e207 Update 0.33 poster
7655603c8 Regenerate the docshelper data
16dc99583 Add Hugo 0.33 poster
ce40cc197 Merge commit '3cf4300097610bb8b5bd0686d96d1df5db641895'
9a3085523 releaser: Prepare repository for 0.33-DEV
a52db97d8 fixing typos and syntax for consistency
64525670f ádd title to some menu entries. This needs hugo >= v0.32
85d415ab2 ádd examples for menu .Title and .Page

git-subtree-dir: docs
git-subtree-split: dce236ad12
2018-01-31 11:07:47 +01:00
Anthony Fok f0c0ece44d Add "removable-media" interface to snapcraft.yaml
Closes #3837
2018-01-31 02:00:16 -07:00
Ryan Skoblenick a34213f0b5 Fix Docker build
The present Dockerfile in master does not build a Hugo container. The
build container prematurely exits because `dep ensure` can not locate
`Gopkg.toml` due to the source files not being copied/added to the
container prior to running this command. The minimal change require
to resolve the issue is merely move the ADD source before the RUN dep.

Fixes #4076
Resolves #4077
2018-01-31 09:16:28 +01:00
Bjørn Erik Pedersen fe40823de0 readme: Update list of "builders" to include myself 2018-01-30 19:56:29 +01:00
Bjørn Erik Pedersen ae742cb1bd Fix language params handling
This fixes some issues with language params handling by separating params from configuration values per language.

This means that you can now do this:

```toml
[languages]
[languages.en]
languageName = "English"
weight = 1
title = "My Cool Site"
[languages.en.params]
myParam = "Hi!"
```

This is not a breaking change, but the above is a less suprising way of configuring custom params.

It also fixes some hard-to-debug corner-cases in multilingual sites.

Fixes #4356
Fixes #4352
2018-01-30 18:53:07 +01:00
Bjørn Erik Pedersen feeed073c3 commands: Remove some now superflous Fast Render Mode code
Updates #4339
2018-01-30 10:49:24 +01:00
Bjørn Erik Pedersen 94e736c5e1 hugolib: Extract the Fast Render Mode logic into a method
This also improves on the previous commit as it takes pages without content files into account.

Closes #4339
2018-01-30 10:49:24 +01:00
Alexey Grachov 1707dae8d3 hugolib: Handle newly created files in Fast Render Mode
Updates #4339
2018-01-30 10:49:24 +01:00
Robert Basic 2fa70c9344 command: Remove undraft command
According to @bep, it is easier to undraft content by
editing manually the frontmatter of said content by
setting the draft flag to `false`, or removing it completely,
than to rely on the undraft command which is a source of
many bugs.

Fixes #4353
2018-01-29 16:56:35 +01:00
Bjørn Erik Pedersen b6f3f087aa commands: Mark deprecated flags in the CLI help
See #4347
2018-01-29 14:07:46 +01:00
Bjørn Erik Pedersen adfd4370b6 hugolib: Deprecate useModTimeAsFallback
Fixes #4351
2018-01-29 13:52:04 +01:00
Bjørn Erik Pedersen 25d691daff tpl: Update Twitter card to also consider images in .Resources
The new lookup order:

1) Page.Params.images if set
2) Image resources: images with name "feature" (priority), "cover", "thumbnail"
3) Site.Params.images if set

Fixes #4349
2018-01-29 11:44:41 +01:00
Bjørn Erik Pedersen df20b05463 resource: Make resource counters for name and title independent
This is the most flexible with the current syntax, and probably what most people would expcect.

Updates #4335
2018-01-29 10:44:09 +01:00
Bjørn Erik Pedersen 863a812e07 create: Provide .Name to the archetype templates
This value will have a better suited value to base the titles on in your archetype templates when creating bundle ´index.md` type of files.

The internal template is updates, but you will have to update any custom archetype template to use the new `.Name` variable:

```bash
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---
```

Fixes #4348
2018-01-28 19:41:55 +01:00
Bjørn Erik Pedersen f08ea02d24 commands: Deprecate CLI flags canonifyURLs, pluralizeListTitles, preserveTaxonomyNames, uglyURLs
You can of course still set them in site config.

Fixes #4347
2018-01-28 17:22:08 +01:00
Bjørn Erik Pedersen 016398ffe2 hugolib: Fix --uglyURLs from comand line regression
This bug was introduced in Hugo 0.33.

Fixes #4343
2018-01-28 17:03:10 +01:00
Colin Seymour 3752348ef1 Only set 'url' if permalink in metadata and remove duplicate confirm msg
The current behaviour addes a `url` attribute to the frontmatter of all posts imported from Jeklly and assumes the desired permalink structure is /:year/:month/:day/:title/. This may be the case for most peeps, but poses a problem for those that don't use this permalink structure as the `url` attribute takes precedence over the `permalink` attribute in the site-wide configuration meaning it can't be overruled.

This changes the behaviour to only set the `url` attribute if the `permalink` attribute is set in the Jekyll frontmatter.

The duplication of the confirmation message is also removed.

Tests have been updated to reflect this change in behaviour.

Fixes #1887
2018-01-28 11:24:31 +01:00
Bjørn Erik Pedersen 4eb2fec67c Fix handling of top-level page bundles
Fixes #4332
2018-01-27 19:13:34 +01:00
liguoqinjim 83c761b71a tpl/collections: Seed random on init only 2018-01-27 18:51:12 +01:00
Bjørn Erik Pedersen ed4a00e46f commands: Fix baseURL server regression for multilingual sites
This was introduced in 6413559f75 a couple of days ago, and demonstrates that we really need better tests for the server/commands package.

Fixes #4333
2018-01-27 10:58:30 +01:00
Bjørn Erik Pedersen 7b472e4608 resource: Start Resources :counter first time they're used
This is less surprising and more flexible than the original implementation.

Given:

```toml
[[resources]]
  src = "documents/photo_specs.pdf"
  title = "Photo Specifications"
[[resources]]
  src = "**.pdf"
  name = "pdf-file-:counter"
```

Every `pdf` in the bundle will have an unique counter, but the `photo_specs.pdf` is still allowed to have its specific `title`.

If you change the above example to:

```toml
[[resources]]
  src = "documents/*specs.pdf"
  title = "Photo Specifications #:conter"
[[resources]]
  src = "**.pdf"
  name = "pdf-file-:counter"
```

We are talking about two different groups of documents, each with its own counters starting at 1.

Fixes #4335
2018-01-27 10:22:42 +01:00
Bjørn Erik Pedersen 96e3fbcf23 travis: Re-enable macOS builds 2018-01-26 17:08:32 +01:00
Bjørn Erik Pedersen a91aba1c15 Update to Go 1.9.3
Fixes #4328
2018-01-26 17:07:08 +01:00
Bjørn Erik Pedersen 6413559f75 Add a way to disable one or more languages
This commit adds a new config setting:

```toml
disableLanguages = ["fr"]
```

If this is a multilingual site:

* No site for the French language will be created
* French content pages will be ignored/not read
* The French language configuration (menus etc.) will also be ignored

This makes it possible to start translating new languages and turn it on when you're happy etc.

Fixes #4297
Fixed #4329
2018-01-26 14:04:14 +01:00
Vas Sudanagunta 322c567220 Fix "date" page param
Add test coverage for all date type page params that shadow date type page variables.

Fixes #4323
2018-01-26 09:17:27 +01:00
Vas Sudanagunta 91bb774ae4 Support pages without front matter
* Page without front matter now treated same as a page with empty front matter.
* Test cases added to cover this and repro issue #4320.
* Type safety of front matter code improved.

Fixes #4320
2018-01-26 09:17:27 +01:00
Vas Sudanagunta 3f0379adb7 Add page metadata dates tests 2018-01-26 09:17:27 +01:00
Bjørn Erik Pedersen ae5a45be6f hugolib: Remove unused code 2018-01-25 17:14:03 +01:00
Bjørn Erik Pedersen 4d912e2aad hugolib, output: Fix robots.txt in multihost mode
Fixes #4193
2018-01-25 10:36:53 +01:00
Bjørn Erik Pedersen 1e27d05891 docs: Re-generate CLI docs 2018-01-25 10:24:59 +01:00
Bjørn Erik Pedersen d418c2c2ea Remove and update deprecation status 2018-01-25 10:22:11 +01:00
Bjørn Erik Pedersen b2fcbb1f97 output: Remove duplicate layout lookup layouts
This can happen for sections if Type and Section are equal.

Of no real practical difference, but it makes the docs less confusing.

Fixes #4319
2018-01-25 09:37:05 +01:00
Bjørn Erik Pedersen 3446fe9b89 hugolib: Add the last lookup variant for the GetPage index
Now, even for nun-bundles it is possible to do lookup without path or extension.

So, given `blog/my-blog-post.en.md` these lookups will succeed:

* `blog/my-blog-post.en.md`
* `blog/my-blog-post`
* `my-blog-post.en.md`
* `my-blog-post`

See #4312
See https://github.com/gohugoio/hugoDocs/issues/307
2018-01-24 13:36:06 +01:00
Bjørn Erik Pedersen 4a7c2b3695 github: Shorten the stale setup 2018-01-24 13:10:44 +01:00
Alexey Grachov 912147ab89 resource: Fix typo in comment 2018-01-24 10:24:21 +01:00
Bjørn Erik Pedersen 517b6b6238 hugolib: Simplify bundle lookup via .Site.GetPage, ref, relref
Given a bundle in `blog/my-bundle/index.en.md` all of these will now worK:

* `blog/my-bundle/index.en.md`
* `blog/my-bundle/index`
* `blog/my-bundle`
* `my-bundle`

The last one is potentially ambigous.

Fixes #4312
2018-01-24 10:05:20 +01:00
Bjørn Erik Pedersen a19563910e Add a GetPage to the site benchmarks 2018-01-24 09:08:26 +01:00
Bjørn Erik Pedersen 0432c64dd2 Add headless bundle support
This commit adds  support for `headless bundles` for the `index` bundle type.

So:

```toml
headless = true
```

In front matter means that

* It will have no `Permalink` and no rendered HTML in /public
* It will not be part of `.Site.RegularPages` etc.

But you can get it by:

* `.Site.GetPage ...`

The use cases are many:

* Shared media galleries
* Reusable page content "snippets"
* ...

Fixes #4311
2018-01-24 09:00:21 +01:00
Bjørn Erik Pedersen 5a0819b9b5 Merge matching resources params maps
This allows setting default params values in the more general resource matchers. I also allows override with more specific values if needed.

```toml
[[resources]]
src = "documents/photo_specs.pdf"
title = "Photo Specifications"
[resources.params]
ref = 90564687
icon = "photo"
[[resources]]
src = "documents/guide.pdf"
title = "Instruction Guide"
[resources.params]
ref = 90564568
[[resources]]
src = "documents/checklist.pdf"
title = "Document Checklist"
[resources.params]
ref = 90564572
[[resources]]
src = "documents/payment.docx"
title = "Proof of Payment"
[[resources]]
src = "documents/*.pdf"
title = "PDF file"
[resources.params]
icon = "pdf"
[[resources]]
src = "documents/*.docx"
title = "Word document"
[resources.params]
icon = "word"

```

In the above `TOML` example, `photo_specs.pdf` will get the `photo` icon, the other pdf files will get the default `pdf` icon.

Note that in the example above, the order matters: It will take the first value for a given params key, title or name that it finds.

Fixes #4315
2018-01-23 17:11:38 +01:00
Bjørn Erik Pedersen 78c863305f Add some general code contribution criterias 2018-01-23 13:33:51 +01:00
Bjørn Erik Pedersen 22ad1ebdbb travis: Disable macOS builds for now
Travis have not been able to build those the last week or so.
2018-01-23 12:59:40 +01:00
Bjørn Erik Pedersen ebdd8cba3f helpers: Avoid unescape in highlight
Fixes #4219
2018-01-23 09:48:04 +01:00
Vas Sudanagunta 8125b4b03d Tighten page kind logic, introduce tests 2018-01-22 13:55:08 +01:00
hugoreleaser 87217d1d0a releaser: Prepare repository for 0.35-DEV
[ci skip]
2018-01-22 12:08:54 +00:00
hugoreleaser ffd7dc396e releaser: Add release notes to /docs for release of 0.34
[ci skip]
2018-01-22 12:06:38 +00:00
hugoreleaser 2228d3e289 releaser: Bump versions for release of 0.34
[ci skip]
2018-01-22 12:06:38 +00:00
Bjørn Erik Pedersen 5903a9ce10 Release 0.34 2018-01-22 13:02:01 +01:00
hugoreleaser 4d644c9d68 releaser: Add release notes draft for 0.34
Rename to *-ready.md to continue. [ci skip]
2018-01-22 10:40:52 +00:00
Bjørn Erik Pedersen 34a216fe67 resource: Avoid some strings.ToLower in globbing
See #4301
2018-01-22 11:29:33 +01:00
Bjørn Erik Pedersen adee04f4b4 releaser: Fix BuildDate in release binaries
Fixes #4299
2018-01-22 11:21:58 +01:00
Bjørn Erik Pedersen 9421380168 resource: Add Match and GetMatch
These methods takes a glob pattern as argument:

* by default matching from the bundle root
* matching is case insensitive and the separator is Unix style slashes: "/"
* the bundle root does (by default) not start with a leading slash
* if you renames the `Name` for the rsource in front matter (`src=...`), then that is the value used in `Match`.
* double asterisk matches beyond directory borders, so "**.jpg" will match any JPEG image in the bundle

See https://github.com/gobwas/glob

This commit also deprecates `ByPrefix` and `GetByPrefix`.

This should also be more effective, given a fair amount of reuse of the glob patterns:

```bash
BenchmarkResourcesByPrefix-4         300000          4284 ns/op        1130 B/op           7 allocs/op
BenchmarkResourcesMatch-4            300000          5220 ns/op         505 B/op           3 allocs/op
```

Fixes #4301
2018-01-22 10:28:12 +01:00
Bjørn Erik Pedersen 5d03086981 hugolib: Fix handling of pages bundled in sub-folders in ByPrefix etc.
Fixes #4295
2018-01-21 14:42:54 +01:00
Bjørn Erik Pedersen 07700aab0d output: Add some more layout docshelper variants 2018-01-19 11:39:34 +01:00
Bjørn Erik Pedersen 4d5e4f379a hugolib: Add validation for defaultContentLanguage
When `languages` are defined, then `defaultContentLanguage` must match one of those.

Fixes #4298
2018-01-19 08:24:10 +01:00
hugoreleaser cd77968284 releaser: Prepare repository for 0.34-DEV
[ci skip]
2018-01-18 10:16:12 +00:00
hugoreleaser c7b9347be0 releaser: Add release notes to /docs for release of 0.33
[ci skip]
2018-01-18 10:13:30 +00:00
hugoreleaser c6b9037294 releaser: Bump versions for release of 0.33
[ci skip]
2018-01-18 10:13:30 +00:00
Bjørn Erik Pedersen 09a934b321 Release 0.33 2018-01-18 11:09:11 +01:00
hugoreleaser e6cc2a6551 releaser: Add release notes draft for 0.33
Rename to *-ready.md to continue. [ci skip]
2018-01-18 09:24:11 +00:00
Bjørn Erik Pedersen a39ae4bb07 output: Redo the docshelper layouts examples 2018-01-18 10:16:21 +01:00
Bjørn Erik Pedersen b3eeb97642 Merge commit '3cf4300097610bb8b5bd0686d96d1df5db641895' 2018-01-17 22:33:07 +01:00
Bjørn Erik Pedersen 3cf4300097 Squashed 'docs/' changes from ddb7d8fae..56c34962c
56c34962c Fix multilingual config examples
14fa0b4ed Release 0.32.4
18779d54a releaser: Add release notes to /docs for release of 0.32.4
0d47d0673 releaser: Bump versions for release of 0.32.4
424acf02e Release 0.32.3
f6f04e084 releaser: Prepare repository for 0.33-DEV
1a9b36286 releaser: Add release notes to /docs for release of 0.32.3
9284c3284 releaser: Bump versions for release of 0.32.3
796082289 Fix min Go version in installing
74625a654 Add alias to multilingual.md
bf65732b4 Add some new tweets to the front page
7f263353e Bump Netlify to 0.32.2
cbb3a4f1c Update 0.32.2 release notes
e90ae4b4e releaser: Prepare repository for 0.33-DEV
ee74a8f4f releaser: Add release notes to /docs for release of 0.32.2
d889c4fa4 releaser: Bump versions for release of 0.32.2
4a46d3aca Merge commit 'eb738cd35cca1ffc68c5ed688dbe2a19108e8761'
b98d95ff2 releaser: Prepare repository for 0.33-DEV

git-subtree-dir: docs
git-subtree-split: 56c34962c9
2018-01-17 22:31:25 +01:00
Bjørn Erik Pedersen 9409bc0f79 Improve .Site.GetPage for regular translated pages
You can still use the full path with extensions, but to get the current language version:

* If the content file lives in `/content/blog/mypost.en.md`
* Use `.Site.GetPage "page" "blog/mypost"`

Fixes #4285
2018-01-17 22:27:25 +01:00
Bjørn Erik Pedersen 4eb1650bec resource: Use path.Match instead of filepath.Match
They behave similar, but it is a path we're matching.

See #4244
2018-01-17 20:48:31 +01:00
Bjørn Erik Pedersen 20c9b6ec81 resource: Add front matter metadata to Resource
This commit expands the Resource interface with 3 new methods:

* Name
* Title
* Params

All of these can be set in the Page front matter. `Name` will get its default value from the base filename, and is the value used in the ByPrefix and GetByPrefix lookup methods.

Fixes #4244
2018-01-17 16:22:33 +01:00
Bjørn Erik Pedersen f8a119b606 Update Afero to avoid panic on "file name is too long"
Fixes #4240
2018-01-15 20:33:03 +01:00
Bjørn Erik Pedersen ecaf14514e resource: Fix handling of very long image file names
Fixes #4261
2018-01-15 20:22:14 +01:00
Bjørn Erik Pedersen d4f8f88e67 commands: And now really fix the server watch logic
See #4275
2018-01-15 10:02:17 +01:00
Bjørn Erik Pedersen 4e524ffcff commands: Fix server without watch
This was broken in Hugo 0.30.

Fixes #4275
2018-01-14 20:58:52 +01:00
Bjørn Erik Pedersen 64f0e9d1c1 Update Chroma and other third-party deps
Fixes #4267
2018-01-14 20:32:42 +01:00
Bjørn Erik Pedersen 13d53b31f1 commands: Remove superflous BuildDate logic
Fixes #4272
2018-01-14 20:08:28 +01:00
Bjørn Erik Pedersen 51dd462c39 layout: Respect Type and Layout for list template selection
This commit also has some other nice side-effects:

* The layout logic is unified for all page types, which should make it less surprising
* Page.Render now supports all types
* The legacy "indexes" type is removed from the template lookup order. This is an undocumented type from early Hugo days. This means that having a template in, say, `/layouts/indexes/list.html` will no longer work.
* The theme override logic is improved. As an example, an `index.html` in theme will now wn over a `_default/list.html` in the project, which most will expect.

Fixes #3005
Fixes #3245
2018-01-14 19:59:51 +01:00
Bjørn Erik Pedersen b6ea6d07d0 Run benchmarks 3 times 2018-01-14 00:49:01 +01:00
Bjørn Erik Pedersen 4dac1781e3 resource: Add some GoDoc 2018-01-13 00:08:21 +01:00
Bjørn Erik Pedersen 8a409894bd hugolib: Allow url in front matter for list type pages
This enables some potential foot-shooting, but is needed for some special URL requirements.

Fixes #4263
2018-01-12 18:10:40 +01:00
Bjørn Erik Pedersen 46db900dab resource: Implement Resources.ByPrefix
Fixes #4266
2018-01-12 18:06:35 +01:00
Bjørn Erik Pedersen 60c9f3b1c3 resource: Make GetByPrefix work for Page resources
Fixes #4264
2018-01-12 17:46:50 +01:00
Bjørn Erik Pedersen 57e10f174e Support uglyURLs per section
Fixes #4256
2018-01-12 10:39:09 +01:00
Bjørn Erik Pedersen db85e83403 resource: Make .Resources.GetByPrefix case insensitive
Fixes #4258
2018-01-11 18:58:53 +01:00
Vas Sudanagunta 1046e9363f Update CONTRIBUTING.md 2018-01-11 17:22:12 +01:00
Vas Sudanagunta d5803da1be Support offline builds 2018-01-11 17:22:12 +01:00
hugoreleaser 27c77e1ab9 releaser: Prepare repository for 0.33-DEV
[ci skip]
2018-01-11 09:00:51 +00:00
hugoreleaser 218773a82b releaser: Add release notes to /docs for release of 0.32.4
[ci skip]
2018-01-11 08:58:01 +00:00
hugoreleaser a97ef61bad releaser: Bump versions for release of 0.32.4
[ci skip]
2018-01-11 08:58:01 +00:00
Bjørn Erik Pedersen 4aaf27dc55 Release 0.32.4 2018-01-11 09:52:32 +01:00
hugoreleaser f7d0b05f93 releaser: Add release notes draft for 0.32.4
Rename to *-ready.md to continue. [ci skip]
2018-01-11 08:48:10 +00:00
Bjørn Erik Pedersen f82428d2e0 releaser: Git info bounds checking 2018-01-11 09:39:42 +01:00
Bjørn Erik Pedersen 50fb49c3d9 resource: Remove superflous comment 2018-01-11 09:17:48 +01:00
Alexander Borsuk 5235a5bf5e Correct fix for --cleanDestinationDir flag
Fixes #4246
Fixes #4248
2018-01-10 18:26:42 +01:00
Alexander Borsuk 1921a70ab1 Revert "Remove the --cleanDestinationDir flag", there is a better fix.
This reverts commit 768ec5df9f.
2018-01-10 18:26:42 +01:00
Bjørn Erik Pedersen f0eecc6a4f Fix non-ASCII path handling for Page resources
Fixes #4241
2018-01-10 18:23:41 +01:00
Bjørn Erik Pedersen 768ec5df9f Remove the --cleanDestinationDir flag
This is no longer supported. Since Hugo 0.32 we do static sync and build in parallel.

Closes #4246
2018-01-10 09:34:40 +01:00
hugoreleaser 238e7f7fbe releaser: Prepare repository for 0.33-DEV
[ci skip]
2018-01-08 11:12:41 +00:00
hugoreleaser 0aaa38544d releaser: Add release notes to /docs for release of 0.32.3
[ci skip]
2018-01-08 11:10:08 +00:00
hugoreleaser fdec5e3084 releaser: Bump versions for release of 0.32.3
[ci skip]
2018-01-08 11:10:08 +00:00
Bjørn Erik Pedersen 71abb53fff Release 0.32.2 2018-01-08 12:05:52 +01:00
hugoreleaser db5d79862b releaser: Add release notes draft for 0.32.3
Rename to *-ready.md to continue. [ci skip]
2018-01-08 10:57:07 +00:00
Bjørn Erik Pedersen 2d3189b227 hugolib: Fix handling of mixed-case taxonomy folders with content file
* We match by path vs taxonomy to determine if we have a content page for that taxonomy
* The taxonomy name is (if `preserveTaxonomyNames` is not set) normalized to `maxmustermann` while you have the disk folder called `MaxMustermann`.
* This isn't a new issue, but I suspect most people will just name the folder `authors/maxmustermann` and it will just work.
* The inconsistent behaviour you see here is that you will end up with two pages with the same target filename, so it is a little random who will win.

This fixes that by also normalizing the taxonomy path when doing the comparison.

Fixes #4238
2018-01-08 11:47:26 +01:00
Bjørn Erik Pedersen 4b04db0f08 resource: Avoid processing and storing same image for each language
Fixes #4231
2018-01-07 11:58:16 +01:00
Bjørn Erik Pedersen 97c1866e32 resource: Resources.ByType should return Resources
Currently it returns []Resource.

This way the invocations can be nested.

Fixes #4234
2018-01-07 10:53:45 +01:00
Bjørn Erik Pedersen 8969331f5b Fix multihost detection for sites without language definition
Static content was wrongly put into the lang-code subfolder.

Fixes #4221
2018-01-06 19:14:31 +01:00
Bjørn Erik Pedersen 6feb138785 commands: Report build time on config.toml change
Fixes #4232
See #4224
2018-01-06 10:54:16 +01:00
Bjørn Erik Pedersen 059e8458d6 Fix hugo benchmark --renderToMemory
Fixes #4218
2018-01-06 10:37:04 +01:00
Bjørn Erik Pedersen ab82a27d05 Fix URLs for bundle resources in multihost mode
Fixes #4217
2018-01-06 10:29:13 +01:00
Bjørn Erik Pedersen f25d8a9e17 Fix sub-folder baseURL handling for Page resources
I.e. images etc.

Fixes #4228
2018-01-06 10:29:13 +01:00
hugoreleaser 54a89cde69 releaser: Prepare repository for 0.33-DEV
[ci skip]
2018-01-03 09:56:18 +00:00
hugoreleaser 2cd962233f releaser: Add release notes to /docs for release of 0.32.2
[ci skip]
2018-01-03 09:54:04 +00:00
hugoreleaser 865877cd05 releaser: Bump versions for release of 0.32.2
[ci skip]
2018-01-03 09:54:04 +00:00
Bjørn Erik Pedersen 1ff80a8bbe Release 0.32.2 2018-01-03 10:50:57 +01:00
hugoreleaser 956ef40978 releaser: Add release notes draft for 0.32.2
Rename to *-ready.md to continue. [ci skip]
2018-01-03 09:49:11 +00:00
Bjørn Erik Pedersen 196da49c9d resource: Handle publish to /public on fresh build
Fixes #4213
2018-01-03 10:28:16 +01:00
Bjørn Erik Pedersen 2aa4c009ee Merge commit 'eb738cd35cca1ffc68c5ed688dbe2a19108e8761' 2018-01-03 10:19:56 +01:00
Bjørn Erik Pedersen eb738cd35c Squashed 'docs/' changes from fc61378a3..ddb7d8fae
ddb7d8fae Fix spelling in error message
84f7e09ff Add an "sharing image" to the 0.32 doc
a6d39884c Add image processing examples
717e25400 Release 0.32.1
07a4fc1c1 Merge branch 'temp321'
401ed894b releaser: Add release notes to /docs for release of 0.32.1
aa040d965 releaser: Bump versions for release of 0.32.1
6d22558ec Close shortcode
442afa7f5 Add a link to the 0.32 HOWTO with a searchable title
9a9a7e475 Add a note about the shortcode issue
76d731ce2 Add title etc. to release notes
eac596de8 Release v0.32
ede3e25dc Merge branch 'tmp32'
c92f1701b releaser: Prepare repository for 0.33-DEV
e498e97f9 releaser: Add release notes to /docs for release of 0.32
1d476fc59 Fix typo
9bac78a2f Merge commit 'f3cd083961f36dc96d05e98aaf67f650102bc757'
7d8c78391 Add Pandoc support, refactor external helpers

git-subtree-dir: docs
git-subtree-split: ddb7d8fae0
2018-01-03 10:16:56 +01:00
hugoreleaser 3dd8c1c026 releaser: Prepare repository for 0.33-DEV
[ci skip]
2018-01-02 09:10:11 +00:00
hugoreleaser fd301c3c05 releaser: Add release notes to /docs for release of 0.32.1
[ci skip]
2018-01-02 09:07:55 +00:00
hugoreleaser 54ef60b03a releaser: Bump versions for release of 0.32.1
[ci skip]
2018-01-02 09:07:55 +00:00
Bjørn Erik Pedersen 14a758ff24 Release Hugo 0.32.1 2018-01-02 10:04:51 +01:00
hugoreleaser e64eb5ec2b releaser: Add release notes draft for 0.32.1
Rename to *-ready.md to continue. [ci skip]
2018-01-02 08:59:40 +00:00
Bjørn Erik Pedersen d36d71edd3 commands: Fix broken hugo --renderToMemory
The `--renderToMemory` flag stopped working on `hugo` in 0.32.

Note that this is only useful for benchmark testing, as there is no easy way to actually view the result.

Fixes #4212
2018-01-02 09:40:58 +01:00
Bjørn Erik Pedersen a54fd7df21 resource: Use the correct Destination FS
Source and destination will be the same when this happens, but it should be correct.

See #4202
2018-01-01 14:28:19 +01:00
Bjørn Erik Pedersen 16e1d99c6d resource: Create target dir if not exists
This is the case where image processing is triggered from shortcodes, i.e. before the target page's folder in /public is created.

Fixes #4202
2018-01-01 14:23:51 +01:00
Bjørn Erik Pedersen bf8a61fde5 hugolib: Add test for image processing from shortcodes
See #4202
2018-01-01 12:11:36 +01:00
hugoreleaser 72158ab2e8 releaser: Prepare repository for 0.33-DEV
[ci skip]
2017-12-31 09:26:48 +00:00
497 changed files with 17792 additions and 7129 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
defaults: &defaults
working_directory: /go/src/github.com/gohugoio
docker:
- image: bepsays/ci-goreleaser:0.34.2-6
- image: bepsays/ci-goreleaser:0.34.2-11
version: 2
jobs:
+2 -2
View File
@@ -1,7 +1,7 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 120
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 21
daysUntilClose: 30
# Issues with these labels will never be considered stale
exemptLabels:
- Keep
@@ -20,4 +20,4 @@ markComment: >
This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false
closeComment: false
+1
View File
@@ -12,6 +12,7 @@ cover.out
*~
vendor/*/
*.bench
*.debug
coverage*.out
GoBuilds
+10 -8
View File
@@ -1,9 +1,11 @@
language: go
sudo: required
dist: precise
sudo: false
dist: trusty
git:
depth: false
go:
- 1.8.5
- 1.9.2
- 1.9.5
- "1.10.1"
- tip
os:
- linux
@@ -14,12 +16,12 @@ matrix:
fast_finish: true
install:
- go get github.com/magefile/mage
- mage vendor
- mage -v vendor
script:
- mage hugoRace
- mage -v hugoRace
- mage -v 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 asciidoctor
- type asciidoctor
+61 -28
View File
@@ -36,6 +36,23 @@ the GitHub [issue tracker](https://github.com/gohugoio/hugo/issues) to report th
If you're not sure if it's a bug or not, start by asking in the [discussion forum](https://discourse.gohugo.io).
When reporting the issue, please provide the version of Hugo in use (`hugo version`) and your operating system.
## Code Contribution
Hugo has become a fully featured static site generator, so any new functionality must meet these criterias:
* It must be useful to many.
* It must fit natural into _what Hugo does best._
* It must strive not to break existing sites.
* It must close ur update an open [Hugo issue](https://github.com/gohugoio/hugo/issues)
* If it is of some complexity, the contributor is expected to maintain and support the new future (answer questions on the forum, fix any bugs etc.).
So, to avoid doing unneeded work, it is recommended to open up a discussion on the [Hugo Forum](https://discourse.gohugo.io/) to get some acceptance that this is a good idea. Also, if this is a complex feature, create a small design proposal on the [Hugo issue tracker](https://github.com/gohugoio/hugo/issues) before you start coding.
**Bug fixes are, of course, always welcome.**
## Submitting Patches
The Hugo project welcomes all contributors and contributions regardless of skill or experience level.
@@ -88,42 +105,42 @@ new default function more useful for Hugo users.
Fixes #1949
```
### Vendored Dependencies
Hugo uses [Go Dep](https://github.com/golang/dep) to vendor dependencies, but we don't commit the vendored packages themselves to the Hugo git repository.
Therefore, a simple `go get` is not supported since `go get` is not vendor-aware.
You **must use Go Dep** to fetch and manage Hugo's dependencies.
### Fetch the Sources From GitHub
### Fetching the Sources From GitHub
Due to the way Go handles package imports, the best approach for working on a
Hugo fork is to use Git Remotes. Here's a simple walk-through for getting
started:
1. Install Go Dep and get the Hugo source:
1. Get the Hugo source:
```bash
go get -u -v -d github.com/gohugoio/hugo
```
1. Install Mage:
```bash
go get github.com/magefile/mage
```
go get -u -v github.com/golang/dep/cmd/dep
go get -u -v -d github.com/gohugoio/hugo
```
1. Change to the Hugo source directory and fetch the dependencies:
```
```bash
cd $HOME/go/src/github.com/gohugoio/hugo
dep ensure
mage vendor
```
Note that Hugo uses [Go Dep](https://github.com/golang/dep) to vendor dependencies, rather than a a simple `go get`. We don't commit the vendored packages themselves to the Hugo git repository. The call to `mage vendor` takes care of all this for you.
1. Create a new branch for your changes (the branch name is arbitrary):
```
```bash
git checkout -b iss1234
```
1. After making your changes, commit them to your new branch:
```
```bash
git commit -a -v
```
@@ -131,42 +148,58 @@ started:
1. Add your fork as a new remote (the remote name, "fork" in this example, is arbitrary):
```
```bash
git remote add fork git://github.com/USERNAME/hugo.git
```
1. Push the changes to your new remote:
```
```bash
git push --set-upstream fork iss1234
```
1. You're now ready to submit a PR based upon the new branch in your forked repository.
### Build Hugo with Your Changes
### Building Hugo with Your Changes
**Note:** Hugo uses [mage](https://github.com/magefile/mage) to build. To install `mage` run
```bash
go get github.com/magefile/mage
```
`mage -l` lists all available commands with the corresponding description. To build Hugo run
Hugo uses [mage](https://github.com/magefile/mage) to sync vendor dependencies, build Hugo, run the test suite and other things. You must run mage from the Hugo directory.
```bash
cd $HOME/go/src/github.com/gohugoio/hugo
```
To build Hugo:
```bash
mage hugo
# or to install in $HOME/go/bin:
```
To install hugo in `$HOME/go/bin`:
```bash
mage install
```
To run the tests:
```bash
mage hugoRace
mage -v check
```
To list all available commands along with descriptions:
```bash
mage -l
```
### Updating the Hugo Sources
If you want to stay in sync with the Hugo repository, you can easily pull down
the source changes, but you'll need to keep the vendored packages up-to-date as
well.
```
```bash
git pull
mage vendor
```
+1 -1
View File
@@ -4,8 +4,8 @@ RUN apk add --no-cache --virtual git musl-dev
RUN go get github.com/golang/dep/cmd/dep
WORKDIR /go/src/github.com/gohugoio/hugo
RUN dep ensure
ADD . /go/src/github.com/gohugoio/hugo/
RUN dep ensure
RUN go install -ldflags '-s -w'
FROM alpine:3.6
Generated
+111 -48
View File
@@ -20,32 +20,66 @@
revision = "de5bf2ad457846296e2031421a34e2568e304e35"
[[projects]]
branch = "master"
name = "github.com/alecthomas/chroma"
packages = [
".",
"formatters",
"formatters/html",
"lexers",
"lexers/a",
"lexers/b",
"lexers/c",
"lexers/circular",
"lexers/d",
"lexers/e",
"lexers/f",
"lexers/g",
"lexers/h",
"lexers/i",
"lexers/internal",
"lexers/j",
"lexers/k",
"lexers/l",
"lexers/m",
"lexers/n",
"lexers/o",
"lexers/p",
"lexers/q",
"lexers/r",
"lexers/s",
"lexers/t",
"lexers/v",
"lexers/w",
"lexers/x",
"lexers/y",
"styles"
]
revision = "v0.2.0"
revision = "6b1131c0069211a7729895c26f8c51765a4baf25"
[[projects]]
name = "github.com/bep/debounce"
packages = ["."]
revision = "844797fa1dd9ba969d71b62797ff19d1e49d4eac"
version = "v1.1.0"
[[projects]]
branch = "master"
name = "github.com/bep/gitmap"
packages = ["."]
revision = "de8030ebafb76c6e84d50ee6d143382637c00598"
revision = "012701e8669671499fc43e9792335a1dcbfe2afb"
[[projects]]
name = "github.com/chaseadamsio/goorgeous"
packages = ["."]
revision = "v1.1.0"
revision = "dcf1ef873b8987bf12596fe6951c48347986eb2f"
version = "v1.1.0"
[[projects]]
name = "github.com/cpuguy83/go-md2man"
packages = ["md2man"]
revision = "1d903dcb749992f3741d744c0f8376b4bd7eb3e1"
version = "v1.0.7"
revision = "20f5889cbdc3c73dbd2862796665e7c465ade7d1"
version = "v1.0.8"
[[projects]]
branch = "master"
@@ -62,7 +96,8 @@
[[projects]]
name = "github.com/disintegration/imaging"
packages = ["."]
revision = "v1.2.4"
revision = "dd50a3ee9985ccd313a2f03c398fcaedc96dc707"
version = "v1.2.4"
[[projects]]
name = "github.com/dlclark/regexp2"
@@ -85,14 +120,29 @@
[[projects]]
name = "github.com/fortytw2/leaktest"
packages = ["."]
revision = "7dad53304f9614c1c365755c1176a8e876fee3e8"
version = "v1.1.0"
revision = "a5ef70473c97b71626b9abeda80ee92ba2a7de9e"
version = "v1.2.0"
[[projects]]
name = "github.com/fsnotify/fsnotify"
packages = ["."]
revision = "629574ca2a5df945712d3079857300b5e4da0236"
version = "v1.4.2"
revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9"
version = "v1.4.7"
[[projects]]
name = "github.com/gobwas/glob"
packages = [
".",
"compiler",
"match",
"syntax",
"syntax/ast",
"syntax/lexer",
"util/runes",
"util/strings"
]
revision = "5ccd90ef52e1e632236f7326478d4faa74f99438"
version = "v0.2.3"
[[projects]]
name = "github.com/gorilla/websocket"
@@ -104,13 +154,13 @@
branch = "master"
name = "github.com/hashicorp/go-immutable-radix"
packages = ["."]
revision = "8aac2701530899b64bdea735a1de8da899815220"
revision = "7f3cd4390caab3250a57f30efdb2a65dd7649ecf"
[[projects]]
branch = "master"
name = "github.com/hashicorp/golang-lru"
packages = ["simplelru"]
revision = "0a025b7e63adc15a622f29b0b2c4c3848243bbf6"
revision = "0fb14efe8c47ae851c0034ed7a448854d3d34cf3"
[[projects]]
branch = "master"
@@ -119,6 +169,7 @@
".",
"hcl/ast",
"hcl/parser",
"hcl/printer",
"hcl/scanner",
"hcl/strconv",
"hcl/token",
@@ -126,7 +177,7 @@
"json/scanner",
"json/token"
]
revision = "23c074d0eceb2b8a5bfdbb271ab780cde70f05a8"
revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168"
[[projects]]
name = "github.com/inconshreveable/mousetrap"
@@ -143,12 +194,6 @@
revision = "20d3663d4bc9dd10d75abcde9d92e04b4861c674"
version = "v1.1.0"
[[projects]]
branch = "master"
name = "github.com/kardianos/osext"
packages = ["."]
revision = "ae77be60afb1dcacde03767a8c37337fad28ac14"
[[projects]]
name = "github.com/kyokomi/emoji"
packages = ["."]
@@ -167,14 +212,13 @@
[[projects]]
name = "github.com/magiconair/properties"
packages = ["."]
revision = "be5ece7dd465ab0765a9682137865547526d1dfb"
version = "v1.7.3"
revision = "c3beff4c2358b44d0493c7dda585e7db7ff28ae6"
version = "v1.7.6"
[[projects]]
branch = "master"
name = "github.com/markbates/inflect"
packages = ["."]
revision = "54ffb37507cd7d2ccd4768855e84f9ff6c4352b6"
revision = "a12c3aec81a6a938bf584a4bac567afed9256586"
[[projects]]
name = "github.com/mattn/go-runewidth"
@@ -192,7 +236,16 @@
branch = "master"
name = "github.com/mitchellh/mapstructure"
packages = ["."]
revision = "06020f85339e21b2478f756a78e295255ffa4d6a"
revision = "00c29f56e2386353d58c599509e8dc3801b0d716"
[[projects]]
branch = "master"
name = "github.com/muesli/smartcrop"
packages = [
".",
"options"
]
revision = "f6ebaa786a12a0fdb2d7c6dee72808e68c296464"
[[projects]]
name = "github.com/nicksnyder/go-i18n"
@@ -208,13 +261,13 @@
branch = "master"
name = "github.com/olekukonko/tablewriter"
packages = ["."]
revision = "65fec0d89a572b4367094e2058d3ebe667de3b60"
revision = "b8a9be070da40449e501c3c4730a889e42d87a9e"
[[projects]]
name = "github.com/pelletier/go-toml"
packages = ["."]
revision = "16398bac157da96aa88f98a2df640c7f32af1da2"
version = "v1.0.1"
revision = "acdc4509485b587f5e675510c4f2c63e90ff68a8"
version = "v1.1.0"
[[projects]]
name = "github.com/pmezard/go-difflib"
@@ -225,8 +278,14 @@
[[projects]]
name = "github.com/russross/blackfriday"
packages = ["."]
revision = "4048872b16cc0fc2c5fd9eacf0ed2c2fedaa0c8c"
version = "v1.5"
revision = "55d61fa8aa702f59229e6cff85793c22e580eaf5"
version = "v1.5.1"
[[projects]]
name = "github.com/sanity-io/litter"
packages = ["."]
revision = "ae543b7ba8fd6af63e4976198f146e1348ae53c1"
version = "v1.1.0"
[[projects]]
branch = "master"
@@ -240,23 +299,23 @@
".",
"mem"
]
revision = "ec3a3111d1e1bdff38a61e09d5a5f5e974905611"
version = "v1.0.1"
revision = "63644898a8da0bc22138abf860edaf5277b6102e"
version = "v1.1.0"
[[projects]]
name = "github.com/spf13/cast"
packages = ["."]
revision = "acbeb36b902d72a7a4c18e8f3241075e7ab763e4"
version = "v1.1.0"
revision = "8965335b8c7107321228e3e3702cab9832751bac"
version = "v1.2.0"
[[projects]]
branch = "master"
name = "github.com/spf13/cobra"
packages = [
".",
"doc"
]
revision = "7b2c5ac9fc04fc5efafb60700713d4fa609b777b"
revision = "a1f051bc3eba734da4772d60e2d677f47cf93ef4"
version = "v0.0.2"
[[projects]]
branch = "master"
@@ -268,7 +327,7 @@
branch = "master"
name = "github.com/spf13/jwalterweatherman"
packages = ["."]
revision = "12bd96e66386c1960ab0f74ced1362f66f552f7b"
revision = "7c0cea34c8ece3fbeb2b27ab9b59511d360fb394"
[[projects]]
branch = "master"
@@ -285,8 +344,8 @@
[[projects]]
name = "github.com/spf13/viper"
packages = ["."]
revision = "25b30aa063fc18e48662b86996252eabdcf2f0c7"
version = "v1.0.0"
revision = "b5e8006cbee93ec955a89ab31e0e3ce3204f3736"
version = "v1.0.2"
[[projects]]
name = "github.com/stretchr/testify"
@@ -294,8 +353,8 @@
"assert",
"require"
]
revision = "69483b4bd14f5845b5a1e55bca19e954e827f1d0"
version = "v1.1.4"
revision = "12b6f73e6084dad08a7c6e575284b177ecafbc71"
version = "v1.2.1"
[[projects]]
name = "github.com/yosssi/ace"
@@ -308,6 +367,8 @@
name = "golang.org/x/image"
packages = [
"bmp",
"draw",
"math/f64",
"riff",
"tiff",
"tiff/lzw",
@@ -315,7 +376,7 @@
"vp8l",
"webp"
]
revision = "f7e31b4ea2e3413ab91b4e7d2dc83e5f8d19a44c"
revision = "f315e440302883054d0c2bd85486878cb4f8572c"
[[projects]]
branch = "master"
@@ -324,19 +385,19 @@
"context",
"idna"
]
revision = "cd69bc3fc700721b709c3a59e16e24c67b58f6ff"
revision = "61147c48b25b599e5b561d2e9c4f3e1ef489ca41"
[[projects]]
branch = "master"
name = "golang.org/x/sync"
packages = ["errgroup"]
revision = "fd80eb99c8f653c847d294a001bdf2a3a6f768f5"
revision = "1d60e4601c6fd243af51cc01ddf169918a5407ca"
[[projects]]
branch = "master"
name = "golang.org/x/sys"
packages = ["unix"]
revision = "8dbc5d05d6edcc104950cc299a1ce6641235bc86"
revision = "3b87a42e500a6dc65dae1a55d0b641295971163e"
[[projects]]
branch = "master"
@@ -346,6 +407,8 @@
"collate/build",
"internal/colltab",
"internal/gen",
"internal/language",
"internal/language/compact",
"internal/tag",
"internal/triegen",
"internal/ucd",
@@ -358,17 +421,17 @@
"unicode/rangetable",
"width"
]
revision = "c01e4764d870b77f8abe5096ee19ad20d80e8075"
revision = "2cb43934f0eece38629746959acc633cba083fe4"
[[projects]]
branch = "v2"
name = "gopkg.in/yaml.v2"
packages = ["."]
revision = "eb3733d160e74a9c7e442f435eb3bea458e1d19f"
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
version = "v2.2.1"
[solve-meta]
analyzer-name = "dep"
analyzer-version = 1
inputs-digest = "7259b4caf8e75db0b809f06d4897dc870261252e3aecd68ea1348c87a5da9d50"
inputs-digest = "b9b38ece73fd6c0d0b20eb2ff85dfcc15a82841223b4403566712fd7b7ae7d59"
solver-name = "gps-cdcl"
solver-version = 1
+31 -17
View File
@@ -10,19 +10,19 @@
[[constraint]]
name = "github.com/alecthomas/chroma"
revision = "v0.2.0"
branch = "master"
[[constraint]]
branch = "master"
name = "github.com/bep/gitmap"
[[constraint]]
name = "github.com/chaseadamsio/goorgeous"
revision = "v1.1.0"
version = "^1.1.0"
[[constraint]]
name = "github.com/disintegration/imaging"
revision = "v1.2.4"
version = "~v1.2.4"
[[constraint]]
name = "github.com/magefile/mage"
@@ -38,7 +38,7 @@
[[constraint]]
name = "github.com/fsnotify/fsnotify"
version = "1.4.2"
version = "^1.4.0"
[[constraint]]
name = "github.com/gorilla/websocket"
@@ -52,21 +52,17 @@
name = "github.com/jdkato/prose"
version = "1.1.0"
[[constraint]]
branch = "master"
name = "github.com/kardianos/osext"
[[constraint]]
name = "github.com/kyokomi/emoji"
version = "1.5.0"
[[constraint]]
branch = "master"
name = "github.com/markbates/inflect"
revision = "a12c3aec81a6a938bf584a4bac567afed9256586"
[[constraint]]
name = "github.com/miekg/mmark"
version = "1.3.6"
version = "^1.3.6"
[[constraint]]
branch = "master"
@@ -74,22 +70,22 @@
[[constraint]]
name = "github.com/nicksnyder/go-i18n"
version = "1.10.0"
version = "^1.10.0"
[[constraint]]
name = "github.com/russross/blackfriday"
version = "1.5.0"
branch = "master"
[[constraint]]
name = "github.com/spf13/afero"
version = "1.0.1"
version = "^1.1.0"
[[constraint]]
name = "github.com/spf13/cast"
version = "1.1.0"
version = "^1.1.0"
[[constraint]]
branch = "master"
version = "^0.0.1"
name = "github.com/spf13/cobra"
[[constraint]]
@@ -122,7 +118,7 @@
[[constraint]]
name = "github.com/yosssi/ace"
version = "0.0.5"
version = "^0.0.5"
[[constraint]]
branch = "master"
@@ -135,3 +131,21 @@
[[constraint]]
branch = "v2"
name = "gopkg.in/yaml.v2"
[[constraint]]
name = "github.com/gobwas/glob"
version = "0.2.2"
[[constraint]]
name = "github.com/muesli/smartcrop"
branch = "master"
[[constraint]]
name = "github.com/sanity-io/litter"
version = "1.1.0"
[[constraint]]
name = "github.com/bep/debounce"
version = "^1.1.0"
+201
View File
@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
-194
View File
@@ -1,194 +0,0 @@
Apache License
==============
_Version 2.0, January 2004_
_&lt;<http://www.apache.org/licenses/>&gt;_
### Terms and Conditions for use, reproduction, and distribution
#### 1. Definitions
“License” shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
“Licensor” shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
“Legal Entity” shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, “control” means **(i)** the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the
outstanding shares, or **(iii)** beneficial ownership of such entity.
“You” (or “Your”) shall mean an individual or Legal Entity exercising
permissions granted by this License.
“Source” form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
“Object” form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
“Work” shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
“Derivative Works” shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
“Contribution” shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
“submitted” means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as “Not a Contribution.”
“Contributor” shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
#### 2. Grant of Copyright License
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
#### 3. Grant of Patent License
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
#### 4. Redistribution
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
* **(a)** You must give any other recipients of the Work or Derivative Works a copy of
this License; and
* **(b)** You must cause any modified files to carry prominent notices stating that You
changed the files; and
* **(c)** You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
#### 5. Submission of Contributions
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
#### 6. Trademarks
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
#### 7. Disclaimer of Warranty
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an “AS IS” BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
#### 8. Limitation of Liability
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
#### 9. Accepting Warranty or Additional Liability
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
_END OF TERMS AND CONDITIONS_
### APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets `[]` replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same “printed page” as the copyright notice for easier identification within
third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
+19 -6
View File
@@ -1,6 +1,6 @@
![Hugo](https://raw.githubusercontent.com/gohugoio/hugoDocs/master/static/img/hugo-logo.png)
A Fast and Flexible Static Site Generator built with love by [spf13](http://spf13.com/) and [friends](https://github.com/gohugoio/hugo/graphs/contributors) in [Go][].
A Fast and Flexible Static Site Generator built with love by [bep](https://github.com/bep), [spf13](http://spf13.com/) and [friends](https://github.com/gohugoio/hugo/graphs/contributors) in [Go][].
[Website](https://gohugo.io) |
[Forum](https://discourse.gohugo.io) |
@@ -54,15 +54,28 @@ Use the [installation instructions in the Hugo documentation](https://gohugo.io/
### Build and Install the Binaries from Source (Advanced Install)
Add Hugo and its package dependencies to your go `src` directory.
#### Prerequisite Tools
go get -v github.com/gohugoio/hugo
* [Git](http://git-scm.com/)
* [Go (latest or previous version)](https://golang.org/dl/)
Once the `get` completes, you should find your new `hugo` (or `hugo.exe`) executable sitting inside `$GOPATH/bin/`.
#### Vendored Dependencies
To update Hugos dependencies, use `go get` with the `-u` option.
Hugo uses [dep](https://github.com/golang/dep) to vendor dependencies, but we don't commit the vendored packages themselves to the Hugo git repository. Therefore, a simple `go get` is _not_ supported because the command is not vendor aware.
go get -u -v github.com/gohugoio/hugo
The simplest way is to use [mage](https://github.com/magefile/mage) (a Make alternative for Go projects.)
#### Fetch from GitHub
```bash
go get github.com/magefile/mage
go get -d github.com/gohugoio/hugo
cd ${GOPATH:-$HOME/go}/src/github.com/gohugoio/hugo
mage vendor
mage install
```
**If you are a Windows user, substitute the `$HOME` environment variable above with `%USERPROFILE%`.**
## The Hugo Documentation
+1 -1
View File
@@ -12,7 +12,7 @@ install:
- go get github.com/magefile/mage
build_script:
- mage hugoRace
- mage vendor hugoRace
- mage -v check
- hugo -s docs/
- hugo --renderToMemory -s docs/
+1 -1
View File
@@ -9,4 +9,4 @@ GOEXE="${GOEXE-go}"
echo "Running with BenchmarkSiteBuilding/${1}"
"${GOEXE}" test -run="NONE" -bench="BenchmarkSiteBuilding/${1}" -test.benchmem=true ./hugolib -memprofile mem.prof -cpuprofile cpu.prof
"${GOEXE}" test -run="NONE" -bench="BenchmarkSiteBuilding/${1}" -test.benchmem=true ./hugolib -memprofile mem.prof -count 3 -cpuprofile cpu.prof
+35 -27
View File
@@ -23,47 +23,55 @@ import (
jww "github.com/spf13/jwalterweatherman"
)
var (
type benchmarkCmd struct {
benchmarkTimes int
cpuProfileFile string
memProfileFile string
)
var benchmarkCmd = &cobra.Command{
Use: "benchmark",
Short: "Benchmark Hugo by building a site a number of times.",
Long: `Hugo can build a site many times over and analyze the running process
*baseBuilderCmd
}
func (b *commandsBuilder) newBenchmarkCmd() *benchmarkCmd {
cmd := &cobra.Command{
Use: "benchmark",
Short: "Benchmark Hugo by building a site a number of times.",
Long: `Hugo can build a site many times over and analyze the running process
creating a benchmark.`,
}
c := &benchmarkCmd{baseBuilderCmd: b.newBuilderCmd(cmd)}
cmd.Flags().StringVar(&c.cpuProfileFile, "cpuprofile", "", "path/filename for the CPU profile file")
cmd.Flags().StringVar(&c.memProfileFile, "memprofile", "", "path/filename for the memory profile file")
cmd.Flags().IntVarP(&c.benchmarkTimes, "count", "n", 13, "number of times to build the site")
cmd.Flags().Bool("renderToMemory", false, "render to memory (only useful for benchmark testing)")
cmd.RunE = c.benchmark
return c
}
func init() {
initHugoBuilderFlags(benchmarkCmd)
initBenchmarkBuildingFlags(benchmarkCmd)
func (c *benchmarkCmd) benchmark(cmd *cobra.Command, args []string) error {
cfgInit := func(c *commandeer) error {
return nil
}
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 {
c, err := InitializeConfig(false, nil, benchmarkCmd)
comm, err := initializeConfig(false, &c.hugoBuilderCommon, c, cfgInit)
if err != nil {
return err
}
var memProf *os.File
if memProfileFile != "" {
memProf, err = os.Create(memProfileFile)
if c.memProfileFile != "" {
memProf, err = os.Create(c.memProfileFile)
if err != nil {
return err
}
}
var cpuProf *os.File
if cpuProfileFile != "" {
cpuProf, err = os.Create(cpuProfileFile)
if c.cpuProfileFile != "" {
cpuProf, err = os.Create(c.cpuProfileFile)
if err != nil {
return err
}
@@ -78,8 +86,8 @@ func benchmark(cmd *cobra.Command, args []string) error {
}
t := time.Now()
for i := 0; i < benchmarkTimes; i++ {
if err = c.resetAndBuildSites(); err != nil {
for i := 0; i < c.benchmarkTimes; i++ {
if err = comm.resetAndBuildSites(); err != nil {
return err
}
}
@@ -99,9 +107,9 @@ func benchmark(cmd *cobra.Command, args []string) error {
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))
jww.FEEDBACK.Printf("Average time per operation: %vms\n", int(1000*totalTime.Seconds()/float64(c.benchmarkTimes)))
jww.FEEDBACK.Printf("Average memory allocated per operation: %vkB\n", totalMemAllocated/uint64(c.benchmarkTimes)/1024)
jww.FEEDBACK.Printf("Average allocations per operation: %v\n", totalMallocs/uint64(c.benchmarkTimes))
return nil
}
+15 -4
View File
@@ -1,4 +1,4 @@
// Copyright 2015 The Hugo Authors. All rights reserved.
// Copyright 2018 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.
@@ -11,13 +11,24 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// +build !darwin
package commands
import (
"github.com/spf13/cobra"
)
var checkCmd = &cobra.Command{
Use: "check",
Short: "Contains some verification checks",
var _ cmder = (*checkCmd)(nil)
type checkCmd struct {
*baseCmd
}
func newCheckCmd() *checkCmd {
return &checkCmd{baseCmd: &baseCmd{cmd: &cobra.Command{
Use: "check",
Short: "Contains some verification checks",
},
}}
}
+36
View File
@@ -0,0 +1,36 @@
// Copyright 2018 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"
)
var _ cmder = (*checkCmd)(nil)
type checkCmd struct {
*baseCmd
}
func newCheckCmd() *checkCmd {
cc := &checkCmd{baseCmd: &baseCmd{cmd: &cobra.Command{
Use: "check",
Short: "Contains some verification checks",
},
}}
cc.cmd.AddCommand(newLimitCmd().getCommand())
return cc
}
+182 -11
View File
@@ -1,4 +1,4 @@
// Copyright 2017 The Hugo Authors. All rights reserved.
// Copyright 2018 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.
@@ -14,6 +14,22 @@
package commands
import (
"os"
"path/filepath"
"sync"
"time"
"github.com/gohugoio/hugo/config"
"github.com/spf13/cobra"
"github.com/gohugoio/hugo/utils"
"github.com/spf13/afero"
"github.com/gohugoio/hugo/hugolib"
"github.com/bep/debounce"
"github.com/gohugoio/hugo/common/types"
"github.com/gohugoio/hugo/deps"
"github.com/gohugoio/hugo/helpers"
@@ -23,13 +39,31 @@ import (
type commandeer struct {
*deps.DepsCfg
hugo *hugolib.HugoSites
h *hugoBuilderCommon
ftch flagsToConfigHandler
pathSpec *helpers.PathSpec
visitedURLs *types.EvictingStringQueue
staticDirsConfig []*src.Dirs
serverPorts []int
languages helpers.Languages
// We watch these for changes.
configFiles []string
doWithCommandeer func(c *commandeer) error
// We can do this only once.
fsCreate sync.Once
// Used in cases where we get flooded with events in server mode.
debounce func(f func())
serverPorts []int
languagesConfigured bool
languages helpers.Languages
configured bool
}
@@ -65,16 +99,153 @@ func (c *commandeer) initFs(fs *hugofs.Fs) error {
return nil
}
func newCommandeer(cfg *deps.DepsCfg, running bool) (*commandeer, error) {
cfg.Running = running
func newCommandeer(running bool, h *hugoBuilderCommon, f flagsToConfigHandler, doWithCommandeer func(c *commandeer) error, subCmdVs ...*cobra.Command) (*commandeer, error) {
var languages helpers.Languages
if l, ok := cfg.Cfg.Get("languagesSorted").(helpers.Languages); ok {
languages = l
var rebuildDebouncer func(f func())
if running {
// The time value used is tested with mass content replacements in a fairly big Hugo site.
// It is better to wait for some seconds in those cases rather than get flooded
// with rebuilds.
rebuildDebouncer, _, _ = debounce.New(4 * time.Second)
}
c := &commandeer{DepsCfg: cfg, languages: languages, visitedURLs: types.NewEvictingStringQueue(10)}
c := &commandeer{
h: h,
ftch: f,
doWithCommandeer: doWithCommandeer,
visitedURLs: types.NewEvictingStringQueue(10),
debounce: rebuildDebouncer,
}
return c, c.loadConfig(running)
}
func (c *commandeer) loadConfig(running bool) error {
if c.DepsCfg == nil {
c.DepsCfg = &deps.DepsCfg{}
}
cfg := c.DepsCfg
c.configured = false
cfg.Running = running
var dir string
if c.h.source != "" {
dir, _ = filepath.Abs(c.h.source)
} else {
dir, _ = os.Getwd()
}
var sourceFs afero.Fs = hugofs.Os
if c.DepsCfg.Fs != nil {
sourceFs = c.DepsCfg.Fs.Source
}
doWithConfig := func(cfg config.Provider) error {
if c.ftch != nil {
c.ftch.flagsToConfig(cfg)
}
cfg.Set("workingDir", dir)
return nil
}
doWithCommandeer := func(cfg config.Provider) error {
c.Cfg = cfg
if c.doWithCommandeer == nil {
return nil
}
err := c.doWithCommandeer(c)
return err
}
config, configFiles, err := hugolib.LoadConfig(
hugolib.ConfigSourceDescriptor{Fs: sourceFs, Path: c.h.source, WorkingDir: dir, Filename: c.h.cfgFile},
doWithCommandeer,
doWithConfig)
if err != nil {
return err
}
c.configFiles = configFiles
if l, ok := c.Cfg.Get("languagesSorted").(helpers.Languages); ok {
c.languagesConfigured = true
c.languages = l
}
// This is potentially double work, but we need to do this one more time now
// that all the languages have been configured.
if c.doWithCommandeer != nil {
if err := c.doWithCommandeer(c); err != nil {
return err
}
}
logger, err := c.createLogger(config)
if err != nil {
return err
}
cfg.Logger = logger
createMemFs := config.GetBool("renderToMemory")
if createMemFs {
// Rendering to memoryFS, publish to Root regardless of publishDir.
config.Set("publishDir", "/")
}
c.fsCreate.Do(func() {
fs := hugofs.NewFrom(sourceFs, config)
// Hugo writes the output to memory instead of the disk.
if createMemFs {
fs.Destination = new(afero.MemMapFs)
}
err = c.initFs(fs)
})
if err != nil {
return err
}
cacheDir := config.GetString("cacheDir")
if cacheDir != "" {
if helpers.FilePathSeparator != cacheDir[len(cacheDir)-1:] {
cacheDir = cacheDir + helpers.FilePathSeparator
}
isDir, err := helpers.DirExists(cacheDir, sourceFs)
utils.CheckErr(cfg.Logger, err)
if !isDir {
mkdir(cacheDir)
}
config.Set("cacheDir", cacheDir)
} else {
config.Set("cacheDir", helpers.GetTempDir("hugo_cache", sourceFs))
}
cfg.Logger.INFO.Println("Using config file:", config.ConfigFileUsed())
themeDir := c.PathSpec().GetThemeDir()
if themeDir != "" {
if _, err := sourceFs.Stat(themeDir); os.IsNotExist(err) {
return newSystemError("Unable to find theme Directory:", themeDir)
}
}
themeVersionMismatch, minVersion := c.isThemeVsHugoVersionMismatch(sourceFs)
if themeVersionMismatch {
cfg.Logger.ERROR.Printf("Current theme does not support Hugo version %s. Minimum version required is %s\n",
helpers.CurrentHugoVersion.ReleaseVersion(), minVersion)
}
return nil
return c, nil
}
+243
View File
@@ -0,0 +1,243 @@
// 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/gohugoio/hugo/config"
"github.com/gohugoio/hugo/helpers"
"github.com/spf13/cobra"
"github.com/spf13/nitro"
)
type commandsBuilder struct {
hugoBuilderCommon
commands []cmder
}
func newCommandsBuilder() *commandsBuilder {
return &commandsBuilder{}
}
func (b *commandsBuilder) addCommands(commands ...cmder) *commandsBuilder {
b.commands = append(b.commands, commands...)
return b
}
func (b *commandsBuilder) addAll() *commandsBuilder {
b.addCommands(
b.newServerCmd(),
newVersionCmd(),
newEnvCmd(),
newConfigCmd(),
newCheckCmd(),
b.newBenchmarkCmd(),
newConvertCmd(),
newNewCmd(),
newListCmd(),
newImportCmd(),
newGenCmd(),
createReleaser(),
)
return b
}
func (b *commandsBuilder) build() *hugoCmd {
h := b.newHugoCmd()
addCommands(h.getCommand(), b.commands...)
return h
}
func addCommands(root *cobra.Command, commands ...cmder) {
for _, command := range commands {
cmd := command.getCommand()
if cmd == nil {
continue
}
root.AddCommand(cmd)
}
}
type baseCmd struct {
cmd *cobra.Command
}
var _ commandsBuilderGetter = (*baseBuilderCmd)(nil)
// Used in tests.
type commandsBuilderGetter interface {
getCmmandsBuilder() *commandsBuilder
}
type baseBuilderCmd struct {
*baseCmd
*commandsBuilder
}
func (b *baseBuilderCmd) getCmmandsBuilder() *commandsBuilder {
return b.commandsBuilder
}
func (c *baseCmd) getCommand() *cobra.Command {
return c.cmd
}
func newBaseCmd(cmd *cobra.Command) *baseCmd {
return &baseCmd{cmd: cmd}
}
func (b *commandsBuilder) newBuilderCmd(cmd *cobra.Command) *baseBuilderCmd {
bcmd := &baseBuilderCmd{commandsBuilder: b, baseCmd: &baseCmd{cmd: cmd}}
bcmd.hugoBuilderCommon.handleFlags(cmd)
return bcmd
}
func (c *baseCmd) flagsToConfig(cfg config.Provider) {
initializeFlags(c.cmd, cfg)
}
type hugoCmd struct {
*baseBuilderCmd
// Need to get the sites once built.
c *commandeer
}
var _ cmder = (*nilCommand)(nil)
type nilCommand struct {
}
func (c *nilCommand) getCommand() *cobra.Command {
return nil
}
func (c *nilCommand) flagsToConfig(cfg config.Provider) {
}
func (b *commandsBuilder) newHugoCmd() *hugoCmd {
cc := &hugoCmd{}
cc.baseBuilderCmd = b.newBuilderCmd(&cobra.Command{
Use: "hugo",
Short: "hugo builds your site",
Long: `hugo is the main command, used to build your Hugo site.
Hugo is a Fast and Flexible Static Site Generator
built with love by spf13 and friends in Go.
Complete documentation is available at http://gohugo.io/.`,
RunE: func(cmd *cobra.Command, args []string) error {
cfgInit := func(c *commandeer) error {
if cc.buildWatch {
c.Set("disableLiveReload", true)
}
return nil
}
c, err := initializeConfig(cc.buildWatch, &cc.hugoBuilderCommon, cc, cfgInit)
if err != nil {
return err
}
cc.c = c
return c.build()
},
})
cc.cmd.PersistentFlags().StringVar(&cc.cfgFile, "config", "", "config file (default is path/config.yaml|json|toml)")
cc.cmd.PersistentFlags().BoolVar(&cc.quiet, "quiet", false, "build in quiet mode")
// Set bash-completion
validConfigFilenames := []string{"json", "js", "yaml", "yml", "toml", "tml"}
_ = cc.cmd.PersistentFlags().SetAnnotation("config", cobra.BashCompFilenameExt, validConfigFilenames)
cc.cmd.PersistentFlags().BoolVarP(&cc.verbose, "verbose", "v", false, "verbose output")
cc.cmd.PersistentFlags().BoolVarP(&cc.debug, "debug", "", false, "debug output")
cc.cmd.PersistentFlags().BoolVar(&cc.logging, "log", false, "enable Logging")
cc.cmd.PersistentFlags().StringVar(&cc.logFile, "logFile", "", "log File path (if set, logging enabled automatically)")
cc.cmd.PersistentFlags().BoolVar(&cc.verboseLog, "verboseLog", false, "verbose logging")
cc.cmd.Flags().BoolVarP(&cc.buildWatch, "watch", "w", false, "watch filesystem for changes and recreate as needed")
cc.cmd.Flags().Bool("renderToMemory", false, "render to memory (only useful for benchmark testing)")
// Set bash-completion
_ = cc.cmd.PersistentFlags().SetAnnotation("logFile", cobra.BashCompFilenameExt, []string{})
cc.cmd.SetGlobalNormalizationFunc(helpers.NormalizeHugoFlags)
cc.cmd.SilenceUsage = true
return cc
}
type hugoBuilderCommon struct {
source string
baseURL string
buildWatch bool
gc bool
// TODO(bep) var vs string
logging bool
verbose bool
verboseLog bool
debug bool
quiet bool
cfgFile string
logFile string
}
func (cc *hugoBuilderCommon) handleFlags(cmd *cobra.Command) {
cmd.Flags().Bool("cleanDestinationDir", false, "remove files from destination not found in static directories")
cmd.Flags().BoolP("buildDrafts", "D", false, "include content marked as draft")
cmd.Flags().BoolP("buildFuture", "F", false, "include content with publishdate in the future")
cmd.Flags().BoolP("buildExpired", "E", false, "include expired content")
cmd.Flags().StringVarP(&cc.source, "source", "s", "", "filesystem path to read files relative from")
cmd.Flags().StringP("contentDir", "c", "", "filesystem path to content directory")
cmd.Flags().StringP("layoutDir", "l", "", "filesystem path to layout directory")
cmd.Flags().StringP("cacheDir", "", "", "filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/")
cmd.Flags().BoolP("ignoreCache", "", false, "ignores the cache directory")
cmd.Flags().StringP("destination", "d", "", "filesystem path to write files to")
cmd.Flags().StringP("theme", "t", "", "theme to use (located in /themes/THEMENAME/)")
cmd.Flags().StringP("themesDir", "", "", "filesystem path to themes directory")
cmd.Flags().Bool("uglyURLs", false, "(deprecated) if true, use /filename.html instead of /filename/")
cmd.Flags().Bool("canonifyURLs", false, "(deprecated) if true, all relative URLs will be canonicalized using baseURL")
cmd.Flags().StringVarP(&cc.baseURL, "baseURL", "b", "", "hostname (and path) to the root, e.g. http://spf13.com/")
cmd.Flags().Bool("enableGitInfo", false, "add Git revision, date and author info to the pages")
cmd.Flags().BoolVar(&cc.gc, "gc", false, "enable to run some cleanup tasks (remove unused cache files) after the build")
cmd.Flags().BoolVar(&nitro.AnalysisOn, "stepAnalysis", false, "display memory and timing of different steps of the program")
cmd.Flags().Bool("templateMetrics", false, "display metrics about template executions")
cmd.Flags().Bool("templateMetricsHints", false, "calculate some improvement hints when combined with --templateMetrics")
cmd.Flags().Bool("pluralizeListTitles", true, "(deprecated) pluralize titles in lists using inflect")
cmd.Flags().Bool("preserveTaxonomyNames", false, `(deprecated) preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")`)
cmd.Flags().BoolP("forceSyncStatic", "", false, "copy all files when static is changed.")
cmd.Flags().BoolP("noTimes", "", false, "don't sync modification time of files")
cmd.Flags().BoolP("noChmod", "", false, "don't sync permission mode of files")
cmd.Flags().BoolP("i18n-warnings", "", false, "print missing translations")
cmd.Flags().StringSlice("disableKinds", []string{}, "disable different kind of pages (home, RSS etc.)")
// Set bash-completion.
// Each flag must first be defined before using the SetAnnotation() call.
_ = cmd.Flags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{})
_ = cmd.Flags().SetAnnotation("cacheDir", cobra.BashCompSubdirsInDir, []string{})
_ = cmd.Flags().SetAnnotation("destination", cobra.BashCompSubdirsInDir, []string{})
_ = cmd.Flags().SetAnnotation("theme", cobra.BashCompSubdirsInDir, []string{"themes"})
}
+253
View File
@@ -0,0 +1,253 @@
// Copyright 2018 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 (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
)
func TestExecute(t *testing.T) {
assert := require.New(t)
dir, err := createSimpleTestSite(t)
assert.NoError(err)
defer func() {
os.RemoveAll(dir)
}()
resp := Execute([]string{"-s=" + dir})
assert.NoError(resp.Err)
result := resp.Result
assert.True(len(result.Sites) == 1)
assert.True(len(result.Sites[0].RegularPages) == 1)
}
func TestCommandsPersistentFlags(t *testing.T) {
assert := require.New(t)
noOpRunE := func(cmd *cobra.Command, args []string) error {
return nil
}
tests := []struct {
args []string
check func(command []cmder)
}{{[]string{"server",
"--config=myconfig.toml",
"--contentDir=mycontent",
"--disableKinds=page,home",
"--layoutDir=mylayouts",
"--theme=mytheme",
"--gc",
"--themesDir=mythemes",
"--cleanDestinationDir",
"--navigateToChanged",
"--disableLiveReload",
"--noHTTPCache",
"--i18n-warnings",
"--destination=/tmp/mydestination",
"-b=https://example.com/b/",
"--port=1366",
"--renderToDisk",
"--source=mysource",
"--uglyURLs"}, func(commands []cmder) {
var sc *serverCmd
for _, command := range commands {
if b, ok := command.(commandsBuilderGetter); ok {
v := b.getCmmandsBuilder().hugoBuilderCommon
assert.Equal("myconfig.toml", v.cfgFile)
assert.Equal("mysource", v.source)
assert.Equal("https://example.com/b/", v.baseURL)
}
if srvCmd, ok := command.(*serverCmd); ok {
sc = srvCmd
}
}
assert.NotNil(sc)
assert.True(sc.navigateToChanged)
assert.True(sc.disableLiveReload)
assert.True(sc.noHTTPCache)
assert.True(sc.renderToDisk)
assert.Equal(1366, sc.serverPort)
cfg := viper.New()
sc.flagsToConfig(cfg)
assert.Equal("/tmp/mydestination", cfg.GetString("publishDir"))
assert.Equal("mycontent", cfg.GetString("contentDir"))
assert.Equal("mylayouts", cfg.GetString("layoutDir"))
assert.Equal("mytheme", cfg.GetString("theme"))
assert.Equal("mythemes", cfg.GetString("themesDir"))
assert.Equal("https://example.com/b/", cfg.GetString("baseURL"))
assert.Equal([]string{"page", "home"}, cfg.Get("disableKinds"))
assert.True(cfg.GetBool("uglyURLs"))
assert.True(cfg.GetBool("gc"))
// The flag is named i18n-warnings
assert.True(cfg.GetBool("logI18nWarnings"))
}}}
for _, test := range tests {
b := newCommandsBuilder()
root := b.addAll().build()
for _, c := range b.commands {
if c.getCommand() == nil {
continue
}
// We are only intereseted in the flag handling here.
c.getCommand().RunE = noOpRunE
}
rootCmd := root.getCommand()
rootCmd.SetArgs(test.args)
assert.NoError(rootCmd.Execute())
test.check(b.commands)
}
}
func TestCommandsExecute(t *testing.T) {
assert := require.New(t)
dir, err := createSimpleTestSite(t)
assert.NoError(err)
dirOut, err := ioutil.TempDir("", "hugo-cli-out")
assert.NoError(err)
defer func() {
os.RemoveAll(dir)
os.RemoveAll(dirOut)
}()
sourceFlag := fmt.Sprintf("-s=%s", dir)
tests := []struct {
commands []string
flags []string
expectErrToContain string
}{
// TODO(bep) permission issue on my OSX? "operation not permitted" {[]string{"check", "ulimit"}, nil, false},
{[]string{"env"}, nil, ""},
{[]string{"version"}, nil, ""},
// no args = hugo build
{nil, []string{sourceFlag}, ""},
{nil, []string{sourceFlag, "--renderToMemory"}, ""},
{[]string{"config"}, []string{sourceFlag}, ""},
{[]string{"benchmark"}, []string{sourceFlag, "-n=1"}, ""},
{[]string{"convert", "toTOML"}, []string{sourceFlag, "-o=" + filepath.Join(dirOut, "toml")}, ""},
{[]string{"convert", "toYAML"}, []string{sourceFlag, "-o=" + filepath.Join(dirOut, "yaml")}, ""},
{[]string{"convert", "toJSON"}, []string{sourceFlag, "-o=" + filepath.Join(dirOut, "json")}, ""},
{[]string{"gen", "autocomplete"}, []string{"--completionfile=" + filepath.Join(dirOut, "autocomplete.txt")}, ""},
{[]string{"gen", "chromastyles"}, []string{"--style=manni"}, ""},
{[]string{"gen", "doc"}, []string{"--dir=" + filepath.Join(dirOut, "doc")}, ""},
{[]string{"gen", "man"}, []string{"--dir=" + filepath.Join(dirOut, "man")}, ""},
{[]string{"list", "drafts"}, []string{sourceFlag}, ""},
{[]string{"list", "expired"}, []string{sourceFlag}, ""},
{[]string{"list", "future"}, []string{sourceFlag}, ""},
{[]string{"new", "new-page.md"}, []string{sourceFlag}, ""},
{[]string{"new", "site", filepath.Join(dirOut, "new-site")}, nil, ""},
{[]string{"unknowncommand"}, nil, "unknown command"},
// TODO(bep) cli refactor fix https://github.com/gohugoio/hugo/issues/4450
//{[]string{"new", "theme", filepath.Join(dirOut, "new-theme")}, nil,false},
}
for _, test := range tests {
hugoCmd := newCommandsBuilder().addAll().build().getCommand()
test.flags = append(test.flags, "--quiet")
hugoCmd.SetArgs(append(test.commands, test.flags...))
// TODO(bep) capture output and add some simple asserts
// TODO(bep) misspelled subcommands does not return an error. We should investigate this
// but before that, check for "Error: unknown command".
_, err := hugoCmd.ExecuteC()
if test.expectErrToContain != "" {
assert.Error(err, fmt.Sprintf("%v", test.commands))
assert.Contains(err.Error(), test.expectErrToContain)
} else {
assert.NoError(err, fmt.Sprintf("%v", test.commands))
}
}
}
func createSimpleTestSite(t *testing.T) (string, error) {
d, e := ioutil.TempDir("", "hugo-cli")
if e != nil {
return "", e
}
// Just the basic. These are for CLI tests, not site testing.
writeFile(t, filepath.Join(d, "config.toml"), `
baseURL = "https://example.org"
title = "Hugo Commands"
`)
writeFile(t, filepath.Join(d, "content", "p1.md"), `
---
title: "P1"
weight: 1
---
Content
`)
writeFile(t, filepath.Join(d, "layouts", "_default", "single.html"), `
Single: {{ .Title }}
`)
writeFile(t, filepath.Join(d, "layouts", "_default", "list.html"), `
List: {{ .Title }}
`)
return d, nil
}
func writeFile(t *testing.T, filename, content string) {
must(t, os.MkdirAll(filepath.Dir(filename), os.FileMode(0755)))
must(t, ioutil.WriteFile(filename, []byte(content), os.FileMode(0755)))
}
func must(t *testing.T, err error) {
if err != nil {
t.Fatal(err)
}
}
+19 -8
View File
@@ -22,18 +22,29 @@ import (
"github.com/spf13/viper"
)
var configCmd = &cobra.Command{
Use: "config",
Short: "Print the site configuration",
Long: `Print the site configuration, both default and custom settings.`,
var _ cmder = (*configCmd)(nil)
type configCmd struct {
hugoBuilderCommon
*baseCmd
}
func init() {
configCmd.RunE = printConfig
func newConfigCmd() *configCmd {
cc := &configCmd{}
cc.baseCmd = newBaseCmd(&cobra.Command{
Use: "config",
Short: "Print the site configuration",
Long: `Print the site configuration, both default and custom settings.`,
RunE: cc.printConfig,
})
cc.cmd.Flags().StringVarP(&cc.source, "source", "s", "", "filesystem path to read files relative from")
return cc
}
func printConfig(cmd *cobra.Command, args []string) error {
cfg, err := InitializeConfig(false, nil, configCmd)
func (c *configCmd) printConfig(cmd *cobra.Command, args []string) error {
cfg, err := initializeConfig(false, &c.hugoBuilderCommon, c, nil)
if err != nil {
return err
+62 -51
View File
@@ -28,64 +28,75 @@ import (
"github.com/spf13/cobra"
)
var outputDir string
var unsafe bool
var (
_ cmder = (*convertCmd)(nil)
)
var convertCmd = &cobra.Command{
Use: "convert",
Short: "Convert your content to different formats",
Long: `Convert your content (e.g. front matter) to different formats.
type convertCmd struct {
hugoBuilderCommon
outputDir string
unsafe bool
*baseCmd
}
func newConvertCmd() *convertCmd {
cc := &convertCmd{}
cc.baseCmd = newBaseCmd(&cobra.Command{
Use: "convert",
Short: "Convert your content to different formats",
Long: `Convert your content (e.g. front matter) to different formats.
See convert's subcommands toJSON, toTOML and toYAML for more information.`,
RunE: nil,
}
RunE: nil,
})
var toJSONCmd = &cobra.Command{
Use: "toJSON",
Short: "Convert front matter to JSON",
Long: `toJSON converts all front matter in the content directory
cc.cmd.AddCommand(
&cobra.Command{
Use: "toJSON",
Short: "Convert front matter to JSON",
Long: `toJSON converts all front matter in the content directory
to use JSON for the front matter.`,
RunE: func(cmd *cobra.Command, args []string) error {
return convertContents(rune([]byte(parser.JSONLead)[0]))
},
}
var toTOMLCmd = &cobra.Command{
Use: "toTOML",
Short: "Convert front matter to TOML",
Long: `toTOML converts all front matter in the content directory
RunE: func(cmd *cobra.Command, args []string) error {
return cc.convertContents(rune([]byte(parser.JSONLead)[0]))
},
},
&cobra.Command{
Use: "toTOML",
Short: "Convert front matter to TOML",
Long: `toTOML converts all front matter in the content directory
to use TOML for the front matter.`,
RunE: func(cmd *cobra.Command, args []string) error {
return convertContents(rune([]byte(parser.TOMLLead)[0]))
},
}
var toYAMLCmd = &cobra.Command{
Use: "toYAML",
Short: "Convert front matter to YAML",
Long: `toYAML converts all front matter in the content directory
RunE: func(cmd *cobra.Command, args []string) error {
return cc.convertContents(rune([]byte(parser.TOMLLead)[0]))
},
},
&cobra.Command{
Use: "toYAML",
Short: "Convert front matter to YAML",
Long: `toYAML converts all front matter in the content directory
to use YAML for the front matter.`,
RunE: func(cmd *cobra.Command, args []string) error {
return convertContents(rune([]byte(parser.YAMLLead)[0]))
},
RunE: func(cmd *cobra.Command, args []string) error {
return cc.convertContents(rune([]byte(parser.YAMLLead)[0]))
},
},
)
cc.cmd.PersistentFlags().StringVarP(&cc.outputDir, "output", "o", "", "filesystem path to write files to")
cc.cmd.PersistentFlags().StringVarP(&cc.source, "source", "s", "", "filesystem path to read files relative from")
cc.cmd.PersistentFlags().BoolVar(&cc.unsafe, "unsafe", false, "enable less safe operations, please backup first")
cc.cmd.PersistentFlags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{})
return cc
}
func init() {
convertCmd.AddCommand(toJSONCmd)
convertCmd.AddCommand(toTOMLCmd)
convertCmd.AddCommand(toYAMLCmd)
convertCmd.PersistentFlags().StringVarP(&outputDir, "output", "o", "", "filesystem path to write files to")
convertCmd.PersistentFlags().StringVarP(&source, "source", "s", "", "filesystem path to read files relative from")
convertCmd.PersistentFlags().BoolVar(&unsafe, "unsafe", false, "enable less safe operations, please backup first")
convertCmd.PersistentFlags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{})
}
func convertContents(mark rune) error {
if outputDir == "" && !unsafe {
func (cc *convertCmd) convertContents(mark rune) error {
if cc.outputDir == "" && !cc.unsafe {
return newUserError("Unsafe operation not allowed, use --unsafe or set a different output path")
}
c, err := InitializeConfig(false, nil)
c, err := initializeConfig(false, &cc.hugoBuilderCommon, cc, nil)
if err != nil {
return err
}
@@ -103,17 +114,17 @@ func convertContents(mark rune) error {
site.Log.FEEDBACK.Println("processing", len(site.AllPages), "content files")
for _, p := range site.AllPages {
if err := convertAndSavePage(p, site, mark); err != nil {
if err := cc.convertAndSavePage(p, site, mark); err != nil {
return err
}
}
return nil
}
func convertAndSavePage(p *hugolib.Page, site *hugolib.Site, mark rune) error {
func (cc *convertCmd) convertAndSavePage(p *hugolib.Page, site *hugolib.Site, mark rune) error {
// The resources are not in .Site.AllPages.
for _, r := range p.Resources.ByType("page") {
if err := convertAndSavePage(r.(*hugolib.Page), site, mark); err != nil {
if err := cc.convertAndSavePage(r.(*hugolib.Page), site, mark); err != nil {
return err
}
}
@@ -171,8 +182,8 @@ func convertAndSavePage(p *hugolib.Page, site *hugolib.Site, mark rune) error {
}
newFilename := p.Filename()
if outputDir != "" {
newFilename = filepath.Join(outputDir, p.Dir(), newPage.LogicalName())
if cc.outputDir != "" {
newFilename = filepath.Join(cc.outputDir, p.Dir(), newPage.LogicalName())
}
if err = newPage.SaveSourceAs(newFilename); err != nil {
+20 -11
View File
@@ -20,16 +20,25 @@ import (
jww "github.com/spf13/jwalterweatherman"
)
var envCmd = &cobra.Command{
Use: "env",
Short: "Print Hugo version and environment info",
Long: `Print Hugo version and environment info. This is useful in Hugo bug reports.`,
RunE: func(cmd *cobra.Command, args []string) error {
printHugoVersion()
jww.FEEDBACK.Printf("GOOS=%q\n", runtime.GOOS)
jww.FEEDBACK.Printf("GOARCH=%q\n", runtime.GOARCH)
jww.FEEDBACK.Printf("GOVERSION=%q\n", runtime.Version())
var _ cmder = (*envCmd)(nil)
return nil
},
type envCmd struct {
*baseCmd
}
func newEnvCmd() *envCmd {
return &envCmd{baseCmd: newBaseCmd(&cobra.Command{
Use: "env",
Short: "Print Hugo version and environment info",
Long: `Print Hugo version and environment info. This is useful in Hugo bug reports.`,
RunE: func(cmd *cobra.Command, args []string) error {
printHugoVersion()
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
},
}),
}
}
+21 -3
View File
@@ -17,7 +17,25 @@ import (
"github.com/spf13/cobra"
)
var genCmd = &cobra.Command{
Use: "gen",
Short: "A collection of several useful generators.",
var _ cmder = (*genCmd)(nil)
type genCmd struct {
*baseCmd
}
func newGenCmd() *genCmd {
cc := &genCmd{}
cc.baseCmd = newBaseCmd(&cobra.Command{
Use: "gen",
Short: "A collection of several useful generators.",
})
cc.cmd.AddCommand(
newGenautocompleteCmd().getCommand(),
newGenDocCmd().getCommand(),
newGenManCmd().getCommand(),
createGenDocsHelper().getCommand(),
createGenChromaStyles().getCommand())
return cc
}
+33 -23
View File
@@ -18,15 +18,24 @@ import (
jww "github.com/spf13/jwalterweatherman"
)
var autocompleteTarget string
var _ cmder = (*genautocompleteCmd)(nil)
// bash for now (zsh and others will come)
var autocompleteType string
type genautocompleteCmd struct {
autocompleteTarget string
var genautocompleteCmd = &cobra.Command{
Use: "autocomplete",
Short: "Generate shell autocompletion script for Hugo",
Long: `Generates a shell autocompletion script for Hugo.
// bash for now (zsh and others will come)
autocompleteType string
*baseCmd
}
func newGenautocompleteCmd() *genautocompleteCmd {
cc := &genautocompleteCmd{}
cc.baseCmd = newBaseCmd(&cobra.Command{
Use: "autocomplete",
Short: "Generate shell autocompletion script for Hugo",
Long: `Generates a shell autocompletion script for Hugo.
NOTE: The current version supports Bash only.
This should work for *nix systems with Bash installed.
@@ -44,27 +53,28 @@ or just source them in directly:
$ . /etc/bash_completion`,
RunE: func(cmd *cobra.Command, args []string) error {
if autocompleteType != "bash" {
return newUserError("Only Bash is supported for now")
}
RunE: func(cmd *cobra.Command, args []string) error {
if cc.autocompleteType != "bash" {
return newUserError("Only Bash is supported for now")
}
err := cmd.Root().GenBashCompletionFile(autocompleteTarget)
err := cmd.Root().GenBashCompletionFile(cc.autocompleteTarget)
if err != nil {
return err
}
if err != nil {
return err
}
jww.FEEDBACK.Println("Bash completion file for Hugo saved to", autocompleteTarget)
jww.FEEDBACK.Println("Bash completion file for Hugo saved to", cc.autocompleteTarget)
return nil
},
}
return nil
},
})
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)")
cc.cmd.PersistentFlags().StringVarP(&cc.autocompleteTarget, "completionfile", "", "/etc/bash_completion.d/hugo.sh", "autocompletion file")
cc.cmd.PersistentFlags().StringVarP(&cc.autocompleteType, "type", "", "bash", "autocompletion type (currently only bash supported)")
// For bash-completion
genautocompleteCmd.PersistentFlags().SetAnnotation("completionfile", cobra.BashCompFilenameExt, []string{})
cc.cmd.PersistentFlags().SetAnnotation("completionfile", cobra.BashCompFilenameExt, []string{})
return cc
}
+7 -3
View File
@@ -22,23 +22,27 @@ import (
"github.com/spf13/cobra"
)
var (
_ cmder = (*genChromaStyles)(nil)
)
type genChromaStyles struct {
style string
highlightStyle string
linesStyle string
cmd *cobra.Command
*baseCmd
}
// TODO(bep) highlight
func createGenChromaStyles() *genChromaStyles {
g := &genChromaStyles{
cmd: &cobra.Command{
baseCmd: newBaseCmd(&cobra.Command{
Use: "chromastyles",
Short: "Generate CSS stylesheet for the Chroma code highlighter",
Long: `Generate CSS stylesheet for the Chroma code highlighter for a given style. This stylesheet is needed if pygmentsUseClasses is enabled in config.
See https://help.farbox.com/pygments.html for preview of available styles`,
},
}),
}
g.cmd.RunE = func(cmd *cobra.Command, args []string) error {
+45 -35
View File
@@ -27,7 +27,15 @@ import (
jww "github.com/spf13/jwalterweatherman"
)
const gendocFrontmatterTemplate = `---
var _ cmder = (*genDocCmd)(nil)
type genDocCmd struct {
gendocdir string
*baseCmd
}
func newGenDocCmd() *genDocCmd {
const gendocFrontmatterTemplate = `---
date: %s
title: "%s"
slug: %s
@@ -35,11 +43,12 @@ url: %s
---
`
var gendocdir string
var gendocCmd = &cobra.Command{
Use: "doc",
Short: "Generate Markdown documentation for the Hugo CLI.",
Long: `Generate Markdown documentation for the Hugo CLI.
cc := &genDocCmd{}
cc.baseCmd = newBaseCmd(&cobra.Command{
Use: "doc",
Short: "Generate Markdown documentation for the Hugo CLI.",
Long: `Generate Markdown documentation for the Hugo CLI.
This command is, mostly, used to create up-to-date documentation
of Hugo's command-line interface for http://gohugo.io/.
@@ -47,40 +56,41 @@ of Hugo's command-line interface for http://gohugo.io/.
It creates one Markdown file per command with front matter suitable
for rendering in Hugo.`,
RunE: func(cmd *cobra.Command, args []string) error {
if !strings.HasSuffix(gendocdir, helpers.FilePathSeparator) {
gendocdir += helpers.FilePathSeparator
}
if found, _ := helpers.Exists(gendocdir, hugofs.Os); !found {
jww.FEEDBACK.Println("Directory", gendocdir, "does not exist, creating...")
if err := hugofs.Os.MkdirAll(gendocdir, 0777); err != nil {
return err
RunE: func(cmd *cobra.Command, args []string) error {
if !strings.HasSuffix(cc.gendocdir, helpers.FilePathSeparator) {
cc.gendocdir += helpers.FilePathSeparator
}
if found, _ := helpers.Exists(cc.gendocdir, hugofs.Os); !found {
jww.FEEDBACK.Println("Directory", cc.gendocdir, "does not exist, creating...")
if err := hugofs.Os.MkdirAll(cc.gendocdir, 0777); err != nil {
return err
}
}
now := time.Now().Format("2006-01-02")
prepender := func(filename string) string {
name := filepath.Base(filename)
base := strings.TrimSuffix(name, path.Ext(name))
url := "/commands/" + strings.ToLower(base) + "/"
return fmt.Sprintf(gendocFrontmatterTemplate, now, strings.Replace(base, "_", " ", -1), base, url)
}
}
now := time.Now().Format(time.RFC3339)
prepender := func(filename string) string {
name := filepath.Base(filename)
base := strings.TrimSuffix(name, path.Ext(name))
url := "/commands/" + strings.ToLower(base) + "/"
return fmt.Sprintf(gendocFrontmatterTemplate, now, strings.Replace(base, "_", " ", -1), base, url)
}
linkHandler := func(name string) string {
base := strings.TrimSuffix(name, path.Ext(name))
return "/commands/" + strings.ToLower(base) + "/"
}
linkHandler := func(name string) string {
base := strings.TrimSuffix(name, path.Ext(name))
return "/commands/" + strings.ToLower(base) + "/"
}
jww.FEEDBACK.Println("Generating Hugo command-line documentation in", gendocdir, "...")
doc.GenMarkdownTreeCustom(cmd.Root(), gendocdir, prepender, linkHandler)
jww.FEEDBACK.Println("Done.")
jww.FEEDBACK.Println("Generating Hugo command-line documentation in", cc.gendocdir, "...")
doc.GenMarkdownTreeCustom(cmd.Root(), cc.gendocdir, prepender, linkHandler)
jww.FEEDBACK.Println("Done.")
return nil
},
}
return nil
},
})
func init() {
gendocCmd.PersistentFlags().StringVar(&gendocdir, "dir", "/tmp/hugodoc/", "the directory to write the doc.")
cc.cmd.PersistentFlags().StringVar(&cc.gendocdir, "dir", "/tmp/hugodoc/", "the directory to write the doc.")
// For bash-completion
gendocCmd.PersistentFlags().SetAnnotation("dir", cobra.BashCompSubdirsInDir, []string{})
cc.cmd.PersistentFlags().SetAnnotation("dir", cobra.BashCompSubdirsInDir, []string{})
return cc
}
+7 -3
View File
@@ -23,18 +23,22 @@ import (
"github.com/spf13/cobra"
)
var (
_ cmder = (*genDocsHelper)(nil)
)
type genDocsHelper struct {
target string
cmd *cobra.Command
*baseCmd
}
func createGenDocsHelper() *genDocsHelper {
g := &genDocsHelper{
cmd: &cobra.Command{
baseCmd: newBaseCmd(&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 {
+39 -29
View File
@@ -24,43 +24,53 @@ import (
jww "github.com/spf13/jwalterweatherman"
)
var genmandir string
var genmanCmd = &cobra.Command{
Use: "man",
Short: "Generate man pages for the Hugo CLI",
Long: `This command automatically generates up-to-date man pages of Hugo's
var _ cmder = (*genManCmd)(nil)
type genManCmd struct {
genmandir string
*baseCmd
}
func newGenManCmd() *genManCmd {
cc := &genManCmd{}
cc.baseCmd = newBaseCmd(&cobra.Command{
Use: "man",
Short: "Generate man pages for the Hugo CLI",
Long: `This command automatically generates up-to-date man pages of Hugo's
command-line interface. By default, it creates the man page files
in the "man" directory under the current directory.`,
RunE: func(cmd *cobra.Command, args []string) error {
header := &doc.GenManHeader{
Section: "1",
Manual: "Hugo Manual",
Source: fmt.Sprintf("Hugo %s", helpers.CurrentHugoVersion),
}
if !strings.HasSuffix(genmandir, helpers.FilePathSeparator) {
genmandir += helpers.FilePathSeparator
}
if found, _ := helpers.Exists(genmandir, hugofs.Os); !found {
jww.FEEDBACK.Println("Directory", genmandir, "does not exist, creating...")
if err := hugofs.Os.MkdirAll(genmandir, 0777); err != nil {
return err
RunE: func(cmd *cobra.Command, args []string) error {
header := &doc.GenManHeader{
Section: "1",
Manual: "Hugo Manual",
Source: fmt.Sprintf("Hugo %s", helpers.CurrentHugoVersion),
}
}
cmd.Root().DisableAutoGenTag = true
if !strings.HasSuffix(cc.genmandir, helpers.FilePathSeparator) {
cc.genmandir += helpers.FilePathSeparator
}
if found, _ := helpers.Exists(cc.genmandir, hugofs.Os); !found {
jww.FEEDBACK.Println("Directory", cc.genmandir, "does not exist, creating...")
if err := hugofs.Os.MkdirAll(cc.genmandir, 0777); err != nil {
return err
}
}
cmd.Root().DisableAutoGenTag = true
jww.FEEDBACK.Println("Generating Hugo man pages in", genmandir, "...")
doc.GenManTree(cmd.Root(), header, genmandir)
jww.FEEDBACK.Println("Generating Hugo man pages in", cc.genmandir, "...")
doc.GenManTree(cmd.Root(), header, cc.genmandir)
jww.FEEDBACK.Println("Done.")
jww.FEEDBACK.Println("Done.")
return nil
},
}
return nil
},
})
func init() {
genmanCmd.PersistentFlags().StringVar(&genmandir, "dir", "man/", "the directory to write the man pages.")
cc.cmd.PersistentFlags().StringVar(&cc.genmandir, "dir", "man/", "the directory to write the man pages.")
// For bash-completion
genmanCmd.PersistentFlags().SetAnnotation("dir", cobra.BashCompSubdirsInDir, []string{})
cc.cmd.PersistentFlags().SetAnnotation("dir", cobra.BashCompSubdirsInDir, []string{})
return cc
}
+79
View File
@@ -0,0 +1,79 @@
// Copyright 2018 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 defines and implements command-line commands and flags
// used by Hugo. Commands and flags are implemented using Cobra.
package commands
import (
"fmt"
"regexp"
"github.com/gohugoio/hugo/config"
"github.com/spf13/cobra"
)
const (
ansiEsc = "\u001B"
clearLine = "\r\033[K"
hideCursor = ansiEsc + "[?25l"
showCursor = ansiEsc + "[?25h"
)
type flagsToConfigHandler interface {
flagsToConfig(cfg config.Provider)
}
type cmder interface {
flagsToConfigHandler
getCommand() *cobra.Command
}
// commandError is an error used to signal different error situations in command handling.
type commandError struct {
s string
userError bool
}
func (c commandError) Error() string {
return c.s
}
func (c commandError) isUserError() bool {
return c.userError
}
func newUserError(a ...interface{}) commandError {
return commandError{s: fmt.Sprintln(a...), userError: true}
}
func newSystemError(a ...interface{}) commandError {
return commandError{s: fmt.Sprintln(a...), userError: false}
}
func newSystemErrorF(format string, a ...interface{}) commandError {
return commandError{s: fmt.Sprintf(format, a...), userError: false}
}
// Catch some of the obvious user errors from Cobra.
// We don't want to show the usage message for every error.
// The below may be to generic. Time will show.
var userErrorRegexp = regexp.MustCompile("argument|flag|shorthand")
func isUserError(err error) bool {
if cErr, ok := err.(commandError); ok && cErr.isUserError() {
return true
}
return userErrorRegexp.MatchString(err.Error())
}
+239 -465
View File
File diff suppressed because it is too large Load Diff
+40 -39
View File
@@ -35,33 +35,42 @@ import (
jww "github.com/spf13/jwalterweatherman"
)
func init() {
importCmd.AddCommand(importJekyllCmd)
var _ cmder = (*importCmd)(nil)
type importCmd struct {
*baseCmd
}
var importCmd = &cobra.Command{
Use: "import",
Short: "Import your site from others.",
Long: `Import your site from other web site generators like Jekyll.
func newImportCmd() *importCmd {
cc := &importCmd{}
cc.baseCmd = newBaseCmd(&cobra.Command{
Use: "import",
Short: "Import your site from others.",
Long: `Import your site from other web site generators like Jekyll.
Import requires a subcommand, e.g. ` + "`hugo import jekyll jekyll_root_path target_path`.",
RunE: nil,
}
RunE: nil,
})
var importJekyllCmd = &cobra.Command{
Use: "jekyll",
Short: "hugo import from Jekyll",
Long: `hugo import from Jekyll.
importJekyllCmd := &cobra.Command{
Use: "jekyll",
Short: "hugo import from Jekyll",
Long: `hugo import from Jekyll.
Import from Jekyll requires two paths, e.g. ` + "`hugo import jekyll jekyll_root_path target_path`.",
RunE: importFromJekyll,
}
RunE: cc.importFromJekyll,
}
func init() {
importJekyllCmd.Flags().Bool("force", false, "allow import into non-empty target directory")
cc.cmd.AddCommand(importJekyllCmd)
return cc
}
func importFromJekyll(cmd *cobra.Command, args []string) error {
func (i *importCmd) importFromJekyll(cmd *cobra.Command, args []string) error {
if len(args) < 2 {
return newUserError(`Import from Jekyll requires two paths, e.g. ` + "`hugo import jekyll jekyll_root_path target_path`.")
@@ -86,12 +95,12 @@ func importFromJekyll(cmd *cobra.Command, args []string) error {
forceImport, _ := cmd.Flags().GetBool("force")
fs := afero.NewOsFs()
jekyllPostDirs, hasAnyPost := getJekyllDirInfo(fs, jekyllRoot)
jekyllPostDirs, hasAnyPost := i.getJekyllDirInfo(fs, jekyllRoot)
if !hasAnyPost {
return errors.New("Your Jekyll root contains neither posts nor drafts, aborting.")
}
site, err := createSiteFromJekyll(jekyllRoot, targetDir, jekyllPostDirs, forceImport)
site, err := i.createSiteFromJekyll(jekyllRoot, targetDir, jekyllPostDirs, forceImport)
if err != nil {
return newUserError(err)
@@ -144,22 +153,17 @@ func importFromJekyll(cmd *cobra.Command, args []string) error {
"$ git clone https://github.com/spf13/herring-cove.git " + args[1] + "/themes/herring-cove")
jww.FEEDBACK.Println("$ cd " + args[1] + "\n$ hugo server --theme=herring-cove")
jww.FEEDBACK.Println("Congratulations!", fileCount, "post(s) imported!")
jww.FEEDBACK.Println("Now, start Hugo by yourself:\n" +
"$ git clone https://github.com/spf13/herring-cove.git " + args[1] + "/themes/herring-cove")
jww.FEEDBACK.Println("$ cd " + args[1] + "\n$ hugo server --theme=herring-cove")
return nil
}
func getJekyllDirInfo(fs afero.Fs, jekyllRoot string) (map[string]bool, bool) {
func (i *importCmd) getJekyllDirInfo(fs afero.Fs, jekyllRoot string) (map[string]bool, bool) {
postDirs := make(map[string]bool)
hasAnyPost := false
if entries, err := ioutil.ReadDir(jekyllRoot); err == nil {
for _, entry := range entries {
if entry.IsDir() {
subDir := filepath.Join(jekyllRoot, entry.Name())
if isPostDir, hasAnyPostInDir := retrieveJekyllPostDir(fs, subDir); isPostDir {
if isPostDir, hasAnyPostInDir := i.retrieveJekyllPostDir(fs, subDir); isPostDir {
postDirs[entry.Name()] = hasAnyPostInDir
if hasAnyPostInDir {
hasAnyPost = true
@@ -171,7 +175,7 @@ func getJekyllDirInfo(fs afero.Fs, jekyllRoot string) (map[string]bool, bool) {
return postDirs, hasAnyPost
}
func retrieveJekyllPostDir(fs afero.Fs, dir string) (bool, bool) {
func (i *importCmd) retrieveJekyllPostDir(fs afero.Fs, dir string) (bool, bool) {
if strings.HasSuffix(dir, "_posts") || strings.HasSuffix(dir, "_drafts") {
isEmpty, _ := helpers.IsEmpty(dir, fs)
return true, !isEmpty
@@ -181,7 +185,7 @@ func retrieveJekyllPostDir(fs afero.Fs, dir string) (bool, bool) {
for _, entry := range entries {
if entry.IsDir() {
subDir := filepath.Join(dir, entry.Name())
if isPostDir, hasAnyPost := retrieveJekyllPostDir(fs, subDir); isPostDir {
if isPostDir, hasAnyPost := i.retrieveJekyllPostDir(fs, subDir); isPostDir {
return isPostDir, hasAnyPost
}
}
@@ -191,7 +195,7 @@ func retrieveJekyllPostDir(fs afero.Fs, dir string) (bool, bool) {
return false, true
}
func createSiteFromJekyll(jekyllRoot, targetDir string, jekyllPostDirs map[string]bool, force bool) (*hugolib.Site, error) {
func (i *importCmd) createSiteFromJekyll(jekyllRoot, targetDir string, jekyllPostDirs map[string]bool, force bool) (*hugolib.Site, error) {
s, err := hugolib.NewSiteDefaultLang()
if err != nil {
return nil, err
@@ -210,7 +214,7 @@ func createSiteFromJekyll(jekyllRoot, targetDir string, jekyllPostDirs map[strin
}
}
jekyllConfig := loadJekyllConfig(fs, jekyllRoot)
jekyllConfig := i.loadJekyllConfig(fs, jekyllRoot)
mkdir(targetDir, "layouts")
mkdir(targetDir, "content")
@@ -219,14 +223,14 @@ func createSiteFromJekyll(jekyllRoot, targetDir string, jekyllPostDirs map[strin
mkdir(targetDir, "data")
mkdir(targetDir, "themes")
createConfigFromJekyll(fs, targetDir, "yaml", jekyllConfig)
i.createConfigFromJekyll(fs, targetDir, "yaml", jekyllConfig)
copyJekyllFilesAndFolders(jekyllRoot, filepath.Join(targetDir, "static"), jekyllPostDirs)
i.copyJekyllFilesAndFolders(jekyllRoot, filepath.Join(targetDir, "static"), jekyllPostDirs)
return s, nil
}
func loadJekyllConfig(fs afero.Fs, jekyllRoot string) map[string]interface{} {
func (i *importCmd) loadJekyllConfig(fs afero.Fs, jekyllRoot string) map[string]interface{} {
path := filepath.Join(jekyllRoot, "_config.yml")
exists, err := helpers.Exists(path, fs)
@@ -255,10 +259,10 @@ func loadJekyllConfig(fs afero.Fs, jekyllRoot string) map[string]interface{} {
return nil
}
return c.(map[string]interface{})
return c
}
func createConfigFromJekyll(fs afero.Fs, inpath string, kind string, jekyllConfig map[string]interface{}) (err error) {
func (i *importCmd) createConfigFromJekyll(fs afero.Fs, inpath string, kind string, jekyllConfig map[string]interface{}) (err error) {
title := "My New Hugo Site"
baseURL := "http://example.org/"
@@ -353,7 +357,7 @@ func copyDir(source string, dest string) error {
return nil
}
func copyJekyllFilesAndFolders(jekyllRoot, dest string, jekyllPostDirs map[string]bool) (err error) {
func (i *importCmd) copyJekyllFilesAndFolders(jekyllRoot, dest string, jekyllPostDirs map[string]bool) (err error) {
fi, err := os.Stat(jekyllRoot)
if err != nil {
return err
@@ -478,8 +482,6 @@ func convertJekyllPost(s *hugolib.Site, path, relPath, targetDir string, draft b
}
func convertJekyllMetaData(m interface{}, postName string, postDate time.Time, draft bool) (interface{}, error) {
url := postDate.Format("/2006/01/02/") + postName + "/"
metadata, err := cast.ToStringMapE(m)
if err != nil {
return nil, err
@@ -497,7 +499,7 @@ func convertJekyllMetaData(m interface{}, postName string, postDate time.Time, d
delete(metadata, key)
case "permalink":
if str, ok := value.(string); ok {
url = str
metadata["url"] = str
}
delete(metadata, key)
case "category":
@@ -526,7 +528,6 @@ func convertJekyllMetaData(m interface{}, postName string, postDate time.Time, d
}
metadata["url"] = url
metadata["date"] = postDate.Format(time.RFC3339)
return metadata, nil
+5 -5
View File
@@ -51,9 +51,9 @@ func TestConvertJekyllMetadata(t *testing.T) {
expect string
}{
{map[interface{}]interface{}{}, "testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
`{"date":"2015-10-01T00:00:00Z","url":"/2015/10/01/testPost/"}`},
`{"date":"2015-10-01T00:00:00Z"}`},
{map[interface{}]interface{}{}, "testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), true,
`{"date":"2015-10-01T00:00:00Z","draft":true,"url":"/2015/10/01/testPost/"}`},
`{"date":"2015-10-01T00:00:00Z","draft":true}`},
{map[interface{}]interface{}{"Permalink": "/permalink.html", "layout": "post"},
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
`{"date":"2015-10-01T00:00:00Z","url":"/permalink.html"}`},
@@ -62,13 +62,13 @@ func TestConvertJekyllMetadata(t *testing.T) {
`{"date":"2015-10-01T00:00:00Z","url":"/permalink.html"}`},
{map[interface{}]interface{}{"category": nil, "permalink": 123},
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
`{"date":"2015-10-01T00:00:00Z","url":"/2015/10/01/testPost/"}`},
`{"date":"2015-10-01T00:00:00Z"}`},
{map[interface{}]interface{}{"Excerpt_Separator": "sep"},
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
`{"date":"2015-10-01T00:00:00Z","excerpt_separator":"sep","url":"/2015/10/01/testPost/"}`},
`{"date":"2015-10-01T00:00:00Z","excerpt_separator":"sep"}`},
{map[interface{}]interface{}{"category": "book", "layout": "post", "Others": "Goods", "Date": "2015-10-01 12:13:11"},
"testPost", time.Date(2015, 10, 1, 0, 0, 0, 0, time.UTC), false,
`{"Others":"Goods","categories":["book"],"date":"2015-10-01T12:13:11Z","url":"/2015/10/01/testPost/"}`},
`{"Others":"Goods","categories":["book"],"date":"2015-10-01T12:13:11Z"}`},
}
for _, data := range testDataList {
+34 -41
View File
@@ -1,17 +1,4 @@
// 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.
// Copyright 2015 The Hugo Authors. All rights reserved.
// Copyright 2018 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.
@@ -33,39 +20,45 @@ import (
jww "github.com/spf13/jwalterweatherman"
)
func init() {
checkCmd.AddCommand(limit)
var _ cmder = (*limitCmd)(nil)
type limitCmd struct {
*baseCmd
}
var limit = &cobra.Command{
Use: "ulimit",
Short: "Check system ulimit settings",
Long: `Hugo will inspect the current ulimit settings on the system.
func newLimitCmd() *limitCmd {
ccmd := &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)
}
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("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)
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
},
return nil
},
}
return &limitCmd{baseCmd: newBaseCmd(ccmd)}
}
func tweakLimit() {
+1 -13
View File
@@ -1,4 +1,4 @@
// Copyright 2015 The Hugo Authors. All rights reserved.
// Copyright 2018 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.
@@ -12,18 +12,6 @@
// 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
+105 -97
View File
@@ -21,129 +21,137 @@ import (
jww "github.com/spf13/jwalterweatherman"
)
func init() {
listCmd.AddCommand(listDraftsCmd)
listCmd.AddCommand(listFutureCmd)
listCmd.AddCommand(listExpiredCmd)
listCmd.PersistentFlags().StringVarP(&source, "source", "s", "", "filesystem path to read files relative from")
listCmd.PersistentFlags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{})
var _ cmder = (*listCmd)(nil)
type listCmd struct {
hugoBuilderCommon
*baseCmd
}
var listCmd = &cobra.Command{
Use: "list",
Short: "Listing out various types of content",
Long: `Listing out various types of content.
func newListCmd() *listCmd {
cc := &listCmd{}
cc.baseCmd = newBaseCmd(&cobra.Command{
Use: "list",
Short: "Listing out various types of content",
Long: `Listing out various types of content.
List requires a subcommand, e.g. ` + "`hugo list drafts`.",
RunE: nil,
}
RunE: nil,
})
var listDraftsCmd = &cobra.Command{
Use: "drafts",
Short: "List all drafts",
Long: `List all of the drafts in your content directory.`,
RunE: func(cmd *cobra.Command, args []string) error {
cfgInit := func(c *commandeer) error {
c.Set("buildDrafts", true)
return nil
}
c, err := InitializeConfig(false, cfgInit)
if err != nil {
return err
}
cc.cmd.AddCommand(
&cobra.Command{
Use: "drafts",
Short: "List all drafts",
Long: `List all of the drafts in your content directory.`,
RunE: func(cmd *cobra.Command, args []string) error {
cfgInit := func(c *commandeer) error {
c.Set("buildDrafts", true)
return nil
}
c, err := initializeConfig(false, &cc.hugoBuilderCommon, cc, cfgInit)
if err != nil {
return err
}
sites, err := hugolib.NewHugoSites(*c.DepsCfg)
sites, err := hugolib.NewHugoSites(*c.DepsCfg)
if err != nil {
return newSystemError("Error creating sites", err)
}
if err != nil {
return newSystemError("Error creating sites", err)
}
if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
return newSystemError("Error Processing Source Content", err)
}
if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
return newSystemError("Error Processing Source Content", err)
}
for _, p := range sites.Pages() {
if p.IsDraft() {
jww.FEEDBACK.Println(filepath.Join(p.File.Dir(), p.File.LogicalName()))
}
for _, p := range sites.Pages() {
if p.IsDraft() {
jww.FEEDBACK.Println(filepath.Join(p.File.Dir(), p.File.LogicalName()))
}
}
}
return nil
return nil
},
}
var listFutureCmd = &cobra.Command{
Use: "future",
Short: "List all posts dated in the future",
Long: `List all of the posts in your content directory which will be
},
},
&cobra.Command{
Use: "future",
Short: "List all posts dated in the future",
Long: `List all of the posts in your content directory which will be
posted in the future.`,
RunE: func(cmd *cobra.Command, args []string) error {
cfgInit := func(c *commandeer) error {
c.Set("buildFuture", true)
return nil
}
c, err := InitializeConfig(false, cfgInit)
if err != nil {
return err
}
RunE: func(cmd *cobra.Command, args []string) error {
cfgInit := func(c *commandeer) error {
c.Set("buildFuture", true)
return nil
}
c, err := initializeConfig(false, &cc.hugoBuilderCommon, cc, cfgInit)
if err != nil {
return err
}
sites, err := hugolib.NewHugoSites(*c.DepsCfg)
sites, err := hugolib.NewHugoSites(*c.DepsCfg)
if err != nil {
return newSystemError("Error creating sites", err)
}
if err != nil {
return newSystemError("Error creating sites", err)
}
if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
return newSystemError("Error Processing Source Content", err)
}
if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
return newSystemError("Error Processing Source Content", err)
}
for _, p := range sites.Pages() {
if p.IsFuture() {
jww.FEEDBACK.Println(filepath.Join(p.File.Dir(), p.File.LogicalName()))
}
for _, p := range sites.Pages() {
if p.IsFuture() {
jww.FEEDBACK.Println(filepath.Join(p.File.Dir(), p.File.LogicalName()))
}
}
}
return nil
return nil
},
}
var listExpiredCmd = &cobra.Command{
Use: "expired",
Short: "List all posts already expired",
Long: `List all of the posts in your content directory which has already
},
},
&cobra.Command{
Use: "expired",
Short: "List all posts already expired",
Long: `List all of the posts in your content directory which has already
expired.`,
RunE: func(cmd *cobra.Command, args []string) error {
cfgInit := func(c *commandeer) error {
c.Set("buildExpired", true)
return nil
}
c, err := InitializeConfig(false, cfgInit)
if err != nil {
return err
}
RunE: func(cmd *cobra.Command, args []string) error {
cfgInit := func(c *commandeer) error {
c.Set("buildExpired", true)
return nil
}
c, err := initializeConfig(false, &cc.hugoBuilderCommon, cc, cfgInit)
if err != nil {
return err
}
sites, err := hugolib.NewHugoSites(*c.DepsCfg)
sites, err := hugolib.NewHugoSites(*c.DepsCfg)
if err != nil {
return newSystemError("Error creating sites", err)
}
if err != nil {
return newSystemError("Error creating sites", err)
}
if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
return newSystemError("Error Processing Source Content", err)
}
if err := sites.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
return newSystemError("Error Processing Source Content", err)
}
for _, p := range sites.Pages() {
if p.IsExpired() {
jww.FEEDBACK.Println(filepath.Join(p.File.Dir(), p.File.LogicalName()))
}
for _, p := range sites.Pages() {
if p.IsExpired() {
jww.FEEDBACK.Println(filepath.Join(p.File.Dir(), p.File.LogicalName()))
}
}
}
return nil
return nil
},
},
},
)
cc.cmd.PersistentFlags().StringVarP(&cc.source, "source", "s", "", "filesystem path to read files relative from")
cc.cmd.PersistentFlags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{})
return cc
}
+33 -247
View File
@@ -1,4 +1,4 @@
// Copyright 2016 The Hugo Authors. All rights reserved.
// Copyright 2018 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.
@@ -15,85 +15,63 @@ package commands
import (
"bytes"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"time"
"github.com/gohugoio/hugo/create"
"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/hugofs"
"github.com/gohugoio/hugo/hugolib"
"github.com/gohugoio/hugo/parser"
"github.com/spf13/afero"
"github.com/spf13/cobra"
jww "github.com/spf13/jwalterweatherman"
"github.com/spf13/viper"
)
var (
configFormat string
var _ cmder = (*newCmd)(nil)
type newCmd struct {
hugoBuilderCommon
contentEditor string
contentType string
)
func init() {
newSiteCmd.Flags().StringVarP(&configFormat, "format", "f", "toml", "config & frontmatter format")
newSiteCmd.Flags().Bool("force", false, "init inside non-empty directory")
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")
newCmd.AddCommand(newSiteCmd)
newCmd.AddCommand(newThemeCmd)
*baseCmd
}
var newCmd = &cobra.Command{
Use: "new [path]",
Short: "Create new content for your site",
Long: `Create a new content file and automatically set the date and title.
func newNewCmd() *newCmd {
cc := &newCmd{}
cc.baseCmd = newBaseCmd(&cobra.Command{
Use: "new [path]",
Short: "Create new content for your site",
Long: `Create a new content file and automatically set the date and title.
It will guess which kind of file to create based on the path provided.
You can also specify the kind with ` + "`-k KIND`" + `.
If archetypes are provided in your theme or site, they will be used.`,
RunE: NewContent,
RunE: cc.newContent,
})
cc.cmd.Flags().StringVarP(&cc.contentType, "kind", "k", "", "content type to create")
cc.cmd.PersistentFlags().StringVarP(&cc.source, "source", "s", "", "filesystem path to read files relative from")
cc.cmd.PersistentFlags().SetAnnotation("source", cobra.BashCompSubdirsInDir, []string{})
cc.cmd.Flags().StringVar(&cc.contentEditor, "editor", "", "edit new content with this editor, if provided")
cc.cmd.AddCommand(newNewSiteCmd().getCommand())
cc.cmd.AddCommand(newNewThemeCmd().getCommand())
return cc
}
var newSiteCmd = &cobra.Command{
Use: "site [path]",
Short: "Create a new site (skeleton)",
Long: `Create a new site in the provided directory.
The new site will have the correct structure, but no content or theme yet.
Use ` + "`hugo new [contentPath]`" + ` to create new content.`,
RunE: NewSite,
}
var newThemeCmd = &cobra.Command{
Use: "theme [name]",
Short: "Create a new theme",
Long: `Create a new theme (skeleton) called [name] in the current directory.
New theme is a skeleton. Please add content to the touched files. Add your
name to the copyright line in the license and adjust the theme.toml file
as you see fit.`,
RunE: NewTheme,
}
// NewContent adds new content to a Hugo site.
func NewContent(cmd *cobra.Command, args []string) error {
func (n *newCmd) newContent(cmd *cobra.Command, args []string) error {
cfgInit := func(c *commandeer) error {
if cmd.Flags().Changed("editor") {
c.Set("newContentEditor", contentEditor)
c.Set("newContentEditor", n.contentEditor)
}
return nil
}
c, err := InitializeConfig(false, cfgInit)
c, err := initializeConfig(false, &n.hugoBuilderCommon, n, cfgInit)
if err != nil {
return err
@@ -109,8 +87,8 @@ func NewContent(cmd *cobra.Command, args []string) error {
createPath, kind = newContentPathSection(createPath)
if contentType != "" {
kind = contentType
if n.contentType != "" {
kind = n.contentType
}
cfg := c.DepsCfg
@@ -130,15 +108,15 @@ func NewContent(cmd *cobra.Command, args []string) error {
return nil, err
}
if err := Hugo.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
if err := c.hugo.Build(hugolib.BuildCfg{SkipRender: true}); err != nil {
return nil, err
}
s = Hugo.Sites[0]
s = c.hugo.Sites[0]
if len(Hugo.Sites) > 1 {
if len(c.hugo.Sites) > 1 {
// Find the best match.
for _, ss := range Hugo.Sites {
for _, ss := range c.hugo.Sites {
if strings.Contains(createPath, "."+ss.Language.Lang) {
s = ss
break
@@ -151,56 +129,6 @@ func NewContent(cmd *cobra.Command, args []string) error {
return create.NewContent(ps, siteFactory, kind, createPath)
}
func doNewSite(fs *hugofs.Fs, basepath string, force bool) error {
archeTypePath := filepath.Join(basepath, "archetypes")
dirs := []string{
filepath.Join(basepath, "layouts"),
filepath.Join(basepath, "content"),
archeTypePath,
filepath.Join(basepath, "static"),
filepath.Join(basepath, "data"),
filepath.Join(basepath, "themes"),
}
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, fs.Source)
switch {
case !isEmpty && !force:
return errors.New(basepath + " already exists and is not empty")
case !isEmpty && force:
all := append(dirs, filepath.Join(basepath, "config."+configFormat))
for _, path := range all {
if exists, _ := helpers.Exists(path, fs.Source); exists {
return errors.New(path + " already exists")
}
}
}
}
for _, dir := range dirs {
if err := fs.Source.MkdirAll(dir, 0777); err != nil {
return fmt.Errorf("Failed to create dir: %s", err)
}
}
createConfig(fs, basepath, configFormat)
// Create a defaul archetype file.
helpers.SafeWriteToDisk(filepath.Join(archeTypePath, "default.md"),
strings.NewReader(create.ArchetypeTemplateTemplate), fs.Source)
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
@@ -222,98 +150,6 @@ Visit https://gohugo.io/ for quickstart guide and full documentation.`)
return nextStepsText.String()
}
// NewSite creates a new Hugo site and initializes a structured Hugo directory.
func NewSite(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return newUserError("path needs to be provided")
}
createpath, err := filepath.Abs(filepath.Clean(args[0]))
if err != nil {
return newUserError(err)
}
forceNew, _ := cmd.Flags().GetBool("force")
return doNewSite(hugofs.NewDefault(viper.New()), createpath, forceNew)
}
// NewTheme creates a new Hugo theme.
func NewTheme(cmd *cobra.Command, args []string) error {
c, err := InitializeConfig(false, nil)
if err != nil {
return err
}
if len(args) < 1 {
return newUserError("theme name needs to be provided")
}
createpath := c.PathSpec().AbsPathify(filepath.Join(c.Cfg.GetString("themesDir"), args[0]))
jww.INFO.Println("creating theme at", createpath)
cfg := c.DepsCfg
if x, _ := helpers.Exists(createpath, cfg.Fs.Source); x {
return newUserError(createpath, "already exists")
}
mkdir(createpath, "layouts", "_default")
mkdir(createpath, "layouts", "partials")
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(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), cfg.Fs.Source)
if err != nil {
return err
}
mkdir(createpath, "static", "js")
mkdir(createpath, "static", "css")
by := []byte(`The MIT License (MIT)
Copyright (c) ` + time.Now().Format("2006") + ` YOUR_NAME_HERE
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
`)
err = helpers.WriteToDisk(filepath.Join(createpath, "LICENSE.md"), bytes.NewReader(by), cfg.Fs.Source)
if err != nil {
return err
}
createThemeMD(cfg.Fs, createpath)
return nil
}
func mkdir(x ...string) {
p := filepath.Join(x...)
@@ -332,39 +168,6 @@ func touchFile(fs afero.Fs, x ...string) {
}
}
func createThemeMD(fs *hugofs.Fs, inpath string) (err error) {
by := []byte(`# theme.toml template for a Hugo theme
# See https://github.com/gohugoio/hugoThemes#themetoml for an example
name = "` + strings.Title(helpers.MakeTitle(filepath.Base(inpath))) + `"
license = "MIT"
licenselink = "https://github.com/yourname/yourtheme/blob/master/LICENSE.md"
description = ""
homepage = "http://example.com/"
tags = []
features = []
min_version = "0.32"
[author]
name = ""
homepage = ""
# If porting an existing theme
[original]
name = ""
homepage = ""
repo = ""
`)
err = helpers.WriteToDisk(filepath.Join(inpath, "theme.toml"), bytes.NewReader(by), fs.Source)
if err != nil {
return
}
return nil
}
func newContentPathSection(path string) (string, string) {
// Forward slashes is used in all examples. Convert if needed.
// Issue #1133
@@ -381,20 +184,3 @@ func newContentPathSection(path string) (string, string) {
return createpath, section
}
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)
var buf bytes.Buffer
err = parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind), &buf)
if err != nil {
return err
}
return helpers.WriteToDisk(filepath.Join(inpath, "config."+kind), &buf, fs.Source)
}
@@ -1,4 +1,4 @@
// Copyright 2016 The Hugo Authors. All rights reserved.
// Copyright 2018 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.
@@ -48,10 +48,11 @@ func checkNewSiteInited(fs *hugofs.Fs, basepath string, t *testing.T) {
}
func TestDoNewSite(t *testing.T) {
n := newNewSiteCmd()
basepath := filepath.Join("base", "blog")
_, fs := newTestCfg()
require.NoError(t, doNewSite(fs, basepath, false))
require.NoError(t, n.doNewSite(fs, basepath, false))
checkNewSiteInited(fs, basepath, t)
}
@@ -59,31 +60,34 @@ func TestDoNewSite(t *testing.T) {
func TestDoNewSite_noerror_base_exists_but_empty(t *testing.T) {
basepath := filepath.Join("base", "blog")
_, fs := newTestCfg()
n := newNewSiteCmd()
require.NoError(t, fs.Source.MkdirAll(basepath, 777))
require.NoError(t, doNewSite(fs, basepath, false))
require.NoError(t, n.doNewSite(fs, basepath, false))
}
func TestDoNewSite_error_base_exists(t *testing.T) {
basepath := filepath.Join("base", "blog")
_, fs := newTestCfg()
n := newNewSiteCmd()
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
require.Error(t, doNewSite(fs, basepath, false))
require.Error(t, n.doNewSite(fs, basepath, false))
}
func TestDoNewSite_force_empty_dir(t *testing.T) {
basepath := filepath.Join("base", "blog")
_, fs := newTestCfg()
n := newNewSiteCmd()
require.NoError(t, fs.Source.MkdirAll(basepath, 777))
require.NoError(t, doNewSite(fs, basepath, true))
require.NoError(t, n.doNewSite(fs, basepath, true))
checkNewSiteInited(fs, basepath, t)
}
@@ -91,23 +95,25 @@ func TestDoNewSite_force_empty_dir(t *testing.T) {
func TestDoNewSite_error_force_dir_inside_exists(t *testing.T) {
basepath := filepath.Join("base", "blog")
_, fs := newTestCfg()
n := newNewSiteCmd()
contentPath := filepath.Join(basepath, "content")
require.NoError(t, fs.Source.MkdirAll(contentPath, 777))
require.Error(t, doNewSite(fs, basepath, true))
require.Error(t, n.doNewSite(fs, basepath, true))
}
func TestDoNewSite_error_force_config_inside_exists(t *testing.T) {
basepath := filepath.Join("base", "blog")
_, fs := newTestCfg()
n := newNewSiteCmd()
configPath := filepath.Join(basepath, "config.toml")
require.NoError(t, fs.Source.MkdirAll(basepath, 777))
_, err := fs.Source.Create(configPath)
require.NoError(t, err)
require.Error(t, doNewSite(fs, basepath, true))
require.Error(t, n.doNewSite(fs, basepath, true))
}
func newTestCfg() (*viper.Viper, *hugofs.Fs) {
+148
View File
@@ -0,0 +1,148 @@
// Copyright 2018 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package commands
import (
"bytes"
"path/filepath"
"github.com/spf13/viper"
"errors"
"github.com/gohugoio/hugo/create"
"fmt"
"strings"
"github.com/gohugoio/hugo/parser"
"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/hugofs"
"github.com/spf13/cobra"
jww "github.com/spf13/jwalterweatherman"
)
var _ cmder = (*newSiteCmd)(nil)
type newSiteCmd struct {
configFormat string
*baseCmd
}
func newNewSiteCmd() *newSiteCmd {
ccmd := &newSiteCmd{}
cmd := &cobra.Command{
Use: "site [path]",
Short: "Create a new site (skeleton)",
Long: `Create a new site in the provided directory.
The new site will have the correct structure, but no content or theme yet.
Use ` + "`hugo new [contentPath]`" + ` to create new content.`,
RunE: ccmd.newSite,
}
cmd.Flags().StringVarP(&ccmd.configFormat, "format", "f", "toml", "config & frontmatter format")
cmd.Flags().Bool("force", false, "init inside non-empty directory")
ccmd.baseCmd = newBaseCmd(cmd)
return ccmd
}
func (n *newSiteCmd) doNewSite(fs *hugofs.Fs, basepath string, force bool) error {
archeTypePath := filepath.Join(basepath, "archetypes")
dirs := []string{
filepath.Join(basepath, "layouts"),
filepath.Join(basepath, "content"),
archeTypePath,
filepath.Join(basepath, "static"),
filepath.Join(basepath, "data"),
filepath.Join(basepath, "themes"),
}
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, fs.Source)
switch {
case !isEmpty && !force:
return errors.New(basepath + " already exists and is not empty")
case !isEmpty && force:
all := append(dirs, filepath.Join(basepath, "config."+n.configFormat))
for _, path := range all {
if exists, _ := helpers.Exists(path, fs.Source); exists {
return errors.New(path + " already exists")
}
}
}
}
for _, dir := range dirs {
if err := fs.Source.MkdirAll(dir, 0777); err != nil {
return fmt.Errorf("Failed to create dir: %s", err)
}
}
createConfig(fs, basepath, n.configFormat)
// Create a defaul archetype file.
helpers.SafeWriteToDisk(filepath.Join(archeTypePath, "default.md"),
strings.NewReader(create.ArchetypeTemplateTemplate), fs.Source)
jww.FEEDBACK.Printf("Congratulations! Your new Hugo site is created in %s.\n\n", basepath)
jww.FEEDBACK.Println(nextStepsText())
return nil
}
// newSite creates a new Hugo site and initializes a structured Hugo directory.
func (n *newSiteCmd) newSite(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return newUserError("path needs to be provided")
}
createpath, err := filepath.Abs(filepath.Clean(args[0]))
if err != nil {
return newUserError(err)
}
forceNew, _ := cmd.Flags().GetBool("force")
return n.doNewSite(hugofs.NewDefault(viper.New()), createpath, forceNew)
}
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)
var buf bytes.Buffer
err = parser.InterfaceToConfig(in, parser.FormatToLeadRune(kind), &buf)
if err != nil {
return err
}
return helpers.WriteToDisk(filepath.Join(inpath, "config."+kind), &buf, fs.Source)
}
+162
View File
@@ -0,0 +1,162 @@
// Copyright 2018 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 (
"path/filepath"
"bytes"
"strings"
"time"
"github.com/gohugoio/hugo/hugofs"
"github.com/gohugoio/hugo/helpers"
"github.com/spf13/cobra"
jww "github.com/spf13/jwalterweatherman"
)
var _ cmder = (*newThemeCmd)(nil)
type newThemeCmd struct {
*baseCmd
hugoBuilderCommon
}
func newNewThemeCmd() *newThemeCmd {
ccmd := &newThemeCmd{baseCmd: newBaseCmd(nil)}
cmd := &cobra.Command{
Use: "theme [name]",
Short: "Create a new theme",
Long: `Create a new theme (skeleton) called [name] in the current directory.
New theme is a skeleton. Please add content to the touched files. Add your
name to the copyright line in the license and adjust the theme.toml file
as you see fit.`,
RunE: ccmd.newTheme,
}
ccmd.cmd = cmd
return ccmd
}
func (n *newThemeCmd) newTheme(cmd *cobra.Command, args []string) error {
c, err := initializeConfig(false, &n.hugoBuilderCommon, n, nil)
if err != nil {
return err
}
if len(args) < 1 {
return newUserError("theme name needs to be provided")
}
createpath := c.PathSpec().AbsPathify(filepath.Join(c.Cfg.GetString("themesDir"), args[0]))
jww.INFO.Println("creating theme at", createpath)
cfg := c.DepsCfg
if x, _ := helpers.Exists(createpath, cfg.Fs.Source); x {
return newUserError(createpath, "already exists")
}
mkdir(createpath, "layouts", "_default")
mkdir(createpath, "layouts", "partials")
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(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), cfg.Fs.Source)
if err != nil {
return err
}
mkdir(createpath, "static", "js")
mkdir(createpath, "static", "css")
by := []byte(`The MIT License (MIT)
Copyright (c) ` + time.Now().Format("2006") + ` YOUR_NAME_HERE
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
`)
err = helpers.WriteToDisk(filepath.Join(createpath, "LICENSE.md"), bytes.NewReader(by), cfg.Fs.Source)
if err != nil {
return err
}
n.createThemeMD(cfg.Fs, createpath)
return nil
}
func (n *newThemeCmd) createThemeMD(fs *hugofs.Fs, inpath string) (err error) {
by := []byte(`# theme.toml template for a Hugo theme
# See https://github.com/gohugoio/hugoThemes#themetoml for an example
name = "` + strings.Title(helpers.MakeTitle(filepath.Base(inpath))) + `"
license = "MIT"
licenselink = "https://github.com/yourname/yourtheme/blob/master/LICENSE.md"
description = ""
homepage = "http://example.com/"
tags = []
features = []
min_version = "0.38"
[author]
name = ""
homepage = ""
# If porting an existing theme
[original]
name = ""
homepage = ""
repo = ""
`)
err = helpers.WriteToDisk(filepath.Join(inpath, "theme.toml"), bytes.NewReader(by), fs.Source)
if err != nil {
return
}
return nil
}
+11 -4
View File
@@ -18,13 +18,12 @@ package commands
import (
"errors"
"github.com/gohugoio/hugo/config"
"github.com/gohugoio/hugo/releaser"
"github.com/spf13/cobra"
)
func init() {
HugoCmd.AddCommand(createReleaser().cmd)
}
var _ cmder = (*releaseCommandeer)(nil)
type releaseCommandeer struct {
cmd *cobra.Command
@@ -35,7 +34,7 @@ type releaseCommandeer struct {
try bool
}
func createReleaser() *releaseCommandeer {
func createReleaser() cmder {
// 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{
@@ -57,6 +56,14 @@ func createReleaser() *releaseCommandeer {
return r
}
func (c *releaseCommandeer) getCommand() *cobra.Command {
return c.cmd
}
func (c *releaseCommandeer) flagsToConfig(cfg config.Provider) {
}
func (r *releaseCommandeer) release() error {
if r.version == "" {
return errors.New("must set the --rel flag to the relevant version number")
+20
View File
@@ -0,0 +1,20 @@
// +build !release
// Copyright 2018 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 createReleaser() cmder {
return &nilCommand{}
}
+149 -100
View File
@@ -1,4 +1,4 @@
// Copyright 2016 The Hugo Authors. All rights reserved.
// Copyright 2018 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.
@@ -19,10 +19,13 @@ import (
"net/http"
"net/url"
"os"
"os/signal"
"path/filepath"
"runtime"
"strconv"
"strings"
"sync"
"syscall"
"time"
"github.com/gohugoio/hugo/livereload"
@@ -35,7 +38,10 @@ import (
jww "github.com/spf13/jwalterweatherman"
)
var (
type serverCmd struct {
// Can be used to stop the server. Useful in tests
stop <-chan bool
disableLiveReload bool
navigateToChanged bool
renderToDisk bool
@@ -47,13 +53,22 @@ var (
noHTTPCache bool
disableFastRender bool
)
var serverCmd = &cobra.Command{
Use: "server",
Aliases: []string{"serve"},
Short: "A high performance webserver",
Long: `Hugo provides its own webserver which builds and serves the site.
*baseBuilderCmd
}
func (b *commandsBuilder) newServerCmd() *serverCmd {
return b.newServerCmdSignaled(nil)
}
func (b *commandsBuilder) newServerCmdSignaled(stop <-chan bool) *serverCmd {
cc := &serverCmd{stop: stop}
cc.baseBuilderCmd = b.newBuilderCmd(&cobra.Command{
Use: "server",
Aliases: []string{"serve"},
Short: "A high performance webserver",
Long: `Hugo provides its own webserver which builds and serves the site.
While hugo server is high performance, it is a webserver with limited options.
Many run it in production, but the standard behavior is for people to use it
in development and use a more full featured server such as Nginx or Caddy.
@@ -65,7 +80,24 @@ By default hugo will also watch your files for any changes you make and
automatically rebuild the site. It will then live reload any open browser pages
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.`,
//RunE: server,
RunE: cc.server,
})
cc.cmd.Flags().IntVarP(&cc.serverPort, "port", "p", 1313, "port on which the server will listen")
cc.cmd.Flags().IntVar(&cc.liveReloadPort, "liveReloadPort", -1, "port for live reloading (i.e. 443 in HTTPS proxy situations)")
cc.cmd.Flags().StringVarP(&cc.serverInterface, "bind", "", "127.0.0.1", "interface to which the server will bind")
cc.cmd.Flags().BoolVarP(&cc.serverWatch, "watch", "w", true, "watch filesystem for changes and recreate as needed")
cc.cmd.Flags().BoolVar(&cc.noHTTPCache, "noHTTPCache", false, "prevent HTTP caching")
cc.cmd.Flags().BoolVarP(&cc.serverAppend, "appendPort", "", true, "append port to baseURL")
cc.cmd.Flags().BoolVar(&cc.disableLiveReload, "disableLiveReload", false, "watch without enabling live browser reload on rebuild")
cc.cmd.Flags().BoolVar(&cc.navigateToChanged, "navigateToChanged", false, "navigate to changed content file on live browser reload")
cc.cmd.Flags().BoolVar(&cc.renderToDisk, "renderToDisk", false, "render to Destination path (default is render to memory & serve from there)")
cc.cmd.Flags().BoolVar(&cc.disableFastRender, "disableFastRender", false, "enables full re-renders on changes")
cc.cmd.Flags().String("memstats", "", "log memory usage to this file")
cc.cmd.Flags().String("meminterval", "100ms", "interval to poll memory usage (requires --memstats), valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".")
return cc
}
type filesOnlyFs struct {
@@ -88,106 +120,105 @@ func (f noDirFile) Readdir(count int) ([]os.FileInfo, error) {
return nil, nil
}
func init() {
initHugoBuilderFlags(serverCmd)
var serverPorts []int
serverCmd.Flags().IntVarP(&serverPort, "port", "p", 1313, "port on which the server will listen")
serverCmd.Flags().IntVar(&liveReloadPort, "liveReloadPort", -1, "port for live reloading (i.e. 443 in HTTPS proxy situations)")
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().BoolVar(&noHTTPCache, "noHTTPCache", false, "prevent HTTP caching")
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(&navigateToChanged, "navigateToChanged", false, "navigate to changed content file on live browser reload")
serverCmd.Flags().BoolVar(&renderToDisk, "renderToDisk", false, "render to Destination path (default is render to memory & serve from there)")
serverCmd.Flags().BoolVar(&disableFastRender, "disableFastRender", false, "enables full re-renders on changes")
serverCmd.Flags().String("memstats", "", "log memory usage to this file")
serverCmd.Flags().String("meminterval", "100ms", "interval to poll memory usage (requires --memstats), valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".")
serverCmd.RunE = server
}
func server(cmd *cobra.Command, args []string) error {
func (s *serverCmd) server(cmd *cobra.Command, args []string) error {
// If a Destination is provided via flag write to disk
destination, _ := cmd.Flags().GetString("destination")
if destination != "" {
renderToDisk = true
s.renderToDisk = true
}
var serverCfgInit sync.Once
cfgInit := func(c *commandeer) error {
c.Set("renderToMemory", !renderToDisk)
c.Set("renderToMemory", !s.renderToDisk)
if cmd.Flags().Changed("navigateToChanged") {
c.Set("navigateToChanged", navigateToChanged)
c.Set("navigateToChanged", s.navigateToChanged)
}
if cmd.Flags().Changed("disableLiveReload") {
c.Set("disableLiveReload", disableLiveReload)
c.Set("disableLiveReload", s.disableLiveReload)
}
if cmd.Flags().Changed("disableFastRender") {
c.Set("disableFastRender", disableFastRender)
c.Set("disableFastRender", s.disableFastRender)
}
if serverWatch {
if s.serverWatch {
c.Set("watch", true)
}
serverPorts := make([]int, 1)
if c.languages.IsMultihost() {
if !serverAppend {
return newSystemError("--appendPort=false not supported when in multihost mode")
}
serverPorts = make([]int, len(c.languages))
// TODO(bep) yes, we should fix.
if !c.languagesConfigured {
return nil
}
currentServerPort := serverPort
var err error
for i := 0; i < len(serverPorts); i++ {
l, err := net.Listen("tcp", net.JoinHostPort(serverInterface, strconv.Itoa(currentServerPort)))
if err == nil {
l.Close()
serverPorts[i] = currentServerPort
} else {
if i == 0 && serverCmd.Flags().Changed("port") {
// port set explicitly by user -- he/she probably meant it!
return newSystemErrorF("Server startup failed: %s", err)
// We can only do this once.
serverCfgInit.Do(func() {
serverPorts = make([]int, 1)
if c.languages.IsMultihost() {
if !s.serverAppend {
err = newSystemError("--appendPort=false not supported when in multihost mode")
}
jww.ERROR.Println("port", serverPort, "already in use, attempting to use an available port")
sp, err := helpers.FindAvailablePort()
if err != nil {
return newSystemError("Unable to find alternative port to use:", err)
}
serverPorts[i] = sp.Port
serverPorts = make([]int, len(c.languages))
}
currentServerPort = serverPorts[i] + 1
}
currentServerPort := s.serverPort
for i := 0; i < len(serverPorts); i++ {
l, err := net.Listen("tcp", net.JoinHostPort(s.serverInterface, strconv.Itoa(currentServerPort)))
if err == nil {
l.Close()
serverPorts[i] = currentServerPort
} else {
if i == 0 && s.cmd.Flags().Changed("port") {
// port set explicitly by user -- he/she probably meant it!
err = newSystemErrorF("Server startup failed: %s", err)
}
jww.ERROR.Println("port", s.serverPort, "already in use, attempting to use an available port")
sp, err := helpers.FindAvailablePort()
if err != nil {
err = newSystemError("Unable to find alternative port to use:", err)
}
serverPorts[i] = sp.Port
}
currentServerPort = serverPorts[i] + 1
}
})
c.serverPorts = serverPorts
c.Set("port", serverPort)
if liveReloadPort != -1 {
c.Set("liveReloadPort", liveReloadPort)
c.Set("port", s.serverPort)
if s.liveReloadPort != -1 {
c.Set("liveReloadPort", s.liveReloadPort)
} else {
c.Set("liveReloadPort", serverPorts[0])
}
if c.languages.IsMultihost() {
for i, language := range c.languages {
baseURL, err := fixURL(language, baseURL, serverPorts[i])
if err != nil {
return err
}
isMultiHost := c.languages.IsMultihost()
for i, language := range c.languages {
var serverPort int
if isMultiHost {
serverPort = serverPorts[i]
} else {
serverPort = serverPorts[0]
}
baseURL, err := s.fixURL(language, s.baseURL, serverPort)
if err != nil {
return nil
}
if isMultiHost {
language.Set("baseURL", baseURL)
}
} else {
baseURL, err := fixURL(c.Cfg, baseURL, serverPorts[0])
if err != nil {
return err
if i == 0 {
c.Set("baseURL", baseURL)
}
c.Set("baseURL", baseURL)
}
return nil
return err
}
@@ -195,25 +226,21 @@ func server(cmd *cobra.Command, args []string) error {
jww.ERROR.Println("memstats error:", err)
}
c, err := InitializeConfig(true, cfgInit, serverCmd)
c, err := initializeConfig(true, &s.hugoBuilderCommon, s, cfgInit)
if err != nil {
return err
}
if err := c.build(serverWatch); err != nil {
if err := c.serverBuild(); err != nil {
return err
}
for _, s := range Hugo.Sites {
for _, s := range c.hugo.Sites {
s.RegisterMediaTypes()
}
if serverWatch {
c.watchConfig()
}
// Watch runs its own server as part of the routine
if serverWatch {
if s.serverWatch {
watchDirs, err := c.getDirList()
if err != nil {
@@ -229,20 +256,25 @@ func server(cmd *cobra.Command, args []string) error {
rootWatchDirs := strings.Join(helpers.UniqueStrings(helpers.ExtractRootPaths(relWatchDirs)), ",")
jww.FEEDBACK.Printf("Watching for changes in %s%s{%s}\n", baseWatchDir, helpers.FilePathSeparator, rootWatchDirs)
err = c.newWatcher(true, watchDirs...)
watcher, err := c.newWatcher(watchDirs...)
if err != nil {
return err
}
defer watcher.Close()
}
return nil
return c.serve(s)
}
type fileServer struct {
baseURLs []string
roots []string
c *commandeer
s *serverCmd
}
func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, error) {
@@ -259,7 +291,7 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, erro
absPublishDir := f.c.PathSpec().AbsPathify(publishDir)
if i == 0 {
if renderToDisk {
if f.s.renderToDisk {
jww.FEEDBACK.Println("Serving pages from " + absPublishDir)
} else {
jww.FEEDBACK.Println("Serving pages from memory")
@@ -269,7 +301,7 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, erro
httpFs := afero.NewHttpFs(f.c.Fs.Destination)
fs := filesOnlyFs{httpFs.Dir(absPublishDir)}
doLiveReload := !buildWatch && !f.c.Cfg.GetBool("disableLiveReload")
doLiveReload := !f.s.buildWatch && !f.c.Cfg.GetBool("disableLiveReload")
fastRenderMode := doLiveReload && !f.c.Cfg.GetBool("disableFastRender")
if i == 0 && fastRenderMode {
@@ -284,7 +316,7 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, erro
decorate := func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if noHTTPCache {
if f.s.noHTTPCache {
w.Header().Set("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0")
w.Header().Set("Pragma", "no-cache")
}
@@ -308,14 +340,14 @@ func (f *fileServer) createEndpoint(i int) (*http.ServeMux, string, string, erro
mu.Handle(u.Path, http.StripPrefix(u.Path, fileserver))
}
endpoint := net.JoinHostPort(serverInterface, strconv.Itoa(port))
endpoint := net.JoinHostPort(f.s.serverInterface, strconv.Itoa(port))
return mu, u.String(), endpoint, nil
}
func (c *commandeer) serve() {
func (c *commandeer) serve(s *serverCmd) error {
isMultiHost := Hugo.IsMultihost()
isMultiHost := c.hugo.IsMultihost()
var (
baseURLs []string
@@ -323,12 +355,12 @@ func (c *commandeer) serve() {
)
if isMultiHost {
for _, s := range Hugo.Sites {
for _, s := range c.hugo.Sites {
baseURLs = append(baseURLs, s.BaseURL.String())
roots = append(roots, s.Language.Lang)
}
} else {
s := Hugo.Sites[0]
s := c.hugo.Sites[0]
baseURLs = []string{s.BaseURL.String()}
roots = []string{""}
}
@@ -337,6 +369,7 @@ func (c *commandeer) serve() {
baseURLs: baseURLs,
roots: roots,
c: c,
s: s,
}
doLiveReload := !c.Cfg.GetBool("disableLiveReload")
@@ -345,14 +378,17 @@ func (c *commandeer) serve() {
livereload.Initialize()
}
for i, _ := range baseURLs {
var sigs = make(chan os.Signal)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
for i := range baseURLs {
mu, serverURL, endpoint, err := srv.createEndpoint(i)
if doLiveReload {
mu.HandleFunc("/livereload.js", livereload.ServeJS)
mu.HandleFunc("/livereload", livereload.Handler)
}
jww.FEEDBACK.Printf("Web Server is available at %s (bind address %s)\n", serverURL, serverInterface)
jww.FEEDBACK.Printf("Web Server is available at %s (bind address %s)\n", serverURL, s.serverInterface)
go func() {
err = http.ListenAndServe(endpoint, mu)
if err != nil {
@@ -363,11 +399,22 @@ func (c *commandeer) serve() {
}
jww.FEEDBACK.Println("Press Ctrl+C to stop")
if s.stop != nil {
select {
case <-sigs:
case <-s.stop:
}
} else {
<-sigs
}
return nil
}
// fixURL massages the baseURL into a form needed for serving
// all pages correctly.
func fixURL(cfg config.Provider, s string, port int) (string, error) {
func (sc *serverCmd) fixURL(cfg config.Provider, s string, port int) (string, error) {
useLocalhost := false
if s == "" {
s = cfg.GetString("baseURL")
@@ -402,7 +449,7 @@ func fixURL(cfg config.Provider, s string, port int) (string, error) {
u.Host = "localhost"
}
if serverAppend {
if sc.serverAppend {
if strings.Contains(u.Host, ":") {
u.Host, _, err = net.SplitHostPort(u.Host)
if err != nil {
@@ -416,9 +463,11 @@ func fixURL(cfg config.Provider, s string, port int) (string, error) {
}
func memStats() error {
memstats := serverCmd.Flags().Lookup("memstats").Value.String()
b := newCommandsBuilder()
sc := b.newServerCmd().getCommand()
memstats := sc.Flags().Lookup("memstats").Value.String()
if memstats != "" {
interval, err := time.ParseDuration(serverCmd.Flags().Lookup("meminterval").Value.String())
interval, err := time.ParseDuration(sc.Flags().Lookup("meminterval").Value.String())
if err != nil {
interval, _ = time.ParseDuration("100ms")
}
+55 -4
View File
@@ -14,11 +14,60 @@
package commands
import (
"fmt"
"net/http"
"os"
"testing"
"time"
"github.com/gohugoio/hugo/helpers"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
)
func TestServer(t *testing.T) {
assert := require.New(t)
dir, err := createSimpleTestSite(t)
assert.NoError(err)
// Let us hope that this port is available on all systems ...
port := 1331
defer func() {
os.RemoveAll(dir)
}()
stop := make(chan bool)
b := newCommandsBuilder()
scmd := b.newServerCmdSignaled(stop)
cmd := scmd.getCommand()
cmd.SetArgs([]string{"-s=" + dir, fmt.Sprintf("-p=%d", port)})
go func() {
_, err = cmd.ExecuteC()
assert.NoError(err)
}()
// There is no way to know exactly when the server is ready for connections.
// We could improve by something like https://golang.org/pkg/net/http/httptest/#Server
// But for now, let us sleep and pray!
time.Sleep(2 * time.Second)
resp, err := http.Get("http://localhost:1331/")
assert.NoError(err)
defer resp.Body.Close()
homeContent := helpers.ReaderToString(resp.Body)
assert.Contains(homeContent, "List: Hugo Commands")
// Stop the server.
stop <- true
}
func TestFixURL(t *testing.T) {
type data struct {
TestName string
@@ -42,12 +91,14 @@ func TestFixURL(t *testing.T) {
}
for i, test := range tests {
b := newCommandsBuilder()
s := b.newServerCmd()
v := viper.New()
baseURL = test.CLIBaseURL
baseURL := test.CLIBaseURL
v.Set("baseURL", test.CfgBaseURL)
serverAppend = test.AppendPort
serverPort = test.Port
result, err := fixURL(v, baseURL, serverPort)
s.serverAppend = test.AppendPort
s.serverPort = test.Port
result, err := s.fixURL(v, baseURL, s.serverPort)
if err != nil {
t.Errorf("Test #%d %s: unexpected error %s", i, test.TestName, err)
}
-157
View File
@@ -1,157 +0,0 @@
// Copyright 2015 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package commands
import (
"bytes"
"errors"
"os"
"time"
"github.com/gohugoio/hugo/parser"
"github.com/spf13/cobra"
)
var undraftCmd = &cobra.Command{
Use: "undraft path/to/content",
Short: "Undraft resets the content's draft status",
Long: `Undraft resets the content's draft status
and updates the date to the current date and time.
If the content's draft status is 'False', nothing is done.`,
RunE: Undraft,
}
// Undraft publishes the specified content by setting its draft status
// to false and setting its publish date to now. If the specified content is
// not a draft, it will log an error.
func Undraft(cmd *cobra.Command, args []string) error {
c, err := InitializeConfig(false, nil)
if err != nil {
return err
}
if len(args) < 1 {
return newUserError("a piece of content needs to be specified")
}
cfg := c.DepsCfg
location := args[0]
// open the file
f, err := cfg.Fs.Source.Open(location)
if err != nil {
return err
}
// get the page from file
p, err := parser.ReadFrom(f)
f.Close()
if err != nil {
return err
}
w, err := undraftContent(p)
if err != nil {
return newSystemErrorF("an error occurred while undrafting %q: %s", location, err)
}
f, err = cfg.Fs.Source.OpenFile(location, os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
return newSystemErrorF("%q not be undrafted due to error opening file to save changes: %q\n", location, err)
}
defer f.Close()
_, err = w.WriteTo(f)
if err != nil {
return newSystemErrorF("%q not be undrafted due to save error: %q\n", location, err)
}
return nil
}
// undraftContent: if the content is a draft, change its draft status to
// 'false' and set the date to time.Now(). If the draft status is already
// 'false', don't do anything.
func undraftContent(p parser.Page) (bytes.Buffer, error) {
var buff bytes.Buffer
// get the metadata; easiest way to see if it's a draft
meta, err := p.Metadata()
if err != nil {
return buff, err
}
// since the metadata was obtainable, we can also get the key/value separator for
// Front Matter
fm := p.FrontMatter()
if fm == nil {
return buff, errors.New("Front Matter was found, nothing was finalized")
}
var isDraft, gotDate bool
var date string
L:
for k, v := range meta.(map[string]interface{}) {
switch k {
case "draft":
if !v.(bool) {
return buff, errors.New("not a Draft: nothing was done")
}
isDraft = true
if gotDate {
break L
}
case "date":
date = v.(string) // capture the value to make replacement easier
gotDate = true
if isDraft {
break L
}
}
}
// if draft wasn't found in FrontMatter, it isn't a draft.
if !isDraft {
return buff, errors.New("not a Draft: nothing was done")
}
// get the front matter as bytes and split it into lines
var lineEnding []byte
fmLines := bytes.Split(fm, []byte("\n"))
if len(fmLines) == 1 { // if the result is only 1 element, try to split on dos line endings
fmLines = bytes.Split(fm, []byte("\r\n"))
if len(fmLines) == 1 {
return buff, errors.New("unable to split FrontMatter into lines")
}
lineEnding = append(lineEnding, []byte("\r\n")...)
} else {
lineEnding = append(lineEnding, []byte("\n")...)
}
// Write the front matter lines to the buffer, replacing as necessary
for _, v := range fmLines {
pos := bytes.Index(v, []byte("draft"))
if pos != -1 {
continue
}
pos = bytes.Index(v, []byte("date"))
if pos != -1 { // if date field wasn't found, add it
v = bytes.Replace(v, []byte(date), []byte(time.Now().Format(time.RFC3339)), 1)
}
buff.Write(v)
buff.Write(lineEnding)
}
// append the actual content
buff.Write(p.Content())
return buff, nil
}
-87
View File
@@ -1,87 +0,0 @@
// Copyright 2015 The Hugo Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package commands
// TODO Support Mac Encoding (\r)
import (
"bytes"
"strings"
"testing"
"time"
"github.com/gohugoio/hugo/parser"
)
var (
jsonFM = "{\n \"date\": \"12-04-06\",\n \"title\": \"test json\"\n}"
jsonDraftFM = "{\n \"draft\": true,\n \"date\": \"12-04-06\",\n \"title\":\"test json\"\n}"
tomlFM = "+++\n date= \"12-04-06\"\n title= \"test toml\"\n+++"
tomlDraftFM = "+++\n draft= true\n date= \"12-04-06\"\n title=\"test toml\"\n+++"
yamlFM = "---\n date: \"12-04-06\"\n title: \"test yaml\"\n---"
yamlDraftFM = "---\n draft: true\n date: \"12-04-06\"\n title: \"test yaml\"\n---"
yamlYesDraftFM = "---\n draft: yes\n date: \"12-04-06\"\n title: \"test yaml\"\n---"
)
func TestUndraftContent(t *testing.T) {
tests := []struct {
fm string
expectedErr string
}{
{jsonFM, "not a Draft: nothing was done"},
{jsonDraftFM, ""},
{tomlFM, "not a Draft: nothing was done"},
{tomlDraftFM, ""},
{yamlFM, "not a Draft: nothing was done"},
{yamlDraftFM, ""},
{yamlYesDraftFM, ""},
}
for i, test := range tests {
r := bytes.NewReader([]byte(test.fm))
p, _ := parser.ReadFrom(r)
res, err := undraftContent(p)
if test.expectedErr != "" {
if err == nil {
t.Errorf("[%d] Expected error, got none", i)
continue
}
if err.Error() != test.expectedErr {
t.Errorf("[%d] Expected %q, got %q", i, test.expectedErr, err)
continue
}
} else {
r = bytes.NewReader(res.Bytes())
p, _ = parser.ReadFrom(r)
meta, err := p.Metadata()
if err != nil {
t.Errorf("[%d] unexpected error %q", i, err)
continue
}
for k, v := range meta.(map[string]interface{}) {
if k == "draft" {
if v.(bool) {
t.Errorf("[%d] Expected %q to be \"false\", got \"true\"", i, k)
continue
}
}
if k == "date" {
if !strings.HasPrefix(v.(string), time.Now().Format("2006-01-02")) {
t.Errorf("[%d] Expected %v to start with %v", i, v.(string), time.Now().Format("2006-01-02"))
}
}
}
}
}
}
+18 -46
View File
@@ -14,67 +14,39 @@
package commands
import (
"os"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/gohugoio/hugo/helpers"
"github.com/gohugoio/hugo/hugolib"
"github.com/kardianos/osext"
"github.com/spf13/cobra"
jww "github.com/spf13/jwalterweatherman"
)
var versionCmd = &cobra.Command{
Use: "version",
Short: "Print the version number of Hugo",
Long: `All software has versions. This is Hugo's.`,
RunE: func(cmd *cobra.Command, args []string) error {
printHugoVersion()
return nil
},
var _ cmder = (*versionCmd)(nil)
type versionCmd struct {
*baseCmd
}
func newVersionCmd() *versionCmd {
return &versionCmd{
newBaseCmd(&cobra.Command{
Use: "version",
Short: "Print the version number of Hugo",
Long: `All software has versions. This is Hugo's.`,
RunE: func(cmd *cobra.Command, args []string) error {
printHugoVersion()
return nil
},
}),
}
}
func printHugoVersion() {
if hugolib.BuildDate == "" {
setBuildDate() // set the build date from executable's mdate
} else {
formatBuildDate() // format the compile time
}
if hugolib.CommitHash == "" {
jww.FEEDBACK.Printf("Hugo Static Site Generator v%s %s/%s BuildDate: %s\n", helpers.CurrentHugoVersion, runtime.GOOS, runtime.GOARCH, hugolib.BuildDate)
} else {
jww.FEEDBACK.Printf("Hugo Static Site Generator v%s-%s %s/%s BuildDate: %s\n", helpers.CurrentHugoVersion, strings.ToUpper(hugolib.CommitHash), runtime.GOOS, runtime.GOARCH, hugolib.BuildDate)
}
}
// setBuildDate checks the ModTime of the Hugo executable and returns it as a
// formatted string. This assumes that the executable name is Hugo, if it does
// not exist, an empty string will be returned. This is only called if the
// hugolib.BuildDate wasn't set during compile time.
//
// osext is used for cross-platform.
func setBuildDate() {
fname, _ := osext.Executable()
dir, err := filepath.Abs(filepath.Dir(fname))
if err != nil {
jww.ERROR.Println(err)
return
}
fi, err := os.Lstat(filepath.Join(dir, filepath.Base(fname)))
if err != nil {
jww.ERROR.Println(err)
return
}
t := fi.ModTime()
hugolib.BuildDate = t.Format(time.RFC3339)
}
// formatBuildDate formats the hugolib.BuildDate according to the value in
// .Params.DateFormat, if it's set.
func formatBuildDate() {
t, _ := time.Parse("2006-01-02T15:04:05-0700", hugolib.BuildDate)
hugolib.BuildDate = t.Format(time.RFC3339)
}
+6
View File
@@ -20,6 +20,12 @@ import (
"github.com/spf13/cast"
)
// KeyValueStr is a string tuple.
type KeyValueStr struct {
Key string
Value string
}
// KeyValues holds an key and a slice of values.
type KeyValues struct {
Key interface{}
+8
View File
@@ -19,3 +19,11 @@ package compare
type Eqer interface {
Eq(other interface{}) bool
}
// Comparer can be used to compare two values.
// This will be used when using the le, ge etc. operators in the templates.
// Compare returns -1 if the given version is less than, 0 if equal and 1 if greater than
// the running version.
type Comparer interface {
Compare(other interface{}) int
}
+1
View File
@@ -20,6 +20,7 @@ type Provider interface {
GetBool(key string) bool
GetStringMap(key string) map[string]interface{}
GetStringMapString(key string) map[string]string
GetStringSlice(key string) []string
Get(key string) interface{}
Set(key string, value interface{})
IsSet(key string) bool
+16 -1
View File
@@ -63,7 +63,22 @@ func NewContent(
return err
}
contentPath := s.PathSpec.AbsPathify(filepath.Join(s.Cfg.GetString("contentDir"), targetPath))
// The site may have multiple content dirs, and we currently do not know which contentDir the
// user wants to create this content in. We should improve on this, but we start by testing if the
// provided path points to an existing dir. If so, use it as is.
var contentPath string
var exists bool
targetDir := filepath.Dir(targetPath)
if targetDir != "" && targetDir != "." {
exists, _ = helpers.Exists(targetDir, ps.Fs.Source)
}
if exists {
contentPath = targetPath
} else {
contentPath = s.PathSpec.AbsPathify(filepath.Join(s.Cfg.GetString("contentDir"), targetPath))
}
if err := helpers.SafeWriteToDisk(contentPath, bytes.NewReader(content), s.Fs.Source); err != nil {
return err
+23 -12
View File
@@ -16,6 +16,7 @@ package create
import (
"bytes"
"fmt"
"path/filepath"
"strings"
"time"
@@ -43,6 +44,12 @@ type ArchetypeFileData struct {
// on the presence of language code in the filename.
Site *hugolib.Site
// Name will in most cases be the same as TranslationBaseName, e.g. "my-post".
// But if that value is "index" (bundles), the Name is instead the owning folder.
// This is the value you in most cases would want to use to construct the title in your
// archetype template.
Name string
// The target content file. Note that the .Content will be empty, as that
// has not been created yet.
source.File
@@ -51,7 +58,7 @@ type ArchetypeFileData struct {
const (
// ArchetypeTemplateTemplate is used as initial template when adding an archetype template.
ArchetypeTemplateTemplate = `---
title: "{{ replace .TranslationBaseName "-" " " | title }}"
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---
@@ -81,12 +88,25 @@ func executeArcheTypeAsTemplate(s *hugolib.Site, kind, targetPath, archetypeFile
err error
)
sp := source.NewSourceSpec(s.Deps.Cfg, s.Deps.Fs)
f := sp.NewFileInfo("", targetPath, nil)
ps, err := helpers.NewPathSpec(s.Deps.Fs, s.Deps.Cfg)
sp := source.NewSourceSpec(ps, ps.Fs.Source)
if err != nil {
return nil, err
}
f := sp.NewFileInfo("", targetPath, false, nil)
name := f.TranslationBaseName()
if name == "index" || name == "_index" {
// Page bundles; the directory name will hopefully have a better name.
dir := strings.TrimSuffix(f.Dir(), helpers.FilePathSeparator)
_, name = filepath.Split(dir)
}
data := ArchetypeFileData{
Type: kind,
Date: time.Now().Format(time.RFC3339),
Name: name,
File: f,
Site: s,
}
@@ -122,15 +142,6 @@ func executeArcheTypeAsTemplate(s *hugolib.Site, kind, targetPath, archetypeFile
archetypeContent = []byte(archetypeShortcodeReplacementsPost.Replace(buff.String()))
if !bytes.Contains(archetypeContent, []byte("date")) || !bytes.Contains(archetypeContent, []byte("title")) {
// TODO(bep) remove some time in the future.
s.Log.FEEDBACK.Println(fmt.Sprintf(`WARNING: date and/or title missing from archetype file %q.
From Hugo 0.24 this must be provided in the archetype file itself, if needed. Example:
%s
`, archetypeFilename, ArchetypeTemplateTemplate))
}
return archetypeContent, nil
}
+1 -1
View File
@@ -75,7 +75,7 @@ func TestNewContent(t *testing.T) {
for i, v := range c.expected {
found := strings.Contains(content, v)
if !found {
t.Errorf("[%d] %q missing from output:\n%q", i, v, content)
t.Fatalf("[%d] %q missing from output:\n%q", i, v, content)
}
}
}
+1 -1
View File
@@ -126,7 +126,7 @@ func New(cfg DepsCfg) (*Deps, error) {
return nil, err
}
sp := source.NewSourceSpec(cfg.Language, fs)
sp := source.NewSourceSpec(ps, fs.Source)
d := &Deps{
Fs: fs,
+1
View File
@@ -1,3 +1,4 @@
/.idea
/public
nohup.out
.DS_Store
+6
View File
@@ -10,6 +10,12 @@ Note that this repository contains solely the documentation for Hugo. For contri
*Pull requests shall **only** contain changes to the actual documentation. However, changes on the code base of Hugo **and** the documentation shall be a single, atomic pull request in the [hugo](https://github.com/gohugoio/hugo) repository.*
Spelling fixes are most welcomed, and if you want to contribute longer sections to the documentation, it would be great if you had these in mind when writing:
* Short is good. People go to the library to read novels. If there is more than one way to _do a thing_ in Hugo, describe the current _best practice_ (avoid "… but you can also do …" and "… in older versions of Hugo you had to …".
* For examples, try to find short snippets that teaches people about the concept. If the example is also useful as-is (copy and paste), then great, but don't list long and similar examples just so people can use them on their sites.
* Hugo has users from all over the world, so an easy to understand and [simple English](https://simple.wikipedia.org/wiki/Basic_English) is good.
## Branches
* The `master` branch is where the site is automatically built from, and is the place to put changes relevant to the current Hugo version.
+7 -5
View File
@@ -1,11 +1,13 @@
---
title: "{{ replace .TranslationBaseName "-" " " | title }}"
date: {{ .Date }}
linktitle: ""
description: ""
godocref: ""
publishdate: ""
lastmod: ""
categories: []
keywords: []
tags: []
weight: 00
slug: ""
aliases: []
toc: false
draft: true
---
---
+22 -4
View File
@@ -16,7 +16,6 @@ pluralizeListTitles = false
# We do redirects via Netlify's _redirects file, generated by Hugo (see "outputs" below).
disableAliases = true
# Highlighting config (Pygments)
# It is (currently) not in use, but you can do ```go in a content file if you want to.
pygmentsCodeFences = true
@@ -27,7 +26,7 @@ pygmentsUseClasses = true
pygmentsUseClassic = false
# See https://help.farbox.com/pygments.html
pygmentsStyle = "friendly"
pygmentsStyle = "trac"
[outputs]
home = [ "HTML", "RSS", "REDIR", "HEADERS" ]
@@ -71,7 +70,7 @@ twitter = "GoHugoIO"
[params]
description = "The worlds fastest framework for building websites"
## Used for views in rendered HTML (i.e., rather than using the .Hugo variable)
release = "0.32"
release = "0.39"
## Setting this to true will add a "noindex" to *EVERY* page on the site
removefromexternalsearch = false
## Gh repo for site footer (include trailing slash)
@@ -98,10 +97,23 @@ twitter = "GoHugoIO"
## Configuration for BlackFriday markdown parser: https://github.com/russross/blackfriday
[blackfriday]
plainIDAnchors = true
hrefTargetBlank = true
# See https://github.com/gohugoio/hugo/issues/2424
hrefTargetBlank = false
angledQuotes = false
latexDashes = true
[imaging]
# See https://github.com/disintegration/imaging
# CatmullRom is a sharp bicubic filter which should fit the docs site well with its many screenshots.
# Note that you can also set this per image processing.
resampleFilter = "CatmullRom"
# Defatult JPEG quality setting. Default is 75.
quality = 75
anchor = "smart"
## As of v0.20, all content files include a default "categories" value that's the same as the section. This was a cheap future-proofing method and should/could be changed accordingly.
[taxonomies]
category = "categories"
@@ -237,6 +249,12 @@ twitter = "GoHugoIO"
identifier = "themes"
url = "https://themes.gohugo.io/"
[[menu.global]]
name = "Showcase"
weight = 20
identifier = "showcase"
url = "/showcase/"
# Anything with a weight > 100 gets an external icon
[[menu.global]]
name = "Community"
+1 -1
View File
@@ -1,5 +1,5 @@
---
title: "A Fast and Flexible Website Generator"
title: "The worlds fastest framework for building websites"
date: 2017-03-02T12:00:00-05:00
features:
- heading: Blistering Speed
+2 -2
View File
@@ -29,14 +29,14 @@ This has many benefits. The most noticeable is performance. HTTP servers are *ve
* ["An Introduction to Static Site Generators", David Walsh][]
* ["Hugo vs. Wordpress page load speed comparison: Hugo leaves WordPress in its dust", GettingThingsTech][hugovwordpress]
* ["Static Site Generators", O-Reilly][]
* ["Static Site Generators", O'Reilly][]
* [StaticGen: Top Open-Source Static Site Generators (GitHub Stars)][]
* ["Top 10 Static Website Generators", Netlify blog][]
* ["The Resurgence of Static", dotCMS][dotcms]
["An Introduction to Static Site Generators", David Walsh]: https://davidwalsh.name/introduction-static-site-generators
["Static Site Generators", O-Reilly]: /documents/oreilly-static-site-generators.pdf
["Static Site Generators", O'Reilly]: http://www.oreilly.com/web-platform/free/files/static-site-generators.pdf
["Top 10 Static Website Generators", Netlify blog]: https://www.netlify.com/blog/2016/05/02/top-ten-static-website-generators/
[hugovwordpress]: https://gettingthingstech.com/hugo-vs.-wordpress-page-load-speed-comparison-hugo-leaves-wordpress-in-its-dust/
[StaticGen: Top Open-Source Static Site Generators (GitHub Stars)]: https://www.staticgen.com/
-2
View File
@@ -55,7 +55,6 @@ toc: true
* Support for [Go][], [Amber], and [Ace][] HTML templates
* [Syntax highlighting][] powered by [Pygments][]
See what's coming next in the [Hugo roadmap][].
[Ace]: /templates/alternatives/
[aliases]: /content-management/urls/#aliases
@@ -71,7 +70,6 @@ See what's coming next in the [Hugo roadmap][].
[Google Analytics]: https://google-analytics.com/
[homepage]: /templates/homepage/
[hostanywhere]: /hosting-and-deployment/
[Hugo roadmap]: /about/roadmap
[install]: /getting-started/installing/
[LiveReload]: /getting-started/usage/
[organization for your projects]: /getting-started/directory-structure/
@@ -12,6 +12,8 @@ sections_weight: 10
draft: false
aliases: []
toc: true
images:
- images/blog/sunset.jpg
---
@@ -59,7 +61,7 @@ Note that changes to any resource inside the `content` folder will trigger a rel
#### List all Resources
```html
```go-html-template
{{ range .Resources }}
<li><a href="{{ .RelPermalink }}">{{ .ResourceType | title }}</a></li>
{{ end }}
@@ -71,7 +73,7 @@ For an absolute URL, use `.Permalink`.
#### List All Resources by Type
```html
```go-html-template
{{ with .Resources.ByType "image" }}
{{ end }}
@@ -81,7 +83,7 @@ Type here is `page` for pages, else the main type in the MIME type, so `image`,
#### Get a Specific Resource
```html
```go-html-template
{{ $logo := .Resources.GetByPrefix "logo" }}
{{ with $logo }}
{{ end }}
@@ -89,7 +91,7 @@ Type here is `page` for pages, else the main type in the MIME type, so `image`,
#### Include Page Resource Content
```html
```go-html-template
{{ with .Resources.ByType "page" }}
{{ range . }}
<h3>{{ .Title }}</h3>
@@ -119,6 +121,35 @@ Image operations in Hugo currently **do not preserve EXIF data** as this is not
{{% /note %}}
### Image Processing Examples
_The photo of the sunset used in the examples below is Copyright [Bjørn Erik Pedersen](https://commons.wikimedia.org/wiki/User:Bep) (Creative Commons Attribution-Share Alike 4.0 International license)_
{{< imgproc sunset Resize "300x" />}}
{{< imgproc sunset Fill "90x120 left" />}}
{{< imgproc sunset Fill "90x120 right" />}}
{{< imgproc sunset Fit "90x90" />}}
{{< imgproc sunset Resize "300x q10" />}}
This is the shortcode used in the examples above:
{{< code file="layouts/shortcodes/imgproc.html" >}}
{{< readfile file="layouts/shortcodes/imgproc.html" >}}
{{< /code >}}
And it is used like this:
```go-html-template
{{</* imgproc sunset Resize "300x" */>}}
```
### Image Processing Options
In addition to the dimensions (e.g. `200x100`) where either height or width can be omitted, Hugo supports a set of additional image options:
Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

+3 -3
View File
@@ -7,7 +7,7 @@ publishdate: 2017-02-01
lastmod: 2017-02-01
layout: single
menu:
main:
docs:
parent: "about"
weight: 10
weight: 10
@@ -19,7 +19,7 @@ toc: true
Hugo is a general-purpose website framework. Technically speaking, Hugo is a [static site generator][]. Unlike systems that dynamically build a page with each visitor request, Hugo builds pages when you create or update your content. Since websites are viewed far more often than they are edited, Hugo is designed to provide an optimal viewing experience for your website's end users and an ideal writing experience for website authors.
Websites built with Hugo are extremely fast and secure. Hugo sites can be hosted anywhere, including [Netlify][], [Heroku][], [GoDaddy][], [DreamHost][], [GitHub Pages][], [Surge][], [Aerobatic][], [Firebase][], [Google Cloud Storage][], [Amazon S3][], [Rackspace][], [Azure][], and [CloudFront][] and work well with CDNs. Hugo sites run without the need for a database or dependencies on expensive runtimes like Ruby, Python, or PHP.
Websites built with Hugo are extremely fast and secure. Hugo sites can be hosted anywhere, including [Netlify][], [Heroku][], [GoDaddy][], [DreamHost][], [GitHub Pages][], [GitLab Pages][], [Surge][], [Aerobatic][], [Firebase][], [Google Cloud Storage][], [Amazon S3][], [Rackspace][], [Azure][], and [CloudFront][] and work well with CDNs. Hugo sites run without the need for a database or dependencies on expensive runtimes like Ruby, Python, or PHP.
We think of Hugo as the ideal website creation tool with nearly instant build times, able to rebuild whenever a change is made.
@@ -50,7 +50,7 @@ Hugo is for people building a blog, a company site, a portfolio site, documentat
[DreamHost]: http://www.dreamhost.com/
[Firebase]: https://firebase.google.com/docs/hosting/ "Firebase static hosting"
[GitHub Pages]: https://pages.github.com/
[GitLab]: https://about.gitlab.com
[GitLab Pages]: https://about.gitlab.com/features/pages/
[Go language]: https://golang.org/
[GoDaddy]: https://www.godaddy.com/ "Godaddy.com Hosting"
[Google Cloud Storage]: http://cloud.google.com/storage/
+7 -11
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo"
slug: hugo
url: /commands/hugo/
@@ -10,7 +10,6 @@ hugo builds your site
### Synopsis
hugo is the main command, used to build your Hugo site.
Hugo is a Fast and Flexible Static Site Generator
@@ -30,16 +29,13 @@ hugo [flags]
-E, --buildExpired include expired content
-F, --buildFuture include content with publishdate in the future
--cacheDir string filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
--canonifyURLs (deprecated) if true, all relative URLs will be canonicalized using baseURL
--cleanDestinationDir remove files from destination not found in static directories
--config string config file (default is path/config.yaml|json|toml)
-c, --contentDir string filesystem path to content directory
--debug debug output
-d, --destination string filesystem path to write files to
--disable404 do not render 404 page
--disableKinds stringSlice disable different kind of pages (home, RSS etc.)
--disableRSS do not build RSS files
--disableSitemap do not build Sitemap file
--enableGitInfo add Git revision, date and author info to the pages
--forceSyncStatic copy all files when static is changed.
--gc enable to run some cleanup tasks (remove unused cache files) after the build
@@ -51,8 +47,8 @@ hugo [flags]
--logFile string log File path (if set, logging enabled automatically)
--noChmod don't sync permission mode of files
--noTimes don't sync modification time of files
--pluralizeListTitles pluralize titles in lists using inflect (default true)
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
--pluralizeListTitles (deprecated) pluralize titles in lists using inflect (default true)
--preserveTaxonomyNames (deprecated) preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
--quiet build in quiet mode
--renderToMemory render to memory (only useful for benchmark testing)
-s, --source string filesystem path to read files relative from
@@ -61,13 +57,14 @@ hugo [flags]
--templateMetricsHints calculate some improvement hints when combined with --templateMetrics
-t, --theme string theme to use (located in /themes/THEMENAME/)
--themesDir string filesystem path to themes directory
--uglyURLs if true, use /filename.html instead of /filename/
--uglyURLs (deprecated) if true, use /filename.html instead of /filename/
-v, --verbose verbose output
--verboseLog verbose logging
-w, --watch watch filesystem for changes and recreate as needed
```
### SEE ALSO
* [hugo benchmark](/commands/hugo_benchmark/) - Benchmark Hugo by building a site a number of times.
* [hugo check](/commands/hugo_check/) - Contains some verification checks
* [hugo config](/commands/hugo_config/) - Print the site configuration
@@ -78,7 +75,6 @@ hugo [flags]
* [hugo list](/commands/hugo_list/) - Listing out various types of content
* [hugo new](/commands/hugo_new/) - Create new content for your site
* [hugo server](/commands/hugo_server/) - A high performance webserver
* [hugo undraft](/commands/hugo_undraft/) - Undraft resets the content's draft status
* [hugo version](/commands/hugo_version/) - Print the version number of Hugo
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+7 -10
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo benchmark"
slug: hugo_benchmark
url: /commands/hugo_benchmark/
@@ -10,7 +10,6 @@ Benchmark Hugo by building a site a number of times.
### Synopsis
Hugo can build a site many times over and analyze the running process
creating a benchmark.
@@ -26,16 +25,13 @@ hugo benchmark [flags]
-E, --buildExpired include expired content
-F, --buildFuture include content with publishdate in the future
--cacheDir string filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
--canonifyURLs (deprecated) if true, all relative URLs will be canonicalized using baseURL
--cleanDestinationDir remove files from destination not found in static directories
-c, --contentDir string filesystem path to content directory
-n, --count int number of times to build the site (default 13)
--cpuprofile string path/filename for the CPU profile file
-d, --destination string filesystem path to write files to
--disable404 do not render 404 page
--disableKinds stringSlice disable different kind of pages (home, RSS etc.)
--disableRSS do not build RSS files
--disableSitemap do not build Sitemap file
--enableGitInfo add Git revision, date and author info to the pages
--forceSyncStatic copy all files when static is changed.
--gc enable to run some cleanup tasks (remove unused cache files) after the build
@@ -46,8 +42,8 @@ hugo benchmark [flags]
--memprofile string path/filename for the memory profile file
--noChmod don't sync permission mode of files
--noTimes don't sync modification time of files
--pluralizeListTitles pluralize titles in lists using inflect (default true)
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
--pluralizeListTitles (deprecated) pluralize titles in lists using inflect (default true)
--preserveTaxonomyNames (deprecated) preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
--renderToMemory render to memory (only useful for benchmark testing)
-s, --source string filesystem path to read files relative from
--stepAnalysis display memory and timing of different steps of the program
@@ -55,7 +51,7 @@ hugo benchmark [flags]
--templateMetricsHints calculate some improvement hints when combined with --templateMetrics
-t, --theme string theme to use (located in /themes/THEMENAME/)
--themesDir string filesystem path to themes directory
--uglyURLs if true, use /filename.html instead of /filename/
--uglyURLs (deprecated) if true, use /filename.html instead of /filename/
```
### Options inherited from parent commands
@@ -71,6 +67,7 @@ hugo benchmark [flags]
```
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo check"
slug: hugo_check
url: /commands/hugo_check/
@@ -10,7 +10,6 @@ Contains some verification checks
### Synopsis
Contains some verification checks
### Options
@@ -32,7 +31,8 @@ Contains some verification checks
```
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo check ulimit](/commands/hugo_check_ulimit/) - Check system ulimit settings
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo check ulimit"
slug: hugo_check_ulimit
url: /commands/hugo_check_ulimit/
@@ -10,7 +10,6 @@ Check system ulimit settings
### Synopsis
Hugo will inspect the current ulimit settings on the system.
This is primarily to ensure that Hugo can watch enough files on some OSs
@@ -37,6 +36,7 @@ hugo check ulimit [flags]
```
### SEE ALSO
* [hugo check](/commands/hugo_check/) - Contains some verification checks
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo config"
slug: hugo_config
url: /commands/hugo_config/
@@ -10,7 +10,6 @@ Print the site configuration
### Synopsis
Print the site configuration, both default and custom settings.
```
@@ -36,6 +35,7 @@ hugo config [flags]
```
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo convert"
slug: hugo_convert
url: /commands/hugo_convert/
@@ -10,7 +10,6 @@ Convert your content to different formats
### Synopsis
Convert your content (e.g. front matter) to different formats.
See convert's subcommands toJSON, toTOML and toYAML for more information.
@@ -37,9 +36,10 @@ See convert's subcommands toJSON, toTOML and toYAML for more information.
```
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo convert toJSON](/commands/hugo_convert_tojson/) - Convert front matter to JSON
* [hugo convert toTOML](/commands/hugo_convert_totoml/) - Convert front matter to TOML
* [hugo convert toYAML](/commands/hugo_convert_toyaml/) - Convert front matter to YAML
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo convert toJSON"
slug: hugo_convert_toJSON
url: /commands/hugo_convert_tojson/
@@ -10,7 +10,6 @@ Convert front matter to JSON
### Synopsis
toJSON converts all front matter in the content directory
to use JSON for the front matter.
@@ -40,6 +39,7 @@ hugo convert toJSON [flags]
```
### SEE ALSO
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo convert toTOML"
slug: hugo_convert_toTOML
url: /commands/hugo_convert_totoml/
@@ -10,7 +10,6 @@ Convert front matter to TOML
### Synopsis
toTOML converts all front matter in the content directory
to use TOML for the front matter.
@@ -40,6 +39,7 @@ hugo convert toTOML [flags]
```
### SEE ALSO
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo convert toYAML"
slug: hugo_convert_toYAML
url: /commands/hugo_convert_toyaml/
@@ -10,7 +10,6 @@ Convert front matter to YAML
### Synopsis
toYAML converts all front matter in the content directory
to use YAML for the front matter.
@@ -40,6 +39,7 @@ hugo convert toYAML [flags]
```
### SEE ALSO
* [hugo convert](/commands/hugo_convert/) - Convert your content to different formats
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo env"
slug: hugo_env
url: /commands/hugo_env/
@@ -10,7 +10,6 @@ Print Hugo version and environment info
### Synopsis
Print Hugo version and environment info. This is useful in Hugo bug reports.
```
@@ -36,6 +35,7 @@ hugo env [flags]
```
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo gen"
slug: hugo_gen
url: /commands/hugo_gen/
@@ -10,7 +10,6 @@ A collection of several useful generators.
### Synopsis
A collection of several useful generators.
### Options
@@ -32,10 +31,11 @@ A collection of several useful generators.
```
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo gen autocomplete](/commands/hugo_gen_autocomplete/) - Generate shell autocompletion script for Hugo
* [hugo gen chromastyles](/commands/hugo_gen_chromastyles/) - Generate CSS stylesheet for the Chroma code highlighter
* [hugo gen doc](/commands/hugo_gen_doc/) - Generate Markdown documentation for the Hugo CLI.
* [hugo gen man](/commands/hugo_gen_man/) - Generate man pages for the Hugo CLI
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo gen autocomplete"
slug: hugo_gen_autocomplete
url: /commands/hugo_gen_autocomplete/
@@ -10,7 +10,6 @@ Generate shell autocompletion script for Hugo
### Synopsis
Generates a shell autocompletion script for Hugo.
NOTE: The current version supports Bash only.
@@ -54,6 +53,7 @@ hugo gen autocomplete [flags]
```
### SEE ALSO
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo gen chromastyles"
slug: hugo_gen_chromastyles
url: /commands/hugo_gen_chromastyles/
@@ -10,7 +10,6 @@ Generate CSS stylesheet for the Chroma code highlighter
### Synopsis
Generate CSS stylesheet for the Chroma code highlighter for a given style. This stylesheet is needed if pygmentsUseClasses is enabled in config.
See https://help.farbox.com/pygments.html for preview of available styles
@@ -41,6 +40,7 @@ hugo gen chromastyles [flags]
```
### SEE ALSO
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo gen doc"
slug: hugo_gen_doc
url: /commands/hugo_gen_doc/
@@ -10,7 +10,6 @@ Generate Markdown documentation for the Hugo CLI.
### Synopsis
Generate Markdown documentation for the Hugo CLI.
This command is, mostly, used to create up-to-date documentation
@@ -43,6 +42,7 @@ hugo gen doc [flags]
```
### SEE ALSO
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo gen man"
slug: hugo_gen_man
url: /commands/hugo_gen_man/
@@ -10,7 +10,6 @@ Generate man pages for the Hugo CLI
### Synopsis
This command automatically generates up-to-date man pages of Hugo's
command-line interface. By default, it creates the man page files
in the "man" directory under the current directory.
@@ -39,6 +38,7 @@ hugo gen man [flags]
```
### SEE ALSO
* [hugo gen](/commands/hugo_gen/) - A collection of several useful generators.
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo import"
slug: hugo_import
url: /commands/hugo_import/
@@ -10,7 +10,6 @@ Import your site from others.
### Synopsis
Import your site from other web site generators like Jekyll.
Import requires a subcommand, e.g. `hugo import jekyll jekyll_root_path target_path`.
@@ -34,7 +33,8 @@ Import requires a subcommand, e.g. `hugo import jekyll jekyll_root_path target_p
```
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo import jekyll](/commands/hugo_import_jekyll/) - hugo import from Jekyll
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo import jekyll"
slug: hugo_import_jekyll
url: /commands/hugo_import_jekyll/
@@ -10,7 +10,6 @@ hugo import from Jekyll
### Synopsis
hugo import from Jekyll.
Import from Jekyll requires two paths, e.g. `hugo import jekyll jekyll_root_path target_path`.
@@ -39,6 +38,7 @@ hugo import jekyll [flags]
```
### SEE ALSO
* [hugo import](/commands/hugo_import/) - Import your site from others.
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo list"
slug: hugo_list
url: /commands/hugo_list/
@@ -10,7 +10,6 @@ Listing out various types of content
### Synopsis
Listing out various types of content.
List requires a subcommand, e.g. `hugo list drafts`.
@@ -35,9 +34,10 @@ List requires a subcommand, e.g. `hugo list drafts`.
```
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo list drafts](/commands/hugo_list_drafts/) - List all drafts
* [hugo list expired](/commands/hugo_list_expired/) - List all posts already expired
* [hugo list future](/commands/hugo_list_future/) - List all posts dated in the future
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo list drafts"
slug: hugo_list_drafts
url: /commands/hugo_list_drafts/
@@ -10,7 +10,6 @@ List all drafts
### Synopsis
List all of the drafts in your content directory.
```
@@ -37,6 +36,7 @@ hugo list drafts [flags]
```
### SEE ALSO
* [hugo list](/commands/hugo_list/) - Listing out various types of content
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo list expired"
slug: hugo_list_expired
url: /commands/hugo_list_expired/
@@ -10,7 +10,6 @@ List all posts already expired
### Synopsis
List all of the posts in your content directory which has already
expired.
@@ -38,6 +37,7 @@ hugo list expired [flags]
```
### SEE ALSO
* [hugo list](/commands/hugo_list/) - Listing out various types of content
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo list future"
slug: hugo_list_future
url: /commands/hugo_list_future/
@@ -10,7 +10,6 @@ List all posts dated in the future
### Synopsis
List all of the posts in your content directory which will be
posted in the future.
@@ -38,6 +37,7 @@ hugo list future [flags]
```
### SEE ALSO
* [hugo list](/commands/hugo_list/) - Listing out various types of content
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo new"
slug: hugo_new
url: /commands/hugo_new/
@@ -10,7 +10,6 @@ Create new content for your site
### Synopsis
Create a new content file and automatically set the date and title.
It will guess which kind of file to create based on the path provided.
@@ -44,8 +43,9 @@ hugo new [path] [flags]
```
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
* [hugo new site](/commands/hugo_new_site/) - Create a new site (skeleton)
* [hugo new theme](/commands/hugo_new_theme/) - Create a new theme
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo new site"
slug: hugo_new_site
url: /commands/hugo_new_site/
@@ -10,7 +10,6 @@ Create a new site (skeleton)
### Synopsis
Create a new site in the provided directory.
The new site will have the correct structure, but no content or theme yet.
Use `hugo new [contentPath]` to create new content.
@@ -41,6 +40,7 @@ hugo new site [path] [flags]
```
### SEE ALSO
* [hugo new](/commands/hugo_new/) - Create new content for your site
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo new theme"
slug: hugo_new_theme
url: /commands/hugo_new_theme/
@@ -10,7 +10,6 @@ Create a new theme
### Synopsis
Create a new theme (skeleton) called [name] in the current directory.
New theme is a skeleton. Please add content to the touched files. Add your
name to the copyright line in the license and adjust the theme.toml file
@@ -40,6 +39,7 @@ hugo new theme [name] [flags]
```
### SEE ALSO
* [hugo new](/commands/hugo_new/) - Create new content for your site
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+7 -10
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo server"
slug: hugo_server
url: /commands/hugo_server/
@@ -10,7 +10,6 @@ A high performance webserver
### Synopsis
Hugo provides its own webserver which builds and serves the site.
While hugo server is high performance, it is a webserver with limited options.
Many run it in production, but the standard behavior is for people to use it
@@ -38,16 +37,13 @@ hugo server [flags]
-E, --buildExpired include expired content
-F, --buildFuture include content with publishdate in the future
--cacheDir string filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
--canonifyURLs if true, all relative URLs will be canonicalized using baseURL
--canonifyURLs (deprecated) if true, all relative URLs will be canonicalized using baseURL
--cleanDestinationDir remove files from destination not found in static directories
-c, --contentDir string filesystem path to content directory
-d, --destination string filesystem path to write files to
--disable404 do not render 404 page
--disableFastRender enables full re-renders on changes
--disableKinds stringSlice disable different kind of pages (home, RSS etc.)
--disableLiveReload watch without enabling live browser reload on rebuild
--disableRSS do not build RSS files
--disableSitemap do not build Sitemap file
--enableGitInfo add Git revision, date and author info to the pages
--forceSyncStatic copy all files when static is changed.
--gc enable to run some cleanup tasks (remove unused cache files) after the build
@@ -62,9 +58,9 @@ hugo server [flags]
--noChmod don't sync permission mode of files
--noHTTPCache prevent HTTP caching
--noTimes don't sync modification time of files
--pluralizeListTitles pluralize titles in lists using inflect (default true)
--pluralizeListTitles (deprecated) pluralize titles in lists using inflect (default true)
-p, --port int port on which the server will listen (default 1313)
--preserveTaxonomyNames preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
--preserveTaxonomyNames (deprecated) preserve taxonomy names as written ("Gérard Depardieu" vs "gerard-depardieu")
--renderToDisk render to Destination path (default is render to memory & serve from there)
-s, --source string filesystem path to read files relative from
--stepAnalysis display memory and timing of different steps of the program
@@ -72,7 +68,7 @@ hugo server [flags]
--templateMetricsHints calculate some improvement hints when combined with --templateMetrics
-t, --theme string theme to use (located in /themes/THEMENAME/)
--themesDir string filesystem path to themes directory
--uglyURLs if true, use /filename.html instead of /filename/
--uglyURLs (deprecated) if true, use /filename.html instead of /filename/
-w, --watch watch filesystem for changes and recreate as needed (default true)
```
@@ -89,6 +85,7 @@ hugo server [flags]
```
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
-43
View File
@@ -1,43 +0,0 @@
---
date: 2017-12-28T18:49:29+01:00
title: "hugo undraft"
slug: hugo_undraft
url: /commands/hugo_undraft/
---
## hugo undraft
Undraft resets the content's draft status
### Synopsis
Undraft resets the content's draft status
and updates the date to the current date and time.
If the content's draft status is 'False', nothing is done.
```
hugo undraft path/to/content [flags]
```
### Options
```
-h, --help help for undraft
```
### Options inherited from parent commands
```
--config string config file (default is path/config.yaml|json|toml)
--debug debug output
--log enable Logging
--logFile string log File path (if set, logging enabled automatically)
--quiet build in quiet mode
-v, --verbose verbose output
--verboseLog verbose logging
```
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
###### Auto generated by spf13/cobra on 28-Dec-2017
+3 -3
View File
@@ -1,5 +1,5 @@
---
date: 2017-12-28T18:49:29+01:00
date: 2018-01-31T11:40:21+01:00
title: "hugo version"
slug: hugo_version
url: /commands/hugo_version/
@@ -10,7 +10,6 @@ Print the version number of Hugo
### Synopsis
All software has versions. This is Hugo's.
```
@@ -36,6 +35,7 @@ hugo version [flags]
```
### SEE ALSO
* [hugo](/commands/hugo/) - hugo builds your site
###### Auto generated by spf13/cobra on 28-Dec-2017
###### Auto generated by spf13/cobra on 31-Jan-2018
+1 -1
View File
@@ -17,4 +17,4 @@ aliases: [/content/,/content/organization]
toc: false
---
A static site generator needs to extend beyond front matter and a couple templates to be both scalable and *manageable*. Hugo was designed with not only developers in mind, but also content managers and authors.
A static site generator needs to extend beyond front matter and a couple of templates to be both scalable and *manageable*. Hugo was designed with not only developers in mind, but also content managers and authors.
+27 -144
View File
@@ -1,10 +1,9 @@
---
title: Archetypes
linktitle: Archetypes
description: Archetypes allow you to create new instances of content types and set default parameters from the command line.
description: Archetypes are templates used when creating new content.
date: 2017-02-01
publishdate: 2017-02-01
lastmod: 2017-02-01
keywords: [archetypes,generators,metadata,front matter]
categories: ["content management"]
menu:
@@ -18,175 +17,59 @@ aliases: [/content/archetypes/]
toc: true
---
{{% note %}}
This section is outdated, see https://github.com/gohugoio/hugoDocs/issues/11
{{% /note %}}
{{% todo %}}
See above
{{% /todo %}}
## What are Archetypes?
**Archetypes** are content files in the [archetypes directory][] of your project that contain preconfigured [front matter][] for your website's [content types][]. Archetypes facilitate consistent metadata across your website content and allow content authors to quickly generate instances of a content type via the `hugo new` command.
**Archetypes** are content template files in the [archetypes directory][] of your project that contain preconfigured [front matter][] and possibly also a content disposition for your website's [content types][]. These will be used when you run `hugo new`.
{{< youtube bcme8AzVh6o >}}
The `hugo new` generator for archetypes assumes your working directory is the content folder at the root of your project. Hugo is able to infer the appropriate archetype by assuming the content type from the content section passed to the CLI command:
```
hugo new <content-section>/<file-name.md>
```
We can use this pattern to create a new `.md` file in the `posts` section:
The `hugo new` uses the `content-section` to find the most suitable archetype template in your project. If your project does not contain any archetype files, it will also look in the theme.
{{< code file="archetype-example.sh" >}}
hugo new posts/my-first-post.md
{{< /code >}}
{{% note "Override Content Type in a New File" %}}
To override the content type Hugo infers from `[content-section]`, add the `--kind` flag to the end of the `hugo new` command.
{{% /note %}}
Running this command in a new site that does not have default or custom archetypes will create the following file:
{{< output file="content/posts/my-first-post.md" >}}
+++
date = "2017-02-01T19:20:04-07:00"
title = "my first post"
draft = true
+++
{{< /output >}}
{{% note %}}
In this example, if you do not already have a `content/posts` directory, Hugo will create both `content/posts/` and `content/posts/my-first-post.md` for you.
{{% /note %}}
The auto-populated fields are worth examining:
* `title` is generated from the new content's filename (i.e. in this case, `my-first-post` becomes `"my first post"`)
* `date` and `title` are the variables that ship with Hugo and are therefore included in *all* content files created with the Hugo CLI. `date` is generated in [RFC 3339 format][] by way of Go's [`now()`][] function, which returns the current time.
* The third variable, `draft = true`, is *not* inherited by your default or custom archetypes but is included in Hugo's automatically scaffolded `default.md` archetype for convenience.
Three variables per content file are often not enough for effective content management of larger websites. Luckily, Hugo provides a simple mechanism for extending the number of variables through custom archetypes, as well as default archetypes to keep content creation DRY.
## Lookup Order for Archetypes
Similar to the [lookup order for templates][lookup] in your `layouts` directory, Hugo looks for a section- or type-specific archetype, then a default archetype, and finally an internal archetype that ships with Hugo. For example, Hugo will look for an archetype for `content/posts/my-first-post.md` in the following order:
The above will create a new content file in `content/posts/my-first-post.md` using the first archetype file found of these:
1. `archetypes/posts.md`
2. `archetypes/default.md`
3. `themes/<THEME>/archetypes/posts.md`
4. `themes/<THEME>/archetypes/default.md` (Auto-generated with `hugo new site`)
3. `themes/my-theme/posts.md`
4. `themes/my-theme/default.md`
{{% note "Using a Theme Archetype" %}}
If you wish to use archetypes that ship with a theme, the `theme` field must be specified in your [configuration file](/getting-started/configuration/).
{{% /note %}}
The last two list items is only applicable if you use a theme and it uses the `my-theme` theme name as an example.
## Choose Your Archetype's Front Matter Format
## Create a New Archetype Template
By default, `hugo new` content files include front matter in the TOML format regardless of the format used in `archetypes/*.md`.
A fictional example for the section `newsletter` and the archetype file `archetypes/newsletter.md`. Create a new file in `archetypes/newsletter.md` and open it in a text editor.
You can specify a different default format in your site [configuration file][] file using the `metaDataFormat` directive. Possible values are `toml`, `yaml`, and `json`.
{{< code file="archetypes/newsletter.md" >}}
---
title: "{{ replace .Name "-" " " | title }}"
date: {{ .Date }}
draft: true
---
## Default Archetypes
**Insert Lead paragraph here.**
Default archetypes are convenient if your content's front matter stays consistent across multiple [content sections][sections].
## New Cool Posts
### Create the Default Archetype
When you create a new Hugo project using `hugo new site`, you'll notice that Hugo has already scaffolded a file at `archetypes/default.md`.
The following examples are from a site that's using `tags` and `categories` as [taxonomies][]. If we assume that all content files will require these two key-values, we can create a `default.md` archetype that *extends* Hugo's base archetype. In this example, we are including "golang" and "hugo" as tags and "web development" as a category.
{{< code file="archetypes/default.md" >}}
+++
tags = ["golang", "hugo"]
categories = ["web development"]
+++
{{ range first 10 ( where .Site.RegularPages "Type" "cool" ) }}
* {{ .Title }}
{{ end }}
{{< /code >}}
{{% warning "EOL Characters in Text Editors"%}}
If you get an `EOF error` when using `hugo new`, add a carriage return after the closing `+++` or `---` for your TOML or YAML front matter, respectively. (See the [troubleshooting article on EOF errors](/troubleshooting/eof-error/) for more information.)
{{% /warning %}}
When you create a new newsletter with:
### Use the Default Archetype
```bash
hugo new newsletter/the-latest-cool.stuff.md
```
With an `archetypes/default.md` in place, we can use the CLI to create a new post in the `posts` content section:
It will create a new newsletter type of content file based on the archetype template.
{{< code file="new-post-from-default.sh" >}}
$ hugo new posts/my-new-post.md
{{< /code >}}
**Note:** the site will only be built if the `.Site` is in use in the archetype file, and this can be time consuming for big sites.
Hugo then creates a new markdown file with the following front matter:
The above _newsletter type archetype_ illustrates the possibilities: The full Hugo `.Site` and all of Hugo&#39;s template funcs can be used in the archetype file.
{{< output file="content/posts/my-new-post.md" >}}
+++
categories = ["web development"]
date = "2017-02-01T19:20:04-07:00"
tags = ["golang", "hugo"]
title = "my new post"
+++
{{< /output >}}
We see that the `title` and `date` key-values have been added in addition to the `tags` and `categories` key-values from `archetypes/default.md`.
{{% note "Ordering of Front Matter" %}}
You may notice that content files created with `hugo new` do not respect the order of the key-values specified in your archetype files. This is a [known issue](https://github.com/gohugoio/hugo/issues/452).
{{% /note %}}
## Custom Archetypes
Suppose your site's `posts` section requires more sophisticated front matter than what has been specified in `archetypes/default.md`. You can create a custom archetype for your posts at `archetypes/posts.md` that includes the full set of front matter to be added to the two default archetypes fields.
### Create a Custom Archetype
{{< code file="archetypes/posts.md">}}
+++
description = ""
tags = ""
categories = ""
+++
{{< /code >}}
### Use a Custom Archetype
With an `archetypes/posts.md` in place, you can use the Hugo CLI to create a new post with your preconfigured front matter in the `posts` content section:
{{< code file="new-post-from-custom.sh" >}}
$ hugo new posts/post-from-custom.md
{{< /code >}}
This time, Hugo recognizes our custom `archetypes/posts.md` archetype and uses it instead of `archetypes/default.md`. The generated file will now include the full list of front matter parameters, as well as the base archetype's `title` and `date`:
{{< output file="content/posts/post-from-custom-archetype.md" >}}
+++
categories = ""
date = 2017-02-13T17:24:43-08:00
description = ""
tags = ""
title = "post from custom archetype"
+++
{{< /output >}}
### Hugo Docs Custom Archetype
As an example of archetypes in practice, the following is the `functions` archetype from the Hugo docs:
{{< code file="archetypes/functions.md" >}}
{{< readfile file="/themes/gohugoioTheme/archetypes/functions.md" >}}
{{< /code >}}
{{% note %}}
The preceding archetype is kept up to date with every Hugo build by using Hugo's [`readFile` function](/functions/readfile/). For similar examples, see [Local File Templates](/templates/files/).
{{% /note %}}
[archetypes directory]: /getting-started/directory-structure/
[`now()`]: http://golang.org/pkg/time/#Now
[configuration file]: /getting-started/configuration/
[sections]: /content-management/sections/
[content types]: /content-management/types/
[front matter]: /content-management/front-matter/
[RFC 3339 format]: https://www.ietf.org/rfc/rfc3339.txt
[taxonomies]: /content-management/taxonomies/
[lookup]: /templates/lookup/
[templates]: /templates/
+3 -7
View File
@@ -27,15 +27,11 @@ Hugo comes with all the code you need to load Disqus into your templates. Before
### Configure Disqus
Disqus comments require you set a single value in your [site's configuration file][configuration]. The following show the configuration variable in a `config.toml` and `config.yml`, respectively:
Disqus comments require you set a single value in your [site's configuration file][configuration] like so:
```
{{< code-toggle copy="false" >}}
disqusShortname = "yourdiscussshortname"
```
```
disqusShortname: "yourdiscussshortname"
```
{{</ code-toggle >}}
For many websites, this is enough configuration. However, you also have the option to set the following in the [front matter][] of a single content file:
@@ -61,13 +61,6 @@ To be sure to get the correct reference in this case, use the full path:
{{</* relref "events/my-birthday.md" */>}} => /events/my-birthday/
{{< /code >}}
{{< todo >}}Remove this warning when https://github.com/gohugoio/hugo/issues/3703 is released.{{< /todo >}}
A relative document name must *not* begin with a slash (`/`).
```
{{</* relref "/events/my-birthday.md" */>}} => ""
```
### With Multiple Output Formats
If the page exists in multiple [output formats][], `ref` or `relref` can be used with a output format name:
@@ -116,8 +109,22 @@ Ensuring heading uniqueness across the site is accomplished with a unique identi
/content-management/cross-references/#hugo-heading-anchors:77cd9ea530577debf4ce0f28c8dca242
```
### Manually Specifying Anchors
For Markdown content files, if the `headerIds` [Blackfriday extension][bfext] is
enabled (which it is by default), user can manually specify the anchor for any
heading.
Few examples:
```
## Alpha 101 {#alpha}
## Version 1.0 {#version-1-dot-0}
```
[built-in Hugo shortcodes]: /content-management/shortcodes/#using-the-built-in-shortcodes
[lists]: /templates/lists/
[output formats]: /templates/output-formats/
[shortcode]: /content-management/shortcodes/
[bfext]: /content-management/formats/#blackfriday-extensions
+2 -2
View File
@@ -84,7 +84,7 @@ See [Shortcodes][sc] for usage, particularly for the built-in shortcodes that sh
### Code Blocks
Hugo supports GitHub-flavored markdown's use of triple back ticks, as well as provides a special [`highlight` nested shortcode][hlsc] to render syntax highlighting via [Pygments][]. For usage examples and a complete explanation, see the [syntax highlighting documentation][hl] in [developer tools][].
Hugo supports GitHub-flavored markdown's use of triple back ticks, as well as provides a special [`highlight` shortcode][hlsc], and syntax highlights those code blocks natively using *Chroma*. Users also have an option to use *Pygments* instead. See the [Syntax Highlighting][hl] section for details.
## Mmark
@@ -231,7 +231,7 @@ Markdown syntax is simple enough to learn in a single sitting. The following are
[fireball]: https://daringfireball.net/projects/markdown/
[gfmtasks]: https://guides.github.com/features/mastering-markdown/#syntax
[helperssource]: https://github.com/gohugoio/hugo/blob/77c60a3440806067109347d04eb5368b65ea0fe8/helpers/general.go#L65
[hl]: /tools/syntax-highlighting/
[hl]: /content-management/syntax-highlighting/
[hlsc]: /content-management/shortcodes/#highlight
[hugocss]: /css/style.css
[ietf]: https://tools.ietf.org/html/
+11 -37
View File
@@ -34,9 +34,9 @@ YAML
JSON
: a single JSON object surrounded by '`{`' and '`}`', followed by a new line.
### TOML Example
### Example
```
{{< code-toggle >}}
+++
title = "spf13-vim 3.0 release and new website"
description = "spf13-vim is a cross platform distribution of vim plugins and resources for Vim."
@@ -48,39 +48,7 @@ categories = [
]
slug = "spf13-vim-3-0-release-and-new-website"
+++
```
### YAML Example
```
---
title: "spf13-vim 3.0 release and new website"
description: "spf13-vim is a cross platform distribution of vim plugins and resources for Vim."
tags: [ ".vimrc", "plugins", "spf13-vim", "vim" ]
lastmod: 2015-12-23
date: "2012-04-06"
categories:
- "Development"
- "VIM"
slug: "spf13-vim-3-0-release-and-new-website"
---
```
### JSON Example
```
{
"title": "spf13-vim 3.0 release and new website",
"description": "spf13-vim is a cross platform distribution of vim plugins and resources for Vim.",
"tags": [ ".vimrc", "plugins", "spf13-vim", "vim" ],
"date": "2012-04-06",
"categories": [
"Development",
"VIM"
],
"slug": "spf13-vim-3-0-release-and-new-website"
}
```
{{</ code-toggle >}}
## Front Matter Variables
@@ -103,6 +71,9 @@ There are a few predefined variables that Hugo is aware of. See [Page Variables]
`expiryDate`
: the datetime at which the content should no longer be published by Hugo; expired content will not be rendered unless the `--buildExpired` flag is passed to the `hugo` command.
`headless`
: if `true`, sets a leaf bundle to be [headless][headless-bundle].
`isCJKLanguage`
: if `true`, Hugo will explicitly treat the content as a CJK language; both `.Summary` and `.WordCount` work properly in CJK languages.
@@ -127,6 +98,9 @@ There are a few predefined variables that Hugo is aware of. See [Page Variables]
`publishDate`
: if in the future, content will not be rendered unless the `--buildFuture` flag is passed to `hugo`.
`resources`
: used for configuring page bundle resources. See [Page Resources][page-resources].
`slug`
: appears as the tail of the output URL. A value specified in front matter will override the segment of the URL based on the filename.
@@ -161,8 +135,6 @@ include_toc: true
show_comments: false
```
These two user-defined fields can then be accessed via `.Params.include_toc` and `.Params.show_comments`, respectively. The [Variables][variables] section provides more information on using Hugo's page- and site-level variables in your templates.
## Order Content Through Front Matter
@@ -186,11 +158,13 @@ It's possible to set some options for Markdown rendering in a content's front ma
[content type]: /content-management/types/
[contentorg]: /content-management/organization/
[definetype]: /content-management/types/#defining-a-content-type "Learn how to specify a type and a layout in a content's front matter"
[headless-bundle]: /content-management/page-bundles/#headless-bundle
[json]: https://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf "Specification for JSON, JavaScript Object Notation"
[lists]: /templates/lists/#ordering-content "See how to order content in list pages; for example, templates that look to specific _index.md for content and front matter."
[lookup]: /templates/lookup-order/ "Hugo traverses your templates in a specific order when rendering content to allow for DRYer templating."
[ordering]: /templates/lists/ "Hugo provides multiple ways to sort and order your content in list templates"
[outputs]: /templates/output-formats/ "With the release of v22, you can output your content to any text format using Hugo's familiar templating"
[page-resources]: /content-management/page-resources/
[pagevars]: /variables/page/
[section]: /content-management/sections/
[taxweight]: /content-management/taxonomies/
@@ -0,0 +1,195 @@
---
title: "Image Processing"
description: "Image Page resources can be resized and cropped."
date: 2018-01-24T13:10:00-05:00
lastmod: 2018-01-26T15:59:07-05:00
linktitle: "Image Processing"
categories: ["content management"]
keywords: [bundle,content,resources,images]
weight: 4004
draft: false
toc: true
menu:
docs:
parent: "content-management"
weight: 32
---
## The Image Page Resource
The `image` is a [Page Resource]({{< relref "content-management/page-resources" >}}), and the processing methods listed below does not work on images inside your `/static` folder.
To get all images in a [Page Bundle]({{< relref "content-management/organization#page-bundles" >}}):
```go-html-template
{{ with .Resources.ByType "image" }}
{{ end }}
```
## Image Processing Methods
The `image` resource implements the methods `Resize`, `Fit` and `Fill`, each returning the transformed image using the specified dimensions and processing options.
Resize
: Resizes the image to the specified width and height.
```go
// Resize to a width of 600px and preserve ratio
{{ $image := $resource.Resize "600x" }}
// Resize to a height of 400px and preserve ratio
{{ $image := $resource.Resize "x400" }}
// Resize to a width 600px and a height of 400px
{{ $image := $resource.Resize "600x400" }}
```
Fit
: Scale down the image to fit the given dimensions while maintaining aspect ratio. Both height and width are required.
```go
{{ $image := $resource.Fit "600x400" }}
```
Fill
: Resize and crop the image to match the given dimensions. Both height and width are required.
```go
{{ $image := $resource.Fill "600x400" }}
```
{{% note %}}
Image operations in Hugo currently **do not preserve EXIF data** as this is not supported by Go's [image package](https://github.com/golang/go/search?q=exif&type=Issues&utf8=%E2%9C%93). This will be improved on in the future.
{{% /note %}}
## Image Processing Options
In addition to the dimensions (e.g. `600x400`), Hugo supports a set of additional image options.
JPEG Quality
: Only relevant for JPEG images, values 1 to 100 inclusive, higher is better. Default is 75.
```go
{{ $image.Resize "600x q50" }}
```
Rotate
: Rotates an image by the given angle counter-clockwise. The rotation will be performed first to get the dimensions correct. The main use of this is to be able to manually correct for [EXIF orientation](https://github.com/golang/go/issues/4341) of JPEG images.
```go
{{ $image.Resize "600x r90" }}
```
Anchor
: Only relevant for the `Fill` method. This is useful for thumbnail generation where the main motive is located in, say, the left corner.
Valid are `Center`, `TopLeft`, `Top`, `TopRight`, `Left`, `Right`, `BottomLeft`, `Bottom`, `BottomRight`.
```go
{{ $image.Fill "300x200 BottomLeft" }}
```
Resample Filter
: Filter used in resizing. Default is `Box`, a simple and fast resampling filter appropriate for downscaling.
Examples are: `Box`, `NearestNeighbor`, `Linear`, `Gaussian`.
See https://github.com/disintegration/imaging for more. If you want to trade quality for faster processing, this may be a option to test.
```go
{{ $image.Resize "600x400 Gaussian" }}
```
## Image Processing Examples
_The photo of the sunset used in the examples below is Copyright [Bjørn Erik Pedersen](https://commons.wikimedia.org/wiki/User:Bep) (Creative Commons Attribution-Share Alike 4.0 International license)_
{{< imgproc sunset Resize "300x" />}}
{{< imgproc sunset Fill "90x120 left" />}}
{{< imgproc sunset Fill "90x120 right" />}}
{{< imgproc sunset Fit "90x90" />}}
{{< imgproc sunset Resize "300x q10" />}}
This is the shortcode used in the examples above:
{{< code file="layouts/shortcodes/imgproc.html" >}}
{{< readfile file="layouts/shortcodes/imgproc.html" >}}
{{< /code >}}
And it is used like this:
```go-html-template
{{</* imgproc sunset Resize "300x" /*/>}}
```
{{% note %}}
**Tip:** Note the self-closing shortcode syntax above. The `imgproc` shortcode can be called both with and without **inner content**.
{{% /note %}}
## Image Processing Config
You can configure an `imaging` section in `config.toml` with default image processing options:
```toml
[imaging]
# Default resample filter used for resizing. Default is Box,
# a simple and fast averaging filter appropriate for downscaling.
# See https://github.com/disintegration/imaging
resampleFilter = "box"
# Defatult JPEG quality setting. Default is 75.
quality = 75
# Anchor used when cropping pictures.
# Default is "smart" which does Smart Cropping, using https://github.com/muesli/smartcrop
# Smart Cropping is content aware and tries to find the best crop for each image.
# Valid values are Smart, Center, TopLeft, Top, TopRight, Left, Right, BottomLeft, Bottom, BottomRight
anchor = "smart"
```
All of the above settings can also be set per image procecssing.
## Smart Cropping of Images
By default, Hugo will use the [Smartcrop](https://github.com/muesli/smartcrop), a library created by [muesli](https://github.com/muesli), when cropping images with `.Fill`. You can set the anchor point manually, but in most cases the smart option will make a good choice. And we will work with the libray author to improve this in the future.
An example using the sunset image from above:
{{< imgproc sunset Fill "200x200 smart" />}}
## Image Processing Performance Consideration
Processed images are stored below `<project-dir>/resources` (can be set with `resourceDir` config setting). This folder is deliberately placed in the project, as it is recommended to check these into source control as part of the project. These images are not "Hugo fast" to generate, but once generated they can be reused.
If you change your image settings (e.g. size), remove or rename images etc., you will end up with unused images taking up space and cluttering your project.
To clean up, run:
```bash
hugo --gc
```
{{% note %}}
**GC** is short for **Garbage Collection**.
{{% /note %}}
Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

+4 -22
View File
@@ -118,9 +118,9 @@ menu:
You can also add entries to menus that arent attached to a piece of content. This takes place in your Hugo project's [`config` file][config].
Heres an example snippet pulled from a `config.toml`:
Heres an example snippet pulled from a configuration file:
{{< code file="config.toml" >}}
{{< code-toggle file="config.toml" >}}
[[menu.main]]
name = "about hugo"
pre = "<i class='fa fa-heart'></i>"
@@ -132,28 +132,10 @@ Heres an example snippet pulled from a `config.toml`:
pre = "<i class='fa fa-road'></i>"
weight = -100
url = "/getting-started/"
{{< /code >}}
Here's the equivalent snippet in a `config.yaml`:
{{< code file="config.yml" >}}
---
menu:
docs:
- Name: "about hugo"
Pre: "<i class='fa fa-heart'></i>"
Weight: -110
Identifier: "about"
URL: "/about/"
- Name: "getting started"
Pre: "<i class='fa fa-road'></i>"
Weight: -100
URL: "/getting-started/"
---
{{< /code >}}
{{< /code-toggle >}}
{{% note %}}
The URLs must be relative to the context root. If the `baseURL` is `https://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 value used for `URL` in the above example is `https://subdomain.example.com/`, the output will be `https://subdomain.example.com`.
The URLs must be relative to the context root. If the `baseURL` is `https://example.com/mysite/`, then the URLs in the menu must not include the context root `mysite`. Using an absolute URL will override the baseURL. If the value used for `URL` in the above example is `https://subdomain.example.com/`, the output will be `https://subdomain.example.com`.
{{% /note %}}
## Nesting

Some files were not shown because too many files have changed in this diff Show More