This change is motivated by Netlify's `_redirects` files, which is currently not possible to generate with Hugo.
This commit adds a `Delimiter` field to media type, which defaults to ".", but can be blanked out.
Fixes#3614
Note that even with this setting enabled, the aliases themselves are preserved on the pages.
The big motivation for this change is to be able to use the alias definitions to generate `.htaccess` or Netlify's `_redirect` files with server-side redirects.
Fixes#3613
This commit completes the "The Revival of the Archetypes!"
If `.Site` is used in the arcetype template, the site is built and added to the template context.
Note that this may be potentially time consuming for big sites.
A more complete example would then be for the section `newsletter` and the archetype file `archetypes/newsletter.md`:
```
---
title: "{{ replace .TranslationBaseName "-" " " | title }}"
date: {{ .Date }}
tags:
- x
categories:
- x
draft: true
---
<!--more-->
{{ range first 10 ( where .Site.RegularPages "Type" "cool" ) }}
* {{ .Title }}
{{ end }}
```
And then create a new post with:
```bash
hugo new newsletter/the-latest-cool.stuff.md
```
**Hot Tip:** If you set the `newContentEditor` configuration variable to an editor on your `PATH`, the newly created article will be opened.
The above _newsletter type archetype_ illustrates the possibilities: The full Hugo `.Site` and all of Hugo's template funcs can be used in the archetype file.
Fixes#1629
This commit removes the fragile front matter decoding, and takes the provided archetype file as-is and processes it as a template.
This also means that we no longer will attempt to fill in default values for `title` and `date`.
The upside is that it is now easy to create these values in a dynamic way:
```toml
+++
title = {{ .BaseFileName | title }}
date = {{ .Date }}
draft = true
+++
```
You can currently use all of Hugo's template funcs, but the data context is currently very shallow:
* `.Type` gives the archetype kind provided
* `.Name` gives the target file name without extension.
* `.Path` gives the target file name
* `.Date` gives the current time as RFC3339 formatted string
The above will probably be extended in #1629.
Fixes#452
Updates #1629
This commit fixes an issue introduced in the recently released Hugo 0.22.
This logic did not handle the case with root sections with non-section subfolders very well.
Fixes#3586
This enables both the variants below:
Current (first level only):
```
"blog": ":section/:title",
```
Nested (all levels):
```
"blog": ":sections/:title",
```
Should ideally been part of Hugo 0.22, but better late than never ...
Fixes#3580
The rel attribute supports specifying a set of values, not only a single
one.
Using two link elements can also cause browsers to show the feed twice
in menus.
This issue is more visible now that we support nested sections.
This commit makes operations like pasting new content folders or deleting content folders during server watch just work.
Fixes#3570
We still have go-toml as a transitive dependency, and it is the way to go eventually, but we care about speed, so let us wait that one out.
Note that the issue this fixes is about taxonomies, but I guess this is a general issue for sites with many pages that uses TOML as front matter.
```
benchmark old ns/op new ns/op delta
BenchmarkFrontmatterTags/TOML:1-4 23206 8543 -63.19%
BenchmarkFrontmatterTags/TOML:11-4 80117 18495 -76.92%
BenchmarkFrontmatterTags/TOML:21-4 140676 28727 -79.58%
benchmark old allocs new allocs delta
BenchmarkFrontmatterTags/TOML:1-4 173 60 -65.32%
BenchmarkFrontmatterTags/TOML:11-4 625 138 -77.92%
BenchmarkFrontmatterTags/TOML:21-4 1106 210 -81.01%
benchmark old bytes new bytes delta
BenchmarkFrontmatterTags/TOML:1-4 9231 2912 -68.45%
BenchmarkFrontmatterTags/TOML:11-4 19808 5184 -73.83%
BenchmarkFrontmatterTags/TOML:21-4 31200 7536 -75.85%
```
See #3541
Updates #3464
So you can do and get:
```
▶ ./benchSite.sh "YAML,num_pages=10"
Running with BenchmarkSiteBuilding/YAML,num_pages=10
BenchmarkSiteBuilding/YAML,num_pages=10-4 1000 1611261 ns/op 730749 B/op 6458 allocs/op
PASS
ok github.com/spf13/hugo/hugolib 8.168s
```
And change site benchmark separator to comma to make it Bash and regexp friendly, example:
./benchSite.sh "frontmatter=YAML,num_root_sections=1,num_pages=.*,tags_per_page=20,shortcodes=false,render=false"
To run a subset of these benchmark, one can do something like this:
```
go test -run="NONE" -bench="BenchmarkSiteBuilding/tags_per_page=0.*shortcodes=true.*render=false" -test.benchmem=true ./hugolib
```
Which will run without any tags, with shortcodes, but will skip rendering.
Fixes#3535
Looks to be slightly slower with the low number of section pages, but the 1000 regular pages seem to add value.
```
benchmark old ns/op new ns/op delta
BenchmarkGetPage-4 97.7 145 +48.41%
BenchmarkGetPageRegular-4 7933 161 -97.97%
benchmark old allocs new allocs delta
BenchmarkGetPage-4 0 0 +0.00%
BenchmarkGetPageRegular-4 0 0 +0.00%
benchmark old bytes new bytes delta
BenchmarkGetPage-4 0 0 +0.00%
BenchmarkGetPageRegular-4 0 0 +0.00%
```
When we know to look into the index pages collection, do that:
```
benchmark old ns/op new ns/op delta
BenchmarkGetPage-4 51483 7072 -86.26%
benchmark old allocs new allocs delta
BenchmarkGetPage-4 71 71 +0.00%
benchmark old bytes new bytes delta
BenchmarkGetPage-4 2648 2648 +0.00%
```
This commit also returns an error if .Site.GetPage is called with the regular Page Kind, as that is currently not supported.
Fixes#3503
The unmaintained Rango frontend and the Hugopit "experiment" should be removed from the Hugo Tools/Frontends section of the documentation as they are unusable.
Rango can mess up with other dependencies installed in the Go Path as reported here:
https://github.com/stayradiated/rango/issues/4
Hugopit's developer himself stated that this is an unmaintained experiment and he seemed a bit surprised that it is included in Hugo's documentation over here: https://github.com/sjardim/Hugopit/issues/3
Unsupported types are currently silently ignored by IsSet. An earlier
attempt was made to solve the issue by returning an error. That attempt
was reverted since it broke some existing themes.
So instead, we'll log an error. Hopefully, people will stop using IsSet
in this way, and we can eventually return an error outright.
Updates #3092
A common use case for this is to redefine the built-in output format `RSS` to give it a different URL.
Before this commit, that was not possible without also providing an `outputs` definition.
Fixes#3447
It's pointless to set `/bin/sh` as entrypoint. `/bin/sh` is already the default command, and on the top of that, setting `/bin/sh` as entrypoint ignores the command.
This commit allows shortcode per output format, a typical use case would be the special AMP media tags.
Note that this will only re-render the "overridden" shortcodes and only in pages where these are used, so performance in the normal case should not suffer.
Closes#3220
Hugo looks for the list/single templates of a taxonomy in `/layouts/taxonomy`, not `/layouts/taxonomies` as correctly mentioned in [this doc page](https://gohugo.io/templates/list/). This change is simply a minor reconciliation.
Join calls Clean as it says in docs.
Minor performance improvement:
Before:
Average time per operation: 432ms
Average memory allocated per operation: 127322kB
Average allocations per operation: 2138137
After:
Average time per operation: 428ms
Average memory allocated per operation: 127350kB
Average allocations per operation: 2137892
- Move the main GetCSV and GetJSON into data.go.
- Add error returns to GetCSV and GetJSON.
- Add http client to Namespace for test mocking.
- Send accept headers on remote requests. Fixes#3395
- Return an error on non-2XX HTTP response codes and don't retry.
- Move cache tests to cache_test.go.
As a first step to remove the hard ties between `tplimpl` and the different namespace packages.
The `lang` package is used as the first example use case.
See #3042
This commit moves almost all of the template functions into separate
packages under tpl/ and adds a namespace framework. All changes should
be backward compatible for end users, as all existing function names in
the template funcMap are left intact.
Seq and DoArithmatic have been moved out of the helpers package and into
template namespaces.
Most of the tests involved have been refactored, and many new tests have
been written. There's still work to do, but this is a big improvement.
I got a little overzealous and added some new functions along the way:
- strings.Contains
- strings.ContainsAny
- strings.HasSuffix
- strings.TrimPrefix
- strings.TrimSuffix
Documentation is forthcoming.
Fixes#3042
Hugo 0.20 broke some sites that grouped their blog post and images together in subfolders.
This commit re-introduces that behaviour:
* If the file base name resolves to the same as the base name for the output type (i.e. "index" for HTML), the user probably meant it, so we treat that as an `uglyURL`, i.e. `my-blog-post-1.md`=> `/my-blog-post-1/index.html`
* The main use case for this is to group blog post and images together.
* Note that for the top level folder there will be a potential name conflict with a `section` `index.html` (if enabled)
* This issue will not be relevant for subfolders in sections
* Hugo will soon add support for nested sections, but we will have to find a way to separate them from the rest (`/content/_mysubsection` maybe).
Fixes#3396
This commit adds a work flow aroung GoReleaser to get the Hugo release process automated and more uniform:
* It can be run fully automated or in two steps to allow for manual edits of the relase notes.
* It supports both patch and full releases.
* It fetches author, issue, repo info. etc. for the release notes from GitHub.
* The file names produced are mainly the same as before, but we no use tar.gz as archive for all Unix versions.
* There isn't a fully automated CI setup in place yet, but the release tag is marked in the commit message with "[ci deploy]"
Fixes#3358
Partial rebuild does not have the same logic as normal rebuild on
selecting which file to build. This change makes it possible to
share the file select logic between two kinds of build.
Fix#3325.
For pages with translations, add links with hreflang attributes to the
default sitemap template. This helps Google to show the correct
language page in its search results. The syntax used is based on
Google's example at [1].
Also update the sitemap template docs to reflect the changes in the
default template.
[1]
https://support.google.com/webmasters/answer/2620865?hl=en&topic=2370587&ctx=topicFixes#2569
The check-vendor target will exit with an error if any files in vendor/
differ from what's checked into git.
govendor checksums can get out of sync if extraneous files are in the
local, third-party repo (see kardianos/govendor#129). govendor also
updates the vendor.json upon "sync." We can use that quirk to detect
out of sync checksums in CI, so I've added check-vendor to the check
target dependencies.
Most obvius benefit of this is to include CSS partials with css file suffix into HTML templates.
A valid workaround would be to rename the file `mystyles.html`, but that doesn't work too good for external editors etc.
The css partial is a method used in some themes before Hugo 0.20, but then it stopped working.
This commit reintroduces that behaviour.
Note that the regular layout lookups for text templates, i.e. "single.json" will be
prefixed with "_text/" on lookup and will only match in the text collection.
Fixes#3273
This makes it consistent with how it behaves when it's set in config.toml.
This commit also unifies BaseURL in Site.Info so we now have one source for this value.
Fixes#3262
This commit also adds a new command, docshelper, with some utility funcs that adds a JSON datafiles to /docs/data that would be a pain to create and maintain by hand.
Fixes#3242
Before this commit, Hugo used `html/template` for all Go templates.
While this is a fine choice for HTML and maybe also RSS feeds, it is painful for plain text formats such as CSV, JSON etc.
This commit fixes that by using the `IsPlainText` attribute on the output format to decide what to use.
A couple of notes:
* The above requires a nonambiguous template name to type mapping. I.e. `/layouts/_default/list.json` will only work if there is only one JSON output format, `/layouts/_default/list.mytype.json` will always work.
* Ambiguous types will fall back to HTML.
* Partials inherits the text vs HTML identificator of the container template. This also means that plain text templates can only include plain text partials.
* Shortcode templates are, by definition, currently HTML templates only.
Fixes#3221
Having the content page name in the log key for the distinct error logger isnt't very usable when you have an error in a commonly used partial.
Using the Page Kind reduces the amount of log entries. Here is an example from an error in the partial menu.html, used in all the page templates:
```
Started building sites ...
ERROR 2017/04/02 12:19:43 Error while rendering "page": template: /Users/bep/sites/bepsays.com/layouts/_default/single.html:17:7: executing "/Users/bep/sites/bepsays.com/layouts/_default/single.html" at <partial "menu.html" ...>: error calling partial: template: partials/menu.html:9:11: executing "partials/menu.html" at <.DoesNotExist>: can't evaluate field DoesNotExist in type *hugolib.PageOutput
ERROR 2017/04/02 12:19:43 Error while rendering "section": template: /Users/bep/sites/bepsays.com/layouts/_default/section.html:17:7: executing "/Users/bep/sites/bepsays.com/layouts/_default/section.html" at <partial "menu.html" ...>: error calling partial: template: partials/menu.html:9:11: executing "partials/menu.html" at <.DoesNotExist>: can't evaluate field DoesNotExist in type *hugolib.PageOutput
ERROR 2017/04/02 12:19:43 Error while rendering "taxonomy": template: /Users/bep/sites/bepsays.com/layouts/_default/list.html:17:7: executing "/Users/bep/sites/bepsays.com/layouts/_default/list.html" at <partial "menu.html" ...>: error calling partial: template: partials/menu.html:9:11: executing "partials/menu.html" at <.DoesNotExist>: can't evaluate field DoesNotExist in type *hugolib.PageOutput
ERROR 2017/04/02 12:19:43 Error while rendering "home": template: /Users/bep/sites/bepsays.com/layouts/index.html:17:7: executing "/Users/bep/sites/bepsays.com/layouts/index.html" at <partial "menu.html" ...>: error calling partial: template: partials/menu.html:9:11: executing "partials/menu.html" at <.DoesNotExist>: can't evaluate field DoesNotExist in type *hugolib.PageOutput
ERROR 2017/04/02 12:19:43 Error while rendering "404": template: 404.html:2:3: executing "404.html" at <partial "menu.html" ...>: error calling partial: template: partials/menu.html:9:11: executing "partials/menu.html" at <.DoesNotExist>: can't evaluate field DoesNotExist in type *hugolib.PageOutput
Built site for language nn:
```
Which is pretty good.
Before this commit, Hugo used `html/template` for all Go templates.
While this is a fine choice for HTML and maybe also RSS feeds, it is painful for plain text formats such as CSV, JSON etc.
This commit fixes that by using the `IsPlainText` attribute on the output format to decide what to use.
A couple of notes:
* The above requires a nonambiguous template name to type mapping. I.e. `/layouts/_default/list.json` will only work if there is only one JSON output format, `/layouts/_default/list.mytype.json` will always work.
* Ambiguous types will fall back to HTML.
* Partials inherits the text vs HTML identificator of the container template. This also means that plain text templates can only include plain text partials.
* Shortcode templates are, by definition, currently HTML templates only.
Fixes#3221
Livefyre.com is down.
Livefyre was integrated into Adobe's offering.
The product is now called Adobe Experience Manager Livefyre.
Wikipedia points to web.livefyre.com which redirects to the link I provided in the commit.
Using it for list pages doesn't work and has potential weird side-effects.
The user probably meant to range over .Site.ReqularPages, and that is now marked clearly in the log.
Will have to fix this in a better way later in relation to the non-renderable pages.
But this commit brings the Hugo Benchmark down to "only slightly slower" than master.
```
benchmark old ns/op new ns/op delta
BenchmarkHugo-4 10074504521 10071236251 -0.03%
benchmark old allocs new allocs delta
BenchmarkHugo-4 43623091 49271859 +12.95%
benchmark old bytes new bytes delta
BenchmarkHugo-4 9468322704 9725848376 +2.72%
```
Which is something we can work with.
This is a pretty fundamental change in Hugo, but absolutely needed if we should have any hope of getting "multiple outputs" done.
This commit's goal is to say:
* Every file target path is created by `createTargetPath`, i.e. one function for all.
* That function takes every page and site parameter into account, to avoid fragile string parsing to uglify etc. later on.
* The path creation logic has full test coverage.
* All permalinks, paginator URLs etc. are then built on top of that same logic.
Fixes#1252Fixes#2110Closes#2374Fixes#1885Fixes#3102Fixes#3179Fixes#1641Fixes#1989
Changing it to PageOutput was a mistake. You may think that the increased parallelism should be a good thing.
But not so much with the increased lock contention and more complex concurrency model.
This page was a real chore chore on the POC. In the event that a new doc site won't be approved by v20, this will at least clean up the broken links I found during my audit. I would like to eventually create this as a [data file](https://github.com/spf13/hugo/pull/2508#commitcomment-18705617) since md tables get unwieldy pretty quickly.
Difference between toml.Load(string(datum)) and
toml.LoadReader(bytes.NewReader(datum)):
benchmark old ns/op new ns/op delta
BenchmarkLoad-4 82068 78489 -4.36%
benchmark old allocs new allocs delta
BenchmarkLoad-4 494 493 -0.20%
benchmark old bytes new bytes delta
BenchmarkLoad-4 17009 16913 -0.56%
Add vendoring and make targets. Require Go 1.8+ and remove mention of
GOPATH (just assume $HOME/go).
Due to time contraints, the contributing tutorial was only slightly
updated to make obvious corrections.
Fixes#3153
This commit fixes two different, but related issues:
1) Live-reload when a new shortcode was defined in the content file before the shortcode itself was created.
2) Live-reload when a newly defined shortcode changed its "inner content" status.
This commit also improves the shortcode related error messages to include the full path to the content file in question.
Fixes#3156
Lots of cleanups here:
- Refactor InterfaceToConfig and InterfaceToFrontMatter to use io.Writer.
- Simplify InterfaceToFrontMatter by wrapping InterfaceToConfig.
- Export FrontmatterType since we return it in DetectFrontMatter.
- Refactor removeTOMLIdentifier to avoid blindly replacing "+++".
- Update HandleJSONMetaData to return an empty map on nil input.
- Updates vendored goorgeous package and test for org-mode frontmatter.
- Add tests and godoc comments.
Coverage for parser package increased from 45.2% to 85.2%.
Previously this was left empty, but it is very handy to have a list
of term pages for a given taxonomy. This list can now be paginated
like other page lists. It makes it possible to render summary
content from each terms index page for instance. It also makes it
possible to sort the term pages in the same way that other page
lists can be sorted. An RSS feed is now generated for
KindTaxonomyTerm pages as well.
This also fixes a bug in HugoSites.createMissingPages. Previously
it would only check for existing KindTaxonomyTerm pages if the
taxonomy had any terms defined. So for a taxonomy with no terms
but a taxonomy terms page it would generate a second empty terms
page.
This relates to #3123.
The interfaces and types in `target` made sense at some point, but now this package is too restricted to a hardcoded set of media types.
The overall current logic:
* Create a file path based on some `Translator` with some hardcoded logic handling uglyURLs, hardcoded html suffix etc.
* In in some cases (alias), a template is applied to create the alias file.
* Then the content is written to destination.
One could argue that it is the last bullet that is the actual core responsibility.
This commit fixes that by moving the `hugolib`-related logic where it belong, and simplify the code, i.e. remove the abstractions.
This code will most certainly evolve once we start on #3123, but now it is at least possible to understand where to start.
Fixes#3123
Previously it would only check for existing KindTaxonomyTerm pages
if the taxonomy had any terms defined. So for a taxonomy with no terms
but a taxonomy terms page it would generate a second empty terms page.
Added article from gettingthingstech.com.
I also cleaned up some poorly-aligned entries near the top of markdown table
(though it doesn't affect the HTML output either way).
When using the lazy blogger setting to automatically generate menu
entries from section pages, we now recognize section pages that have
content, and use the weight and linktitle configured in the frontmatter.
This way, we can use the lazy blogger automatic generation, and
influence menu order and translations, directly from the frontmatter.
Updates #2974
This commit makes sure that the `.Site.LastChange` is fetched from the latest page modification date.
Previously, this value was fetched from the last page in the default page sort, which may not be the last by date
if weight is set.
Fixes#2909Closes#2910
This fixes the behavior of .Truncated that was introduced with commit
bef496b97e which was later broken. The
desired behavior is that .Truncated would evaluate to false when there
was nothing after the user defined summary marker.
This also adds a simple unit test to ensure that this feature isn't
broken again. The check for content after the user defined summary
marker is done on the raw content instead of the working copy because
some of the markup renderers add elements after the marker, making it
difficult to determine if there is actually any content.
The behavior (evaluating to false when there is no content, just
summary) is also now documented.
The Param method currently assumes that its argument is a single,
distinct, top-level key to look up in the Params map. This enhances the
Param method; it will now also attempt to see if the key can be
interpreted as a nested chain of keys to look up in Params.
Fixes#2598
Add a new rssLimit site configuration option with default of 15. Prior
to this fix, you could create your own RSS feed to override the default
limit of 15, but we still had a hardcoded limit of 50 items set in
`hugolib.renderRSS()`.
With this option in place, the `range first 15 .Data.Pages` logic is no
longer hardcoded into the embedded RSS template.
Because the size of the slice passed to the template is now limited to
rssLimit instead of 50, this commit is a breaking change for sites
with a custom RSS template that expects more than 15 items.
Fixes#3035
Aerobatic.io migrated their Bitbucket hosting plugin and no longer provide
a free tier with a custom domain. This tutorial covers setting up Firebase
to host a Hugo site that was previously hosted on Aerobatic.
Allow all nodes/pages to use date-related OpenGraph meta tags, not
only sites which are using the as-of-yet unfinished .Site.Authors
functionality.
Improve compliance of tags with Facebook's OpenGraph docs for the
"website" and "article" types[0][1]. Also, use the proper tag for
modification date (og:update_time vs article:modified_time).
Generate date published using either .PublishDate or .Date, and use
.Lastmod for modification date, which can use the new enableGitInfo
functionality from Hugo 0.18, but seamlessly falls back to .Date if
the site does not have this enabled/supported.
[0] https://developers.facebook.com/docs/reference/opengraph/object-type/website/
[1] https://developers.facebook.com/docs/reference/opengraph/object-type/article/
I've written a DokuWiki to hugo conversion tool in python to migrate my blog content to Hugo. I hope others will also benefit from it. Feel free to take a look and give some feedback.
Note that this looks like overkill for just the logger, and that is correct,
but this will make sense once we start with the template handling etc.
Updates #2701
This commit adds a truncate template function for safely truncating text without
breaking words. The truncate function is HTML aware, so if the input text is a
template.HTML it will be truncated without leaving broken or unclosed HTML tags.
{{ "this is a very long text" | truncate 10 " ..." }}
{{ "With [Markdown](/markdown) inside." | markdownify | truncate 10 }}
HugoPhotoSwipe is a command line tool to create and manage PhotoSwipe galleries with Hugo. It resizes images for responsive layouts in PhotoSwipe and generates the Markdown necessary for Hugo to create the gallery. I think this can be a useful tool for Hugo users.
The new logic for creating Page objects from old node types
didn't include itself in the translation logic, so
`IsTranslated` returned falsely false for sites with only two languages.
The `AllTranslations` method also returned too few pages in that case.
This commit fixes that.
Fixes#2812
The tutorial for installing on windows didn't mention the exact name of the
hugo executable in windows which is generally hugo_<hugo-version>_windows_<arch>.exe.
The tutorial mentioned the windows executable's name as hugo.exe, which
can be confusing sometimes. So extra information has been added to
rename the executable to hugo.exe which would be easy to use.
Fixes#2656
This commit fixes the base template lookup order to match the behaviour of regular templates.
```
1. <current-path>/<template-name>-baseof.<suffix>, e.g. list-baseof.<suffix>.
2. <current-path>/baseof.<suffix>
3. _default/<template-name>-baseof.<suffix>, e.g. list-baseof.<suffix>.
4. _default/baseof.<suffix>
For each of the steps above, it will first look in the project, then, if theme is set,
in the theme's layouts folder.
```
Fixes#2783
Fix golint warning: hugolib/site.go:922:13: should omit type
*helpers.Language from declaration of var lang; it will be inferred from
the right-hand side
See #2014
There are currently several Params and case related issues floating around in Hugo.
This is very confusing for users and one of the most common support questions on the forum.
And while there have been done some great leg work in Viper etc., this is of limited value since this and similar doesn't work:
`Params.myCamelCasedParam`
Hugo has control over all the template method invocations, and can take care of all the lower-casing of the map lookup keys.
But that doesn't help with direct template lookups of type `Site.Params.TWITTER_CONFIG.USER_ID`.
This commit solves that by doing some carefully crafted modifications of the templates' AST -- lowercasing the params keys.
This is low-level work, but it's not like the template API wil change -- and this is important enough to defend such "bit fiddling".
Tests are added for all the template engines: Go templates, Ace and Amber.
Fixes#2615Fixes#1129Fixes#2590
Some sites, Hugo docs included, have faulty alias definitions that point
to itself or another real page. These will be overwritten in the next step.
This is how it behaves in Hugo 0.17, too.
Updates #2297
This includes removing the error return value from Permalink and RelPermalink.
We ignore that error all over the place, so we might as well remove it.
Updates #2297
To make it easier to follow and understand.
Both building and rebuilding now follow a four step flow:
1. Init
2. Process
3. Assemble
4. Render
And now there are only one Build method, used for both builds and rebuilds.
Updates #2297
There are currently several Params and case related issues floating around in Hugo.
This is very confusing for users and one of the most common support questions on the forum.
And while there have been done some great leg work in Viper etc., this is of limited value since this and similar doesn't work:
`Params.myCamelCasedParam`
Hugo has control over all the template method invocations, and can take care of all the lower-casing of the map lookup keys.
But that doesn't help with direct template lookups of type `Site.Params.TWITTER_CONFIG.USER_ID`.
This commit solves that by doing some carefully crafted modifications of the templates' AST -- lowercasing the params keys.
This is low-level work, but it's not like the template API wil change -- and this is important enough to defend such "bit fiddling".
Tests are added for all the template engines: Go templates, Ace and Amber.
Fixes#2615Fixes#1129Fixes#2590
* Add information about average time, memory consumption and
allocations.
* Fix situation, when user provides memprofile and cpuprofile, but
cpuprofile will not created.
Fixes#2432
Add imageConfig function which calls image.DecodeConfig and returns the height, width and color mode of the image. (#2677)
This allows for more advanced image shortcodes and templates such as those required by AMP.
layouts/shortcodes/amp-img.html
```
{{ $src := .Get "src" }}
{{ $config := imageConfig (printf "/static/%s" $src) }}
<amp-img src="{{$src}}"
height="{{$config.Height}}"
width="{{$config.Width}}"
layout="responsive">
</amp-img>
```
tpl/template_funcs.go:1019:3: the surrounding loop is unconditionally terminated
source/lazy_file_reader.go:66:5: err != nil is always true for all possible
values ([nil:error] != [nil:error])
This commit adds a `GitInfo` object to `Page` if `EnableGitInfo` is set.
It then also sets `Lastmod` for the given `Page` to the author date provided by Git.
The Git integrations should be fairly performant, but it adds "some time" to the build, somewhat depending on the Git history size.
If you want, you can run without during development and turn it on when deploying to the live server: `hugo --enableGitInfo`.
Fixes#2102
changes:
- in hugolib/page.go, `func permalink` and `func TargetPath`
Fixed the attempt to *replace* the extension of something
that was *already* a basename.
- in source/file.go, `func NewFile`
added check for allowed languages before translating filename
Fixes#2555
- removed comma on line 16 to avoid confusion between clauses
- added period to line 24 for consistency
- clarified "read on" on line 30 to follow style above it while
also verbally writing what the author seems to intend
- removed "You probably know what to do." on line 30 due to wordiness
that could lead to confusion and a drag in reading speed
- changed preposition into intended infinitive for syntactical clarity
- removed "easily" as it doesn't describe anything technical and is
confusing (which is why the author may have used a preposition)
All config variables starts with low-case and uses camelCase.
If there is abbreviation at the beginning of the name, the whole
abbreviation will be written in low-case.
If there is abbreviation at the end of the name, the
whole abbreviation will be written in upper-case.
For example, rssURI.
The gain, given the "real sites benchmark" below, is obvious:
```
benchmark old ns/op new ns/op delta
BenchmarkHugo-4 14497594101 13084156335 -9.75%
benchmark old allocs new allocs delta
BenchmarkHugo-4 57404335 48282002 -15.89%
benchmark old bytes new bytes delta
BenchmarkHugo-4 9933505624 9721984424 -2.13%
```
Fixes#2495
Add logging of the errors/warnings which rst2html outputs to its stderr
stream when rendering rst documents. Note that rst2html outputs warnings
and errors to stderr but it also adds them to the generated html. ->
hugo logs everything in stderr as error.
Add / complete adding page context (path to file being rendered) to
anything logged by getRstContent and getAsciidocContent.
See #2570
Also refactor the rendering pages test to accept more than one page source per test run, which wasn't really needed for this issue, but may be in the future.
Closes#2586Fixes#2538
Maps in Viper, Hugo's config backing store, is now properly lower-cased not just on top level, the current situation.
While this is mostly a good thing, as you don't need to know the original casing to look up a value, it will be breaking for people doing direct lookups in the ´Site.Params` map.
We will try to find a solution to this "breakage", but the recommended method to get params values is via the `.Param` methods.
This method is now implemented on `Node`, `Page` and `Site` and is case-insensitive:
* Use `.Param "someKey" ` if you want page param with fall back to site param if not found on page.
* Use `.Site.Param "someKey"` to get a site param
See #2590
This change adds a canonical alias.html template that is used for page
redirects, and passes the page as data to the template under .Page
Fixes#2533Closes#2576
Add DocumentName (path to the file being rendered) to RenderingContext
and use that information to include the path in the error print.
See #2399Closes#2567
Add logging of the errors which asciidoc and asciidoctor output to their
stderr stream when converting asciidoc documents. Note that
asciidoctor's exit code may be SUCCESS even if there are ERROR messages
in its stderr output (tested with Asciidoctor 0.1.4 and 1.5.5).
Therefore log the stderr output whenever it is non-empty.
See #2399
Changes `%q` to `%s`. `%q` was safely escaping the `\` in windows so that it was printing `\\`. Uses `filepath.Join` for example filepath so that the output is OS specific and since this required splitting up the multiline string, it's refactored into a separate function..
Fixes#2401
Organize CSS and Javascript files into directories, separating vendor
source code from home-grown.
Separate new properties and selectors in Bootstrap CSS (already edited
for Hugo) from:
1. Original property values; and
2. Changed property values.
For the home page:
1. Clarify the English text;
2. Add some element names to classes in CSS selectors (to speed loading);
3. Document the Owl Carousel and Highlight.js versions;
4. Add Owl Carousel's license;
5. Restore HTML comments to browser source views;
6. Make the beginning GitHub button transparent on focus (like the others);
7. For the final, colored Twitter and Github buttons:
a. Remove the dotted box on focus; and
b. Color them green on active.
8. To increase (layout/) source readability:
a. Place `class` attributes before `href` attributes;
b. In `class` attributes, place more-specific class names before
less-specific; and
c. Comment the beginnings and ends of Bootstrap rows.
9. To increase understandability during development:
a. Document the meaning of CSS file, `HPstyles` by renaming it to
`home-page-style`;
b. Move inline styling to CSS stylesheets;
c. Separate @media queries to a file;
d. Separate the inline Owl Carousel custom Javascript to a file;
e. Use regular Owl Carousel CSS files instead of minified ones; and
f. Rename the wide, landscape desk background image filename from
`desk-long` to `desk-wide`.
* Make the type/var names more specific. They live in the test namespace, but there are other tests there.
* Camel case variable
* Small change suggested by Golint
There were some breaking changes etc. that is too late to fix for 0.17.
Let us think this through and add proper author support for Hugo 0.18.
Fixes#2464
Revert "docs: Add documentation for author profiles"
This reverts commit b6673e5309.
Revert "Add First Class Author Support"
This reverts commit cf978c0649.
This avoids having to execute these expensive operations for sites not using these values.
This commit sums up a set of wordcounting and autosummary related performance improvements.
The effect of these kind of depends on what features your site use, but a benchmark from 4 Hugo sites in the wild shows promise:
```
benchmark old ns/op new ns/op delta
BenchmarkHugo-4 21293005843 20032857342 -5.92%
benchmark old allocs new allocs delta
BenchmarkHugo-4 65290922 65186032 -0.16%
benchmark old bytes new bytes delta
BenchmarkHugo-4 9771213416 9681866464 -0.91%
```
Closes#2378
It is obviously more efficient when we do not care about the actual words.
```
BenchmarkTotalWords-4 100000 18795 ns/op 0 B/op 0 allocs/op
BenchmarkTotalWordsOld-4 30000 46751 ns/op 6400 B/op 1 allocs/op
```
For people using autogenerated summaries, this is one of the hot spots in the memory department.
We don't need to split al the content into words to do proper summary truncation.
This is obviously more effective:
```
BenchmarkTestTruncateWordsToWholeSentence-4 300000 4720 ns/op 0 B/op 0 allocs/op
BenchmarkTestTruncateWordsToWholeSentenceOld-4 100000 17699 ns/op 3072 B/op 3 allocs/op
```
Hugo 0.16 announced support for symbolic links for the root folders, /content, /static etc., but this got broken pretty fast.
The main problem this commit tries to solve is the matching of file change events to "what changed".
An example:
ContentDir: /mysites/site/content where /mysites/site/content is a symlink to /mycontent
/mycontent:
/mypost1.md
/post/mypost2.md
* A change to mypost1.md (on OS X) will trigger a file change event with name "/mycontent/mypost1.md"
* A change to mypost2.md gives event with name "/mysites/site/content/mypost2.md"
The first change will not trigger a correct update of Hugo before this commit. This commit fixes this by doing a two-step check:
1. Check if "/mysites/site/content/mypost2.md" is within /mysites/site/content
2. Check if "/mysites/site/content/mypost2.md" is within the real path that /mysites/site/content points to
Fixes#2265Closes#2273
Atomic operations with 64 bit values must be aligned for 64-bit on x86-32.
According to the spec:
"The first word in a global variable or in an allocated struct or slice can be relied upon to be 64-bit aligned."
The above wasn't enough for the `paginationPageCount` on `SiteInfo`, maybe due to how `SiteInfo` is embedded.
This commit adds a 4 byte padding before the `uint64` that creates the correct alignment.
Fixes#2415
This is the nth attempt to fix an issue by changing the placeholder token pattern, but
now we actually have tests for all the historic trouble cases.
Fixes#2223
So the Permalink gets correct when listing translations.
I have also checked the other relevant places to make sure we do not overwrite node values we need later.
Pointers can be tricky, but lesson learned is: A copy is cheap.
Updates #2309
For people having trouble building this.
Now `hugo version` should print something like:
```
Hugo Static Site Generator v0.17-MULTILINGUAL BuildDate: 2016-08-10T08:20:36+02:00
```
In a multi-language setup, before this commit the Node's Translations() method
would return some "dummy nodes" that would point to the correct page (Permalink),
but would not be the same as the node it points to -- it would not have the translated
title etc.
The node creation is, however, so mingled with rendering, whihc is too early to have any global state,
so the nodes has to be split in a prepare and a render phase. This commits does that with as small
a change as possible. This implementation is a temp solution until we fix#2297.
Updates #2309
* Fall back to default language on missing translation file
* Add a i18n-warnings build flag
* If that flag is set, print a parseable and greppable string on missing translation strings
See #2303
The current "rendering language" is needed outside of Site. This commit moves the Language type to the helpers package, and then used to get correct correct language configuration in the markdownify template func.
This commit also adds two new template funcs: relLangURL and absLangURL.
See #2309
This is needed to verify #2309, but it closes a big hole in Hugo's automated tests.
The loading of the config is now moved to `hugolib` and the same default settings are now used
in production and tests.
As Viper now uses Afero as its filesystem, we now can write fairly complete integration tests with ease.
See #2309
And in the same go adjusted some minor parts of the language API:
Add LanguagePrefix alias to Node and rename the Multilingual config section to Languages.
See #2309
This is needed to make shortcode users happy with the new multilanguage support,
but it will also solve many other related posts about "stuff not available in the shortcode".
We will have to revisit this re the handler chain at some point, but that will be easier
now as the integration test story has improved so much.
As part of this commit, the site-building tests in page_test.go is refreshed, they now
tests for all the rendering engines (when available), and all of them now uses the
same code-path as used in production.
Fixes#1229Fixes#2323
Fixes ##1076
Work In Progress!
This commit makes a rework of the build and rebuild process to better suit a multi-site setup.
This also includes a complete overhaul of the site tests. Previous these were a messy mix that
were testing just small parts of the build chain, some of it testing code-paths not even used in
"real life". Now all tests that depends on a built site follows the same and real production code path.
See #2309Closes#2211Closes#477Closes#1744
This commit also consolidates URLs on Node vs Page, so now .Permalink should be interoperable.
Note that this implementations should be fairly short-livded, waiting for #2297, but the API should be stable.
Setting the language to use when loading the language bundles just doesn't work.
The template system is unfortanetely a global, and the last languate processed won ...
And a Hugo global variable which contains the site under build.
This is really needed to get some level of control of the "multiple languages" in play.
There are still work related to this scattered around, but that will come.
With this commit, the multilingual feature is starting to work.
Implements:
* support to render:
* content/post/whatever.en.md to /en/2015/12/22/whatever/index.html
* content/post/whatever.fr.md to /fr/2015/12/22/whatever/index.html
* gets enabled when `Multilingual:` is specified in config.
* support having language switchers in templates, that know
where the translated page is (with .Page.Translations)
(when you're on /en/about/, you can have a "Francais" link pointing to
/fr/a-propos/)
* all translations are in the `.Page.Translations` map, including the current one.
* easily tweak themes to support Multilingual mode
* renders in a single swift, no need for two config files.
Adds a couple of variables useful for multilingual sites
Adds documentation (content/multilingual.md)
Added language prefixing for all URL generation/permalinking see in the
code base.
Implements i18n. Leverages the great github.com/nicksnyder/go-i18n lib.. thanks Nick.
* Adds "i18n" and "T" template functions..
Highlight.js has evolved quite a bit since it this doc was written. Updating the example to the latest 9.6 version of Highlight JS hosted by cloudflare
Hugo seems to ignore the meminterval I specify and always uses it's default of 100ms.
This seems to be because Hugo tries to take the meminterval from the command line
(an Int) and converts it to a String and passes it to time.ParseDuration. If you pass a
different meminterval (such as `1000` as above) it will fail (time.ParseDuration requires
some units) and use the default instead.
Changed `meminterval` to be a String and added better documentation for valid time units.
Resolves: #2325
On 4679fbee41, rebuild was disabled on
CHMOD filesystem events, but the code is overly aggressive.
In some situations, specially with older Mac's (using a Late 2008
Macbook), the events we receive might be aggregated. On my
particular laptop, I get this events:
INFO: 2016/07/26 18:08:51 hugo.go:737: Received System Events: ["<path>": WRITE|CHMOD]
These events are ignored because the code only checks for Chmod. This
commit fixes this by checking that the event is also not a Write or Create.
Related to #1587.
i.e., "The PATH entry should be the folder where Hugo lives, not the binary."
Fixes#2280.
Also fix a rendering issue with list entries that consist of multiple
paragraphs by using four spaces instead of two. Special thanks to
@shurcooL for the insight! (Fixes#2285)
Also made a few minor formatting tweaks.
These functions allow trivial escaping and unescaping of HTML entities,
and make it far easier to compose other functions for the creation of
parameterised URLs.
We have to figure out another way. There are perfectly valid reasons not having a layout for a page (I have have some broken sites as result of this).
See #1313
This reverts commit b15934008f.
Add logic to tpl.humanize such that it understands input of int literals
or strings which represent an integer. When tpl.humanize sees this type
of input, it will use inflect.Ordinalize as opposed to the standard
inflect.Humanize.
Fixes#1886
The query function will take a set of parameters specified like a dict and return a url.Values object which can be .Encode'd into a query string.
Example:
<a href="http://www.google.com?{{ (querify "q" "test" "page" 3).Encode | safeHTML }}">Search</a>
Returns:
<a href="http://www.google.com?page=3&q=test">Search</a>
Closes#2257
If hugo server is run on port 80 or 443, LiveReload does not
correctly bind to the same port, instead using port 35729.
This commit adds functionality to inform LiveReload of the
correct port to bind to.
See https://github.com/livereload/livereload-js/issues/16
Partially contributed by Jeff Minard (@chuyskywalker).
Fixes#2205
The install tutorial instructed users to rename the *.exe file to
hugo.exe because it used to have a big long name.
In Hugo 0.16 the file is already named hugo.exe, so the tutorial
made no sense on that point. Edited out those instructions.
Refactor the contribution guidelines in the README and CONTRIBUTING
files.
Simplify the contribution guide in the README and move most of the
complex stuff into CONTRIBUTING.
Add an explicit commit message guidelines section to CONTRIBUTING. Keep
all of the guidelines from Chris Beams except for the 72 character line
limit (we don't follow that, nor does the Go team). Add three new
guidelines: package prefix in subject, references in body, and
encouragement of message body in general.
Add a new section to CONTRIBUTING on using Git Remotes.
This issue was introduced as a fix to shortcode not working in RST.
One could argue that Blackfriday and friends should handle `#` in titles, but that will be a discussion
for another day.
The new placeholder pattern should be RST safe and work with titles.
And now with a test so this doesn't break again.
Fixes#2192Fixes#2209Closes#2210
A couple of internal links use `#toc_4` to attempt to locate a document
element within another document page. In both of these instances, there
is no element on the linked to pages with the id `#toc_4`. This commit
updates those links with the document elements which were the original
intended links, meaning these links now take you directly to the
intended element.
Signed-off-by: mattjmcnaughton <mattjmcnaughton@gmail.com>
Returns true if a given field value that is a slice / array of strings, integers or floats contains elements in common with the matching value. It follows the same rules as the intersect function.
Closes#1945
Useful if using or sharing files with users that use editors that
append a unicode byte order marker header (like Windows notepad).
This will still assume files are UTF-8 encoded.
Closes#2075
The procedure Start button --> Settings --> About was missing a step. Corrected it to: Start --> Settings --> System --> About. Also replaced ASCII arrows (-->) with Unicode right arrow character (U+2192).
If Page.Markup was not set by the user, it will now be set after
guessing from the file extension. This means, Page.Markup will be set in
any case. It can be used by a theme to differentiate between markup
types.
Fixes#1950
We should get some new ones in there.
Also shuffle the order. This also means no merging into 0.15-docs ...
Which also means we should get a release out there ... soon!
See #2055
Also See https://github.com/BurntSushi/toml/issues/129 for an explanation to the little bit ugly dates.
Meny people, including me, have a custom robots.txt in static.
Also remove that option from the command line; it doesn't feel
important enough.
Fixes ##2049
This disables highlighting for fenced code blocks without explicitly specified language. It also introduces a new `PygmentsCodeFencesGuessSyntax` config option (defaulting to false).
To enable syntax guessing again, add the following to your config file: `PygmentsCodeFencesGuessSyntax = true`
This is a breaking change.
While sorting on data sources with missing fields, a panic can occur in
pairList.Less if `Interface()` is called on a invalid `reflect.Value`.
This commit detects an invalid Value and replacing it with a zero value
for the comparison.
This also includes a refactor of the hugofs package and its usage.
The motivation for that is:
The Afero filesystems are brilliant. Hugo's way of adding a dozen of global variables for the different filesystems was a mistake. In readFile (and also in some other places in Hugo today) we need a way to restrict the access inside the working dir. We could use ioutil.ReadFile and implement the path checking, checking the base path and the dots ("..") etc. But it is obviously better to use an Afero BasePathFs combined witha ReadOnlyFs. We could create a use-once-filesystem and handle the initialization ourselves, but since this is also useful to others and the initialization depends on some other global state (which would mean to create a new file system on every invocation), we might as well do it properly and encapsulate the predefined set of filesystems. This change also leads the way, if needed, to encapsulate the file systems in a struct, making it possible to have several file system sets in action at once (parallel multilanguage site building? With Moore's law and all...)
Fixes#1551
It is a fairly costly operation:
```
benchmark old ns/op new ns/op delta
BenchmarkScratchGet-4 109 31.6 -71.01%
benchmark old allocs new allocs delta
BenchmarkScratchGet-4 0 0 +0.00%
benchmark old bytes new bytes delta
BenchmarkScratchGet-4 0 0 +0.00%
´´´
Add some helpful tasks to the Makefile to make it easier to test code quality
prior to committing. Use `make check` to run the standard checks. As of now,
the cyclo and lint tasks are not part of the standard checks since Hugo doesn't
pass those checks.
To strip away any HTML. May be useful for the .Title in head etc.
People may shoot themself in the foot with this, maybe ...
The replacement function is pretty fast.
NewContent is refactored to use the afero.Fs interface that should allow
full testing. This commit also pulls the metadata creation logic out of
NewContent and into a separate function to decrease the cyclomatic
complexity of NewContent.
The `intersect` function uses `in` to avoid adding duplicates to the
resulting set. We were passing `reflect.Value` items when we should
have been using `Value.Interface()` to send the actual data structure.
This fixes that.
See #1952
- updated the instructions to account for Windows 10 path editor
- linked to third-party editors for pre-10 Windows
- separated instructions for technical and non-technical users changed
D drive paths to C drive since D is the default optical drive on most
Windows systems
- cut the assumption about 64-bit Windows since 32-bit binary is also available
- cut the assumption about command line since we're giving GUI instructions
to non-technical users
- cut a bug in the doc where we had people typing D: at the command prompt
*after* submitting `cd D:\Hugo\Sites.` Recommend snipping 386 and AMD from
ZIP file names, since they don't add useful info and will just confuse novices.
This uses the Emoji map from https://github.com/kyokomi/emoji -- but with a custom replacement implementation.
The built-in are fine for most use cases, but in Hugo we do care about pure speed.
The benchmarks below are skewed in Hugo's direction as the source and result is a byte slice,
Kyokomi's implementation works best with strings.
Curious: The easy-to-use `strings.Replacer` is also plenty fast.
```
BenchmarkEmojiKyokomiFprint-4 20000 86038 ns/op 33960 B/op 117 allocs/op
BenchmarkEmojiKyokomiSprint-4 20000 83252 ns/op 38232 B/op 122 allocs/op
BenchmarkEmojiStringsReplacer-4 100000 21092 ns/op 17248 B/op 25 allocs/op
BenchmarkHugoEmoji-4 500000 5728 ns/op 624 B/op 13 allocs/op
```
Fixes#1891
This commit adds a custom index template function that deviates from the stdlib
simply by not returning an "index out of range" error if an array, slice or
string index is out of range. Instead, we just return nil values. This should
help make the new default function more useful for Hugo users.
Fixes#1949
This commit fixes a few things:
1. `given` is now a variadic parameter so that piping works properly
2. add separate template tests to make sure piping works
3. support time values
4. add more tests of the dfault function
Hugo has been confirmed which runs on Golang 1.6, as travis uses 1.6
vesion. Dockerfile must be consistend with it so it has to use golang:1.6
as base image than golang:1.5
We can of course skip reading the entire byte slice again and again.
This was a slip in the original implementation; functionally the same,
but is slightly faster, esp. for larger data sets with many shortcodes:
```
benchmark old ns/op new ns/op delta
BenchmarkReplaceShortcodeTokens-4 15505 14753 -4.85%
benchmark old allocs new allocs delta
BenchmarkReplaceShortcodeTokens-4 1 1 +0.00%
benchmark old bytes new bytes delta
BenchmarkReplaceShortcodeTokens-4 3072 3072 +0.00%
```
The original image was 2055px × 1252px, which was oversized
and did not fit the required dimension of 600px × 400px
(3:2 aspect ratio).
To fix, the image was cropped and resized to the required dimension,
and was further optimized:
$ pngquant --nofs -v --speed 1 --quality 65-80 shelan-tn.png
$ optipng -o7 -zm1-9 shelan-tn-or8.png
$ mv shelan-tn-or8.png shelan-tn.png
reducing its filesize from 334125 bytes to 26929 bytes.
See #1831
The common is the `where` func and this:
```
panic: reflect: call of reflect.Value.Type on zero Value [recovered]
panic: reflect: call of reflect.Value.Type on zero Value
```
There is no good reason to export all the template funcs:
* They're not used outside the templates.
* If usable in other packages, they should be moved (to helpers?)
* They create too broad an interface;
users of the tpl package don't see the forest for all the trees.
Add humanize (inflect.Humanize) to the template funcMap. Documentation and
tests are included.
Various code cleanups of the template funcs:
- Break pluralize and singularize out into stand-alone funcs.
- Sort the list of funcMap entries.
- Add some minimal godoc comments to all public funcs.
- Fix some issues found by golint and grind.
Started to increase coverage in helpers package, now at 74.9% of statements.
In the process, also a few minor changes have been applied to content.go.
* Content.go has undergone a formatting refactor regarding comments
* Unused function TruncateWords has been removed
* RenderingContext's "mmark" has been changed to use MmarkRender
* Content_test.go added to cover content.go's functionality
Site.ReadPagesFromSource returns nil chan error value when a site
content directory is empty but its receiver expects to be passed
something error values via the channel.
This fixes it by returning a channel which will be immediately closed.
Fix#1797
Fixed a path in a Page Params example to reflect real directory
structure, removed extra quotes from sample code, and fixed link to
Archetypes which read "cross-references" before.
See #1805
Expanded on the use of Page Params in the templates/variables.md
documentation. Added sample code for something that keeps coming up on
discuss.github.io
See #1772
Also, force DisableLiveReload to true when running "hugo --watch"
(build-only non-server mode) to prevent livereload.ForceRefresh(),
which would end up blocking watchConfig() forever, from being called
because livereload.Initialize() is never called in this case.
This fixes the bug where "hugo --watch" could only reload config.toml
once before it gets stuck for good at livereload.ForceRefresh().
This is also consistent with Hugo's existing behaviour:
Non-server "hugo --watch" has never injected livereload.js
since the inception of the "watch" feature in Hugo v0.12.
This fixes a exported field check condition in a way described at Go
issue https://golang.org/issue/12367
According to the issue comments, this fix should be safe under Go 1.6.
Remind user to always run "brew update" first in order to avoid
repeated bug reports from users who didn't do that.
See #824, #1067, #1537, #1633 and #1749
Update on the watcher copy static to copy only the
changed files and add an flag forceSyncStatic to
copy all statics always a static is changed
See #1644#1559
- Upgrade Bootswatch Yeti theme (3.2.0+3 → to 3.3.6)
- Upgrade Font Awesome (4.2.0 → 4.5.0)
- Upgrade jQuery (1.11.1 → 1.11.3)
Also keep the upstream filenames, e.g. bootstrap.min.css rather than
bootstrap.css for the minified CSS, and jquery-1.11.3.min.js rather than
jquery.js for the minified jQuery.
with the following added languages in anticipation of document expansion:
apache dockerfile dos less php powershell python tex yaml
To reproduce docs/static/js/highlight.pack.js on Debian/Ubuntu:
$ sudo apt-get install nodejs npm
$ wget https://github.com/isagalaev/highlight.js/archive/9.0.0.tar.gz
$ tar xzf 9.0.0.tar.gz
$ cd highlight.js-9.0.0/
$ npm install
$ nodejs tools/build.js markdown asciidoc xml css javascript \
ini yaml json go bash diff dockerfile dos powershell makefile \
apache nginx tex http php python ruby django haml handlebars \
scss less coffeescript
Then, copy the resulting build/highlight.pack.js as well as
src/styles/monokai-sublime.css to the appropriate Hugo docs directories.
because our bootstrap-theme.css was originally a customized
core bootstrap.css file from Bootstrap v3.0.0.
This rename helps to avoid confusion with Bootstrap’s official
bootstrap-theme.css files.
The GitHub octicons fonts, which, in our case, came with GitHub:buttons,
are not actually used on gohugo.io. Rather, the icons inside the GitHub
buttons are actually glyphs from Font Awesome.
The GitHub:buttons JavaScript code docs/static/js/buttons.js
from https://github.com/ntkme/github-buttons was referenced
in docs/layouts/partials/footer.html but never used.
Apparently, the actual code for the GitHub buttons on the upper-left
corner of gohugo.io documentation was written by @spf13 in
docs/static/js/scripts.js.
especially when the given `--source` path is a relative directory.
Also, when `--source` is specified, make WorkingDir an absolute path
from the very beginning, to be consistent with the case when `--source`
is not given. Otherwise, the function name helpers.AbsPathify(), which
prepends WorkingDir to a relative path, does not really make sense.
Fixes#1721
v0.15 had it, but I removed it inadvertently for 0.16-DEV
in commit 00d04774 in PR #1652.
Also add directory bash-completion for `--source`
for `hugo convert`, `hugo list` and `hugo new`.
See #1624, #1589
`where` template function's internal condition check function doesn't
check boolean values and always returns `false` silently.
This adds missing boolean value comparison to the function.
`where Values ".Param.key" true` like clause can be used.
Only "=", "==", "eq", "!=", "<>", "ne" operators are allowed to be used
with a boolean value. If an other operator is passed with it, the
condition check function returns `false` like before.
The crash was introduced by commit 00d04774 in PR #1652
where access to NoTimes was attempted even though --noTimes
was not defined for the config, check and benchmark commands.
Special thanks to @bep for the heads-up!
See also #1624 - CLI UX: Flags shouldn't be global
This is to ensure that only the relevant command-line flags
for a certain Hugo subcommand is shown to the end user,
reducing clutter and improving user experience.
Fixes#1624 - CLI UX: Flags shouldn't be global
The `gh` shortcode has two modes: users and issues. For user mode, pass a list
of `@username` arguments. For the issues/PR mode, pass a list of issue or PR
numbers. PRs link to the "issues/" URL since Github redirects to the correct
URL.
Thanks to @ryanclarke for suggesting an improved template.
Cobra, the CLI commander in use in Hugo, has some long awaited improvements in the error handling department.
This enables a more centralized error handling approach.
This commit introduces that by changing all the command funcs to `RunE`:
* The core part of the error logging, usage logging and `os.Exit(-1)` is now performed in one place and that one place only.
* The usage text is now only shown on invalid arguments etc. (user errors)
Fixes#1502
Hugo command provides "noTimes" flag but it doesn't affect synced files
timestamp regardless of whether the flag is specified or not.
This fixes it by adding a flag check and overwriting configuration if it
is specified.
Fix#1583
Hugo command doesn't copy site's "static" directory files to "public"
directory if a specified theme doesn't have "static" directory because
theme's "static" directory checking always returns an error.
This fixes it by just showing a warning message about theme's "static"
directory absence and not skipping following processes.
Fix#1655
Also add a note saying that these blackfriday flags are
very case-sensitive as of Hugo v0.15.
Thanks to @ryanclarke for noticing the change in behaviour.
See also spf13/hugo@5838420
It would be helpful to know whether a shortcode was called with positional or
named parameters. This commit adds a boolean `IsNamedParams` property to the
`ShortcodeWithPage` struct.
using pngquant and OptiPNG. Result:
arresteddevops-tn.png 154734 bytes → 47184 bytes
maximeguitare-tn.png 95571 bytes → 24183 bytes
ridingbytes-tn.png 262222 bytes → 66491 bytes
And a small one to an even smaller one too:
goin5minutes-tn.png 26220 bytes → 9297 bytes
Write and rename operations are often followed by CHMOD.
There may be valid use cases for rebuilding the site on CHMOD,
but that will require more complex logic than this simple conditional.
On OS X this seems to be related to Spotlight, see:
https://github.com/go-fsnotify/fsnotify/issues/15
A workaround is to put your site(s) on the Spotlight exception list,
but that may be a little mysterious for most end users.
So, for now, we skip reload on CHMOD.
This small commit will be a 100% improvement for most OS X-users.
Fixes#1587
Currently a `[]byte` copy is returned. In most cases this is the safe thing to do, but we should just modify/grow the slice as needed.
This is faster and consumes less memory:
```
benchmark old ns/op new ns/op delta
BenchmarkReplaceShortcodeTokens-4 7350 4419 -39.88%
benchmark old allocs new allocs delta
BenchmarkReplaceShortcodeTokens-4 5 1 -80.00%
benchmark old bytes new bytes delta
BenchmarkReplaceShortcodeTokens-4 4816 1152 -76.08%
```
This commit is aso a small spring cleaning of duplicated code in the different `PageConvert` methods.
Fixes#1516
Page.GroupByParam function internally uses Page.GetParam to get a
parameter value for a key of a page group but now Page.GetParam returns
a lowercase character string every time. It has no need to using
lowercase character string as a group key value and it confuse a
function user.
This fixes it to keep and return an original parameter string as a group
key value.
Fix#1564
Prevent some frequently occurring problems
* Ensure version number is between quotes
* Ensure git and SSH are installed for the deployment step
* Focus extra attention on the wercker.yml verification site
To allow the end users to disable any form of smart dashes
(LaTeX-style or not) while keeping the rest of Blackfriday
SmartyPants features.
Depends on https://github.com/russross/blackfriday/pull/190
"Add HTML_SMARTYPANTS_DASHES for toggling smart dashes"
to be accepted by Blackfriday developers.
All-around improvements to the README.
Each sentence now gets its own line to eliminate ultra-long lines in the
source (expect in bullet points--separating a bullet point into multiple
lines looks weird and decreases readability).
HTTPS links are now preferred to HTTP links and used where applicable.
Link to Mercurial's website corrected to www.mercurial-scm.org
Link to Hugo's docs is now accessible with [Hugo Documentatio][] since
it is used more than once in the README.
Multiline code blocks are now fenced rather than indented and include
syntax highlighting.
If flag is passed the site will be created inside non-empty folder
only if there are no existent folders or config with the same name
hugo creates.
Resolves: #1163
The lack of the directory would be worth to warn, since the directory is
created by "huge new site". But it doesn't have to fail the build.
This change fixes#759.
Inserts a code tag into Pygments output with the language-info that is present when using client-side highlighting (useful for CSS hooks)
```html
<code class="language-go" data-lang="go">
```
closes#1490
* add global `hasCJKLanguage` flag, if true, turn on auto-detecting CJKLanguage
* add `isCJKLanguage` frontmatter to force specify whether is CJKLanguage or not
* For .Summary: If isCJKLanguage is true, use the runes as basis for truncation, else keep as today.
* For WordCount: If isCJKLanguage is true, use the runes as basis for calculation, else keep as today.
* Unexport RuneCount
Fixes#1377
usage: hugo import jekyll jekyll_root_path target_path
Implemented:
* Create new hugo site
* Create config.yaml
* Convert all markdown contents.
* Copy all other files and folders to static
Fixes#101
Add validation before creating aliases:
* Prevent creating aliases outside webroot (public/ dir)
* Skip empty "" alias
* Skip "/" → "/index.html", which gets overwritten anyway
* Refuse to create Windows-invalid filenames on Windows;
warn on other platforms
* In case of invalid aliases, after skipping them,
return `err = nil` to prevent the error passing up
all the way to `hugolib.Render()` and causing Hugo to abort.
* Update alias tests.
Fixes#701: Add support for alias with whitespace
Fixes#1418: Add validation for alias
It currently handles --baseUrl to --baseURL, and --uglyUrls to --uglyURLs.
Special thanks to Eric Paris (@eparis) for writing the
"normalized name" support in Cobra, and for showing us
how it is used in Kubernetes.
See Issue #959
Increases clarity on the different between `section` and `type`.
The current `section` information here is wrong (sections can *not* be specified in front matter). This caused quite the headache. This change fixes this and also adds `type`, since it *can* be specified in front matter.
A new "published" setting that is the opposite of "draft" is added and
left intentionally undocumented.
This setting comes from jekyll and eases the transition to hugo
greatly. We leave it undocumented so that folks don't rely on it, but
also don't shoot themselves in the foot during a jekyll migration.
The foot-shooting occurs if they have only a few documents that were
drafts ("published: false") in the jekyll version of their site and
don't notice that they were published in the migration to hugo.
Simple ioutil.ReadFile is used for reading file contents but it reads
all of the file contents and copies them into the memory and is run in a
single goroutine. It causes much memory consumption at copying media
files in content directory to publish directory and it is not good at
performance.
This improves the both issue by replacing ReadFile with LazyFileReader.
It postpones reading the file contents until it is really needed. As the
result, actual file read is run in parallelized goroutine. It improves
performance especially in a really big site.
In addition, if this reader is called from io.Copy, it does not copy the
file contents into the memory but just copies them into destination
file. It improves much memory consumption issue when the site has many
media files.
Fix#1181
LazyFileReader is an io.Reader implementation to postpone reading the
file contents until it is really needed. It is introduced for improving
performance and memory consumption at reading media files in content
directory.
As of 2015-08-16, Viper no longer searches the CWD
for config file by default to avoid unintended surprises,
but Hugo relies on the original behaviour.
Fixed by calling
viper.AddConfigPath(".")
at the appropriate place.
See https://github.com/spf13/viper/issues/73 for more information.
Fixes#1363
Some of the thumbnails in Showcase were out of place
because of several irregularly sized thumbnails,
and some of them almost 300KB in filesize.
Resize them all to 600x400 (pixels), and use the `-tn.png`
suffix.
When necessary, the website snapshot is re-captured using
gnome-web-photo. Then, the following commands (or a combination
thereof) are used to crop and resize the image into a thumbnail,
and to reduce its filesize:
$ convert example.png -crop 900x600+0+0 \
-filter Lanczos2Sharp -distort Resize 600x400 \
example-tn.png
$ pngquant --nofs -v --speed 1 --quality 65-80 example-tn.png
$ optipng -o7 -zm1-9 example-tn-or8.png
$ mv example-tn-or8.png example-tn.png
To prevent "Showcase" from becoming "Showcases",
also to have the RSS feed display correct titles,
i.e. "Showcase on gohugo.io" rather than "Showcase on ".
As Hugo now supports more formats thanks to the new "external helpers"
feature recently introduced, and as requested by some people, I added
some lines in the doc:
* basically confirming it actually exists
* how to use it
'sort' template function used to accept only each element's struct field
name, method name and map key name as its second argument. This extends
it to accept a field/method/key chaining key string like
'Params.foo.bar' as the argument. It evaluates sub elements of each
array or map elements and sorts by them.
Typical use case would be sorting pages by user defined front matter
value. For example, sorting pages by 'Params.foo.bar' is possible by
writing the following template code
{{ range sort .Data.Pages "Params.foo.bar" }}
{{ .Content }}
{{ end }}
It ignores all leading and trailing dots so "Params.foo.bar" can be
written in ".Params.foo.bar"
This also fixes the issue that 'sort' cannot evaluate a pointer value.
Fix#1330
sort template function returns `[]interface{}` type slice value
regardless of its original element type.
This fixes it to keep the original element type. For example, if it
sorts `map[string]int` type value, it returns `[]int` slice value
instead of `[]interface{}` slice value.
When a YAML/TOML's delimiter character sequence is included in a
frontmatter string, parser mistakes it as a delimiter. This fixes it by
checking a character right before the delimiter sequence is '\n' or it
is the beginning of the frontmatter.
Fix#1320
This simplifies the retrieval of the HTML (no more need to extract the
part within body) and also removes the unwanted "Last Updated" part in
the article.
- Add a step to Contributor instructions for those modifying commands
- Change forum link to http (https does not work)
- Add "Sign the forum release thread" to contributor instructions
The custom sort functions used from the templates had some subtle data race- and related issues,
especially when used in the single page template.
This commit fixes this by making copies and protect the read and writes with a RWMutex.
The results are cached (it will typically be invoked *number of pages* times with exactly the same data).
This is, not surprisingly, also faster:
```
benchmark old ns/op new ns/op delta
BenchmarkSortByWeightAndReverse 14228 491 -96.55%
benchmark old allocs new allocs delta
BenchmarkSortByWeightAndReverse 1 0 -100.00%
benchmark old bytes new bytes delta
BenchmarkSortByWeightAndReverse 32 0 -100.00%
```
Fixes#1293
The documentation for the RSS templating is a little unclear.
http://gohugo.io/templates/rss/
Some users may attempt to look for a ```__internal``` directory rather than assume that's the aforementioned "Hugo own template."
Here's my suggestion.
This commit adds a new PygmentsCodeFences config option (default false), which if true will allow GitHub style backtick code fences around code, which will then be rendered by Pygments.
For example:
``` language
your code
```
can be used instead of {{< highlight language >}}your code {{< /highlight >}}.
Fixes#362
Previously if no language was specified, then illegal args would be passed to pygments, for example `pygments -l -fhtml`, which would result in pygments printing an error.
I could be wrong here, but it looks to me like .Site.Social.facebook is used in tpl/template_embedded.go, but the variable is never set. I've added a line to initializeSiteInfo to map the info from config into this variable.
In particular, RawContent() excludes the metadata header.
This is necessary in the use case of embedding remarkjs.com slides, as it needs
the unprocessed Markdown content to generate the slides.
`where` template function's internal condition check function always
returns `false` when a target value doesn't exist or it's nil value but
this behavior makes it difficult to filter values which doesn't have a
particular parameter.
To solve it, this adds nil value comparison to the function.
`where Values ".Param.key" nil` like clause can be used for the case
above.
Only "=", "==", "eq", "!=", "<>", "ne" operators are allowed to be used
with `nil`. If an other operator is passed with `nil`, the condition
check function returns `false` like before.
Fix#1232
There have been some changes to the ´helpers.GetThemesDirPath()´ so it now returns an empty string when no theme.
This is correct, but it broke the watch service (at lest on OSX), as `strings.HasPrefix("", "somestring") evaluates to true somehow, and content changes are incorrectly branded as static.
There are other issues in there, but that will come later ...
See #1236
Reduce duplication (`x + FilePathSeparator + y` a few lines away from `filepath.Join(x, y)`) and add a `GetThemeDir()` function to get the current theme's directory.
Also add a comment complaining about the `GetThemesDirPath()` function, which doesn't seem to do what its name would suggest. This might be a candidate for deprecation?
Even as a copy at the end is needed, this consumes way less memory on Go 1.4.2:
```benchmark old ns/op new ns/op delta
BenchmarkParsePage 145979 139964 -4.12%
BenchmarkReplaceShortcodeTokens 633574 631946 -0.26%
BenchmarkShortcodeLexer 195842 187938 -4.04%
benchmark old allocs new allocs delta
BenchmarkParsePage 87 87 +0.00%
BenchmarkReplaceShortcodeTokens 9424 9415 -0.10%
BenchmarkShortcodeLexer 274 274 +0.00%
benchmark old bytes new bytes delta
BenchmarkParsePage 141830 141830 +0.00%
BenchmarkReplaceShortcodeTokens 35219 25385 -27.92%
BenchmarkShortcodeLexer 30178 30177 -0.00%
```
See #1148
This commit replaces the regexp driven `replaceShortcodeTokens` with a handwritten one.
It wasnt't possible to handle the p-tags case without breaking performance.
This fix actually improves in that area:
```
benchmark old ns/op new ns/op delta
BenchmarkParsePage 142738 142667 -0.05%
BenchmarkReplaceShortcodeTokens 665590 575645 -13.51%
BenchmarkShortcodeLexer 176038 181074 +2.86%
benchmark old allocs new allocs delta
BenchmarkParsePage 87 87 +0.00%
BenchmarkReplaceShortcodeTokens 9631 9424 -2.15%
BenchmarkShortcodeLexer 274 274 +0.00%
benchmark old bytes new bytes delta
BenchmarkParsePage 141830 141830 +0.00%
BenchmarkReplaceShortcodeTokens 52275 35219 -32.63%
BenchmarkShortcodeLexer 30177 30178 +0.00%
```
Fixes#1148
Where `first` will return the first N items of a rangeable list,
`after` will return all items after the Nth item.
This allows the user to do something with the first N items and
something different with the remaining items after N.
`substr` template function takes one or two range arguments. Both
arguments must be int type values but if it is used with a calclation
function e.g. `add`, `len` etc, it causes a wrong type error.
This fixes the issue to allow the function to take other integer type
variant like `int64` etc.
This also includes a small fix on no range argument case.
Fix#1190
The following inside `config.toml` will ignore files ending with `.foo` and `.boo`.
```
watchIgnoreFiles = [ "\\.foo$", "\\.boo$" ]
```
The above is is a list of Reqular Expressions, but note the escaping of the `\` to make TOML happy.
Fixes#1189
Before this commit, taxonomy names were hyphenated, lower-cased and normalized -- then fixed and titleized on the archive page.
So what you entered in the front matter isn't necessarily what you got in the final site.
To preserve backwards compability, `PreserveTaxonomyNames` is default `false`.
Setting it to `true` will preserve what you type (the first characters is made toupper for titles), but normalized in URLs.
This also means that, if you manually construct URLs to the archive pages, you will have to pass the Taxonomy names through the `urlize` func.
Fixes#1180
So the taxonomy `Gérard Depardieu` gives paths on the form `gerard-depardieu`.
Unfortunately this introduces two imports from the `golang.org/`, but Unicode-normalization isn't something we'd want to write from scratch.
See https://blog.golang.org/normalization
See #1180
Section names are also used as the title of the list pages, but naming section folders as `Fish and Chips` and similar didn't work very well.
This commit fixes that.
This commit also changes the title casing of the section titles. Some may argue that this is a breaking change, but the old behaviour was also pretty broken,
even for languages that use title capitalizations, as it didn't follow any particular style guide, `fish and chips` became `Fish And Chips` etc.
Now it just turns the first letter into upper case, so `Fish and Chips` will be left as `Fish and Chips`.
People wanting the good old behaviour can use the `title` template func.
Fixes#1176
To determine if a page is the "Home Page" has inspired lots of creativity in the template department.
This commit makes it simpler: IsHome will tell the truth.
`where` tpl function doesn't support `time.Time` type so if people want
to compare such values, it's required that these values are converted
into `int` and compare them.
This improves it. If `time.Time` values are passed to `where`, it
converts them into `int` internally, compares them and returns the
result.
See also
http://discuss.gohugo.io/t/future-posts-and-past-posts/1229/3
This information was previously scattered around in the forums and
mailing list. Add it to the official docs to make things easier for new
users.
Fixes#1167
We welcome contributions to Hugo of any kind including documentation, themes,
organization, tutorials, blog posts, bug reports, issues, feature requests,
feature implementations, pull requests, answering questions on the forum,
helping to manage issues, etc.
The Hugo community and maintainers are [very active](https://github.com/gohugoio/hugo/pulse/monthly) and helpful, and the project benefits greatly from this activity. We created a [step by step guide](https://gohugo.io/tutorials/how-to-contribute-to-hugo/) if you're unfamiliar with GitHub or contributing to open source projects in general.
## Table of Contents
* [Asking Support Questions](#asking-support-questions)
* [Fetching the Sources From GitHub](#fetching-the-sources-from-github)
* [Using Git Remotes](#using-git-remotes)
* [Build Hugo with Your Changes](#build-hugo-with-your-changes)
* [Updating the Hugo Sources](#updating-the-hugo-sources)
## Asking Support Questions
We have an active [discussion forum](https://discourse.gohugo.io) where users and developers can ask questions.
Please don't use the GitHub issue tracker to ask questions.
## Reporting Issues
If you believe you have found a defect in Hugo or its documentation, use
the GitHub [issue tracker](https://github.com/gohugoio/hugo/issues) to report the problem to the Hugo maintainers.
If you're not sure if it's a bug or not, start by asking in the [discussion forum](https://discourse.gohugo.io).
When reporting the issue, please provide the version of Hugo in use (`hugo version`) and your operating system.
## Submitting Patches
The Hugo project welcomes all contributors and contributions regardless of skill or experience level.
If you are interested in helping with the project, we will help you with your contribution.
Hugo is a very active project with many contributions happening daily.
Because we want to create the best possible product for our users and the best contribution experience for our developers,
we have a set of guidelines which ensure that all contributions are acceptable.
The guidelines are not intended as a filter or barrier to participation.
If you are unfamiliar with the contribution process, the Hugo team will help you and teach you how to bring your contribution in accordance with the guidelines.
### Code Contribution Guidelines
To make the contribution process as seamless as possible, we ask for the following:
* Go ahead and fork the project and make your changes. We encourage pull requests to allow for review and discussion of code changes.
* When you’re ready to create a pull request, be sure to:
* Sign the [CLA](https://cla-assistant.io/gohugoio/hugo).
* Have test cases for the new code. If you have questions about how to do this, please ask in your pull request.
* Run `go fmt`.
* Add documentation if you are adding new features or changing functionality. The docs site lives in `/docs`.
* Squash your commits into a single commit. `git rebase -i`. It’s okay to force update your pull request with `git push -f`.
* Ensure that `make check` succeeds. [Travis CI](https://travis-ci.org/gohugoio/hugo) (Linux and macOS) and [AppVeyor](https://ci.appveyor.com/project/gohugoio/hugo/branch/master) (Windows) will fail the build if `make check` fails.
* Follow the **Git Commit Message Guidelines** below.
### Git Commit Message Guidelines
This [blog article](http://chris.beams.io/posts/git-commit/) is a good resource for learning how to write good commit messages,
the most important part being that each commit message should have a title/subject in imperative mood starting with a capital letter and no trailing period:
*"Return error on wrong use of the Paginator"*, **NOT***"returning some error."*
Also, if your commit references one or more GitHub issues, always end your commit message body with *See #1234* or *Fixes #1234*.
Replace *1234* with the GitHub issue ID. The last example will close the issue when the commit is merged into *master*.
Sometimes it makes sense to prefix the commit message with the packagename (or docs folder) all lowercased ending with a colon.
That is fine, but the rest of the rules above apply.
So it is "tpl: Add emojify template func", not "tpl: add emojify template func.", and "docs: Document emoji", not "doc: document emoji."
Please consider to use a short and descriptive branch name, e.g. **NOT** "patch-1". It's very common but creates a naming conflict each time when a submission is pulled for a review.
An example:
```text
tpl: Add custom index function
Add a custom index template function that deviates from the stdlib simply by not
returning an "index out of range" error if an array, slice or string index is
out of range. Instead, we just return nil values. This should help make the
new default function more useful for Hugo users.
Fixes #1949
```
### Vendored Dependencies
Hugo uses [govendor](https://github.com/kardianos/govendor) to vendor dependencies, but we don't commit the vendored packages themselves to the Hugo git repository.
Therefore, a simple `go get` is not supported since `go get` is not vendor-aware.
You **must use govendor** to fetch and manage Hugo's dependencies.
### Fetch the Sources From GitHub
```
go get github.com/kardianos/govendor
govendor get github.com/gohugoio/hugo
```
### Using Git Remotes
Due to the way Go handles package imports, the best approach for working on a
Hugo fork is to use Git Remotes. Here's a simple walk-through for getting
started:
1. Fetch the Hugo sources as described above.
1. Change to the Hugo source directory:
```
cd $HOME/go/src/github.com/gohugoio/hugo
```
1. Create a new branch for your changes (the branch name is arbitrary):
```
git checkout -b iss1234
```
1. After making your changes, commit them to your new branch:
```
git commit -a -v
```
1. Fork Hugo in GitHub.
1. Add your fork as a new remote (the remote name, "fork" in this example, is arbitrary):
A Fast and Flexible Static Site Generator built with love by [spf13](http://spf13.com/) and [friends](https://github.com/spf13/hugo/graphs/contributors) in [Go][].
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][].
[](https://travis-ci.org/gohugoio/hugo)
[](https://gitter.im/spf13/hugo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Hugo is a static site generator written in [Go][]. It is optimized for speed, easy use and configurability. Hugo takes a directory with content and templates and renders them into a full HTML website.
Hugo is a static HTML and CSS website generator written in [Go][].
It is optimized for speed, easy use and configurability.
Hugo takes a directory with content and templates and renders them into a full HTML website.
Hugo relies on Markdown files with front matter for meta data. And you can run Hugo from any directory. This works well for shared hosts and other systems where you don’t have a privileged account.
Hugo relies on Markdown files with front matter for meta data.
And you can run Hugo from any directory.
This works well for shared hosts and other systems where you don’t have a privileged account.
Hugo renders a typical website of moderate size in a fraction of a second. A good rule of thumb is that each piece of content renders in around 1 millisecond.
Hugo renders a typical website of moderate size in a fraction of a second.
A good rule of thumb is that each piece of content renders in around 1 millisecond.
Hugo is meant to work well for any kind of website including blogs, tumbles and docs.
Hugo is designed to work well for any kind of website including blogs, tumbles and docs.
#### Supported Architectures
Currently, we provide pre-built Hugo binaries for Windows, Linux, FreeBSD, NetBSD and OS X (Darwin) for x64, i386 and ARM architectures.
Currently, we provide pre-built Hugo binaries for Windows, Linux, FreeBSD, NetBSD and macOS (Darwin) and [Android](https://gist.github.com/bep/a0d8a26cf6b4f8bc992729b8e50b480b) for x64, i386 and ARM architectures.
Hugo may also be compiled from source wherever the Go compiler tool chain can run, e.g. for other operating systems including DragonFly BSD, OpenBSD, Plan 9 and Solaris.
**Complete documentation is available at [Hugo Documentation](http://gohugo.io/).**
**Complete documentation is available at [Hugo Documentation][].**
## Choose How to Install
If you want to use Hugo as your site generator, simply install the Hugo binaries. The Hugo binaries have no external dependencies.
If you want to use Hugo as your site generator, simply install the Hugo binaries.
The Hugo binaries have no external dependencies.
To contribute to the Hugo source code or documentation, you should fork the Hugo GitHub project and clone it to your local machine.
To contribute to the Hugo source code or documentation, you should [fork the Hugo GitHub project](https://github.com/gohugoio/hugo#fork-destination-box) and clone it to your local machine.
Finally, you can install the Hugo source code with `go`, build the binaries yourself, and run Hugo that way. Building the binaries is an easy task for an experienced `go` getter.
Finally, you can install the Hugo source code with `go`, build the binaries yourself, and run Hugo that way.
Building the binaries is an easy task for an experienced `go` getter.
### Install Hugo as Your Site Generator (Binary Install)
Use the [installation instructions in the Hugo documentation](http://gohugo.io/overview/installing/).
### Clone the Hugo Project (Contributor)
1. Make sure your local environment has the following software installed:
* [Git](http://git-scm.com/)
* [Mercurial](http://mercurial.selenic.com/)
* [Go][] 1.3+ (Go 1.4+ on Windows, see Go [Issue #8090](https://code.google.com/p/go/issues/detail?id=8090))
2. Fork the [Hugo project on GitHub](https://github.com/spf13/hugo).
3. Clone your fork:
git clone https://github.com/YOURNAME/hugo
4. Change into the `hugo` directory:
cd hugo
5. Install the Hugo project’s package dependencies:
go get -u -v github.com/spf13/hugo
6. Use a symbolic link to add your locally cloned Hugo repository to your `$GOPATH`, assuming you prefer doing development work outside of `$GOPATH`:
rm -rf "$GOPATH/src/github.com/spf13/hugo"
ln -s `pwd` "$GOPATH/src/github.com/spf13/hugo"
Go expects all of your libraries to be found in`$GOPATH`.
Use the [installation instructions in the Hugo documentation](https://gohugo.io/overview/installing/).
### Build and Install the Binaries from Source (Advanced Install)
Add Hugo and its package dependencies to your go `src` directory.
go get -v github.com/spf13/hugo
go get -v github.com/gohugoio/hugo
Once the `get` completes, you should find your new `hugo` (or `hugo.exe`) executable sitting inside `$GOPATH/bin/`.
To update Hugo’s dependencies, use `go get` with the `-u` option.
go get -u -v github.com/spf13/hugo
go get -u -v github.com/gohugoio/hugo
## Contributing to Hugo
We welcome contributions to Hugo of any kind including documentation, themes, organization, tutorials, blog posts, bug reports, issues, feature requests, feature implementation, pull requests, answering questions on the forum, helping to manage issues, etc. The Hugo community and maintainers are very active and helpful and the project benefits greatly from this activity.
For a complete guide to contributing to Hugo, see the [Contribution Guide](CONTRIBUTING.md).
We welcome contributions to Hugo of any kind including documentation, themes,
organization, tutorials, blog posts, bug reports, issues, feature requests,
feature implementations, pull requests, answering questions on the forum,
helping to manage issues, etc.
If you have any questions about how to contribute or what to contribute please ask on the [forum](http://discuss.gohugo.io)
The Hugo community and maintainers are [very active](https://github.com/gohugoio/hugo/pulse/monthly) and helpful, and the project benefits greatly from this activity.
## Code Contribution Guideline
### Asking Support Questions
We welcome your contributions. To make the process as seamless as possible, we ask for the following:
We have an active [discussion forum](https://discourse.gohugo.io) where users and developers can ask questions.
Please don't use the GitHub issue tracker to ask questions.
* Go ahead and fork the project and make your changes. We encourage pull requests to discuss code changes.
* When you’re ready to create a pull request, be sure to:
* Have test cases for the new code. If you have questions about how to do it, please ask in your pull request.
* Run `go fmt`
* Squash your commits into a single commit. `git rebase -i`. It’s okay to force update your pull request.
* This [blog article](http://chris.beams.io/posts/git-commit/) is a good resource for learning how to write good commit messages, the most important part being that each commit message should have a title/subject in imperative mode without trailing period: *"Return error on wrong use of the Paginator"*, **NOT***"Returning some error."* Also, if your commit references one or more GitHub issues, always end your commit message body with *See #1234* or *Fixes #1234*. Replace *1234* with the GitHub issue ID. The last example will close the issue when the commit is merged into *master*.
* Make sure `go test ./...` passes, and `go build` completes. Our [Travis CI loop](https://travis-ci.org/spf13/hugo) (Linux) and [AppVeyor](https://ci.appveyor.com/project/spf13/hugo/branch/master) (Windows) will catch most things that are missing.
### Reporting Issues
### Building Hugo with Your Changes
If you believe you have found a defect in Hugo or its documentation, use
the GitHub issue tracker to report the problem to the Hugo maintainers.
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`).
cd /path/to/hugo
go build -o hugo main.go
mv hugo /usr/local/bin/
### Submitting Patches
### Adding compile information to Hugo
The Hugo project welcomes all contributors and contributions regardless of skill or experience level.
If you are interested in helping with the project, we will help you with your contribution.
Hugo is a very active project with many contributions happening daily.
Because we want to create the best possible product for our users and the best contribution experience for our developers,
we have a set of guidelines which ensure that all contributions are acceptable.
The guidelines are not intended as a filter or barrier to participation.
If you are unfamiliar with the contribution process, the Hugo team will help you and teach you how to bring your contribution in accordance with the guidelines.
When Hugo is built using the above steps, the `version` sub-command will include the `mdate` of the Hugo executable, similar to the following:
Hugo Static Site Generator v0.13-DEV buildDate: 2014-12-24T04:46:03-07:00
Instead, it is possible to have the `version` sub-command return information about the git commit used and time of compilation using `build` flags.
To do this, replace the `go build` command with the following *(replace `/path/to/hugo` with the actual path)*:
go build -ldflags "-X /path/to/hugo/hugolib.CommitHash `git rev-parse --short HEAD 2>/dev/null` -X github.com/spf13/hugo/hugolib.BuildDate `date +%FT%T%z`"
This will result in `hugo version` output that looks similar to:
Hugo Static Site Generator v0.13-DEV-8042E77 buildDate: 2014-12-25T03:25:57-07:00
Alternatively, just run `make` — all the “magic” above is already in the `Makefile`. :wink:
### Running Hugo
cd /path/to/hugo
go install github.com/spf13/hugo/hugolib
go run main.go
**Complete documentation is available at [Hugo Documentation](http://gohugo.io/).**
For a complete guide to contributing code to Hugo, see the [Contribution Guide](CONTRIBUTING.md).
site.Log.ERROR.Printf("Failed to set source metadata for file %q: %s. For more info see For more info see https://github.com/gohugoio/hugo/issues/2458",page.FullFilePath(),err)
serverCmd.Flags().IntVarP(&serverPort,"port","p",1313,"port on which the server will listen")
serverCmd.Flags().StringVarP(&serverInterface,"bind","","127.0.0.1","interface to which the server will bind")
serverCmd.Flags().BoolVarP(&serverWatch,"watch","w",false,"watch filesystem for changes and recreate as needed")
serverCmd.Flags().BoolVarP(&serverAppend,"appendPort","",true,"append port to baseurl")
serverCmd.Flags().BoolVarP(&serverWatch,"watch","w",true,"watch filesystem for changes and recreate as needed")
serverCmd.Flags().BoolVarP(&serverAppend,"appendPort","",true,"append port to baseURL")
serverCmd.Flags().BoolVar(&disableLiveReload,"disableLiveReload",false,"watch without enabling live browser reload on rebuild")
serverCmd.Flags().BoolVar(&renderToDisk,"renderToDisk",false,"render to Destination path (default is render to memory & serve from there)")
serverCmd.Flags().String("memstats","","log memory usage to this file")
serverCmd.Flags().Int("meminterval",100,"interval to poll memory usage (requires --memstats)")
serverCmd.Run=server
serverCmd.Flags().String("meminterval","100ms","interval to poll memory usage (requires --memstats), valid time units are \"ns\", \"us\" (or \"µs\"), \"ms\", \"s\", \"m\", \"h\".")
// Copyright 2015 The Hugo Authors. All rights reserved.
//
// Licensed under the Simple Public License, Version 2.0 (the "License");
// 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://opensource.org/licenses/Simple-2.0
// 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.
packagecommands
import(
"bytes"
"fmt"
"errors"
"os"
"time"
"github.com/gohugoio/hugo/parser"
"github.com/spf13/cobra"
"github.com/spf13/hugo/parser"
jww"github.com/spf13/jwalterweatherman"
)
varundraftCmd=&cobra.Command{
Use:"undraft path/to/content",
Short:"Undraft changes the content's draft status from 'True' to 'False'",
Long:`Undraft changes the content's draft status from 'True' to 'False' and updates the date to the current date and time. If the content's draft status is 'False', nothing is done`,
Run:Undraft,
Long:`Undraft changes the content's draft status from 'True' to 'False'
and updates the date to the current date and time.
If the content's draft status is 'False', nothing is done.`,
RunE:Undraft,
}
// Publish publishes the specified content by setting its draft status
// 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.
funcUndraft(cmd*cobra.Command,args[]string){
InitializeConfig()
funcUndraft(cmd*cobra.Command,args[]string)error{
cfg,err:=InitializeConfig()
iferr!=nil{
returnerr
}
iflen(args)<1{
cmd.Usage()
jww.FATAL.Fatalln("a piece of content needs to be specified")
returnnewUserError("a piece of content needs to be specified")
}
location:=args[0]
// open the file
f,err:=os.Open(location)
f,err:=cfg.Fs.Source.Open(location)
iferr!=nil{
jww.ERROR.Print(err)
return
returnerr
}
// get the page from file
p,err:=parser.ReadFrom(f)
f.Close()
iferr!=nil{
jww.ERROR.Print(err)
return
returnerr
}
w,err:=undraftContent(p)
iferr!=nil{
jww.ERROR.Printf("an error occurred while undrafting %q: %s",location,err)
return
returnnewSystemErrorF("an error occurred while undrafting %q: %s",location,err)
Undraft changes the content's draft status from 'True' to 'False'
### Synopsis
Undraft changes the content's draft status from 'True' to 'False' 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
```
### Options
```
-h, --help=false: help for undraft
```
### Options inherited from parent commands
```
-b, --baseUrl="": hostname (and path) to the root eg. http://spf13.com/
-D, --buildDrafts=false: include content marked as draft
-F, --buildFuture=false: include content with publishdate in the future
--cacheDir="": filesystem path to cache directory. Defaults: $TMPDIR/hugo_cache/
--config="": config file (default is path/config.yaml|json|toml)
-d, --destination="": filesystem path to write files to
--disableRSS=false: Do not build RSS files
--disableSitemap=false: Do not build Sitemap file
--editor="": edit new content with this editor, if provided
--ignoreCache=false: Ignores the cache directory for reading but still writes to it
All contributions to Hugo are welcome. Whether you want to scratch an itch, or simply contribute to the project, feel free to pick something from the roadmap
or contact [spf13](http://spf13.com/) about what may make sense
to do next.
You should fork the project and make your changes. *We encourage pull requests to discuss code changes.*
When you're ready to create a pull request, be sure to:
* Have test cases for the new code. If you have questions about how to do it, please ask in your pull request.
* Run `go fmt`
* Squash your commits into a single commit. `git rebase -i`. It's okay to force update your pull request.
* Make sure `go test ./...` passes, and `go build` completes. Our [Travis CI loop](https://travis-ci.org/spf13/hugo) will catch most things that are missing. The exception: Windows. We run on Windows from time to time, but if you have access, please check on a Windows machine too.
## Contribution Overview
1. Fork Hugo from https://github.com/spf13/hugo
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Commit passing tests to validate changes.
5. Run `go fmt`
6. Squash commits into a single (or logically grouped) commits (`git rebase -i`)
7. Push to the branch (`git push origin my-new-feature`)
8. Create new Pull Request
# Building from source
## Clone locally (for contributors):
git clone https://github.com/spf13/hugo
cd hugo
go get
Because Go expects all of your libraries to be found in either
`$GOROOT` or `$GOPATH`, it's helpful to symlink the project to one
| [Static Websites with Hugo on Google Cloud Storage](http://www.moxie.io/post/static-websites-with-hugo-on-google-cloud-storage/) | Moxie Input/Output | 2 Apr 2015 |
| [De nuevo iniciando un blog](http://alvarolizama.net/blog/denuevo-iniciando-un-blog/) | Alvaro Lizama | 29 Mar 2015 |
| [Top Static Site Generators in 2015](http://superdevresources.com/static-site-generators-2015/) | Kanishk Kunal | 12 Mar 2015 |
| [Moving to Hugo](http://abiosoft.com/moving-to-hugo/) | Abiola Ibrahim | 8 Mar 2015 |
| [服务器上 hugo 的安装和配置 <small>(Installing and configuring Hugo on the server)</small>](http://hucsmn.com/post/hugo-tutorial-make-it-work/) | hucsmn | 11 Feb 2015 |
| [blogをoctopressからHugoに乗り換えたメモ](http://blog.jigyakkuma.org/2015/02/11/hugo/) | jigyakkuma | 11 Feb 2015 |
| [Hugoでブログをつくった](http://porgy13.github.io/post/new-hugo-blog/) | porgy13 | 7 Feb 2015 |
| [Hugoにブログを移行した](http://keichi.net/post/first/) | Keichi Takahashi | 4 Feb 2015 |
| [Hugo静态网站生成器中文教程](http://nanshu.wang/post/2015-01-31/) | Nanshu Wang | 31 Jan 2015 |
| [Hugo + Github Pages + Wercker CI =<br> ¥0(無料)でコマンド 1 発(自動化)でサイト・ブログを公開・運営・分析・収益化](http://qiita.com/yoheimuta/items/8a619cac356bed89a4c9) | Yoheimuta | 31 Jan 2015 |
| [Running Hugo websites on anynines](http://blog.anynines.com/running-hugo-websites-on-anynines/) | Julian Weber | 30 Jan 2015 |
| [MiddlemanからHugoへ移行した](http://re-dzine.net/2015/01/hugo/) | Haruki Konishi | 21 Jan 2015 |
| [WordPress から Hugo に乗り換えました](http://rakuishi.com/archives/wordpress-to-hugo/) | rakuishi | 20 Jan 2015 |
| [HUGOを使ってサイトを立ち上げる方法](http://qiita.com/syui/items/869538099551f24acbbf) | Syui | 17 Jan 2015 |
| [Jekyllが許されるのは小学生までだよね](http://t32k.me/mol/log/hugo/) | Ishimoto Koji | 16 Jan 2015 |
| [Getting started with Hugo](http://anthonyfok.org/post/getting-started-with-hugo/) | Anthony Fok | 12 Jan 2015 |
| [把这个博客静态化了 <small>(Migrate to Hugo)</small>](http://lich-eng.com/2015/01/03/migrate-to-hugo/) | Li Cheng | 3 Jan 2015 |
| [My Hugo Experiment](http://tilde.club/~jbaty/2014/12/2014-12-31-my-hugo-experiment/) | Jack Baty | 31 Dec 2014 |
| [Porting my blog with Hugo](http://blog.srackham.com/posts/porting-my-blog-with-hugo/) | Stuart Rackham | 30 Dec 2014 |
| [Hugoを使ってみたときのメモ](http://machortz.github.io/posts/usinghugo/) | Machortz | 29 Dec 2014 |
| [OctopressからHugoへ移行した](http://deeeet.com/writing/2014/12/25/hugo/) | Taichi Nakashima | 25 Dec 2014 |
| [Hugo로 Github에 블로그 호스팅하기](http://cdpython.github.io/post/go/hugo/hugo-github/) | CD Python | 25 Dec 2014 |
| [Migrating to Hugo From Octopress](http://nathanleclaire.com/blog/2014/12/22/migrating-to-hugo-from-octopress/) | Nathan LeClaire | 22 Dec 2014 |
| [Dynamic Pages with GoHugo.io](http://cyrillschumacher.com/2014/12/21/dynamic-pages-with-gohugo.io/) | Cyrill Schumacher | 21 Dec 2014 |
| [6 Static Blog Generators That Aren’t Jekyll](http://www.sitepoint.com/6-static-blog-generators-arent-jekyll/) | David Turnbull | 8 Dec 2014 |
| [Hugo para crear sitios web estáticos](http://www.webbizarro.com/noticias/1076/hugo-para-crear-sitios-web-estaticos/) | Web Bizarro | 19 Aug 2014 |
| [Hello Hugo!](http://commiechink.com/2014/08/hello-hugo/) | Jason Yee | 19 Aug 2014 |
| [Going with hugo](http://www.markuseliasson.se/article/going-with-hugo/) | Markus Eliasson | 18 Aug 2014 |
| [Benchmarking Jekyll, Hugo and Wintersmith](http://www.internaldeployment.se/post/2014-08-12-Jekyll-and-its-alternatives-from-a-site-generation-point-of-view/) | Fredrik Loch | 12 Aug 2014 |
| [Goodbye Octopress, Hello Hugo!](http://andreimihu.com/blog/2014/08/11/goodbye-octopress-hello-hugo/) | Andrei Mihu | 11 Aug 2014 |
| [Beautiful sites for Open Source projects](http://beautifulopen.com/2014/08/09/hugo/) | Beautiful Open | 9 Aug 2014 |
| [Hugo: Beyond the Defaults](http://npf.io/2014/08/hugo-beyond-the-defaults/) | Nate Finch | 8 Aug 2014 |
| [First Impressions of Hugo](https://peteraba.com/blog/first-impressions-of-hugo/) | Peter Aba | 6 Aug 2014 |
| [New Site Workflow](http://vurt.co.uk/post/new_website/) | Giles Paterson | 5 Aug 2014 |
| [How I Learned to Stop Worrying and Love the (Static) Web](http://cognition.ca/post/about-hugo/) | Joshua McKenty | 4 Aug 2014 |
| [Hugo over Octopress](http://kennywoo.com/blog/hugo---golang-based-static-site-generator/) | Kenny Woo | 3 Aug 2014 |
| [Hugo Is Friggin' Awesome](http://npf.io/2014/08/hugo-is-awesome/) | Nate Finch | 1 Aug 2014 |
| [再次搬家 <small>(Move from WordPress to Hugo)</small>](http://www.chingli.com/misc/move-from-wordpress-to-hugo/) | 青砾 (chingli) | 12 July 2014 |
| [Embedding Gists in Hugo](http://danmux.com/posts/embedded_gists/) | Dan Mull | 5 July 2014 |
| [An Introduction To Hugo](http://www.cirrushosting.com/web-hosting-blog/an-introduction-to-hugo/) | Dan Silber | 1 July 2014 |
| [Moving to Hugo](http://danmux.com/posts/hugo_based_blog/) | Dan Mull | 29 May 2014 |
| [开源之静态站点生成器排行榜<br><small>(Leaderboard of open-source static website generators)</small>](http://code.csdn.net/news/2819909) | CSDN.net | 23 May 2014 |
| [How I deploy this site using Fabric](http://carlorat.me/quote/fabric/) | Carlo Ratam | 21 May 2014 |
| [Finally, a satisfying and effective blog setup](http://michaelwhatcott.com/now-powered-by-hugo/) | Michael Whatcott | 20 May 2014 |
| [Hugo from scratch](http://zackofalltrades.com/notes/2014/05/hugo-from-scratch/) | Zack Williams | 18 May 2014 |
| [Why I switched away from Jekyll](http://www.jakejanuzelli.com/why-I-switched-away-from-jekyll/) | Jake Januzelli | 10 May 2014 |
| [Latest Roundup of Useful Tools For Developers](http://codegeekz.com/latest-roundup-of-useful-tools-for-developers/) | CodeGeekz | 13 Feb 2014 |
| [Hugo: Static Site Generator written in Go](http://www.braveterry.com/2014/02/06/hugo-static-site-generator-written-in-go/) | Brave Terry | 6 Feb 2014 |
| [10 Useful HTML5 Tools for Web Designers and Developers](http://designdizzy.com/10-useful-html5-tools-for-web-designers-and-developers/) | Design Dizzy | 4 Feb 2014 |
| [Hugo – Fast, Flexible Static Site Generator](http://cube3x.com/hugo-fast-flexible-static-site-generator/) | Joby Joseph | 18 Jan 2014 |
| [Hugo: A new way to build static website](http://www.w3update.com/opensource/hugo-a-new-way-to-build-static-website.html) | w3update | 17 Jan 2014 |
| [Xaprb now uses Hugo](http://xaprb.com/blog/2014/01/15/using-hugo/) | Baron Schwartz | 15 Jan 2014 |
| [New jQuery Plugins And Resources That Web Designers Need](http://www.designyourway.net/blog/resources/new-jquery-plugins-and-resources-that-web-designers-need/) | Design Your Way | 2014 |
| [On Blog Construction](http://alexla.sh/post/on-blog-construction/) | Alexander Lash | 27 Dec 2013 |
| [Hugo](http://onethingwell.org/post/69070926608/hugo) | One Thing Well | 5 Dec 2013 |
| [In Praise Of Hugo](http://sound-guru.com/blog/post/hello-world/) | sound-guru.com | 19 Oct 2013 |
| [Hosting a blog on S3 and Cloudfront](http://www.danesparza.net/2013/07/hosting-a-blog-on-s3-and-cloudfront/) | Dan Esparza | 24 July 2013 |
Hugo v0.11 introduced the concept of a content builder. Using the
command: <code>hugo new <em>[relative new content path]</em></code>,
you can start a content file with the date and title automatically set.
While this is a welcome feature, active writers need more.
Hugo presents the concept of archetypes, which are archetypal content files
with pre-configured [front matter](content/front-matter) which will
populate each new content file whenever you run the `hugo new` command.
## Example
### Step 1. Creating an archetype
In this example scenario, we have a blog with a single content type (blog post).
We will use ‘tags’ and ‘categories’ for our taxonomies, so let's create an archetype file with ‘tags’ and ‘categories’ pre-defined, as follows:
#### archetypes/default.md
+++
tags = ["x", "y"]
categories = ["x", "y"]
+++
> __CAVEAT:__ Some editors (e.g. Sublime, Emacs) do not insert an EOL (end-of-line) character at the end of the file (i.e. EOF). If you get a [strange EOF error](/troubleshooting/strange-eof-error/) when using `hugo new`, please open each archetype file (i.e. `archetypes/*.md`) and press <kbd>Enter</kbd> to type a carriage return after the closing `+++` or `---` as necessary.
### Step 2. Using the archetype
Now, with `archetypes/default.md` in place, let's create a new post in the `post` section with the `hugo new` command:
$ hugo new post/my-new-post.md
Hugo would create the file with the following contents:
#### content/post/my-new-post.md
+++
title = "my new post"
date = "2015-01-12T19:20:04-07:00"
tags = ["x", "y"]
categories = ["x", "y"]
+++
We see that the `title` and `date` variables have been added, in addition to the `tags` and `categories` variables which were carried over from `archetype/default.md`.
Congratulations! We have successfully created an archetype and used it for our new contents. That's all there is to it!
## Using a different front matter format
By default, the front matter will be created in the TOML format
regardless of what format the archetype is using.
You can specify a different default format in your site-wide config file
(e.g. `config.toml`) using the `MetaDataFormat` directive.
Possible values are `"toml"`, `"yaml"` and `"json"`.
## Which archetype is being used
The following rules apply:
* If an archetype with a filename that matches the content type being created, it will be used.
* If no match is found, `archetypes/default.md` will be used.
* If neither is present and a theme is in use, then within the theme:
* If an archetype with a filename that matches the content type being created, it will be used.
* If no match is found, `archetypes/default.md` will be used.
* If no archetype files are present, then the one that ships with Hugo will be used.
Hugo provides a simple archetype which sets the `title` (based on the
file name) and the `date` in RFC 3339 format based on
[`now()`](http://golang.org/pkg/time/#Now), which returns the current time.
> *Note: `hugo new` does not automatically add `draft = true` when the user
> provides an archetype. This is by design, rationale being that
> the archetype should set its own value for all fields.
> `title` and `date`, which are dynamic and unique for each piece of content,
> are the sole exceptions.*
Content type is automatically detected based on the path. You are welcome to declare which type to create using the `--kind` flag during creation.
Some things are better shown than explained. The following is a very basic example of a content file written in [Markdown](https://help.github.com/articles/github-flavored-markdown/):
With the use of the `.Summary` [page variable](/templates/variables/), Hugo can generate summaries of content for easily showing snippets in summary views. The summary view snippets are automatically generated by Hugo. Where a piece of content is split for the content summary depends on whether the split is Hugo-defined or user-defined.
Content summaries may also provide links to the original content, usually in the form of a "Read More..." link, with the help of the `.RelPermalink` or `.Permalink` variable, as well as the `.Truncated` boolean variable to determine whether such "Read More..." link is necessary.
## Hugo-defined: automatic summary split
By default, Hugo automatically takes the first 70 words of your content as its summary and stores it into the `.Summary` variable, which you may use in your templates.
* Pros: Automatic, no additional work on your part.
* Cons: All HTML tags are stripped from the summary, and the first 70 words, whether they belong to a heading or to different paragraphs, are all lumped into one paragraph. Some people like it, but some people don't.
## User-defined: manual summary split:
Alternatively, you may add the <code><!--more--></code> summary divider[^1] where you want to split the article. Content prior to the summary divider will be used as that content's summary, and stored into the `.Summary` variable with all HTML formatting intact.
[^1]: The **summary divider** is also called "more tag", "excerpt separator", etc. in other literature.
* Pros: Freedom, precision, and improved rendering. All formatting is preserved.
* Cons: Need to remember to type <code><!--more--></code> in your content file. :-)
Be careful to enter <code><!--more--></code> exactly, i.e. all lowercase with no whitespace, otherwise it would be treated as regular comment and ignored.
## Showing Summaries
You can show content summaries with the following code. You could do this, for example, on a [list](/templates/list/) node.
Note how the `.Truncated` boolean valuable may be used to hide the "Read More..." link when the content is not truncated, i.e. when the summary contains the entire article.
For people migrating existing published content to Hugo, there's a good chance you need a mechanism to handle redirecting old URLs.
Luckily, redirects can be handled easily with _aliases_ in Hugo.
## Example
Given a post on your current Hugo site, with a path of:
``content/posts/my-awesome-blog-post.md``
... you create an "aliases" section in the frontmatter of your post, and add previous paths to that.
### TOML frontmatter
~~~yaml
+++
...
aliases = [
"/posts/my-original-url/",
"/2010/01/01/even-earlier-url.html"
]
...
+++
~~~
### YAML frontmatter
~~~yaml
---
...
aliases:
- /posts/my-original-url/
- /2010/01/01/even-earlier-url.html
...
---
~~~
Now when you visit any of the locations specified in aliases, _assuming the same site domain_, you'll be redirected to the page they are specified on.
## Important Behaviors
1. *Hugo makes no assumptions about aliases. They also don't change based
on your UglyUrls setting. You need to provide absolute path to your webroot and the
complete filename or directory.*
2. *Aliases are rendered prior to any content and will be overwritten by
any content with the same location.*
## How Hugo Aliases Work
When aliases are specified, Hugo creates a physical folder structure to match the alias entry, and, an html file specifying the canonical URL for the page, and a redirect target.
Assuming a baseurl of `mysite.tld`, the contents of the html file will look something like:
As Hugo is a static site generator, the content produced is static and doesn’t interact with the users. The most common interaction people ask for is comment capability.
Hugo ships with support for [Disqus](https://disqus.com/), a third-party service that provides comment and community capabilities to website via JavaScript.
Your theme may already support Disqus, but even it if doesn’t, it is easy to add.
# Disqus Support
## Adding Disqus to a template
Hugo comes with all the code you would need to include load Disqus. Simply include the following line where you want your comments to appear:
{{ template "_internal/disqus.html" . }}
## Configuring Disqus
That template requires you to set a single value in your site config file, e.g. config.yaml.
disqusShortname = "XYW"
Additionally, you can optionally set the following in the front matter
for a given piece of content:
* **disqus_identifier**
* **disqus_title**
* **disqus_url**
## Conditional Loading of Disqus Comments
Users have noticed that enabling Disqus comments when running the Hugo web server on localhost causes the creation of unwanted discussions on the associated Disqus account. In order to prevent this, a slightly tweaked partial template is required. So, rather than using the built-in `"_internal/disqus.html"` template referenced above, create a template in your `partials` folder that looks like this:
```html
<divid="disqus_thread"></div>
<scripttype="text/javascript">
(function(){
// Don't ever inject Disqus on localhost--it creates unwanted
// discussions from 'localhost:1313' on your Disqus account...
<noscript>Please enable JavaScript to view the <ahref="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<ahref="http://disqus.com/"class="dsq-brlink">comments powered by <spanclass="logo-disqus">Disqus</span></a>
```
Notice that there is a simple `if` statement that detects when you are running on localhost and skips the initialization of the Disqus comment injection.
Now, reference the partial template from your page template:
{{ partial "disqus.html" . }}
# Alternatives
A few alternatives exist to [Disqus](https://disqus.com/):
* [Discourse](http://www.discourse.org)
* [IntenseDebate](http://intensedebate.com/)
* [Livefyre](http://livefyre.com/)
* [Muut](http://muut.com/)
* [多说](http://duoshuo.com/) ([Duoshuo](http://duoshuo.com/), popular in China)
[Kaiju](https://github.com/spf13/kaiju) is an open-source project started by [spf13](http://spf13.com/) (Hugo’s author) to bring easy and fast real time discussions to the web.
Written using Go, Socket.io and MongoDB, it is very fast and easy to deploy.
It is in early development but shows promise. If you have interest, please help by contributing whether via a pull request, an issue or even just a tweet. Everything helps.
## Discourse
Additionally, you may recognize [Discourse](http://www.discourse.org) as the system that powers the [Hugo Discussion Forum](http://discuss.gohugo.io).
Hugo makes it easy to link documents together with the `ref` and `relref` shortcodes. These shortcodes are also used to safely provide links to headings inside of your content, whether across documents or within a document. The only difference between `ref` and `relref` is whether the resulting URL is absolute (`http://1.com/about/`) or relative (`/about/`).
## Using `ref` and `relref`
{{</* ref "document" */>}}
{{</* ref "#anchor" */>}}
{{</* ref "document#anchor" */>}}
{{</* relref "document" */>}}
{{</* relref "#anchor" */>}}
{{</* relref "document#anchor" */>}}
The single parameter to `ref` is a string with a content _document name_ (`about.md`), an in-document _anchor_ (`#who`), or both (`about.md#who`).
### Document Names
The _document name_ is the name of a document including the format extension; this may be just the filename, or the relative path from the `content/` directory. With a document `content/blog/post.md`, either format will produce the same result.
{{</* relref "blog/post.md" */>}} ⇒ `/blog/post/`
{{</* relref "post.md" */>}} ⇒ `/blog/post/`
If you have multiple sections with the same filename, you should only use the relative path format, because the behaviour is _undefined_. So, if I also have a document `link/post.md`, the output of `ref` is unknown for `post.md`.
A relative document name must *not* begin with a slash (`/`).
{{</* relref "/blog/post.md" */>}} ⇒ `""`
### Anchors
When an _anchor_ is provided by itself, the current page’s unique identifier will be appended; when an _anchor_ is provided with a document name, the found page's unique identifier will be appended.
When using Markdown document types, Hugo generates heading anchors automatically. The generated anchor for this section is `hugo-heading-anchors`. Because the heading anchors are generated automatically, Hugo takes some effort to ensure that heading anchors are unique both inside a document and across the entire site.
Ensuring heading uniqueness across the site is accomplished with a unique identifier for each document based on its path. Unless a document is renamed or moved between sections *in the filesystem*, the unique identifier for the document will not change: `blog/post.md` will always have a unique identifier of `81df004c333b392d34a49fd3a91ba720`.
`ref` and `relref` were added so you can make these reference links without having to know the document’s unique identifier. (The links in document tables of contents are automatically up-to-date with this value.)
> What follows is a deeper discussion of *why* and *how* Hugo generates heading anchors. It is not necessary to know this to use `ref` and `relref`, but it may be useful in understanding how some anchors may not match your expectations.
### How to Generate a Heading Anchor
Convert the text of the heading to lowercase.
Hugo: A Fast & Modern Static Web Engine
hugo: a fast & modern static web engine
Replace anything that isn't an ASCII letter (`a-z`) or number (`0-9`) with a dash (`-`).
hugo: a fast & modern static web engine
hugo--a-fast---modern-static-web-engine
Get rid of extra dashes.
hugo--a-fast---modern-static-web-engine
hugo-a-fast-modern-static-web-engine
You have just converting the text of a heading to a suitable anchor. If your document has unique heading text, all of the anchors will be unique, too.
#### Specifying Heading Anchors
You can also tell Hugo to use a particular heading anchor.
# Hugo: A Fast & Modern Static Web Engine {#hugo-main}
Hugo will use `hugo-main` as the heading anchor.
### What About Duplicate Heading Anchors?
The technique outlined above works well enough, but some documents have headings with identical text, like the [shortcodes](/extras/shortcodes/) page—there are three headings with the text "Example". You can specify heading anchors manually:
### Example {#example-1}
### Example {#example-2}
### Example {#example-3}
It’s easy to forget to do that all the time, and Hugo is smart enough to do it for you. It just adds `-x` to the end of each heading it has already seen.
*`### Example` ⇒ `example`
*`### Example` ⇒ `example-1`
*`### Example` ⇒ `example-2`
Sometimes it's a little harder, but Hugo can recover from those, too, by adding more suffixes:
*`# Heading` ⇒ `heading`
*`# Heading 1` ⇒ `heading-1`
*`# Heading` ⇒ `heading-1-1`
*`# Heading` ⇒ `heading-1-2`
*`# Heading 1` ⇒ `heading-2`
This can even affect specified heading anchors that come after a generated heading anchor.
*`# My Heading` ⇒ `my-heading`
*`# My Heading {#my-heading}` ⇒ `my-heading-1`
> This particular collision and override is unfortunate, but unavoidable because Hugo processes each heading for collision detection as it sees it during conversion.
This technique works well for documents rendered on individual pages, like blog posts. What about on Hugo list pages?
### Unique Heading Anchors in Lists
Hugo converts each document from Markdown independently. it doesn’t know that `blog/post.md` has an "Example" heading that will collide with the "Example" heading in `blog/post2.md`. Even if it did know this, the addition of `blog/post3.md` should not cause the anchors for the headings in the other blog posts to change.
Enter the document’s unique identifier. To prevent this sort of collision on
list pages, Hugo always appends the document's to a generated heading anchor.
So, the "Example" heading in `blog/post.md` actually turns into
`#example:81df004…`, and the "Example" heading in `blog/post2.md` actually
turns into `#example:8cf1599…`. All you have to know is the heading anchor that
was generated, not the document identifier; `ref` and `relref` take care of the
In addition to the [built-in variables](/templates/variables/) available from Hugo, you can specify your own custom data that can be accessed via templates or shortcodes.
Hugo supports loading data from [YAML](http://yaml.org/), [JSON](http://www.json.org/), and [TOML](https://github.com/toml-lang/toml) files located in the `data` directory.
**It even works with [LiveReload](/extras/livereload/).**
Data Files can also be used in [themes](/themes/overview/), but note: If the same `key` is used in both the main data folder and in the theme's data folder, the main one will win. So, for theme authors, for theme specific data items that shouldn't be overridden, it can be wise to prefix the folder structure with a namespace, e.g. `mytheme/data/mytheme/somekey/...`. To check if any such duplicate exists, run hugo with the `-v` flag, e.g. `hugo -v`.
## The Data Folder
As explained in [Source Organization](/overview/source-directory/), the `data` folder is where you can store additional data for Hugo to use when generating your site. These files must be YAML, JSON or TOML files (using either the `.yml`, `.yaml`, `.json` or `toml` extension) and the data will be accessible as a `map` in `.Site.Data`.
**The keys in this map will be a dot chained set of _path_, _filename_ and _key_ in file (if applicable).**
This is best explained with an example:
## Example: Jaco Pastorius' Solo Discography
[Jaco Pastorius](http://en.wikipedia.org/wiki/Jaco_Pastorius_discography) was a great bass player, but his solo discography is short enough to use as an example. [John Patitucci](http://en.wikipedia.org/wiki/John_Patitucci) is another bass giant.
The example below is a bit constructed, but it illustrates the flexibility of Data Files. It uses TOML as file format.
Given the files:
*`data/jazz/bass/jacopastorius.toml`
*`data/jazz/bass/johnpatitucci.toml`
`jacopastorius.toml` contains the content below, `johnpatitucci.toml` contains a similar list:
```
discography = [
"1974 – Modern American Music … Period! The Criteria Sessions",
"1974 – Jaco",
"1976 - Jaco Pastorius",
"1981 - Word of Mouth",
"1981 - The Birthday Concert (released in 1995)",
"1982 - Twins I & II (released in 1999)",
"1983 - Invitation",
"1986 - Broadway Blues (released in 1998)",
"1986 - Honestly Solo Live (released in 1990)",
"1986 - Live In Italy (released in 1991)",
"1986 - Heavy'n Jazz (released in 1992)",
"1991 - Live In New York City, Volumes 1-7.",
"1999 - Rare Collection (compilation)",
"2003 - Punk Jazz: The Jaco Pastorius Anthology (compilation)",
"2007 - The Essential Jaco Pastorius (compilation)"
]
```
The list of bass players can be accessed via `.Site.Data.jazz.bass`, a single bass player by adding the filename without the suffix, e.g. `.Site.Data.jazz.bass.jacopastorius`.
You can now render the list of recordings for all the bass players in a template:
```
{{ range $.Site.Data.jazz.bass }}
{{ partial "artist.html" . }}
{{ end }}
```
And then in `partial/artist.html`:
```
<ul>
{{ range .discography }}
<li>{{ . }}</li>
{{ end }}
</ul>
```
Discover a new favourite bass player? Just add another TOML-file.
- GitHub Starred Repositories [in a posts](https://github.com/SchumacherFM/blog-cs/blob/master/content%2Fposts%2Fgithub-starred.md) with the related [short code](https://github.com/SchumacherFM/blog-cs/blob/master/layouts%2Fshortcodes%2FghStarred.html).
Hugo provides the ability for you to highlight source code in _two different ways_ — either pre-processed server side from your content, or to defer the processing to the client side, using a JavaScript library.
**The advantage of server side** is that it doesn’t depend on a JavaScript library and consequently works very well when read from an RSS feed.
**The advantage of client side** is that it doesn’t cost anything when building your site and some of the highlighting scripts available cover more languages than Pygments does.
## Server-side
For the pre-processed approach, highlighting is performed by an external Python-based program called [Pygments](http://pygments.org/) and is triggered via an embedded Hugo shortcode (see example below). If Pygments is absent from the path, it will silently simply pass the content along unhighlighted.
### Pygments
If you have never worked with Pygments before, here is a brief primer:
+ Install Python from [python.org](https://www.python.org/downloads/). Version 2.7.x is already sufficient.
+ Run `pip install Pygments` in order to install Pygments. Once installed, Pygments gives you a command `pygmentize`. Make sure it sits in your PATH, otherwise Hugo cannot find it.
On Debian and Ubuntu systems, you may also install Pygments by running `sudo apt-get install python3-pygments`.
Hugo gives you two options that you can set with the variable `pygmentsuseclasses` (default `false`) in `config.toml` (or `config.yaml`).
1. Color-codes for highlighting keywords are directly inserted if `pygmentsuseclasses = false` (default). See in the example below. The color-codes depend on your choice of the `pygmentsstyle` (default `"monokai"`). You can explore the different color styles on [pygments.org](http://pygments.org/) after inserting some example code.
2. If you choose `pygmentsuseclasses = true`, Hugo includes class names in your code instead of color-codes. For class-names to be meaningful, you need to include a `.css`-file in your website representing your color-scheme. You can either generate this `.css`-files according to this [description](http://pygments.org/docs/cmdline/) or download the standard ones from the [GitHub pygments-css repository](https://github.com/richleland/pygments-css).
### Usage
Highlighting is carried out via the in-built shortcode `highlight`. `highlight` takes exactly one required parameter of language, and requires a closing shortcode. Note that `highlight` is _not_ used for client-side javascript highlighting.
Options to control highlighting can be added as a quoted, comma separated key-value list as the second argument in the shortcode. The example below will highlight as language `go` with inline line numbers, with line number 2 and 3 highlighted.
```
{{</* highlight go "linenos=inline,hl_lines=2 3" */>}}
var a string
var b string
var c string
var d string
{{</* / highlight */>}}
```
Supported keywords: `style`, `encoding`, `noclasses`, `hl_lines`, `linenos`. Note that `style` and `noclasses` will override the similar setting in the global config.
The keywords are the same you would using with Pygments from the command line, see the [Pygments doc](http://pygments.org/docs/) for more info.
### Disclaimers
* Pygments is relatively slow and _causes a performance hit when building your site_, but Hugo has been designed to cache the results to disk.
* Languages available depends on your Pygments installation.
## Client-side
Alternatively, code highlighting can be done in client-side JavaScript.
Client-side syntax highlighting is very simple to add. You'll need to pick
a library and a corresponding theme. Some popular libraries are:
- [Highlight.js]
- [Prism]
- [Rainbow]
- [Syntax Highlighter]
- [Google Prettify]
### Highlight.js example
This example uses the popular [Highlight.js] library, hosted by [Yandex], a popular Russian search engine.
In your `./layouts/partials/` (or `./layouts/chrome/`) folder, depending on your specific theme, there will be a snippet that will be included in every generated HTML page, such as `header.html` or `header.includes.html`. Simply add the css and js to initialize [Highlight.js]:
Prism is another popular highlighter library, used on some major sites. Similar to Highlight.js, you simply load `prism.css` in your `<head>` via whatever Hugo partial template is creating that part of your pages, like so:
```html
...
<linkhref="/css/prism.css"rel="stylesheet"/>
...
```
... and add `prism.js` near the bottom of your `<body>` tag, again in whatever Hugo partial template is appropriate for your site or theme.
```html
...
<scriptsrc="/js/prism.js"></script>
...
</body>
```
In this example, the local paths indicate that your own copy of these files are being added to the site, typically under `./static/`.
### Using Client-side highlighting
To use client-side highlighting, most of these javascript libraries expect your code to be wrapped in semantically correct `<code>` tags, with the language expressed in a class attribute on the `<code>` tag, such as `class="language-abc"`, where the `abc` is the code the highlighter script uses to represent that language.
The script would be looking for classes like `language-go`, `language-html`, or `language-css`. If you look at the page's source, it would be marked up like so:
~~~html
<pre>
<code class="language-css">
body {
font-family: "Noto Sans", sans-serif;
}
</code>
</pre>
~~~
The markup in your content pages (e.g. `my-css-tutorial.md`) needs to look like the following, with the name of the language to be highlighted entered directly after the first "fence", in a fenced code block:
Hugo has a simple yet powerful menu system that permits content to be
placed in menus with a good degree of control without a lot of work.
*TIP:* If all you want is a simple menu for your sections, see [Section Menu for "the Lazy Blogger"]({{< relref "#section-menu-for-the-lazy-blogger" >}}).
Some of the features of Hugo Menus:
* Place content in one or many menus
* Handle nested menus with unlimited depth
* Create menu entries without being attached to any content
* Distinguish active element (and active branch)
## What is a menu?
A menu is a named array of menu entries accessible on the site under
`.Site.Menus` by name. For example, if I have a menu called `main`, I would
access it via `.Site.Menus.main`.
A menu entry has the following properties:
* **URL** string
* **Name** string
* **Menu** string
* **Identifier** string
* **Pre** template.HTML
* **Post** template.HTML
* **Weight** int
* **Parent** string
* **Children** Menu
And the following functions:
* **HasChildren** bool
Additionally, there are some relevant functions available on the page:
Hugo supports a couple of different methods of adding a piece of content
to the front matter.
### Simple
If all you need to do is add an entry to a menu, the simple form works
well.
**A single menu:**
---
menu: "main"
---
**Multiple menus:**
---
menu: ["main", "footer"]
---
### Advanced
If more control is required, then the advanced approach gives you the
control you want. All of the menu entry properties listed above are
available.
---
menu:
main:
parent: 'extras'
weight: 20
---
## Adding (non-content) entries to a menu
You can also add entries to menus that aren’t attached to a piece of
content. This takes place in the sitewide [config file](/overview/configuration/).
Here’s an example `config.toml`:
[[menu.main]]
name = "about hugo"
pre = "<i class='fa fa-heart'></i>"
weight = -110
identifier = "about"
url = "/about/"
[[menu.main]]
name = "getting started"
pre = "<i class='fa fa-road'></i>"
weight = -100
url = "/getting-started/"
And the equivalent example `config.yaml`:
---
menu:
main:
- 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/"
---
**NOTE:** The URLs must be relative to the context root. If the `BaseURL` is `http://example.com/mysite/`, then the URLs in the menu must not include the context root `mysite`.
## Nesting
All nesting of content is done via the `parent` field.
The parent of an entry should be the identifier of another entry.
Identifier should be unique (within a menu).
The following order is used to determine identity Identifier > Name >
LinkTitle > Title. This means that the title will be used unless
linktitle is present, etc. In practice Name and Identifier are never
displayed and only used to structure relationships.
In this example, the top level of the menu is defined in the config file
and all content entries are attached to one of these entries via the
`parent` field.
## Rendering menus
Hugo makes no assumptions about how your rendered HTML will be
structured. Instead, it provides all of the functions you will need to be
<li> <a href="https://github.com/spf13/hugo/issues" target="blank">Questions and Issues</a> </li>
<li> <a href="#" target="blank">Edit this Page</a> </li>
</ul>
<!-- sidebar menu end-->
</div>
</aside>
<!--sidebar end-->
## Section Menu for "the Lazy Blogger"
To enable this menu, add this to your site config, i.e. `config.toml`:
```
SectionPagesMenu = "main"
```
The menu name can be anything, but take a note of what it is.
This will create a menu with all the sections as menu items and all the sections' pages as "shadow-members". The _shadow_ implies that the pages isn't represented by a menu-item themselves, but this enables you to create a top-level menu like this:
In the above, the menu item is marked as active if on the current section's list page or on a page in that section.
The above is all that's needed. But if you want custom menu items, e.g. changing weight or name, you can define them manually in the site config, i.e. `config.toml`:
```
[[menu.main]]
name = "This is the blog section"
weight = -110
identifier = "blog"
url = "/blog/"
```
**Note** that the `identifier` must match the section name.
Hugo supports pagination for the home page, sections and taxonomies. It's built to be easy use, but with loads of flexibility when needed. The real power shines when you combine it with [`where`](/templates/functions/), with its SQL-like operators, `first` and others --- you can even [order the content](/templates/list/) the way you've become used to with Hugo.
## Configuration
Pagination can be configured in the site configuration (e.g. `config.toml`):
*`Paginate` (default `10`) (this setting can be overridden in the template)
*`PaginatePath` (default `page`)
Setting `Paginate` to a positive value will split the list pages for the home page, sections and taxonomies into chunks of that size. But note that the generation of the pagination pages for sections, taxonomies and home page is *lazy* --- the pages will not be created if not referenced by a `.Paginator` (see below).
`PaginatePath` is used to adapt the `URL` to the pages in the paginator (the default setting will produce URLs on the form `/page/1/`.
## List the pages
**A `.Paginator` is provided to help building a pager menu. This is only relevant for the templates for the home page and the list pages (sections and taxonomies).**
There are two ways to configure and use a `.Paginator`:
1. The simplest way is just to call `.Paginator.Pages` from a template. It will contain the pages for *that page* .
2. Select a sub-set of the pages with the available template functions and ordering options, and pass the slice to `.Paginate`, e.g. `{{ range (.Paginate ( first 50 .Data.Pages.ByTitle )).Pages }}`.
For a given **Node**, it's one of the options above. The `.Paginator` is static and cannot change once created.
The global page size setting (`Paginate`) can be overridden by providing a positive integer as the last argument. The examples below will give five items per page:
The `.Paginator` contains enough information to build a paginator interface.
The easiest way to add this to your pages is to include the built-in template (with `Bootstrap`-compatible styles):
```
{{ template "_internal/pagination.html" . }}
```
**Note:** If you use any filters or ordering functions to create your `.Paginator`**and** you want the navigation buttons to be shown before the page listing, you must create the `.Paginator` before it's used:
`Scratch` -- a "scratchpad" for your node- or page-scoped variables. In most cases you can do well without `Scratch`, but there are some use cases that aren't solvable with Go's templates without `Scratch`'s help, due to scoping issues.
`Scratch` is added to both `Node` and `Page` -- with the three methods `Set`, `Get` and `Add`. `Set` and `Add` takes a `key` and the `value` to add. Get returns the `value` for the `key` given.
`Set` can store values of any type. `Add` accepts values that support Go's `+` operator.
The scope of the backing data is global for the given `Node` or `Page`, and spans partial and shortcode includes.
## Sample usage
The usage is best illustrated with some samples:
```
{{ $.Scratch.Add "a1" 12 }}
{{ $.Scratch.Get "a1" }} {{/* => 12 */}}
{{ $.Scratch.Add "a1" 1 }}
{{ $.Scratch.Get "a1" }} // {{/* => 13 */}}
{{ $.Scratch.Add "a2" "AB" }}
{{ $.Scratch.Get "a2" }} {{/* => AB */}}
{{ $.Scratch.Add "a2" "CD" }}
{{ $.Scratch.Get "a2" }} {{/* => ABCD */}}
{{ $.Scratch.Set "v1" 123 }}
{{ $.Scratch.Get "v1" }} {{/* => 123 */}}
```
**Note:** The examples above uses the special `$` variable, which refers to the top-level node. This is the behavior you most likely want, and will help remove some confusion when using `Scratch` inside page range loops -- and you start inadvertently calling the wrong `Scratch`. But there may be use cases for `{{ .Scratch.Add "key" "some value" }}`.
Hugo uses Markdown for its simple content format. However, there are a lot
of things that Markdown doesn’t support well.
We are unwilling to accept being constrained by our simple format. Also
unacceptable is writing raw HTML in our Markdown every time we want to include
unsupported content such as a video. To do so is in complete opposition to the
intent of using a bare bones format for our content and utilizing templates to
apply styling for display.
To avoid both of these limitations, Hugo created shortcodes.
A shortcode is a simple snippet inside a content file that Hugo will render
using a predefined template. Note that shortcodes will not work in template
files---if you need a functionality like that in a template, you most likely
want a [partial template](/templates/partials/) instead.
## Using a shortcode
In your content files, a shortcode can be called by using '`{{%/* name parameters
*/%}}`' respectively. Shortcodes are space delimited (parameters with spaces
can be quoted).
The first word is always the name of the shortcode. Parameters follow the name.
The format for named parameters models that of HTML with the format
`name="value"`.
Some shortcodes use or require closing shortcodes. Like HTML, the opening and closing
shortcodes match (name only), the closing being prepended with a slash.
Example of a paired shortcode:
{{</* highlight go */>}} A bunch of code here {{</* /highlight */>}}
The examples above use two different delimiters, the difference being the `%` and the `<` character:
### Shortcodes with Markdown
The `%` characters indicates that the shortcode's inner content needs further processing by the page's rendering processor (i.e. Markdown), needed to get the **bold** text in the example below:
By default, Hugo create content with 'pretty' URLs. For example,
content created at `/content/extras/urls.md` will be rendered at
`/public/extras/urls/index.html`, thus accessible from the browser
at http://example.com/extras/urls/. No non-standard server-side
configuration is required for these pretty URLs to work.
If you would like to have what we call "ugly URLs",
e.g. http://example.com/extras/urls.html, you are in luck.
Hugo supports the ability to create your entire site with ugly URLs.
Simply add `uglyurls = true` to your site-wide `config.toml`,
or use the `--uglyUrls=true` flag on the command line.
If you want a specific piece of content to have an exact URL, you can
specify this in the front matter under the `url` key. See [Content
Organization](/content/organization/) for more details.
## Canonicalization
By default, all relative URLs encountered in the input are left unmodified,
e.g. `/css/foo.css` would stay as `/css/foo.css`,
i.e. `canonifyurls` defaults to `false`.
By setting `canonifyurls` to `true`, all relative URLs would instead
be *canonicalized* using `baseurl`. For example, assuming you have
`baseurl = http://yoursite.example.com/` defined in the site-wide
`config.toml`, the relative URL `/css/foo.css` would be turned into
the absolute URL `http://yoursite.example.com/css/foo.css`.
Benefits of canonicalization include fixing all URLs to be absolute, which may
aid with some parsing tasks. Note though that all real browsers handle this
client-side without issues.
Benefits of non-canonicalization include being able to have resource inclusion
be scheme-relative, so that http vs https can be decided based on how this
page was retrieved.
> Note: In the May 2014 release of Hugo v0.11, the default value of `canonifyurls` was switched from `true` to `false`, which we think is the better default and should continue to be the case going forward. So, please verify and adjust your website accordingly if you are upgrading from v0.10 or older versions.
To find out the current value of `canonifyurls` for your website, you may use the handy `hugo config` command added in v0.13:
hugo config | grep -i canon
Or, if you are on Windows and do not have `grep` installed:
> *Note: There is a plan to switch to [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0), for future Hugo releases. This change would only apply forward. Existing versions of Hugo will remain released under the SimPL-2.0 license. For more information, see [the "Switching to Apache 2 license" thread in the public forum](http://discuss.gohugo.io/t/switching-to-apache-2-license/173).*
## Simple Public License (SimPL-2.0)
### Preamble
This Simple Public License 2.0 (SimPL-2.0 for short) is a plain language
implementation of GPL 2.0. The words are different, but the goal is the
same - to guarantee for all users the freedom to share and change
software. If anyone wonders about the meaning of the SimPL, they should
interpret it as consistent with GPL 2.0.
## Simple Public License (SimPL) 2.0
The SimPL applies to the software's source and object code and comes
with any rights that I have in it (other than trademarks). You agree to
the SimPL by copying, distributing, or making a derivative work of the
software.
You get the royalty free right to:
- Use the software for any purpose;
- Make derivative works of it (this is called a "Derived Work");
- Copy and distribute it and any Derived Work.
If you distribute the software or a Derived Work, you must give back to
the community by:
- Prominently noting the date of any changes you make;
- Leaving other people's copyright notices, warranty disclaimers, and
license terms in place;
- Providing the source code, build scripts, installation scripts, and
interface definitions in a form that is easy to get and best to
modify;
- Licensing it to everyone under SimPL, or substantially similar terms
(such as GPL 2.0), without adding further restrictions to the rights
provided;
- Conspicuously announcing that it is available under that license.
There are some things that you must shoulder:
- You get NO WARRANTIES. None of any kind;
- If the software damages you in any way, you may only recover direct
damages up to the amount you paid for it (that is zero if you did
not pay anything). You may not recover any other damages, including
those called "consequential damages." (The state or country where
you live may not allow you to limit your liability in this way, so
this may not apply to you);
The SimPL continues perpetually, except that your license rights end
automatically if:
- You do not abide by the "give back to the community" terms (your
licensees get to keep their rights if they abide);
- Anyone prevents you from distributing the software under the terms
of the SimPL.
## License for the License
You may do anything that you want with the SimPL text; it's a license
form to use in any way that you find helpful. To avoid confusion,
however, if you change the terms in any way then you may not call your
license the Simple Public License or the SimPL (but feel free to
acknowledge that your license is "based on the Simple Public License").
* Addition of truncated bool to content to determine if should show 'more' link
* Support for [linkTitles](/layout/variables/)
* Better handling of most errors with directions on how to resolve
* Support for more date / time formats
* Support for go 1.2
* Support for `first` in templates
## **0.8.0** August 2, 2013
This release represents over 65 code commits from 6 different contributors.
* Added support for pretty urls (filename/index.html vs filename.html)
* Hugo supports a destination directory
* Will efficiently sync content in static to destination directory
* Cleaned up options.. now with support for short and long options
* Added support for TOML
* Added support for YAML
* Added support for Previous & Next
* Added support for indexes for the indexes
* Better Windows compatibility
* Support for series
* Adding verbose output
* Loads of bugfixes
## **0.7.0** July 4, 2013
* Hugo now includes a simple server
* First public release
## **0.6.0** July 2, 2013
* Hugo includes an example documentation site which it builds
## **0.5.0** June 25, 2013
* Hugo is quite usable and able to build spf13.com
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.