Commit graph

124 commits

Author SHA1 Message Date
Bjørn Erik Pedersen
a03c631c42
Rework template handling for function and map lookups
This is a big commit, but it deletes lots of code and simplifies a lot.

* Resolving the template funcs at execution time means we don't have to create template clones per site
* Having a custom map resolver means that we can remove the AST lower case transformation for the special lower case Params map

Not only is the above easier to reason about, it's also faster, especially if you have more than one language, as in the benchmark below:

```
name                          old time/op    new time/op    delta
SiteNew/Deep_content_tree-16    53.7ms ± 0%    48.1ms ± 2%  -10.38%  (p=0.029 n=4+4)

name                          old alloc/op   new alloc/op   delta
SiteNew/Deep_content_tree-16    41.0MB ± 0%    36.8MB ± 0%  -10.26%  (p=0.029 n=4+4)

name                          old allocs/op  new allocs/op  delta
SiteNew/Deep_content_tree-16      481k ± 0%      410k ± 0%  -14.66%  (p=0.029 n=4+4)
```

This should be even better if you also have lots of templates.

Closes #6594
2019-12-12 10:04:35 +01:00
Bjørn Erik Pedersen
167c01530b
Create lightweight forks of text/template and html/template
This commit also removes support for Ace and Amber templates.

Updates #6594
2019-12-12 09:59:34 +01:00
Bjørn Erik Pedersen
a3fe5e5e35
Fix Params case handling in the index, sort and where func
This means that you can now do:

```
{{ range where .Site.Pages "Params.MYPARAM" "foo" }}
```
2019-11-22 18:41:50 +01:00
Bjørn Erik Pedersen
a2670bf460 tpl/collections: Allow dict to create nested structures
Fixes #6497
2019-11-11 21:55:16 +01:00
Bjørn Erik Pedersen
90d0cdf236
tpl/collections: Add collections.Reverse
Fixes #6499
2019-11-11 18:33:22 +01:00
Bjørn Erik Pedersen
95ef93be66
tpl/collections: Make index work with slice as the last arg
Fixes #6496
2019-11-11 13:54:57 +01:00
Bjørn Erik Pedersen
5f6b6ec689
Prepare for Goldmark
This commmit prepares for the addition of Goldmark as the new Markdown renderer in Hugo.

This introduces a new `markup` package with some common interfaces and each implementation in its own package.

See #5963
2019-11-06 19:09:08 +01:00
Bjørn Erik Pedersen
9f46a72c7e tpl/collections: Add some index map test cases
See #3974
2019-11-04 11:13:27 +01:00
Baibhav Vatsa
65b7d4221b tpl: Modify error messages of after, first, and last
Modified the messages functions after, first, and last threw on being passed invalid parameters (index or limit) to be more standardised and resemble what Go compiler would throw.

Fixes #6415
2019-10-12 18:07:46 +02:00
Baibhav Vatsa
0e75af74db tpl: Last now accepts 0 as limit
Modified the if conditional because of which last threw an error if 0 was passed as limit. The function now returns an empty slice if it is called with 0 as limit. The behavior of first and last is now the same when 0 is passed as limit. Also added tests to test the new behavior.

Fixes #6419
2019-10-11 20:34:51 +02:00
Baibhav Vatsa
096a4b67b9 tpl: After now accepts 0 as index
Modified the if conditional because of which after threw an error if called with 0 as index. The function now returns the whole original slice if 0 is passed as an index. Also added tests to test the new behavior.

Fixes #6388
2019-10-11 08:35:27 +02:00
Bjørn Erik Pedersen
9e57182705
tests: Convert from testify to quicktest 2019-08-12 13:26:32 +02:00
Christian Muehlhaeuser
c577a9ed23 Fixed ineffectual assignments
Dropped/fixed ineffectual assignments after static code analysis.
2019-08-10 20:11:51 +02:00
XhmikosR
f7f549e3a7 Fix assorted typos 2019-08-01 13:55:48 +02:00
Bjørn Erik Pedersen
53077b0da5
Merge pull request #6149 from bep/sort-caseinsensitive
Implement lexicographically string sorting
2019-08-01 10:19:19 +02:00
Bjørn Erik Pedersen
c624a77992 tpl/collections: Add Merge function
Merges two maps recursively and returns a new one. Merge is case-insensitive.

