This allows for constructs like:
```
{{ $filters := slice (images.GaussianBlur 8) (images.Grayscale) (images.Process "jpg q30 resize 200x") }}
{{ $img = $img | images.Filter $filters }}
```
Note that the `action` option in `images.Process` is optional (`resize` in the example above), so you can use the above to just set the target format, e.g.:
```
{{ $filters := slice (images.GaussianBlur 8) (images.Grayscale) (images.Process "jpg") }}
{{ $img = $img | images.Filter $filters }}
```
Fixes#8439
Which supports all the existing actions: resize, crop, fit, fill.
But it also allows plain format conversions:
```
{{ $img = $img.Process "webp" }}
```
Which will be a simple re-encoding of the source image.
Fixes#11483
* Move config loading to the page package
* Fix a lower bound panic for the `:sections` slice syntax.
* Always return the `:title`
* Add some permalinks integration tests
* Also see issues below
Fixes#9448Fixes#11184
See #8523
Allows using permalink configuration for sections (branch bundles) and
also for taxonomy pages. Extends the current permalink configuration to
be able to specified per page kind while also staying backward compatible:
all permalink patterns not dedicated to a certain kind, get automatically
added for both normal pages and term pages.
Fixes#8523
Primary motivation is documentation, but it will also hopefully simplify the code.
Also,
* Lower case the default output format names; this is in line with the custom ones (map keys) and how
it's treated all the places. This avoids doing `stringds.EqualFold` everywhere.
Closes#10896Closes#10620
Make sure the context used for timeouts isn't created based on the incoming
context, as we have cases where this can cancel the context prematurely.
Fixes#10789
Applicable to Dart Sass only:
- Sass imports with the .css extension indicate a plain CSS @import.
- Sass imports without the .css extension are imported at compile time.
Fixes#10592
This also speeds up situations where you only need the fragments/toc and not the rendered content, e.g. Related
with fragments type indexing:
```bash
name old time/op new time/op delta
RelatedSite-10 12.3ms ± 2% 10.7ms ± 1% -12.95% (p=0.029 n=4+4)
name old alloc/op new alloc/op delta
RelatedSite-10 38.6MB ± 0% 38.2MB ± 0% -1.08% (p=0.029 n=4+4)
name old allocs/op new allocs/op delta
RelatedSite-10 117k ± 0% 115k ± 0% -1.36% (p=0.029 n=4+4)
```
Fixes#10750
But only in the case where we know that we will need to access the Page fragments/tableofcontents.
In normal situations this will spread naturally across the CPU cores, but not in the situation where
`site.RegularPages.Related` gets called as part of e.g. the single template.
```bash
name old time/op new time/op delta
RelatedSite-10 18.0ms ± 2% 11.9ms ± 1% -34.17% (p=0.029 n=4+4)
name old alloc/op new alloc/op delta
RelatedSite-10 38.6MB ± 0% 38.6MB ± 0% ~ (p=0.114 n=4+4)
name old allocs/op new allocs/op delta
RelatedSite-10 117k ± 0% 117k ± 0% +0.23% (p=0.029 n=4+4)
```
See #10711
Instead of maintaing a list of all CSS units and functions this commit:
* Uses 3 regexps to detect typed CSS values (e.g. `24px`) + properly handle numeric Go types.
* These regexps may have some false positives -- e.g. strings that needs to be quoted.
* For that rare case, you can mark the string with e.g. `"32xxx" | css.Quoted`
* For the opposite case: `"32" | css.Unquoted`
Updates #10632
Variables passed via the hugo:vars function where passed as type string.
This caused problems when using the variables in sass functions because
these expect a specific type. Now we check if the passed variables have
to be quoted and therefore are of type string or if they should not be
quoted and let the type interpretation up to the sass compiler.
Fixes#10632
The main topic of this commit is that you can now index fragments (content heading identifiers) when calling `.Related`.
You can do this by:
* Configure one or more indices with type `fragments`
* The name of those index configurations maps to an (optional) front matter slice with fragment references. This allows you to link
page<->fragment and page<->page.
* This also will index all the fragments (heading identifiers) of the pages.
It's also possible to use type `fragments` indices in shortcode, e.g.:
```
{{ $related := site.RegularPages.Related .Page }}
```
But, and this is important, you need to include the shortcode using the `{{<` delimiter. Not doing so will create infinite loops and timeouts.
This commit also:
* Adds two new methods to Page: Fragments (can also be used to build ToC) and HeadingsFiltered (this is only used in Related Content with
index type `fragments` and `enableFilter` set to true.
* Consolidates all `.Related*` methods into one, which takes either a `Page` or an options map as its only argument.
* Add `context.Context` to all of the content related Page API. Turns out it wasn't strictly needed for this particular feature, but it will
soon become usefil, e.g. in #9339.
Closes#10711
Updates #9339
Updates #10725
Note that this is backed by a LRU cache (which we soon shall see more usage of), so if you're a heavy user of cached partials it may be evicted and
refreshed if needed. But in most cases every partial is only invoked once.
This commit also adds a timeout (the global `timeout` config option) to make infinite recursion in partials
easier to reason about.
```
name old time/op new time/op delta
IncludeCached-10 8.92ms ± 0% 8.48ms ± 1% -4.87% (p=0.016 n=4+5)
name old alloc/op new alloc/op delta
IncludeCached-10 6.65MB ± 0% 5.17MB ± 0% -22.32% (p=0.002 n=6+6)
name old allocs/op new allocs/op delta
IncludeCached-10 117k ± 0% 71k ± 0% -39.44% (p=0.002 n=6+6)
```
Closes#4086
Updates #9588
So you can do `process.env.HUGO_PUBLISHDIR` in your `postcss.config.js` to figure out where Hugo publishes
its files.
Note that the value will always be an absolute file path and will point to a directory on disk even when running `hugo server` in memory mode.
If you write to this folder from PostCSS when running the server, you could run the server with one of these flags:
```
hugo server --renderToDisk
hugo server --renderStaticToDisk
```
Fixes#10554
This commit adds a new `vars` option to both the Sass transpilers (Dart Sass and Libsass).
This means that you can pass a map with key/value pairs to the transpiler:
```handlebars
{{ $vars := dict "$color1" "blue" "$color2" "green" "$font_size" "24px" }}
{{ $cssOpts := (dict "transpiler" "dartsass" "outputStyle" "compressed" "vars" $vars ) }}
{{ $r := resources.Get "scss/main.scss" | toCSS $cssOpts }}
```
And the the variables will be available in the `hugo:vars` namespace. Example usage for Dart Sass:
```scss
@use "hugo:vars" as v;
p {
color: v.$color1;
font-size: v.$font_size;
}
```
Note that Libsass does not support the `use` keyword, so you need to `import` them as global variables:
```scss
@import "hugo:vars";
p {
color: $color1;
font-size: $font_size;
}
```
Hugo will:
* Add a missing leading `$` for the variable names if needed.
* Wrap the values in `unquote('VALUE')` (Sass built-in) to get proper handling of identifiers vs other strings.
This means that you can pull variables directly from e.g. the site config:
```toml
[params]
[params.sassvars]
color1 = "blue"
color2 = "green"
font_size = "24px"
image = "images/hero.jpg"
```
```handlebars
{{ $vars := site.Params.sassvars}}
{{ $cssOpts := (dict "transpiler" "dartsass" "outputStyle" "compressed" "vars" $vars ) }}
{{ $r := resources.Get "scss/main.scss" | toCSS $cssOpts }}
```
Fixes#10555
This fixes the cases where
```js
import 'imp2/index.js';
import 'imp3/foo.js';
```
And these files lives in `assets` as:
```
imp2/index.ts
imp3/foo.ts
```
Fixes#10527
We do lazy initialization and (potentially) reuse of an output format's rendered content. We do this evaluation when we
start a new rendering a new output format. There are, however, situation where these borders gets crossed (e.g.
accessing content from another output format). We have a check for this in place for most cases, but not the content
rendering of inner markdown blocks inside shortcodes. This patch applies that same logic to the newly introduced
RenderContent method (which is not available from the templates).
Fixes#10391
Looking at the code as a whole, we ended up with a little to much "buttons". It turns out that doing case insensitive matching (lower both pattern and strings to match) performs just fine. Or at least, it
gives the penalty to the people who uses mixed case filenames.
```
GetGlob/Default_cache-10 10.6ns ± 2% 10.6ns ± 1% ~ (p=0.657 n=4+4)
GetGlob/Filenames_cache,_lowercase_searchs-10 10.6ns ± 2% 10.6ns ± 0% ~ (p=1.000 n=4+4)
GetGlob/Filenames_cache,_mixed_case_searchs-10 29.7ns ± 1% 29.6ns ± 1% ~ (p=0.886 n=4+4)
GetGlob/GetGlob-10 13.7ns ± 1% 13.7ns ± 0% ~ (p=0.429 n=4+4)
name old alloc/op new alloc/op delta
GetGlob/Default_cache-10 0.00B 0.00B ~ (all equal)
GetGlob/Filenames_cache,_lowercase_searchs-10 0.00B 0.00B ~ (all equal)
GetGlob/Filenames_cache,_mixed_case_searchs-10 5.00B ± 0% 5.00B ± 0% ~ (all equal)
GetGlob/GetGlob-10 0.00B 0.00B ~ (all equal)
name old allocs/op new allocs/op delta
GetGlob/Default_cache-10 0.00 0.00 ~ (all equal)
GetGlob/Filenames_cache,_lowercase_searchs-10 0.00 0.00 ~ (all equal)
GetGlob/Filenames_cache,_mixed_case_searchs-10 1.00 ± 0% 1.00 ± 0% ~ (all equal)
GetGlob/GetGlob-10
```
On Linux, `hugofs.Glob` does not hit any directories which includes
uppercase letters. (This does not happen on macOS.)
Since `resources.GetMatch/Match` uses `Glob`,
```
{{ resources.GetMatch "Foo/bar.css" }}
```
this does not match `assets/Foo/bar.css` .
On the other hand, you can get it with
```
{{ resources.Get "Foo/bar.css" }}
```
Simple sites may only have one css file. Update the replace directive to
correctly match single-file sourcemaps and multi-file sourcemaps.
Verified locally with and without SASS and CSS imports.
Fixes#8174
Same logic as for `index.{js,ts...}` files applies; if both `index.esm.js` and `index.js` exists (unlikely), you need to use the name
with extension when importing, else the `index.js` will win.
Fixes#8631