From e81447e7aeba789a385349aeeeac9df3ca141cf0 Mon Sep 17 00:00:00 2001
From: Xin <5097752+imfing@users.noreply.github.com>
Date: Tue, 20 Jan 2026 22:55:41 +0000
Subject: [PATCH] feat(image-zoom): add image zoom functionality and
documentation (#907)
* feat(image-zoom): add image zoom functionality and documentation
- Introduced a new `imageZoom` parameter in the configuration to enable click-to-zoom for Markdown images.
- Updated the `render-image.html` layout to support zoom functionality by adding a `data-zoomable` attribute to images.
- Created a new `medium-zoom.html` script to handle the zoom effect, with options for CDN or local asset loading.
- Enhanced documentation in `configuration.md` and `markdown.md` to guide users on enabling and configuring image zoom.
* docs(image-zoom): add image zoom documentation in multiple languages
- Added sections for image zoom functionality in Persian, Japanese, and Simplified Chinese documentation.
- Included configuration examples for enabling and disabling image zoom in specific pages.
- Updated related documentation to ensure consistency across languages.
---
docs/content/docs/guide/configuration.fa.md | 28 ++++++
docs/content/docs/guide/configuration.ja.md | 28 ++++++
docs/content/docs/guide/configuration.md | 28 ++++++
.../content/docs/guide/configuration.zh-cn.md | 28 ++++++
docs/hugo.yaml | 3 +
layouts/_markup/render-image.html | 12 ++-
layouts/_partials/scripts.html | 5 ++
layouts/_partials/scripts/medium-zoom.html | 85 +++++++++++++++++++
8 files changed, 215 insertions(+), 2 deletions(-)
create mode 100644 layouts/_partials/scripts/medium-zoom.html
diff --git a/docs/content/docs/guide/configuration.fa.md b/docs/content/docs/guide/configuration.fa.md
index ded4d17..9813dce 100644
--- a/docs/content/docs/guide/configuration.fa.md
+++ b/docs/content/docs/guide/configuration.fa.md
@@ -295,6 +295,34 @@ params:
displayTags: true
```
+### بزرگنمایی تصویر
+
+بزرگنمایی تصویر به طور پیشفرض غیرفعال است. وقتی فعال شود، کلیک روی تصویر Markdown یک نمای بزرگنمایی شده باز میکند.
+
+```yaml {filename="hugo.yaml"}
+params:
+ imageZoom:
+ enable: true
+```
+
+برای غیرفعال کردن بزرگنمایی در یک صفحه خاص، این را به front matter صفحه اضافه کنید:
+
+```yaml {filename="content/docs/guide/configuration.md"}
+---
+imageZoom: false
+---
+```
+
+اگر میخواهید asset Medium Zoom را پین کنید یا از assetهای محلی بارگذاری کنید:
+
+```yaml {filename="hugo.yaml"}
+params:
+ imageZoom:
+ enable: true
+ base: "https://cdn.jsdelivr.net/npm/medium-zoom@1.1.0/dist"
+ # js: "js/medium-zoom.min.js" # اختیاری، نسبت به base یا assetهای محلی
+```
+
### عرض صفحه
عرض صفحه را میتوان با پارامتر `params.page.width` در فایل پیکربندی سفارشی کرد:
diff --git a/docs/content/docs/guide/configuration.ja.md b/docs/content/docs/guide/configuration.ja.md
index 6a067ed..7400213 100644
--- a/docs/content/docs/guide/configuration.ja.md
+++ b/docs/content/docs/guide/configuration.ja.md
@@ -295,6 +295,34 @@ params:
displayTags: true
```
+### 画像ズーム
+
+画像ズームはデフォルトで無効です。有効にすると、Markdown 画像をクリックするとズームビューが開きます。
+
+```yaml {filename="hugo.yaml"}
+params:
+ imageZoom:
+ enable: true
+```
+
+特定のページでズームを無効にするには、ページのフロントマターに以下を追加します:
+
+```yaml {filename="content/docs/guide/configuration.md"}
+---
+imageZoom: false
+---
+```
+
+Medium Zoom アセットを固定するか、ローカルアセットから読み込む場合:
+
+```yaml {filename="hugo.yaml"}
+params:
+ imageZoom:
+ enable: true
+ base: "https://cdn.jsdelivr.net/npm/medium-zoom@1.1.0/dist"
+ # js: "js/medium-zoom.min.js" # オプション、base またはローカルアセットからの相対パス
+```
+
### ページ幅
ページの幅は設定ファイルの `params.page.width` パラメータでカスタマイズできます:
diff --git a/docs/content/docs/guide/configuration.md b/docs/content/docs/guide/configuration.md
index c096a64..c48622f 100644
--- a/docs/content/docs/guide/configuration.md
+++ b/docs/content/docs/guide/configuration.md
@@ -317,6 +317,34 @@ params:
displayTags: true
```
+### Image Zoom
+
+Image zoom is disabled by default. When enabled, clicking a Markdown image opens a zoomed view.
+
+```yaml {filename="hugo.yaml"}
+params:
+ imageZoom:
+ enable: true
+```
+
+To disable zoom on a specific page, add this to the page front matter:
+
+```yaml {filename="content/docs/guide/configuration.md"}
+---
+imageZoom: false
+---
+```
+
+If you want to pin the Medium Zoom asset or load it from local assets:
+
+```yaml {filename="hugo.yaml"}
+params:
+ imageZoom:
+ enable: true
+ base: "https://cdn.jsdelivr.net/npm/medium-zoom@1.1.0/dist"
+ # js: "js/medium-zoom.min.js" # optional, relative to the base or local assets
+```
+
### Page Width
The width of the page can be customized by the `params.page.width` parameter in the config file:
diff --git a/docs/content/docs/guide/configuration.zh-cn.md b/docs/content/docs/guide/configuration.zh-cn.md
index d901f04..c4db6b6 100644
--- a/docs/content/docs/guide/configuration.zh-cn.md
+++ b/docs/content/docs/guide/configuration.zh-cn.md
@@ -295,6 +295,34 @@ params:
displayTags: true
```
+### 图片缩放
+
+图片缩放默认禁用。启用后,点击 Markdown 图片会打开放大视图。
+
+```yaml {filename="hugo.yaml"}
+params:
+ imageZoom:
+ enable: true
+```
+
+要在特定页面禁用缩放,在页面的 front matter 中添加:
+
+```yaml {filename="content/docs/guide/configuration.md"}
+---
+imageZoom: false
+---
+```
+
+如果想固定 Medium Zoom 资源或从本地资源加载:
+
+```yaml {filename="hugo.yaml"}
+params:
+ imageZoom:
+ enable: true
+ base: "https://cdn.jsdelivr.net/npm/medium-zoom@1.1.0/dist"
+ # js: "js/medium-zoom.min.js" # 可选,相对于 base 或本地资源
+```
+
### 页面宽度
页面宽度可以通过配置文件中的 `params.page.width` 参数自定义:
diff --git a/docs/hugo.yaml b/docs/hugo.yaml
index 3989d3a..0e34cac 100644
--- a/docs/hugo.yaml
+++ b/docs/hugo.yaml
@@ -220,6 +220,9 @@ params:
# tabs:
# sync: true
+ imageZoom:
+ enable: true
+
comments:
enable: false
type: giscus
diff --git a/layouts/_markup/render-image.html b/layouts/_markup/render-image.html
index 6c571f2..bbc46ae 100644
--- a/layouts/_markup/render-image.html
+++ b/layouts/_markup/render-image.html
@@ -1,5 +1,9 @@
{{- $alt := .PlainText | safeHTML -}}
{{- $lazyLoading := .Page.Site.Params.enableImageLazyLoading | default true -}}
+{{- $enableImageZoom := .Page.Site.Params.imageZoom.enable | default false -}}
+{{- if not (eq .Page.Params.imageZoom nil) -}}
+ {{- $enableImageZoom = .Page.Params.imageZoom -}}
+{{- end -}}
{{- $dest := .Destination -}}
{{- $url := urls.Parse $dest -}}
@@ -33,11 +37,15 @@
{{- end -}}
{{- end -}}
+{{- if $enableImageZoom -}}
+ {{- .Page.Store.Set "hasImageZoom" true -}}
+{{- end -}}
+
{{- with .Title -}}
-
+
{{ . }}
{{- else -}}
-
+
{{- end -}}
diff --git a/layouts/_partials/scripts.html b/layouts/_partials/scripts.html
index bf49fc9..abf6cd4 100644
--- a/layouts/_partials/scripts.html
+++ b/layouts/_partials/scripts.html
@@ -13,3 +13,8 @@
{{- if (.Store.Get "hasAsciinema") -}}
{{- partial "scripts/asciinema.html" . -}}
{{- end -}}
+
+{{/* Medium Zoom */}}
+{{- if (.Store.Get "hasImageZoom") -}}
+ {{- partial "scripts/medium-zoom.html" . -}}
+{{- end -}}
diff --git a/layouts/_partials/scripts/medium-zoom.html b/layouts/_partials/scripts/medium-zoom.html
new file mode 100644
index 0000000..6203442
--- /dev/null
+++ b/layouts/_partials/scripts/medium-zoom.html
@@ -0,0 +1,85 @@
+{{- /* Medium Zoom */ -}}
+
+{{- $zoomBase := "" -}}
+{{- $useDefaultCdn := true -}}
+{{- with site.Params.imageZoom.base -}}
+ {{- $zoomBase = . -}}
+ {{- $useDefaultCdn = false -}}
+{{- end -}}
+
+{{- $zoomJsAsset := "" -}}
+{{- with site.Params.imageZoom.js -}}
+ {{- $zoomJsAsset = . -}}
+{{- end -}}
+
+{{- /* If only js is set without base, use local asset loading */ -}}
+{{- if and $useDefaultCdn (ne $zoomJsAsset "") -}}
+ {{- $useDefaultCdn = false -}}
+{{- end -}}
+
+{{- /* Set default CDN base if needed */ -}}
+{{- if $useDefaultCdn -}}
+ {{- $zoomBase = "https://cdn.jsdelivr.net/npm/medium-zoom@latest/dist" -}}
+{{- end -}}
+
+{{- $isRemoteBase := or (strings.HasPrefix $zoomBase "http://") (strings.HasPrefix $zoomBase "https://") -}}
+{{- $minSuffix := cond hugo.IsProduction ".min" "" -}}
+
+{{- /* JS retrieval: get raw JS from either local asset or remote, then process */ -}}
+{{- if $isRemoteBase -}}
+ {{- $jsPath := cond (ne $zoomJsAsset "") $zoomJsAsset (printf "medium-zoom%s.js" $minSuffix) -}}
+ {{- $zoomJsUrl := printf "%s/%s" $zoomBase $jsPath -}}
+ {{- with try (resources.GetRemote $zoomJsUrl) -}}
+ {{- with .Err -}}
+ {{- errorf "Could not retrieve Medium Zoom js file from %s. Reason: %s." $zoomJsUrl . -}}
+ {{- else with .Value -}}
+ {{- with resources.Copy (printf "js/medium-zoom%s.js" $minSuffix) . -}}
+ {{- $zoomJs := . | fingerprint -}}
+
+ {{- end -}}
+ {{- end -}}
+ {{- end -}}
+{{- else if $zoomJsAsset -}}
+ {{- with resources.Get $zoomJsAsset -}}
+ {{- $zoomJs := . | fingerprint -}}
+
+ {{- else -}}
+ {{- errorf "Medium Zoom js asset not found at %q" $zoomJsAsset -}}
+ {{- end -}}
+{{- end -}}
+
+