Fixes #5992
2019-07-15 20:47:35 +02:00
Bjørn Erik Pedersen
e8a716b23a tpl/collections: Fix slice type handling in sort
The `sort` template func was producing a `[]page.Page` which did not work in `.Paginate`.

Fixes #6023
2019-06-10 08:32:44 +02:00
Bjørn Erik Pedersen
8d898ad667 tpl/collections: Unwrap any interface value in sort and where
Hugo `0.55.0` introduced some new interface types for `Page` etc.

This worked great in general, but there were cases where this would fail in `where` and `sort`.

One such example would be sorting by `MenuItem.Page.Date` where `Page` on `MenuItem` was a small subset of the bigger `page.Page` interface.

This commit fixes that by unwrapping such interface values.

Fixes #5989
2019-06-09 16:54:36 +02:00
Anton Harniakou
fb007e9ae5 tpl/collections: Convert numeric values to float64 and compare them
Fixes #5685
2019-05-30 11:32:58 +02:00
Cameron Moore
f76e50118b tpl: Provide more detailed errors in Where 2019-04-27 09:54:22 +02:00
Bjørn Erik Pedersen
7fbfedf013
tpl/collections: Return error on invalid input in in
See #5875
2019-04-19 08:58:12 +02:00
Bjørn Erik Pedersen
06f56fc983 tpl/collections: Make Pages etc. work with the in func
Fixes #5875
2019-04-18 23:42:01 +02:00
Bjørn Erik Pedersen
d7a67dcb51 tpl/collections: Make Pages etc. work in uniq
Fixes #5852
2019-04-18 16:50:13 +02:00
Bjørn Erik Pedersen
b5f39d23b8 all: Apply staticcheck recommendations 2019-03-24 16:14:51 +01:00
Bjørn Erik Pedersen
d30e845485
Run gofmt -s 2019-03-23 20:15:06 +01:00
Bjørn Erik Pedersen
597e418cb0
Make Page an interface
The main motivation of this commit is to add a `page.Page` interface to replace the very file-oriented `hugolib.Page` struct.
This is all a preparation step for issue  #5074, "pages from other data sources".

But this also fixes a set of annoying limitations, especially related to custom output formats, and shortcodes.

Most notable changes:

* The inner content of shortcodes using the `{{%` as the outer-most delimiter will now be sent to the content renderer, e.g. Blackfriday.
  This means that any markdown will partake in the global ToC and footnote context etc.
* The Custom Output formats are now "fully virtualized". This removes many of the current limitations.
* The taxonomy list type now has a reference to the `Page` object.
  This improves the taxonomy template `.Title` situation and make common template constructs much simpler.

See #5074
Fixes #5763
Fixes #5758
Fixes #5090
Fixes #5204
Fixes #4695
Fixes #5607
Fixes #5707
Fixes #5719
Fixes #3113
Fixes #5706
Fixes #5767
Fixes #5723
Fixes #5769
Fixes #5770
Fixes #5771
Fixes #5759
Fixes #5776
Fixes #5777
Fixes #5778
2019-03-23 18:51:22 +01:00
Anton Harniakou
908692fae5 Support nested keys/fields with missing values with the where function
Before this commit `where` would produce an error and bail building the
site. Now, `where` simply skips an element of a collection and does not
add it to the final result.

Closes #5637
Closes #5416
2019-02-06 19:53:34 +01:00
Cameron Moore
30a7c9ea37 tpl: Add godoc packages comments
Also fix package name in tpl/templates.
2018-11-30 08:56:30 +01:00
Cameron Moore
112461fded tpl/collections: Add float64 support to where
Fixes #5466
2018-11-27 09:04:02 +01:00
Bjørn Erik Pedersen
79a06aa4b6
tpl/collections: Properly handle pointer types in complement/symdiff
We cannot compare them by values, because that gets `hash of unhashable type` for the prime use case.
2018-11-07 09:29:13 +01:00
Bjørn Erik Pedersen
488776b649 tpl/collections: Add collections.SymDiff
Fixes #5410
2018-11-06 16:51:49 +01:00
Bjørn Erik Pedersen
42d8dfc8c8 tpl/collections: Add collections.Complement
Fixes #5400
2018-11-06 08:48:58 +01:00
Bjørn Erik Pedersen
889aca054a Run gofmt -s 2018-10-24 00:12:32 +02:00
Bjørn Erik Pedersen
35fbfb19a1
commands: Show server error info in browser
The main item in this commit is showing of errors with a file context when running `hugo server`.

