Replace the partial return template rewriting with a sentinel error
trapped in the template executor:
* return now works in any template, not just partials.
* return can be used anywhere in the template, e.g. inside if/range;
it stops execution of the current template, so a bare return in a
block or template include ends just that template.
* {{ return <value> }} sets the return value of the enclosing partial;
using it outside a partial is now an error (it was silently ignored).
The fork changes are limited to hugo_template.go plus one mechanical
rename (walkTemplate -> walkTemplateOld) mirrored in the fork script.
Closes#15212
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
When a transformed resource had been initialized (e.g. via .Data, .Content
or .RelPermalink) before chaining another transformation, the new chain
would run on the transformed output instead of the original source,
re-running all transformations on their own output.
Fixes#15189
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Artifacts are the additional output files published as part of the build:
source maps and files emitted by ESBuild's file loader (e.g. fonts). Each
artifact provides Permalink, RelPermalink and MediaType, so e.g. font
preload links can be constructed in templates.
Also add media type definitions for source maps (application/source-map),
font/woff and font/woff2.
Fixes#15173
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Chroma drops token rules whose color equals the style's default foreground
(e.g. .nx in github-dark). In a paired light/dark setup the other sheet's
explicit rule then leaks in, since an explicit declaration beats inheritance
from .chroma. Apply the chromaCSSOverrides custom CSS unconditionally so
these rules survive in modeSelector sheets too.
Updates #15161
This allows @import statements to be resolved in a set of user provided resources (e.g. from resources.FromString or css.ChromaStyles) before the assets filesystem.
The option also applies to css.PostCSS via the shared import inlining, and css.Sass requires the dartsass transpiler. The import context is part of the transformation cache key.
Fixes#15103
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Move the stylesheet generation from the gen chromastyles command into
markup/highlight and share it with the new template function.
Fixes#15112
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
E.g. {{ .Render "foo/mylayout" }} matches mylayout templates in
<dir>/foo for every dir from the page's layout path up to the layouts root.
Closes#15056
Co-authored-by: Joe Mooring <joe.mooring@veriphor.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The warning logged when calling IsSet with an unsupported type did not
identify which key triggered it, making it hard to locate the offending
template. Include the key in the message.
Fixes#11794
Add a generic crypto.Hash template function returning the hex-encoded
checksum of a string using one of md5, sha1, sha256 (default), sha384 or
sha512. The supported algorithms match those used for the SRI hash in
.Data.Integrity on fingerprinted resources, so an SRI hash can be built
by composing with encoding.HexDecode and encoding.Base64Encode.
Fixes#15072
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Canonicalize integer/hex/octal IPv4 hosts to dotted-decimal before
applying the security.http.urls policy so all encodings of an address
are treated alike.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
IsNode's meaning was murky. Add IsBranch, defined as the set of branch
node kinds (home, section, taxonomy, term), and make IsNode a deprecated
alias for it.
Fixes#11574
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Treat type and code as highlighting options in both transform.Highlight
and transform.HighlightCodeBlock. The type option overrides the language
and code overrides the code, so the two functions now share the same
options handling.
transform.Highlight's LANG argument is now optional:
transform.Highlight CODE [LANG] [OPTIONS]
Fixes#11872
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A partial's rendered output (placeholder included) is cached by
partialCached across rebuilds, but BuildState.DeferredExecutions
is reset every stage. On a fast-render rebuild the cached string
replays the placeholder while doDefer is not called this build,
leaving executeDeferredTemplates to panic with "deferred execution
with id ... not found".
Mark the ctx inside IncludeCached's body execution and have Defer
return a clear error if it sees the flag. Catches transitive cases
(partialCached -> partial -> Defer) via ctx propagation. Defer in
baseof.html and in a plain partial is unaffected.
Fixes#13492
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
When CSS imports assets via the file loader (fonts, images), the emitted
URLs were relative to the CSS output directory. That broke when the CSS
was inlined into HTML, since browsers then resolved the URLs against the
page rather than the CSS file.
Set esbuild's PublicPath to the CSS output directory joined with the
site base path so URLs work whether the CSS is published as a file or
inlined.
Fixes#14849
Fall back to global resources via resources.Get when page resources
don't match for named images in the images front matter parameter.
This aligns get-page-images.html with the existing behavior in
render-image.html, render-link.html, and figure.html.
Fixes#14062
Allow CSS variables to be grouped under sub-paths and imported via
@import "hugo:vars/mobile" (or @use for Dart Sass), so callers can pass
nested dicts like:
{{ dict "primary-color" "blue" "mobile" (dict "primary-color" "red") }}
Top-level "hugo:vars" now skips nested map entries instead of emitting
garbage for them.
Fixes#14705
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Whitelist now treats any pattern prefixed with "! " (the same negation
prefix used by hglob/predicate) as a deny rule. Deny matches take
precedence over allow, and a whitelist made up exclusively of deny
rules implicitly allows everything it does not deny.
The default security.http.urls now reads:
urls = ['(?i)^https?://[a-z]', '! (?i)localhost', '! @']
i.e. allow URLs whose host starts with a letter (the common
"https://example.com" shape), deny anything that looks like localhost,
and deny URLs with userinfo to foil "http://user@127.0.0.1/" bypasses.
Public IP literals are collateral blocks; users who need them (or their
own private hosts) override security.http.urls as before, mixing allow
and deny rules with the same "! " prefix, e.g.
[security.http]
urls = ['.*', '! ^https?://evil\.example\.com']
Fixes#14792
The where function previously fell through to a no-op when comparing
two values whose kinds were not handled by the primitive type switches
(e.g. two Page interface values). This made `where pages "Parent" $page`
return an empty list, while the equivalent `range pages` + `if eq` worked.
Use compare.Eqer for equality operators when either side implements it,
matching the behavior of the eq/ne template funcs.
Fixes#14777
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Use template.JS for the falsy return value of _PopPartialDecorator
so Go's html/template JS escaper doesn't wrap the empty string in
quotes inside <script> tags.
Fixes#14711
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Goldmark v1.8 reports source positions in render hooks.
Use this to build a source map that translates Goldmark positions back to
the original content source.
Now all render hooks' context object implenent the `BaseContext` interface:
```go
type BaseContext interface {
Position() Position
Page() any
PageInner() any
Ordinal() int
}
```
Closes#14663
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>