From 8212d6fd028017201914f382e6f78831fa3e5722 Mon Sep 17 00:00:00 2001 From: Cell <1024@lruihao.cn> Date: Fri, 7 Mar 2025 12:18:40 +0800 Subject: [PATCH] :recycle: Refactor: image rendering aaa~again (#575) --- assets/css/_core/_base.scss | 9 + assets/css/_page/_single.scss | 26 +-- hugo.toml | 12 +- layouts/_default/_markup/render-image.html | 21 ++- layouts/_default/summary.html | 10 +- layouts/partials/feed/rss.html | 8 +- .../partials/function/get-remote-image.html | 22 --- layouts/partials/function/is-url-remote.html | 1 + layouts/partials/function/resource.html | 12 +- .../partials/function/suffix-validation.html | 5 + layouts/partials/header.html | 2 +- layouts/partials/home/profile.html | 9 +- layouts/partials/plugin/image-legacy.html | 114 ++++++++++++ layouts/partials/plugin/image.html | 169 ++++++++---------- layouts/partials/plugin/link.html | 9 - layouts/partials/single/post-author.html | 7 +- layouts/posts/single.html | 10 +- layouts/shortcodes/image.html | 12 +- 18 files changed, 275 insertions(+), 183 deletions(-) delete mode 100644 layouts/partials/function/get-remote-image.html create mode 100644 layouts/partials/function/is-url-remote.html create mode 100644 layouts/partials/plugin/image-legacy.html diff --git a/assets/css/_core/_base.scss b/assets/css/_core/_base.scss index 03b88865..dc96f78e 100644 --- a/assets/css/_core/_base.scss +++ b/assets/css/_core/_base.scss @@ -54,6 +54,15 @@ abbr[title] { text-decoration-skip-ink: none; } +img { + object-fit: cover; +} + +img,video { + max-width: 100%; + height: auto; +} + @include link(true, true); @import '../_partials/scrollbar'; diff --git a/assets/css/_page/_single.scss b/assets/css/_page/_single.scss index 051a2dc1..79be06b6 100644 --- a/assets/css/_page/_single.scss +++ b/assets/css/_page/_single.scss @@ -368,31 +368,6 @@ max-width: 100%; min-height: 1em; - &:not([height]) { - height: auto; - } - - &[loading='lazy'][srcset]:not([data-lazyloaded]) { - &:not(.suffix-invalid__small) { - width: var(--width-small, var(--width)); - aspect-ratio: var(--aspect-ratio-small, var(--aspect-ratio)); - } - - &:not(.suffix-invalid) { - @media (min-resolution: 1.01dppx) and (max-resolution: 1.5dppx) { - width: calc(var(--width) / 1.5); - aspect-ratio: var(--aspect-ratio); - } - } - - &:not(.suffix-invalid__large) { - @media (min-resolution: 1.51dppx) { - width: calc(var(--width-large, var(--width)) / 2); - aspect-ratio: var(--aspect-ratio-large, var(--aspect-ratio)); - } - } - } - &.version { height: 1.25em; vertical-align: text-bottom; @@ -419,6 +394,7 @@ img { display: block; margin: 0 auto; + height: auto; overflow: hidden; } } diff --git a/hugo.toml b/hugo.toml index 286e6eed..8c47a69d 100644 --- a/hugo.toml +++ b/hugo.toml @@ -943,6 +943,13 @@ enableEmoji = true [params.feed.follow] feedId = "" userId = "" + + # FixIt 0.3.17 | NEW Image config + [params.image] + # cache remote images for better optimisations + cacheRemote = false + # Image resizing and optimisation + optimise = false # FixIt 0.3.12 | NEW Custom partials config # Custom partials must be stored in the /layouts/partials/ directory. @@ -1107,11 +1114,6 @@ enableEmoji = true scale = true # whether to add FullscreenControl fullscreen = true - # FixIt 0.3.0 | NEW [Experimental] cache remote images locally, see: https://github.com/hugo-fixit/FixIt/pull/362 - [params.page.cacheRemoteImages] - enable = false - # replace remote image url with local image url (place in public/images/remote/) - replace = false # FixIt 0.3.0 | NEW Related content config (https://gohugo.io/content-management/related/) [params.page.related] enable = false diff --git a/layouts/_default/_markup/render-image.html b/layouts/_default/_markup/render-image.html index 2937c655..dfff9a1b 100644 --- a/layouts/_default/_markup/render-image.html +++ b/layouts/_default/_markup/render-image.html @@ -1,14 +1,27 @@ -{{- /* TODO refactor */ -}} +{{- /* +A Markdown image has three components: the image description, the image destination, and optionally the image title. + +![white kitten](/images/kitten.jpg "A kitten!") + ------------ ------------------ --------- + description destination title + ------------ ------------------ --------- + .Text .Destination .Title +*/ -}} {{- $params := .Page.Params | merge site.Params.page -}} +{{- $optim := slice + (dict "Process" "resize 800x webp q75" "descriptor" "800w") + (dict "Process" "resize 1200x webp q75" "descriptor" "1200w") + (dict "Process" "resize 1600x webp q75" "descriptor" "1600w") +-}} {{- if .Title | and .Text -}} {{- $linked := ne $params.lightgallery false -}}
- {{- dict "Src" .Destination "Alt" .Text "Caption" .Text "Title" .Title "Linked" $linked "Responsive" true "Resources" .Page.Resources | partial "plugin/image.html" -}} + {{- dict "Src" .Destination "Alt" .PlainText "Title" .Title "Caption" .Text "Linked" $linked "Loading" "lazy" "Resources" .Page.Resources "OptimConfig" $optim | partial "plugin/image.html" -}}
- {{- .Text | safeHTML -}} + {{- .Title | safeHTML -}}
{{- else -}} {{- $linked := (eq $params.lightgallery "force") | or ($params.lightgallery | and (ne .Title "")) -}} - {{- dict "Src" .Destination "Alt" .Text "Title" .Title "Linked" $linked "Responsive" true "Resources" .Page.Resources | partial "plugin/image.html" -}} + {{- dict "Src" .Destination "Alt" .PlainText "Title" .Title "Linked" $linked "Loading" "lazy" "Resources" .Page.Resources "OptimConfig" $optim | partial "plugin/image.html" -}} {{- end -}} diff --git a/layouts/_default/summary.html b/layouts/_default/summary.html index 45dc616c..d6750bca 100644 --- a/layouts/_default/summary.html +++ b/layouts/_default/summary.html @@ -3,6 +3,9 @@
{{- /* Featured image */ -}} {{- $image := $params.featuredimagepreview | default $params.featuredimage -}} + {{- with dict "Path" $image "Resources" .Resources | partial "function/resource.html" }} + {{- $image = .RelPermalink }} + {{- end }} {{- with .Resources.GetMatch "featured-image" -}} {{- $image = .RelPermalink -}} {{- end -}} @@ -12,7 +15,12 @@ {{- with $image -}} {{- end -}} diff --git a/layouts/partials/feed/rss.html b/layouts/partials/feed/rss.html index b451b3f2..292cbcb3 100644 --- a/layouts/partials/feed/rss.html +++ b/layouts/partials/feed/rss.html @@ -32,13 +32,9 @@ {{- $params := .Params | merge .Site.Params.Page }} {{- $fullText := ((.Params.feed | default dict) | merge $.Config ).fulltext }} {{- $author := partial "function/get-author-map.html" .Params.author }} - {{- $cacheRemoteImages := $params.cacheRemoteImages }} {{- $image := $params.featuredimagepreview | default $params.featuredimage }} - {{- with dict "Path" $image "Resources" .Resources "CacheRemoteImages" $cacheRemoteImages.enable | partial "function/resource.html" }} - {{- $url := urls.Parse $image }} - {{- if not $url.Host | or $cacheRemoteImages.replace }} - {{- $image = .Permalink }} - {{- end }} + {{- with dict "Path" $image "Resources" .Resources | partial "function/resource.html" }} + {{- $image = .Permalink }} {{- end }} {{- with .Resources.GetMatch "featured-image" }} {{- $image = .Permalink }} diff --git a/layouts/partials/function/get-remote-image.html b/layouts/partials/function/get-remote-image.html deleted file mode 100644 index dbb35508..00000000 --- a/layouts/partials/function/get-remote-image.html +++ /dev/null @@ -1,22 +0,0 @@ -{{- /* cache remote image locally */ -}} -{{- $resource := 0 -}} -{{- $suffixList := slice ".jpeg" ".jpg" ".png" ".gif" ".bmp" ".tif" ".tiff" ".webp" ".avif" ".svg" -}} -{{- $suffixValid := (dict "Path" .Path "Suffixes" $suffixList | partial "function/suffix-validation.html") -}} -{{- /* maybe could add domain validation */ -}} -{{- $pass := $suffixValid | or .Pass -}} - -{{- if $pass -}} - {{- with try ($remoteResource := resources.GetRemote .Path) -}} - {{- with .Err -}} - {{- erroridf "error-get-remote-image" "%s" . -}} - {{- else with .Value -}} - {{- if eq $remoteResource.ResourceType "image" -}} - {{- /* placed remote image in public/images/remote/ */ -}} - {{- $resource = $remoteResource | resources.Copy (add "/images/remote/" $remoteResource.Name) -}} - {{- end -}} - {{- else -}} - {{- erroridf "error-get-remote-image" "Unable to get remote image %q" $.Path -}} - {{- end -}} - {{- end -}} -{{- end -}} -{{- return $resource -}} diff --git a/layouts/partials/function/is-url-remote.html b/layouts/partials/function/is-url-remote.html new file mode 100644 index 00000000..40217f74 --- /dev/null +++ b/layouts/partials/function/is-url-remote.html @@ -0,0 +1 @@ +{{- return and (not (eq .Scheme "")) .Host -}} diff --git a/layouts/partials/function/resource.html b/layouts/partials/function/resource.html index 755c1eb8..c3dbf093 100644 --- a/layouts/partials/function/resource.html +++ b/layouts/partials/function/resource.html @@ -1,22 +1,18 @@ {{- $Resources := .Resources | default page.Resources -}} {{- $resource := 0 -}} {{- $url := urls.Parse .Path -}} -{{- if not $url.Host | and $url.Path | and (strings.HasSuffix $url.Path "/" | not) -}} +{{- if not (partial "function/is-url-remote.html" $url) -}} + {{- $dest := strings.TrimPrefix "./" $url.Path -}} {{- if $Resources -}} - {{- with $Resources.GetMatch $url.Path -}} + {{- with $Resources.GetMatch $dest -}} {{- $resource = . -}} {{- end -}} {{- end -}} {{- if not $resource -}} - {{- with resources.Get $url.Path -}} + {{- with resources.Get $dest -}} {{- $resource = . -}} {{- end -}} {{- end -}} -{{- else -}} - {{- $cacheRemoteImages := .CacheRemoteImages | default false -}} - {{- if $cacheRemoteImages -}} - {{- $resource = partial "function/get-remote-image.html" (dict "Path" .Path) -}} - {{- end -}} {{- end -}} {{- return $resource -}} diff --git a/layouts/partials/function/suffix-validation.html b/layouts/partials/function/suffix-validation.html index 02a35545..ebd21096 100644 --- a/layouts/partials/function/suffix-validation.html +++ b/layouts/partials/function/suffix-validation.html @@ -1,3 +1,8 @@ +{{- /* +Example: +{{- $suffixList := slice ".jpeg" ".jpg" ".png" ".gif" ".bmp" ".tif" ".tiff" ".webp" ".avif" ".svg" -}} +{{- $suffixValid := (dict "Path" .Path "Suffixes" $suffixList | partial "function/suffix-validation.html") -}} +*/ -}} {{- $url := urls.Parse .Path -}} {{- $path := path.Clean ((printf "%v%v" $url.Host $url.Path) | lower) -}} {{- with $url.Scheme -}} diff --git a/layouts/partials/header.html b/layouts/partials/header.html index f4cfa2aa..2a0ebf91 100644 --- a/layouts/partials/header.html +++ b/layouts/partials/header.html @@ -8,7 +8,7 @@ {{- with .Site.Params.header.title -}} {{- with .logo -}} - {{- dict "Src" . "Class" "logo" "Alt" $.Site.Title "Width" 26 "Height" 26 | partial "plugin/image.html" -}} + {{- dict "Src" . "Class" "logo" "Alt" $.Site.Title "Width" 32 "Height" 32 | partial "plugin/image.html" -}} {{- end -}} {{- with .pre -}} {{ . | safeHTML }} diff --git a/layouts/partials/home/profile.html b/layouts/partials/home/profile.html index bb256bad..7154c449 100644 --- a/layouts/partials/home/profile.html +++ b/layouts/partials/home/profile.html @@ -14,6 +14,11 @@ {{- if $avatar -}}
{{- $menus := $.Site.Menus.main | default slice -}} + {{- $optim := slice + (dict "Process" "fill center 96x96 webp q75" "descriptor" "96w") + (dict "Process" "fill center 144x144 webp q75" "descriptor" "144w") + (dict "Process" "fill center 192x192 webp q75" "descriptor" "192w") + -}} {{- $avatarMenuIndex := 0 -}} {{- if $profile.avatarMenu -}} {{- range $index, $menu := $menus -}} @@ -28,10 +33,10 @@ {{- $url = .RelPermalink -}} {{- end -}} - {{- dict "Src" $avatar "Alt" $.Site.Params.author.name "Width" 96 "Height" 96 | partial "plugin/image.html" -}} + {{- dict "Src" $avatar "Alt" "Home avatar" "Width" 96 "Height" 96 "OptimConfig" $optim | partial "plugin/image.html" -}} {{- else -}} - {{- dict "Src" $avatar "Alt" $.Site.Params.author.name "Width" 96 "Height" 96 | partial "plugin/image.html" -}} + {{- dict "Src" $avatar "Alt" "Home avatar" "Width" 96 "Height" 96 "OptimConfig" $optim | partial "plugin/image.html" -}} {{- end -}}
{{- end -}} diff --git a/layouts/partials/plugin/image-legacy.html b/layouts/partials/plugin/image-legacy.html new file mode 100644 index 00000000..c4d01ee0 --- /dev/null +++ b/layouts/partials/plugin/image-legacy.html @@ -0,0 +1,114 @@ +{{- /* + deprecated: image-legacy.html + TODO delete this file in the next minor release +*/ -}} +{{- $params := partial "function/params.html" -}} +{{- $class := .Class | default "" -}} +{{- $style := "" -}} +{{- $loading := .Loading | default "lazy" -}} +{{- $onload := "" -}} +{{- $onerror := "" -}} +{{- $cacheRemoteImages := $params.cacheRemoteImages -}} +{{- $suffixList := slice ".jpeg" ".jpg" ".png" ".gif" ".bmp" ".tif" ".tiff" ".webp" -}} +{{- $responsive := .Responsive -}} + +{{- if hasPrefix .Src "data:image" -}} + {{- $responsive = false -}} +{{- end -}} + +{{- /* handle for default size image */ -}} +{{- $src := .Src -}} +{{- $suffixValid := dict "Path" $src "Suffixes" $suffixList | partial "function/suffix-validation.html" -}} +{{- with dict "Path" $src "Resources" .Resources "CacheRemoteImages" $cacheRemoteImages.enable | partial "function/resource.html" -}} + {{- $url := urls.Parse $src -}} + {{- if not $url.Host | or $cacheRemoteImages.replace -}} + {{- $src = .RelPermalink -}} + {{- end -}} + {{- /* only available for image resources that are raster images */ -}} + {{- if (eq .ResourceType "image") | and $suffixValid | and $responsive -}} + {{- $style = printf "--width: %vpx;--aspect-ratio: %v / %v;" .Width .Width .Height | safeHTMLAttr -}} + {{- end -}} +{{- end -}} + +{{- $srcSmall := .SrcSmall | default $src -}} +{{- $srcMedium := $src -}} +{{- $srcLarge := .SrcLarge | default $src -}} + +{{- if $responsive }} + {{- /* handle for small size image */ -}} + {{- $suffixValidSmall := dict "Path" $srcSmall "Suffixes" $suffixList | partial "function/suffix-validation.html" -}} + {{- with dict "Path" .SrcSmall "Resources" .Resources "CacheRemoteImages" $cacheRemoteImages.enable | partial "function/resource.html" -}} + {{- $url := urls.Parse $.SrcSmall -}} + {{- if not $url.Host | or $cacheRemoteImages.replace -}} + {{- $srcSmall = .RelPermalink -}} + {{- end -}} + {{- if (eq .ResourceType "image") | and $suffixValidSmall -}} + {{- $style = printf "%v--width-small: %vpx;--aspect-ratio-small: %v / %v;" $style .Width .Width .Height | safeHTMLAttr -}} + {{- end -}} + {{- end -}} + + {{- /* handle for large size image */ -}} + {{- $suffixValidLarge := dict "Path" $srcLarge "Suffixes" $suffixList | partial "function/suffix-validation.html" -}} + {{- with dict "Path" .SrcLarge "Resources" .Resources "CacheRemoteImages" $cacheRemoteImages.enable | partial "function/resource.html" -}} + {{- $url := urls.Parse $.SrcLarge -}} + {{- if not $url.Host | or $cacheRemoteImages.replace -}} + {{- $srcLarge = .RelPermalink -}} + {{- end -}} + {{- if (eq .ResourceType "image") | and $suffixValidLarge -}} + {{- $style = printf "%v--width-large: %vpx;--aspect-ratio-large: %v / %v;" $style .Width .Width .Height | safeHTMLAttr -}} + {{- end -}} + {{- end -}} + + {{- /* handle for invalid suffix */ -}} + {{- if not $suffixValid | and $src -}} + {{- $class = printf "%v suffix-invalid" $class -}} + {{- end -}} + {{- if not $suffixValidSmall | and $srcSmall -}} + {{- $class = printf "%v suffix-invalid__small" $class -}} + {{- end -}} + {{- if not $suffixValidLarge | and $srcLarge -}} + {{- $class = printf "%v suffix-invalid__large" $class -}} + {{- end -}} + + {{- /* set image srcset */ -}} + {{- if (eq $src $srcSmall) | and (eq $src $srcLarge) -}} + {{- $srcSmall = printf (cond (strings.Contains $srcSmall "?") "%v&size=small" "%v?size=small") $srcSmall -}} + {{- $srcMedium = printf (cond (strings.Contains $srcMedium "?") "%v&size=medium" "%v?size=medium") $srcMedium -}} + {{- $srcLarge = printf (cond (strings.Contains $srcLarge "?") "%v&size=large" "%v?size=large") $srcLarge -}} + {{- end -}} +{{- end -}} + +{{- /* set image alt and caption */ -}} +{{- $alt := .Alt | default $src -}} +{{- $caption := .Caption | default $alt -}} + +{{- /* set image lazy loading */ -}} +{{- /* for details, see https://lruihao.cn/posts/native-img-loading-lazy/ */ -}} +{{- if eq $loading "lazy" -}} + {{- /* TODO move to theme.js */ -}} + {{- $commonScript := "this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}" -}} + {{- $onload = printf " onload=\"%vthis.dataset.lazyloaded='';\"" $commonScript | safeHTMLAttr -}} + {{- $onerror = printf " onerror=\"%v\"" $commonScript | safeHTMLAttr -}} + {{- $style = printf " style=\"%vbackground: url(%v) no-repeat center;\"" $style (resources.Get "images/loading.svg" | minify).RelPermalink | safeHTMLAttr -}} +{{- end -}} + +{{- /* structure of lightgallery or img */ -}} +{{- if .Linked -}} + +{{- end -}} +{{ $alt }} +{{- if .Linked -}} + +{{- end -}} diff --git a/layouts/partials/plugin/image.html b/layouts/partials/plugin/image.html index c3e4f3dd..db745d90 100644 --- a/layouts/partials/plugin/image.html +++ b/layouts/partials/plugin/image.html @@ -1,111 +1,90 @@ -{{- /* TODO refactor */ -}} -{{- $params := partial "function/params.html" -}} -{{- $class := .Class | default "" -}} -{{- $style := "" -}} -{{- $loading := .Loading | default "lazy" -}} -{{- $onload := "" -}} -{{- $onerror := "" -}} -{{- $cacheRemoteImages := $params.cacheRemoteImages -}} -{{- $suffixList := slice ".jpeg" ".jpg" ".png" ".gif" ".bmp" ".tif" ".tiff" ".webp" -}} -{{- $responsive := .Responsive -}} +{{- /* +The image plugin is a partial that handles image resources. -{{- if hasPrefix .Src "data:image" -}} - {{- $responsive = false -}} +Parameters: +- Src: The path to the image. + It can be a page resource (inside a page bundle) https://gohugo.io/methods/page/resources/ + or a global resource (inside the assets directory) https://gohugo.io/functions/resources/get/ + or a link to a remote resource, which can be cached if the site parameter is set https://gohugo.io/functions/resources/getremote/ +- Resources: If the image is a page resource, this parameter is required. It is the .Resources of the page. +- OptimConfig: optimisation parameter, defined like + {{- $optim := slice + (dict "Process" "resize 800x Center webp q75" "descriptor" "800w") + (dict "Process" "resize 1200x Center webp q75" "descriptor" "1200w") + (dict "Process" "resize 1600x Center webp q75" "descriptor" "1600w") + -}} + See https://gohugo.io/content-management/image-processing/ for more information. +- Alt: alt text for the image. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#alt +- Height: The intrinsic height of the image, in pixels. Must be an integer without a unit. + We try to generate this value automatically if possible. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#height +- Width: The intrinsic width of the image, in pixels. Must be an integer without a unit. + We try to generate this value automatically if possible. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#width +- Loading: Indicates how the browser should load the image: eager or lazy. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#loading +- Optimise: Override the site parameter to optimise the image. +- CacheRemote: Override the site parameter to cache remote images. + +Thanks @HEIGE-PCloud for the original code in the DoIt theme. +https://github.com/HEIGE-PCloud/DoIt/blob/main/layouts/partials/plugin/image.html +*/ -}} + +{{- $isInline := strings.HasPrefix .Src "data:image" -}} +{{- $isRemote := urls.Parse .Src | partial "function/is-url-remote.html" -}} +{{- $resource := dict -}} + +{{- if not $isRemote | and (not $isInline) -}} + {{- $resource = (.Resources.Get .Src) | default (resources.Get .Src) -}} {{- end -}} -{{- /* handle for default size image */ -}} -{{- $src := .Src -}} -{{- $suffixValid := dict "Path" $src "Suffixes" $suffixList | partial "function/suffix-validation.html" -}} -{{- with dict "Path" $src "Resources" .Resources "CacheRemoteImages" $cacheRemoteImages.enable | partial "function/resource.html" -}} - {{- $url := urls.Parse $src -}} - {{- if not $url.Host | or $cacheRemoteImages.replace -}} - {{- $src = .RelPermalink -}} - {{- end -}} - {{- /* only available for image resources that are raster images */ -}} - {{- if (eq .ResourceType "image") | and $suffixValid | and $responsive -}} - {{- $style = printf "--width: %vpx;--aspect-ratio: %v / %v;" .Width .Width .Height | safeHTMLAttr -}} +{{- $cacheRemote := .CacheRemote | default site.Params.image.cacheRemote | default false -}} +{{- $optimise := .Optimise | default site.Params.image.optimise | default false -}} + +{{- if not $resource | and $isRemote | and $cacheRemote -}} + {{- with try (resources.GetRemote .Src) -}} + {{- with .Err -}} + {{- warnf "%s" . -}} + {{- else with .Value -}} + {{- if .ResourceType | eq "image" -}} + {{- /* placed remote image in public/images/remote/ */ -}} + {{- $resource = . | resources.Copy (add "/images/remote/" .Name) -}} + {{- end -}} + {{- else -}} + {{- warnf "Unable to get remote image %q" .Src -}} + {{- end -}} {{- end -}} {{- end -}} -{{- $srcSmall := .SrcSmall | default $src -}} -{{- $srcMedium := $src -}} -{{- $srcLarge := .SrcLarge | default $src -}} - -{{- if $responsive }} - {{- /* handle for small size image */ -}} - {{- $suffixValidSmall := dict "Path" $srcSmall "Suffixes" $suffixList | partial "function/suffix-validation.html" -}} - {{- with dict "Path" .SrcSmall "Resources" .Resources "CacheRemoteImages" $cacheRemoteImages.enable | partial "function/resource.html" -}} - {{- $url := urls.Parse $.SrcSmall -}} - {{- if not $url.Host | or $cacheRemoteImages.replace -}} - {{- $srcSmall = .RelPermalink -}} - {{- end -}} - {{- if (eq .ResourceType "image") | and $suffixValidSmall -}} - {{- $style = printf "%v--width-small: %vpx;--aspect-ratio-small: %v / %v;" $style .Width .Width .Height | safeHTMLAttr -}} - {{- end -}} - {{- end -}} - - {{- /* handle for large size image */ -}} - {{- $suffixValidLarge := dict "Path" $srcLarge "Suffixes" $suffixList | partial "function/suffix-validation.html" -}} - {{- with dict "Path" .SrcLarge "Resources" .Resources "CacheRemoteImages" $cacheRemoteImages.enable | partial "function/resource.html" -}} - {{- $url := urls.Parse $.SrcLarge -}} - {{- if not $url.Host | or $cacheRemoteImages.replace -}} - {{- $srcLarge = .RelPermalink -}} - {{- end -}} - {{- if (eq .ResourceType "image") | and $suffixValidLarge -}} - {{- $style = printf "%v--width-large: %vpx;--aspect-ratio-large: %v / %v;" $style .Width .Width .Height | safeHTMLAttr -}} - {{- end -}} - {{- end -}} - - {{- /* handle for invalid suffix */ -}} - {{- if not $suffixValid | and $src -}} - {{- $class = printf "%v suffix-invalid" $class -}} - {{- end -}} - {{- if not $suffixValidSmall | and $srcSmall -}} - {{- $class = printf "%v suffix-invalid__small" $class -}} - {{- end -}} - {{- if not $suffixValidLarge | and $srcLarge -}} - {{- $class = printf "%v suffix-invalid__large" $class -}} - {{- end -}} - - {{- /* set image srcset */ -}} - {{- if (eq $src $srcSmall) | and (eq $src $srcLarge) -}} - {{- $srcSmall = printf (cond (strings.Contains $srcSmall "?") "%v&size=small" "%v?size=small") $srcSmall -}} - {{- $srcMedium = printf (cond (strings.Contains $srcMedium "?") "%v&size=medium" "%v?size=medium") $srcMedium -}} - {{- $srcLarge = printf (cond (strings.Contains $srcLarge "?") "%v&size=large" "%v?size=large") $srcLarge -}} - {{- end -}} +{{- $isSvg := false -}} +{{- if $resource -}} + {{- $isSvg = (eq $resource.MediaType.SubType "svg") -}} {{- end -}} -{{- /* set image alt and caption */ -}} +{{- $optim := .OptimConfig -}} +{{- $srcset := "" -}} +{{- if $optim | and $resource | and $optimise | and (not $isSvg) -}} + {{ $srcsetSlice := slice -}} + {{- range $optim -}} + {{- if .Process -}} + {{- $processed := $resource.Process .Process -}} + {{- $srcsetSlice = $srcsetSlice | append (printf "%s %s" $processed.RelPermalink .descriptor) -}} + {{- end -}} + {{- end -}} + {{- $srcset = delimit $srcsetSlice ", " -}} +{{- end -}} + +{{- $src := $resource.RelPermalink | default .Src -}} {{- $alt := .Alt | default $src -}} {{- $caption := .Caption | default $alt -}} - -{{- /* set image lazy loading */ -}} -{{- /* for details, see https://lruihao.cn/posts/native-img-loading-lazy/ */ -}} -{{- if eq $loading "lazy" -}} - {{- /* TODO move to theme.js */ -}} - {{- $commonScript := "this.title=this.dataset.title;for(const i of ['style', 'data-title','onerror','onload']){this.removeAttribute(i);}" -}} - {{- $onload = printf " onload=\"%vthis.dataset.lazyloaded='';\"" $commonScript | safeHTMLAttr -}} - {{- $onerror = printf " onerror=\"%v\"" $commonScript | safeHTMLAttr -}} - {{- $style = printf " style=\"%vbackground: url(%v) no-repeat center;\"" $style (resources.Get "images/loading.svg" | minify).RelPermalink | safeHTMLAttr -}} +{{- $height := .Height -}} +{{- $width := .Width -}} +{{- if not $isSvg -}} + {{- $height = $height | default $resource.Height | default "" -}} + {{- $width = $width | default $resource.Width | default "" -}} {{- end -}} -{{- /* structure of lightgallery or img */ -}} {{- if .Linked -}} - + {{- end -}} -{{ $alt }} +{{ . }} {{- if .Linked -}} - + {{- end -}} diff --git a/layouts/partials/plugin/link.html b/layouts/partials/plugin/link.html index a9647e53..a7ccd93e 100644 --- a/layouts/partials/plugin/link.html +++ b/layouts/partials/plugin/link.html @@ -42,15 +42,6 @@ {{- end -}} {{- else -}} {{- $cardIcon := .CardIcon -}} - {{- if $url.Host | and (eq .CardIcon true) -}} - {{- $cardIcon = false -}} - {{- /* 实验性功能:中国大陆地区无法使用,如果你有更好的 API 或者方案,欢迎 PR! */ -}} - {{- $favicon := partial "function/get-remote-image.html" (dict "Path" (add "https://www.google.com/s2/favicons?sz=64&domain=" $url.Host) "Pass" true) -}} - {{- with $favicon -}} - {{- $cardIcon = .RelPermalink -}} - {{- end -}} - {{- end -}} - {{- $attrs := `class="cl-backdrop"` -}} {{- $attrs = printf ` style="--cl-bg-url: url(%v);"` (resources.Get "images/fixit.svg" | minify).RelPermalink | add $attrs -}} diff --git a/layouts/partials/single/post-author.html b/layouts/partials/single/post-author.html index e9bfaa43..87b25684 100644 --- a/layouts/partials/single/post-author.html +++ b/layouts/partials/single/post-author.html @@ -1,13 +1,18 @@ {{- $params := .Params | merge .Site.Params.page -}} {{- $author := partial "function/get-author-map.html" .Params.author -}} {{- .Store.Set "author" $author -}} +{{- $optim := slice + (dict "Process" "resize 16x16 Center webp q75" "descriptor" "16w") + (dict "Process" "resize 24x24 Center webp q75" "descriptor" "24w") + (dict "Process" "resize 32x32 Center webp q75" "descriptor" "32w") +-}} {{- $content := $author.name | default "Anonymous" -}} {{- $icon := dict "Class" "fa-solid fa-user-circle" -}} {{- /* Deprecate $params.authorAvatar in favor of $params.showAvatar and add front matter gravatar {bool} */ -}} {{- if $author.avatar | and $params.authorAvatar -}} - {{- $content = printf "%v %v" (dict "Src" $author.avatar "Class" "avatar" "Alt" $content "Width" 20 "Height" 20 | partial "plugin/image.html") $content -}} + {{- $content = printf "%v %v" (dict "Src" $author.avatar "Class" "avatar" "Alt" $content "Width" 16 "Height" 16 "OptimConfig" $optim | partial "plugin/image.html") $content -}} {{- $icon = "" -}} {{- end -}} {{- if $author.link -}} diff --git a/layouts/posts/single.html b/layouts/posts/single.html index eb4fea2b..c7bdea61 100644 --- a/layouts/posts/single.html +++ b/layouts/posts/single.html @@ -137,12 +137,20 @@ {{- /* Featured image */ -}} {{- $image := $params.featuredimage -}} + {{- with dict "Path" $image "Resources" .Resources | partial "function/resource.html" }} + {{- $image = .RelPermalink }} + {{- end }} {{- with .Resources.GetMatch "featured-image" -}} {{- $image = .RelPermalink -}} {{- end -}} {{- with $image -}} {{- end -}} diff --git a/layouts/shortcodes/image.html b/layouts/shortcodes/image.html index fa0776f5..aee6d35e 100644 --- a/layouts/shortcodes/image.html +++ b/layouts/shortcodes/image.html @@ -3,16 +3,22 @@ {{- $caption := cond .IsNamedParams (.Get "caption") (.Get 2) | .Page.RenderString -}} {{- $options = dict "Caption" $caption | merge $options -}} {{- $options = dict "Resources" .Page.Resources | merge $options -}} +{{- $optim := slice + (dict "Process" "resize 800x webp q75" "descriptor" "800w") + (dict "Process" "resize 1200x webp q75" "descriptor" "1200w") + (dict "Process" "resize 1600x webp q75" "descriptor" "1600w") +-}} +{{- $options = dict "OptimConfig" $optim | merge $options -}} {{- if .IsNamedParams -}} {{- $options = dict "Title" (.Get "title") | merge $options -}} - {{- $options = dict "SrcSmall" (.Get "src_s") | merge $options -}} - {{- $options = dict "SrcLarge" (.Get "src_l") | merge $options -}} {{- $options = dict "Height" (.Get "height") | merge $options -}} {{- $options = dict "Width" (.Get "width") | merge $options -}} {{- $options = .Get "linked" | ne false | dict "Linked" | merge $options -}} {{- $options = dict "Rel" (.Get "rel") | merge $options -}} - {{- $options = dict "Loading" (.Get "loading") | merge $options -}} + {{- $options = dict "Loading" (.Get "loading" | default "lazy") | merge $options -}} + {{- with (.Get "optimise") -}}{{- $options = dict "Optimise" . | merge $options -}}{{- end -}} + {{- with (.Get "cacheRemote") -}}{{- $options = dict "CacheRemote" . | merge $options -}}{{- end -}} {{- else -}} {{- $options = cond $caption true false | dict "Linked" | merge $options -}} {{- end -}}