This can be turned off: `hugo server --disableBrowserError` (can also be set in `config.toml`).

But to get there, the error handling in Hugo needed a revision. There are some items left TODO for commits soon to follow, most notable errors in content and config files.

Fixes #5284
Fixes #5290
See #5325
See #5324
2018-10-16 22:10:56 +02:00
Bjørn Erik Pedersen
31a8bb8c07 common/maps: Improve append in Scratch
This commit consolidates the reflective collections handling in `.Scratch` vs the `tpl` package so they use the same code paths.

This commit also adds support for a corner case where a typed slice is appended to a nil or empty `[]interface{}`.

Fixes #5275
2018-10-08 12:30:50 +02:00
Cameron Moore
0d5110d033 tpl: Cast IsSet key to int for indexed types
Don't assume that the user sends an int as the key when checking against
indexed types.

Fixes #3681
2018-10-03 09:36:27 +03:00
Bjørn Erik Pedersen
10ac2ec446 tpl/collections: Fix handling of different interface types in Slice
In Hugo `0.49` we improved type support in `slice`. This has an unfortunate side effect in that `resources.Concat` now expects something that can resolve to `resource.Resources`.

This worked for most situations, but when you try to `slice` different `Resource` objects, you would be getting `[]interface {}` and not `resource.Resources`. And `concat` would fail:

```bash
error calling Concat: slice []interface {} not supported in concat.
```

This commit fixes that by simplifying the type checking logic in `Slice`:

* If the first item implements the `Slicer` interface, we try that
* If the above fails or the first item does not implement `Slicer`, we just return the `[]interface {}`

Fixes #5269
2018-10-02 23:54:16 +03:00
Ricardo N Feliciano
cae07ce84b tpl/collections: Allow first function to return an empty slice
Fixes #5235
2018-09-22 20:58:46 +02:00
Bjørn Erik Pedersen
e27fd4c1b8 tpl/collections: Add collections.Append
Before this commit you would typically use `.Scratch.Add` to manually create slices in a loop.

With variable overwrite in Go 1.11, we can do better. This commit adds the `append` template func.

A made-up example:

```bash
{{ $p1 := index .Site.RegularPages 0 }}{{ $p2 := index .Site.RegularPages 1 }}
{{ $pages := slice }}
{{ if true }}
  {{ $pages = $pages | append $p2 $p1 }}
{{ end }}
```

Note that with 2 slices as arguments, the two examples below will give the same result:

```bash
{{ $s1 := slice "a" "b" | append (slice "c" "d") }}
{{ $s2 := slice "a" "b" | append "c" "d" }}
```

Both of the above will give `[]string{a, b, c, d}`.

This commit also improves the type handling in the `slice` template function. Now `slice "a" "b"` will give a `[]string` slice. The old behaviour was to return a `[]interface{}`.

Fixes #5190
2018-09-14 10:12:08 +02:00
Cameron Moore
4f72e79120 tpl: Show error on union or intersect of uncomparable types
Fixes #3820
2018-09-11 14:09:29 +02:00
Bjørn Erik Pedersen
fe6676c775 tpl/collections: Improve type handling in collections.Slice
Fixes #5188
2018-09-10 09:19:01 +02:00
Bjørn Erik Pedersen
7a97d3e6bc
tpl/collections: Allow pointer receiver in Group
See #4865
2018-09-08 21:56:36 +02:00
Bjørn Erik Pedersen
6667c6d743 tpl/collections: Add group template func
This extends the page grouping in Hugo with a template function that allows for ad-hoc grouping.

A made-up example:

```
{{ $cool := where .Site.RegularPages "Params.cool" true | group "cool" }}
{{ $blue := where .Site.RegularPages "Params.blue" true | group "blue" }}
{{ $paginator := .Paginate (slice $cool $blue) }}
```

