In Hugo 0.42, this could lead to errors of type `runtime error: invalid memory address or nil pointer dereference` in some rare situations.
Note that this was also an issue before 0.42, but the symptom was then potentially stale list content on rebuilds on content changes.
This commit also improves the above error message.
Fixes#4845
This commit adds support for theme composition and inheritance in Hugo.
With this, it helps thinking about a theme as a set of ordered components:
```toml
theme = ["my-shortcodes", "base-theme", "hyde"]
```
The theme definition example above in `config.toml` creates a theme with the 3 components with presedence from left to right.
So, Hugo will, for any given file, data entry etc., look first in the project, and then in `my-shortcode`, `base-theme` and lastly `hyde`.
Hugo uses two different algorithms to merge the filesystems, depending on the file type:
* For `i18n` and `data` files, Hugo merges deeply using the translation id and data key inside the files.
* For `static`, `layouts` (templates) and `archetypes` files, these are merged on file level. So the left-most file will be chosen.
The name used in the `theme` definition above must match a folder in `/your-site/themes`, e.g. `/your-site/themes/my-shortcodes`. There are plans to improve on this and get a URL scheme so this can be resolved automatically.
Also note that a component that is part of a theme can have its own configuration file, e.g. `config.toml`. There are currently some restrictions to what a theme component can configure:
* `params` (global and per language)
* `menu` (global and per language)
* `outputformats` and `mediatypes`
The same rules apply here: The left-most param/menu etc. with the same ID will win. There are some hidden and experimental namespace support in the above, which we will work to improve in the future, but theme authors are encouraged to create their own namespaces to avoid naming conflicts.
A final note: Themes/components can also have a `theme` definition in their `config.toml` and similar, which is the "inheritance" part of this commit's title. This is currently not supported by the Hugo theme site. We will have to wait for some "auto dependency" feature to be implemented for that to happen, but this can be a powerful feature if you want to create your own theme-variant based on others.
Fixes#4460Fixes#4450
So that a timeout warning does appear if it does happen
especially on a slow machine with soft floating-point CPU.
Special thanks to @bep for the solution.
See #4672
Sets Page.markup earlier (as early as possible, when the page is
loaded). Sets it once and only once, removing many redundant calls
to determineMarkupType().
This kills a sleeping bug that was avoided by the parts of the
code depending on this value making those redundant calls.
There have been one report of a site with truncated `.Content` after the Hugo `0.40.1` release.
This commit fixes this so that race should not be possible anymore. It also adds a stress test with focus on content rendering and multiple output formats.
Fixes#4706
Having them in separate files should make maintainance easier.
When adding new or making changes to the templates:
```bash
mage generate
```
This will get the Go code in sync.
Fixes#4457
This bug was introduced in Hugo 0.40. It is when you use the `<!--more-->` summary marker.
Note that this affects the word stats only. The related `PlainWords`, `Plain`, `Content` all return correct values.
Fixes#4675Fixes#4682
This is a follow-up to #4632. There were some assumptions in that implementation that did not hold water in all situations.
This commit simplifies the content lazy initalization making it more robust.
Fixes#4664
I eturn either:
1. leaf
2. branch
3. empty string
The above sits well with constructs like:
```
{{ with .BundleType }}
// Now we know it is a bundle
{{ end }}
```
Fixes#4662
The count starts at 0 relative to the shortcode's parent: Either the page or the surrounding shortcode.
Access it in a shortcode like this:
```bash
Ordinal is {{ .Ordinal }}
```
Note that this is a shared ordinal for all shortcodes in the relevant context, so, as an example, you have this in a content page:
```markdown
This is a shortcode:
{{< hello >}}
This is another shortcode:
{{< hugo >}}
The `.Ordinal` you get in the two shortcodes above is 0 and 1.
```
See #3359
In most cases we could delay the content init until rendering time, but there could be use cases where the templates would depend on state set in the shortcodes (.Page.Scratch.Set), so we need to do this early.
See #4632
This resolves some surprising behaviour when reading other pages' content from shortcodes. Before this commit, that behaviour was undefined. Note that this has never been an issue from regular templates.
It will still not be possible to get **the current shortcode's page's rendered content**. That would have impressed Einstein.
The new and well defined rules are:
* `.Page.Content` from a shortcode will be empty. The related `.Page.Truncated` `.Page.Summary`, `.Page.WordCount`, `.Page.ReadingTime`, `.Page.Plain` and `.Page.PlainWords` will also have empty values.
* For _other pages_ (retrieved via `.Page.Site.GetPage`, `.Site.Pages` etc.) the `.Content` is there to use as you please as long as you don't have infinite content recursion in your shortcode/content setup. See below.
* `.Page.TableOfContents` is good to go (but does not support shortcodes in headlines; this is unchanged)
If you get into a situation of infinite recursion, the `.Content` will be empty. Run `hugo -v` for more information.
Fixes#4632Fixes#4653Fixes#4655
For the content from other pages in shortcodes there are some chicken and
egg dependencies that is hard to get around. But we can improve on this by preparing the pages in a certain order:
1. The headless bundles goes first. These are page typically page and image collections..
2. Leaf bundles
3. Regular single pages
4. Branch bundles
Fixes#4632
Put guards around TestPageBundlerCaptureSymlinks and
TestPageBundlerSiteWitSymbolicLinksInContent so that they aren't
run on Windows (they both use symbolic links and the Go library
implementation requires administrator mode on Windows).
A sample config:
```toml
defaultContentLanguage = "en"
defaultContentLanguageInSubdir = true
[Languages]
[Languages.en]
weight = 10
title = "In English"
languageName = "English"
contentDir = "content/english"
[Languages.nn]
weight = 20
title = "På Norsk"
languageName = "Norsk"
contentDir = "content/norwegian"
```
The value of `contentDir` can be any valid path, even absolute path references. The only restriction is that the content dirs cannot overlap.
The content files will be assigned a language by
1. The placement: `content/norwegian/post/my-post.md` will be read as Norwegian content.
2. The filename: `content/english/post/my-post.nn.md` will be read as Norwegian even if it lives in the English content folder.
The content directories will be merged into a big virtual filesystem with one simple rule: The most specific language file will win.
This means that if both `content/norwegian/post/my-post.md` and `content/english/post/my-post.nn.md` exists, they will be considered duplicates and the version inside `content/norwegian` will win.
Note that translations will be automatically assigned by Hugo by the content file's relative placement, so `content/norwegian/post/my-post.md` will be a translation of `content/english/post/my-post.md`.
If this does not work for you, you can connect the translations together by setting a `translationKey` in the content files' front matter.
Fixes#4523Fixes#4552Fixes#4553
This allows a `config.toml` (or `yaml`, ´yml`, or `json`) in the theme to set:
1) `params` (but cannot override params in project. Will also get its own "namespace", i.e. `{{ .Site.Params.mytheme.my_param }}` will be the same as `{{ .Site.Params.my_param }}` providing that the main project does not define a param with that key.
2) `menu` -- but cannot redefine/add menus in the project. Must create its own menus with its own identifiers.
3) `languages` -- only `params` and `menu`. Same rules as above.
4) **new** `outputFormats`
5) **new** `mediaTypes`
This should help with the "theme portability" issue and people having to copy and paste lots of setting into their projects.
Fixes#4490
These were written as a development aid in some kind of structural change at some point.
They served their purpose then, but these are tests covered elsewhere and is deleted to reduce maintainance.
The reported test covrage is not reduced because of this.
As an example:
```html
{{ $pages := .Site.RegularPages | lang.Merge $frSite.RegularPages | lang.Merge $enSite.RegularPages }}
```
Will "fill in the gaps" in the current site with, from left to right, content from the French site, and lastly the English.
Fixes#4463
This commit makes it possible to extract the date from the content filename. Also, the filenames in these cases will make for very poor permalinks, so we will also use the remaining part as the page `slug` if that value is not set in front matter.
This should make it easier to move content from Jekyll to Hugo.
To enable, put this in your `config.toml`:
```toml
[frontmatter]
date = [":filename", ":default"]
```
This commit is also a spring cleaning of how the different dates are configured in Hugo. Hugo will check for dates following the configuration from left to right, starting with `:filename` etc.
So, if you want to use the `file modification time`, this can be a good configuration:
```toml
[frontmatter]
date = [ "date",":fileModTime", ":default"]
lastmod = ["lastmod" ,":fileModTime", ":default"]
```
The current `:default` values for the different dates are
```toml
[frontmatter]
date = ["date","publishDate", "lastmod"]
lastmod = ["lastmod", "date","publishDate"]
publishDate = ["publishDate", "date"]
expiryDate = ["expiryDate"]
```
The above will now be the same as:
```toml
[frontmatter]
date = [":default"]
lastmod = [":default"]
publishDate = [":default"]
expiryDate = [":default"]
```
Note:
* We have some built-in aliases to the above: lastmod => modified, publishDate => pubdate, published and expiryDate => unpublishdate.
* If you want a new configuration for, say, `date`, you can provide only that line, and the rest will be preserved.
* All the keywords to the right that does not start with a ":" maps to front matter parameters, and can be any date param (e.g. `myCustomDateParam`).
* The keywords to the left are the **4 predefined dates in Hugo**, i.e. they are constant values.
* The current "special date handlers" are `:fileModTime` and `:filename`. We will soon add `:git` to that list.
Fixes#285Closes#3310Closes#3762Closes#4340
Site.assembleSections logic assumes that the the home page would always be the first in the Site's list of pages. This is not in fact guaranteed to be true. When it is not, the method can fail to set the parent for some or all root-level pages.
Fixes#4447
This means that you can do something ala:
```html
{{ if ge .Hugo.Version "0.36" }}Reasonable new Hugo version!{{ end }}
```
The intented use is feature toggling, but please note that it will take some time and Hugo versions until this can be trusted. It does not work in older Hugo versions.
Fixes#4443
The same code now cycles through equivalent JSON, YAML and TOML data sets,
verifying output both proper and identical. Coverage increased by applying
previous tests for one format to the others.
More DRY. Added tests for numeric and bool value types.
Also:
- Remove unnecessary space from `figure` tag if no class is specified.
- Update related tests.
- Add test cases for the changes made to the figure shortcode.
- Document the newly added target and rel parameters
- Add more detail to the documentation of all figure shortcode parameters.
Add an additional test to "Variant 4, theme, use site base" to also test
for the index.html base (from by testing of #3505). Also add a "name"
field to the test cases to make it easier to know which test is failing
versus just getting a slice index.
* Adds retro-coverage for #4361
* Verifies open issues #4138, #3890, #4366, 4083
* Removes test reliance on the very code it is testing (hugo/parser package).
Expected results are now all built manually / are more precise.
Tests can run against different versions (no linkage errs)
This fixes some issues with language params handling by separating params from configuration values per language.
This means that you can now do this:
```toml
[languages]
[languages.en]
languageName = "English"
weight = 1
title = "My Cool Site"
[languages.en.params]
myParam = "Hi!"
```
This is not a breaking change, but the above is a less suprising way of configuring custom params.
It also fixes some hard-to-debug corner-cases in multilingual sites.
Fixes#4356Fixes#4352
This commit adds a new config setting:
```toml
disableLanguages = ["fr"]
```
If this is a multilingual site:
* No site for the French language will be created
* French content pages will be ignored/not read
* The French language configuration (menus etc.) will also be ignored
This makes it possible to start translating new languages and turn it on when you're happy etc.
Fixes#4297Fixed#4329
* Page without front matter now treated same as a page with empty front matter.
* Test cases added to cover this and repro issue #4320.
* Type safety of front matter code improved.
Fixes#4320
Now, even for nun-bundles it is possible to do lookup without path or extension.
So, given `blog/my-blog-post.en.md` these lookups will succeed:
* `blog/my-blog-post.en.md`
* `blog/my-blog-post`
* `my-blog-post.en.md`
* `my-blog-post`
See #4312
See https://github.com/gohugoio/hugoDocs/issues/307
Given a bundle in `blog/my-bundle/index.en.md` all of these will now worK:
* `blog/my-bundle/index.en.md`
* `blog/my-bundle/index`
* `blog/my-bundle`
* `my-bundle`
The last one is potentially ambigous.
Fixes#4312
This commit adds support for `headless bundles` for the `index` bundle type.
So:
```toml
headless = true
```
In front matter means that
* It will have no `Permalink` and no rendered HTML in /public
* It will not be part of `.Site.RegularPages` etc.
But you can get it by:
* `.Site.GetPage ...`
The use cases are many:
* Shared media galleries
* Reusable page content "snippets"
* ...
Fixes#4311
You can still use the full path with extensions, but to get the current language version:
* If the content file lives in `/content/blog/mypost.en.md`
* Use `.Site.GetPage "page" "blog/mypost"`
Fixes#4285
This commit expands the Resource interface with 3 new methods:
* Name
* Title
* Params
All of these can be set in the Page front matter. `Name` will get its default value from the base filename, and is the value used in the ByPrefix and GetByPrefix lookup methods.
Fixes#4244
This commit also has some other nice side-effects:
* The layout logic is unified for all page types, which should make it less surprising
* Page.Render now supports all types
* The legacy "indexes" type is removed from the template lookup order. This is an undocumented type from early Hugo days. This means that having a template in, say, `/layouts/indexes/list.html` will no longer work.
* The theme override logic is improved. As an example, an `index.html` in theme will now wn over a `_default/list.html` in the project, which most will expect.
Fixes#3005Fixes#3245
* We match by path vs taxonomy to determine if we have a content page for that taxonomy
* The taxonomy name is (if `preserveTaxonomyNames` is not set) normalized to `maxmustermann` while you have the disk folder called `MaxMustermann`.
* This isn't a new issue, but I suspect most people will just name the folder `authors/maxmustermann` and it will just work.
* The inconsistent behaviour you see here is that you will end up with two pages with the same target filename, so it is a little random who will win.
This fixes that by also normalizing the taxonomy path when doing the comparison.
Fixes#4238
We still do lowering of the param strings in some internal use of this, but the exported `GetParam` method is changed to a more sensible default.
This was used for the `disqus_title` etc. in the internal Disqus template, which was obviously not right.
If you really want to lowercase your params, do it with `.GetParam "myparam" | lower` or similar.
Fixes#4187
This commit is not the smallest in Hugo's history.
Some hightlights include:
* Page bundles (for complete articles, keeping images and content together etc.).
* Bundled images can be processed in as many versions/sizes as you need with the three methods `Resize`, `Fill` and `Fit`.
* Processed images are cached inside `resources/_gen/images` (default) in your project.
* Symbolic links (both files and dirs) are now allowed anywhere inside /content
* A new table based build summary
* The "Total in nn ms" now reports the total including the handling of the files inside /static. So if it now reports more than you're used to, it is just **more real** and probably faster than before (see below).
A site building benchmark run compared to `v0.31.1` shows that this should be slightly faster and use less memory:
```bash
▶ ./benchSite.sh "TOML,num_langs=.*,num_root_sections=5,num_pages=(500|1000),tags_per_page=5,shortcodes,render"
benchmark old ns/op new ns/op delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 101785785 78067944 -23.30%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 185481057 149159919 -19.58%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 103149918 85679409 -16.94%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 203515478 169208775 -16.86%
benchmark old allocs new allocs delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 532464 391539 -26.47%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 1056549 772702 -26.87%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 555974 406630 -26.86%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 1086545 789922 -27.30%
benchmark old bytes new bytes delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 53243246 43598155 -18.12%
BenchmarkSiteBuilding/TOML,num_langs=1,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 105811617 86087116 -18.64%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=500,tags_per_page=5,shortcodes,render-4 54558852 44545097 -18.35%
BenchmarkSiteBuilding/TOML,num_langs=3,num_root_sections=5,num_pages=1000,tags_per_page=5,shortcodes,render-4 106903858 86978413 -18.64%
```
Fixes#3651Closes#3158Fixes#1014Closes#2021Fixes#1240
Updates #3757
This is in heavy use in rendering, so this makes a difference:
```bash
benchmark old ns/op new ns/op delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_pages=500,tags_per_page=5,shortcodes,render-4 124551144 107743429 -13.49%
benchmark old allocs new allocs delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_pages=500,tags_per_page=5,shortcodes,render-4 528684 435118 -17.70%
benchmark old bytes new bytes delta
BenchmarkSiteBuilding/TOML,num_langs=1,num_pages=500,tags_per_page=5,shortcodes,render-4 53306848 45147832 -15.31%
```
It was clever, but storing the items in a slice is faster -- and it gives room to more goroutines in other places.
```bash
benchmark old ns/op new ns/op delta
BenchmarkShortcodeLexer-4 180173 79614 -55.81%
benchmark old allocs new allocs delta
BenchmarkShortcodeLexer-4 309 328 +6.15%
benchmark old bytes new bytes delta
BenchmarkShortcodeLexer-4 35456 47008 +32.58%
```
Recognize the Pandoc format under the file extension .pandoc or .pdc,
and shell out to pandoc as an external helper to format Pandoc content.
Refactor out repeated code with external helpers. Change the error
output formatting. I did not see any of the external helpers print the
string "<input>" to represent stdin as a file; just prepending the file
name to error output is more general and doesn't sacrifice that much in
terms of readability.
Closes#234
This commit refines the key used to map translations:
* Use `translationKey` set in front matter
* Fall back to path + base filename (i.e. the filename without extension and language code)
Note that the Page Kinde will be prepended to both cases above. It does not make sense to have a section as translation for the home page.
Fixes#2699
This commit adds support for multiple statDirs both on the global and language level.
A simple `config.toml` example:
```bash
staticDir = ["static1", "static2"]
[languages]
[languages.no]
staticDir = ["staticDir_override", "static_no"]
baseURL = "https://example.no"
languageName = "Norsk"
weight = 1
title = "På norsk"
[languages.en]
staticDir2 = "static_en"
baseURL = "https://example.com"
languageName = "English"
weight = 2
title = "In English"
```
In the above, with no theme used:
the English site will get its static files as a union of "static1", "static2" and "static_en". On file duplicates, the right-most version will win.
the Norwegian site will get its static files as a union of "staticDir_override" and "static_no".
This commit also concludes the Multihost support in #4027.
Fixes#36Closes#4027
Return the correct virtual Section for Taxonomy and TaxonomyTerm.
Restrict permalink expansion to only Pages and Taxonomies, but then
actually use expanded permalinks even for non-Pages.
Fixes#1208.
Hugo already, in its server mode, support partial rebuilds. To put it simply: If you change `about.md`, only that content page is read and processed, then Hugo does some processing (taxonomies etc.) and the full site is rendered.
This commit covers the rendering part: We now only re-render the pages you work on, i.e. the last n pages you watched in the browser (which obviously also includes the page in the example above).
To be more specific: When you are running the hugo server in watch (aka. livereload) mode, and change a template or a content file, then we do a partial re-rendering of the following:
* The current content page (if it is a content change)
* The home page
* Up to the last 10 pages you visited on the site.
This should in most cases be enough, but if you navigate to something completely different, you may see stale content. Doing an edit will then refresh that page.
Note that this feature is enabled by default. To turn it off, run `hugo server --disableFastRender`.
Fixes#3962
See #1643
Changes fall into one of the following:
- gofmt -s
- receiver name is inconsistent
- omit unused 2nd value from range
- godoc comment formed incorrectly
- err assigned and not used
- if block ends with a return statement followed by else
Move SummaryLength into the ContentSpec struct and refactor the
relevant summary functions to be methods of ContentSpec. The new
summaryLength struct member is configurable by the summaryLength config
value, and the default remains 70. Also updates hugolib/page to use the
refactored methods.
Resolves#3734
This makes live reloading behind a HTTPS proxy working, as in the example below using the service from https://ngrok.com:
```
hugo server -b https://ba6sdfe72.ngrok.io --appendPort=false --liveReloadPort=443 --navigateToChanged
```
Fixes#3882
Also related:
* support "modified" as an optional way to signal "last modified"
* make sure all relevant page dates are also added to params
Fixes#3867
This closes#98, even if this commit does not do full content text search.
We may revisit that problem in the future, but that deserves its own issue.
Fixes#98
And use it in `eq` and `ne` so `Page` values can be compared directly in the templates without thinking about it being a `Page` or a `PageOutput` wrapper.
Fixes#3807
As pointed out by the linter, some exported functions and types are
missing doc comments.
The linter warnings have been reduced from 194 to 116.
Not all missing comments have been added in this commit though.
This works for the `title` func and the other places where Hugo makes title case.
* AP style (new default)
* Chicago style
* Go style (what we have today)
Fixes#989
Why:
* first time using hugo I got very little info from --verbose output
but I noticed there is quite a lot of useful DEBUG logging
* asked for in other issues like https://github.com/gohugoio/hugo/issues/3514
This change addreses the need by:
* adding a simple --debug flag which simply turns on debug level in stdout
and logoutput if enabled.
This applies to both regular templates and shortcodes. So, if the site language is French and the output format is AMP, this is the (start) of the lookup order for the home page:
1. index.fr.amp.html
2. index.amp.html
3. index.fr.html
4. index.html
5. ...
Fixes#3360
This commit adds a new `--navigateToChanged` and config setting with the same name, that, when running the Hugo server with live reload enabled, will navigate to the current content file's URL on save.
This is really useful for site-wide content changes (copyedits etc.).
Fixes#3643
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 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
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