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..
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.
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
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
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
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 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%
´´´
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
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%
```
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
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
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.
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
* 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
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
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.