This commit is contained in:
Fran Simó 2025-06-12 17:23:32 +02:00 committed by GitHub
commit d64db3fd57
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,19 +1,168 @@
{{- if .Page.Site.Params.BookPortableLinks -}}
{{- template "portable-image" . -}}
{{- else -}}
<img src="{{ .Destination | safeURL }}" alt="{{ .Text }}" {{ with .Title }}title="{{ . }}"{{ end }}/>
{{- end -}}
{{- /* Last modified: 2025-04-25T11:05:22-07:00 */}}
{{- define "portable-image" -}}
{{- $isRemote := or (in .Destination "://") (strings.HasPrefix .Destination "//") }}
{{- if not $isRemote }}
{{- $path := print .Page.File.Dir .Destination }}
{{- if strings.HasPrefix .Destination "/" }}
{{- $path = print "/static" .Destination }}
{{- end }}
{{- if not (fileExists $path) }}
{{- warnf "Image '%s' not found in '%s'" .Destination .Page.File }}
{{- /*
Copyright 2025 Veriphor, LLC
https://www.veriphor.com/articles/link-and-image-render-hooks/
Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations under
the License.
*/}}
{{- /*
This render hook resolves internal destinations by looking for a matching:
1. Page resource (an image in the current page bundle)
2. Section resource (an image in the current section)
3. Global resource (an image in the assets directory)
It skips the section resource lookup if the current page is a leaf bundle, and
captures external destinations as resources for local hosting.
You must place global resources in the assets directory. If you have placed
your resources in the static directory, and you are unable or unwilling to move
them, you must mount the static directory to the assets directory by including
both of these entries in your site configuration:
[[module.mounts]]
source = 'assets'
target = 'assets'
[[module.mounts]]
source = 'static'
target = 'assets'
By default, if this render hook is unable to resolve a destination, it passes
the destination through without modification. To emit a warning or error, set
the error level in your site configuration:
[params.render_hooks.image]
errorLevel = 'warning' # ignore (default), warning, or error (fails the build)
Image render hooks are also used to:
- Resize, crop, rotate, filter, and convert images
- Build responsive images using srcset and sizes attributes
- Wrap images inside of a picture element
- Transform standalone images into figure elements
To perform any of these operations, you can “hook” into this render hook with a
partial template, after the render hook has captured the resource.
@context {map} Attributes The Markdown attributes, available if (a) markup.goldmark.parser.attribute.block is true, and (b) markup.goldmark.parser.wrapStandAloneImageWithinParagraph is false in site configuration.
@context {string} Destination The image destination.
@context {bool} IsBlock Returns true if a standalone image is not wrapped within a paragraph element.
@context {int} Ordinal The zero-based ordinal of the image on the page.
@context {page} Page A reference to the page containing the image.
@context {string} PlainText The image description as plain text.
@context {string} Text The image description.
@context {string} Title The image title.
@returns {template.html}
*/}}
{{- /* Initialize. */}}
{{- $renderHookName := "image" }}
{{- /* Verify minimum required version. */}}
{{- $minHugoVersion := "0.147.0" }}
{{- if lt hugo.Version $minHugoVersion }}
{{- errorf "The %q render hook requires Hugo v%s or later." $renderHookName $minHugoVersion }}
{{- end }}
{{- /* Error level when unable to resolve destination: ignore, warning, or error. */}}
{{- $errorLevel := or site.Params.render_hooks.image.errorLevel "ignore" | lower }}
{{- /* Validate error level. */}}
{{- if not (in (slice "ignore" "warning" "error") $errorLevel) }}
{{- errorf "The %q render hook is misconfigured. The errorLevel %q is invalid. Please check your site configuration." $renderHookName $errorLevel }}
{{- end }}
{{- /* Determine content path for warning and error messages. */}}
{{- $contentPath := "" }}
{{- with .Page.File }}
{{- $contentPath = .Path }}
{{- else }}
{{- $contentPath = .Path }}
{{- end }}
{{- /* Parse destination. */}}
{{- $u := urls.Parse .Destination }}
{{- /* Set common message. */}}
{{- $msg := printf "The %q render hook was unable to resolve the destination %q in %s" $renderHookName $u.String $contentPath }}
{{- /* Get image resource. */}}
{{- $r := "" }}
{{- if $u.IsAbs }}
{{- with try (resources.GetRemote $u.String) }}
{{- with .Err }}
{{- if eq $errorLevel "warning" }}
{{- warnf "%s. See %s" . $contentPath }}
{{- else if eq $errorLevel "error" }}
{{- errorf "%s. See %s" . $contentPath }}
{{- end }}
{{- else with .Value }}
{{- /* Destination is a remote resource. */}}
{{- $r = . }}
{{- else }}
{{- if eq $errorLevel "warning" }}
{{- warnf $msg }}
{{- else if eq $errorLevel "error" }}
{{- errorf $msg }}
{{- end }}
{{- end }}
{{- end }}
<img src="{{ .Destination | safeURL }}" alt="{{ .Text }}" {{ with .Title }}title="{{ . }}"{{ end }}/>
{{- end -}}
{{- else }}
{{- with .PageInner.Resources.Get (strings.TrimPrefix "./" $u.Path) }}
{{- /* Destination is a page resource. */}}
{{- $r = . }}
{{- else with (and (ne .Page.BundleType "leaf") (.Page.CurrentSection.Resources.Get (strings.TrimPrefix "./" $u.Path))) }}
{{- /* Destination is a section resource, and current page is not a leaf bundle. */}}
{{- $r = . }}
{{- else with resources.Get $u.Path }}
{{- /* Destination is a global resource. */}}
{{- $r = . }}
{{- else }}
{{- if eq $errorLevel "warning" }}
{{- warnf $msg }}
{{- else if eq $errorLevel "error" }}
{{- errorf $msg }}
{{- end }}
{{- end }}
{{- end }}
{{- /* Determine id attribute. */}}
{{- $id := printf "h-rh-i-%d" .Ordinal }}
{{- with .Attributes.id }}
{{- $id = . }}
{{- end }}
{{- /* Initialize attributes. */}}
{{- $attrs := merge .Attributes (dict "id" $id "alt" .PlainText "title" (.Title | transform.HTMLEscape) "src" $u.String) }}
{{- /* Merge attributes from resource. */}}
{{- with $r }}
{{- $attrs = merge $attrs (dict "src" .RelPermalink) }}
{{- if not (eq .MediaType.SubType "svg") }}
{{- $attrs = merge $attrs (dict "height" (string .Height) "width" (string .Width)) }}
{{- end }}
{{- end }}
{{- /* Render image element. */ -}}
<img
{{- range $k, $v := $attrs }}
{{- if or $v (eq $k "alt") }}
{{- printf " %s=%q" $k $v | safeHTMLAttr }}
{{- end }}
{{- end -}}
>
{{- /**/ -}}