Closes #4865
2018-09-08 20:20:26 +02:00
Bjørn Erik Pedersen
2b8d907ab7 Add a newScratch template func
Fixes #4685
2018-07-06 17:51:38 +02:00
Bjørn Erik Pedersen
dea71670c0
Add Hugo Piper with SCSS support and much more
Before this commit, you would have to use page bundles to do image processing etc. in Hugo.

This commit adds

* A new `/assets` top-level project or theme dir (configurable via `assetDir`)
* A new template func, `resources.Get` which can be used to "get a resource" that can be further processed.

This means that you can now do this in your templates (or shortcodes):

```bash
{{ $sunset := (resources.Get "images/sunset.jpg").Fill "300x200" }}
```

This also adds a new `extended` build tag that enables powerful SCSS/SASS support with source maps. To compile this from source, you will also need a C compiler installed:

```
HUGO_BUILD_TAGS=extended mage install
```

Note that you can use output of the SCSS processing later in a non-SCSSS-enabled Hugo.

The `SCSS` processor is a _Resource transformation step_ and it can be chained with the many others in a pipeline:

```bash
{{ $css := resources.Get "styles.scss" | resources.ToCSS | resources.PostCSS | resources.Minify | resources.Fingerprint }}
<link rel="stylesheet" href="{{ $styles.RelPermalink }}" integrity="{{ $styles.Data.Digest }}" media="screen">
```

The transformation funcs above have aliases, so it can be shortened to:

```bash
{{ $css := resources.Get "styles.scss" | toCSS | postCSS | minify | fingerprint }}
<link rel="stylesheet" href="{{ $styles.RelPermalink }}" integrity="{{ $styles.Data.Digest }}" media="screen">
```

A quick tip would be to avoid the fingerprinting part, and possibly also the not-superfast `postCSS` when you're doing development, as it allows Hugo to be smarter about the rebuilding.

Documentation will follow, but have a look at the demo repo in https://github.com/bep/hugo-sass-test

New functions to create `Resource` objects:

* `resources.Get` (see above)
* `resources.FromString`: Create a Resource from a string.

New `Resource` transformation funcs:

* `resources.ToCSS`: Compile `SCSS` or `SASS` into `CSS`.
* `resources.PostCSS`: Process your CSS with PostCSS. Config file support (project or theme or passed as an option).
* `resources.Minify`: Currently supports `css`, `js`, `json`, `html`, `svg`, `xml`.
* `resources.Fingerprint`: Creates a fingerprinted version of the given Resource with Subresource Integrity..
* `resources.Concat`: Concatenates a list of Resource objects. Think of this as a poor man's bundler.
* `resources.ExecuteAsTemplate`: Parses and executes the given Resource and data context (e.g. .Site) as a Go template.

Fixes #4381
Fixes #4903
Fixes #4858
2018-07-06 11:46:12 +02:00
Bjørn Erik Pedersen
f8212d2000
tpl/collections: Return en empty slice in after instead of error
When the given index is out of bounds. So it can safely be used with `with` etc. without extra length checking.

Fixes #4894
2018-07-01 20:34:02 +02:00
Bjørn Erik Pedersen
80230f26a3
Add support for theme composition and inheritance
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 #4460
Fixes #4450
2018-06-10 23:55:20 +02:00
Bjørn Erik Pedersen
eb42774e58
Add support for a content dir set per language
A sample config:

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

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

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

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

The content files will be assigned a language by

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

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

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

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

Fixes #4523
Fixes #4552
Fixes #4553
2018-04-02 08:06:21 +02:00
liguoqinjim
83c761b71a tpl/collections: Seed random on init only 2018-01-27 18:51:12 +01:00
Cameron Moore
47fdfd5196 Clean up lint in various packages
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
2017-09-29 16:23:16 +02:00
Bjørn Erik Pedersen
fb33d8286d Use Chroma as new default syntax highlighter
If you want to use Pygments, set `pygmentsUseClassic=true` in your site config.

Fixes #3888
2017-09-25 08:59:02 +02:00
Bjørn Erik Pedersen
3b4f17bbc9 hugolib: Implement "related content"
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
2017-09-06 00:20:02 +02:00
Bjørn Erik Pedersen
4b54fb0701 all: gofmt -s 2017-08-07 20:03:15 +02:00
Cameron Moore
55d0b89417 tpl/collections: Fix intersect on []interface{} handling
Fixes #3718
2017-07-28 07:21:21 +02:00
Bjørn Erik Pedersen
e0cf2e05bb tpl/collections: Add some empty slice tests to intersect
See #3686
2017-07-08 10:34:42 +02:00
Bjørn Erik Pedersen
dbbc5c4810 tpl/collections: Fix union when the first slice is empty
Fixes #3686
2017-07-08 10:31:09 +02:00
Bjørn Erik Pedersen
ccdd08d57a tpl/collections: Add Pages support to Intersect and Union
This enables `AND` (`intersect`)  and `OR` (`union`)  filters when combined with `where`.

Example:

```go
{{ $pages := where .Site.RegularPages "Type" "not in" (slice "page" "about") }}
{{ $pages := $pages | union (where .Site.RegularPages "Params.pinned" true) }}
{{ $pages := $pages | intersect (where .Site.RegularPages "Params.images" "!=" nil) }}
```

The above fetches regular pages not of `page` or `about` type unless they are pinned. And finally, we exclude all pages with no `images` set in Page params.

Fixes #3174
2017-07-03 21:48:03 +02:00
Bjørn Erik Pedersen
d12cf5a25d tpl/collections: Fix In function for JSON arrays
Fixes #1468
2017-07-03 10:23:03 +02:00
Bjørn Erik Pedersen
873a6f1885 Run gofmt to get imports in line vs gohugoio/hugo 2017-06-13 19:12:10 +02:00
Bjørn Erik Pedersen
d8717cd4c7 all: Update import paths to gohugoio/hugo 2017-06-13 18:42:45 +02:00
Cameron Moore
b82cd82f11 tpl/collections: Add uint support to In 2017-06-08 21:01:15 +02:00
Cameron Moore
204c3a9e32 tpl/collections: Support interfaces in union
Fixes #3411
2017-06-08 21:01:15 +02:00
Nathan Sharfi
e28d9aa42c tpl: Add uniq function 2017-06-03 19:13:58 +02:00
Bjørn Erik Pedersen
1f9e8dcc60 tpl: Make the Namespace func signature explicit
This makes it cleaner and avoids breaking client code, such as the docs helper JSON generator.
2017-05-20 11:34:38 +03:00
Bjørn Erik Pedersen
93c5774dd7 tpl/collections: Make IsSet WARNING less chatty
Updates #3092
2017-05-19 21:14:37 +03:00
Cameron Moore
58d4c25e50 tpl/collections: Use Feedback log instead of Error in IsSet
Using the Error log will cause Hugo to exit with an error, which could
break site build workflows.
2017-05-18 21:54:42 +03:00
Cameron Moore
38661c17bb tpl/collections: Log an error on unsupported types in IsSet
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
2017-05-18 21:54:42 +03:00
Cameron Moore
f1c29b017b tpl/collections: Add support for interfaces to intersect
Fixes #1952
2017-05-18 10:13:44 +03:00
Cameron Moore
f69df916df tpl: Add basic tests for all namespace init funcs 2017-05-02 00:07:33 +02:00
Bjørn Erik Pedersen
690b0f8ff5 tpl: Add docshelper for template funcs
And fix some other minor related issues.

Updates #3418
2017-05-01 21:44:15 +02:00
Bjørn Erik Pedersen
0e2260421e tpl: Fix the remaining template funcs namespace issues
See #3042
2017-05-01 15:13:41 +02:00
Bjørn Erik Pedersen
8a49c0b3b8 tpl/collections: Make it a package that stands on its own
See #3042
2017-05-01 15:13:41 +02:00
Bjørn Erik Pedersen
a3bf118eaa tpl/compare: Make it a package that stands on its own
See #3042
2017-05-01 15:13:41 +02:00
Cameron Moore
de7c32a1a8 tpl: Add template function namespaces
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
2017-04-30 10:56:38 +02:00