Complete rewrite (#1)

A complete rewrite of the gallery plugin:

* Using flexbox
* Using lightweight JS for lightbox to avoid anchor links, and allow full rotation
* Add slideshow as an additional field
* Make many more things configurable
* Better support for dirs, allow mixed paths
* Translatable captions for many files using metadata files
* SCSS instead of CSS

Reviewed-on: #1
Co-authored-by: Max Mehl <mail@mehl.mx>
Co-committed-by: Max Mehl <mail@mehl.mx>
This commit was merged in pull request #1.
This commit is contained in:
2024-02-07 22:17:49 +01:00
committed by mxmehl
parent 0e16b03230
commit 437b0202ba
11 changed files with 588 additions and 211 deletions

View File

@@ -0,0 +1,14 @@
{{- $imgs := .imgs -}}
{{- $galno := .galno -}}
<div class="snap-gallery" style="--columns:{{ default 4 .columns }};--min-width:{{ default "200px" .minwidth }};--gap:10px;--cursor:{{ .cursor }};--aspectratio:{{ safeCSS (default "16/10" .aspectratio) }};">
{{- range $i, $img := $imgs }}
<div class="snap-image">
<img
src="{{ relURL $img.src }}"
{{ range $attr, $value := $img.html -}}
{{ safeHTMLAttr $attr }}={{ $value }}
{{ end -}}
onclick="openLightbox({{ $galno }});openLightboxItem({{ $galno }}, {{ add $i 1 }});" />
</div>
{{- end }}
</div>

View File

@@ -0,0 +1,24 @@
{{- $imgs := .imgs -}}
{{- $galno := .galno -}}
<div class="snap-lightbox" id="snap-lightbox-{{ $galno }}">
{{- range $i, $img := $imgs }}
<div class="snap-lightbox-inner">
<div class="snap-numbertext">{{ add $i 1 }} / {{ len $imgs }}</div>
<img
src="{{ relURL $img.src }}"
{{ range $attr, $value := $img.html -}}
{{ safeHTMLAttr $attr }}={{ $value }}
{{ end -}}
/>
{{- with $img.html.title }}
<div class="snap-caption">{{ . }}</div>
{{- end }}
</div>
{{- end -}}
<!-- Close and Next/previous controls -->
<span class="snap-close" onclick="closeLightbox({{ $galno }})">&times;</span>
<a class="snap-prev" onclick="moveLightboxItem({{ $galno }}, -1)"><span>&#10094;</span></a>
<a class="snap-next" onclick="moveLightboxItem({{ $galno }}, 1)"><span>&#10095;</span></a>
</div>

View File

@@ -0,0 +1,21 @@
{{- $imgs := .imgs -}}
{{- $galno := .galno -}}
<div class="snap-slideshow" id="snap-slideshow-{{ $galno }}" style="--columns:1;--min-width:0px;--gap:0px;--slideshow-width:{{ default "100%" .width }};--cursor:{{ .cursor }};--aspectratio:{{ safeCSS (default "16/10" .aspectratio) }};">
{{- range $i, $img := $imgs }}
<div class="snap-image">
<div class="snap-numbertext">{{ add $i 1 }} / {{ len $imgs }}</div>
{{- with $img.html.title }}
<div class="snap-caption">{{ . }}</div>
{{- end }}
<img
src="{{ relURL $img.src }}"
{{ range $attr, $value := $img.html -}}
{{ safeHTMLAttr $attr }}={{ $value }}
{{ end -}}
onclick="openLightbox({{ $galno }});openLightboxItem({{ $galno }}, {{ add $i 1 }});" />
</div>
{{- end }}
<a class="snap-prev" onclick="moveSlideshowItem({{ $galno }}, -1)"><span>&#10094;</span></a>
<a class="snap-next" onclick="moveSlideshowItem({{ $galno }}, 1)"><span>&#10095;</span></a>
</div>

View File

@@ -1,87 +1,68 @@
<!--
SPDX-FileCopyrightText: 2020 Max Mehl <mail@mehl.mx>
SPDX-License-Identifier: MIT
-->
<!-- count how many times we've called this shortcode; load the css if it's the first time -->
{{- if not ($.Page.Scratch.Get "figurecount") }}<link rel="stylesheet" href="/css/snap-gallery.css" />{{ end }}
{{- $.Page.Scratch.Add "figurecount" 1 -}}
<!-- use src image -->
{{- $thumb := .Get "src" -}}
<!-- set unique ID depending on whether part of gallery or alone -->
{{- $figid := "" -}}
{{- $galid := "" -}}
{{- $id := "" -}}
{{- $previd := "" -}}
{{- $nextid := "" -}}
{{- if .Parent -}} <!-- gallery -->
{{- $galid = .Page.Scratch.Get "gallery" -}}
{{- if not $galid }}{{ $galid = 0 }}{{ end -}}
{{- $galid = add $galid 1 -}}
{{- $.Page.Scratch.Add "thisgalfig" 1 -}}
{{- $figid = .Page.Scratch.Get "thisgalfig" -}}
{{- else -}} <!-- standalone figure -->
{{- $.Page.Scratch.Add "nogalfig" 1 -}}
{{- $figid = .Page.Scratch.Get "nogalfig" -}}
{{- end -}}
{{- if $galid -}} <!-- gallery -->
{{- $id = print "gal" $galid "-" "fig" $figid -}}
{{- $previd = print "gal" $galid "-" "fig" (sub $figid 1) -}}
{{- $nextid = print "gal" $galid "-" "fig" (add $figid 1) -}}
{{- else -}} <!-- standalone figure -->
{{- $id = print "fig" $figid -}}
{{- end -}}
<figure {{ with .Get "class" }}class="{{.}}"{{ end }}>
<div class="snap-wrapper">
{{ if (.Get "link") -}}
<a href="{{ .Get "link" }}"
{{- with .Get "target" }} target="{{ . }}"{{ end -}}
{{- with .Get "rel" }} rel="{{ . }}"{{ end -}}
>
{{ else -}}
{{ if not (eq (.Get "lightbox") "none") }}<a href="#{{ $id }}">{{ end }}
{{- end -}}
<!-- THUMBNAIL -->
<img src="{{ $thumb | relURL }}" class="snap-thumb"
{{- with .Get "alt" }} alt="{{ . }}"{{ end -}}
{{- with .Get "title" }} title="{{ . }}"{{ end -}}
{{- with .Get "height" }} height="{{ . }}"{{ end -}}
{{- with .Get "width" }} width="{{ . }}"{{ end -}}
/>
{{- if or (.Get "caption") (.Get "attr")}}
<figcaption>
{{- .Get "caption" | markdownify -}}
{{- with .Get "attr" }} {{ . | markdownify}}{{ end -}}
</figcaption>
{{- end }}
</a>
<!-- FULL IMAGE; HIDDEN -->
{{- if not (eq (.Get "lightbox") "none") -}}
<div class="snap-lightbox" id="{{ $id }}">
<a href="#_" class="snap-lightbox-close"></a>
<div class="snap-lightbox-inner">
<img src="{{ .Get "src" }}" {{ with .Get "alt" }}alt="{{ . }}"{{ end }} />
<p>
{{- if or (.Get "caption") (.Get "attr") -}}
{{- .Get "caption" | markdownify -}}
{{- with .Get "attrlink" }} <a href="{{ . }}">{{- end -}}
{{- with .Get "attr" }} {{ . | markdownify}}{{ end -}}
{{- with .Get "attrlink" }}</a>{{- end -}}
{{- end }}
</p>
</div>
<a href="#_" class="snap-lightbox-close-button"><i class="snap-lightbox-x"></i></a>
{{- if .Parent -}}
{{- if not (eq $figid 1) -}}
<a href="#{{ $previd }}" class="snap-lightbox-prev"><i class="snap-lightbox-arrow"></i></a>
{{- else -}}
<span class="snap-lightbox-prev"><i class="snap-lightbox-arrow"></i></span>
{{- end -}}
<!-- TODO: Somehow try to identify whether this is the last element in the gallery -->
<a href="#{{ $nextid }}" class="snap-lightbox-next"><i class="snap-lightbox-arrow"></i></a>
{{- end }}
</div>
{{- end -}}
<!-- Images used to open the lightbox -->
<div class="row">
<div class="column">
<img src="img1.jpg" onclick="openModal();currentSlide(1)" class="hover-shadow">
</div>
</figure>
<div class="column">
<img src="img2.jpg" onclick="openModal();currentSlide(2)" class="hover-shadow">
</div>
<div class="column">
<img src="img3.jpg" onclick="openModal();currentSlide(3)" class="hover-shadow">
</div>
<div class="column">
<img src="img4.jpg" onclick="openModal();currentSlide(4)" class="hover-shadow">
</div>
</div>
<!-- The Modal/Lightbox -->
<div id="myModal" class="modal">
<span class="close cursor" onclick="closeModal()">&times;</span>
<div class="modal-content">
<div class="mySlides">
<div class="numbertext">1 / 4</div>
<img src="img1.jpg" style="width:100%">
</div>
<div class="mySlides">
<div class="numbertext">2 / 4</div>
<img src="img2.jpg" style="width:100%">
</div>
<div class="mySlides">
<div class="numbertext">3 / 4</div>
<img src="img3.jpg" style="width:100%">
</div>
<div class="mySlides">
<div class="numbertext">4 / 4</div>
<img src="img4.jpg" style="width:100%">
</div>
<!-- Next/previous controls -->
<a class="prev" onclick="plusSlides(-1)">&#10094;</a>
<a class="next" onclick="plusSlides(1)">&#10095;</a>
<!-- Caption text -->
<div class="caption-container">
<p id="caption"></p>
</div>
<!-- Thumbnail image controls -->
<div class="column">
<img class="demo" src="img1.jpg" onclick="currentSlide(1)" alt="Nature">
</div>
<div class="column">
<img class="demo" src="img2.jpg" onclick="currentSlide(2)" alt="Snow">
</div>
<div class="column">
<img class="demo" src="img3.jpg" onclick="currentSlide(3)" alt="Mountains">
</div>
<div class="column">
<img class="demo" src="img4.jpg" onclick="currentSlide(4)" alt="Lights">
</div>
</div>
</div>

View File

@@ -1,11 +0,0 @@
<!--
SPDX-FileCopyrightText: 2020 Max Mehl <mail@mehl.mx>
SPDX-License-Identifier: MIT
-->
<!-- count how many times we've called this shortcode; load the css if it's the first time -->
{{- .Page.Scratch.Add "gallery" 1 -}}
<div class="snap-gallery">
{{ .Inner }}
</div>
<!-- delete count of gallery figures (but not those of standalone figures -->
{{- .Page.Scratch.Delete "thisgalfig" -}}

View File

@@ -1,59 +0,0 @@
<!--
SPDX-FileCopyrightText: 2020 Max Mehl <mail@mehl.mx>
SPDX-License-Identifier: MIT
-->
<!-- This file is a variation of figure.html specifically to load all
files from a directory. Assumes that is has the gallery shortcode
as parent
-->
<!-- count how many times we've called this shortcode; load the css if it's the first time -->
{{- if not ($.Page.Scratch.Get "figurecount") }}<link rel="stylesheet" href="/css/snap-gallery.css" />{{ end }}
{{- $.Page.Scratch.Add "figurecount" 1 -}}
{{- $files := readDir (print "/static" (.Get "srcdir")) -}}
{{- $maxid := len $files -}}
{{- range $files -}}
{{ $src := (print ($.Get "srcdir") "/" .Name) }}
{{- $thumb := $src -}}
<!-- set unique ID for gallery and figure -->
{{- $figid := "" -}}
{{- $galid := "" -}}
{{- $id := "" -}}
{{- $previd := "" -}}
{{- $nextid := "" -}}
{{- $galid = $.Page.Scratch.Get "gallery" -}}
{{- if not $galid }}{{ $galid = 0 }}{{ end -}}
{{- $galid = add $galid 1 -}}
{{- $.Page.Scratch.Add "thisgalfig" 1 -}}
{{- $figid = $.Page.Scratch.Get "thisgalfig" -}}
{{- $id = print "gal" $galid "-" "fig" $figid -}}
{{- $previd = print "gal" $galid "-" "fig" (sub $figid 1) -}}
{{- $nextid = print "gal" $galid "-" "fig" (add $figid 1) -}}
<figure>
<!-- THUMBNAIL -->
<a href="#{{ $id }}">
<img src="{{ $thumb | relURL }}" class="snap-thumb" />
</a>
<!-- FULL IMAGE; HIDDEN -->
<div class="snap-lightbox" id="{{ $id }}">
<a href="#_" class="snap-lightbox-close"></a>
<div class="snap-lightbox-inner">
<img src='{{ $src }}' />
</div>
<a href="#_" class="snap-lightbox-close-button"><i class="snap-lightbox-x"></i></a>
{{- if not (eq $figid 1) -}}
<a href="#{{ $previd }}" class="snap-lightbox-prev"><i class="snap-lightbox-arrow"></i></a>
{{- else -}}
<span class="snap-lightbox-prev"><i class="snap-lightbox-arrow"></i></span>
{{- end -}}
{{- if not (eq $figid $maxid) -}}
<a href="#{{ $nextid }}" class="snap-lightbox-next"><i class="snap-lightbox-arrow"></i></a>
{{- else -}}
<span class="snap-lightbox-next"><i class="snap-lightbox-arrow"></i></span>
{{- end }}
</div>
</figure>
{{ end }}

View File

@@ -0,0 +1,83 @@
{{/* Count number of gallery on page */}}
{{- $.Page.Scratch.Add "gallerycount" 1 -}}
{{- $galno := $.Page.Scratch.Get "gallerycount" -}}
{{/* Load CSS/JS and make sure it is only loaded once */}}
{{- if eq ($.Page.Scratch.Get "gallerycount") 1 -}}
{{- with resources.Get "scss/snap-gallery.scss" | toCSS -}}
<link rel="stylesheet" href="{{ .RelPermalink }}" crossorigin="anonymous">
{{- end -}}
<script src="/js/snap-gallery.js"></script>
{{- end -}}
{{/* Initialise index of this gallery */}}
<script>imageIndex[{{ $galno }}] = 1;</script>
{{/* Initialise variables holding image paths and extension */}}
{{- $imgs_collect := slice -}}
{{- $imgs := slice -}}
{{- $img_exts := slice ".jpg" ".jpeg" ".png" ".gif" ".webp" ".tiff" -}}
{{/* Get information from optional metadata file */}}
{{- $metadata := dict -}}
{{- with .Params.metadata -}}
{{- $metadata = index $.Site.Data . -}}
{{- end -}}
{{/* Get images from src Param, separated by comma */}}
{{- range (split .Params.src ",") -}}
{{- $img := (trim . " ") -}}
{{- $img_static := print "/static/" $img -}}
{{/* Only proceed when path exists */}}
{{- if os.FileExists $img_static -}}
{{/* If current item is a directory, range each of them, and add with full path to the slice */}}
{{- if (os.Stat $img_static).IsDir -}}
{{- range readDir $img_static -}}
{{- $imgs_collect = $imgs_collect | append (path.Join $img .Name ) -}}
{{- end -}}
{{/* If a single file, just add it to the slice */}}
{{- else -}}
{{- $imgs_collect = $imgs_collect | append $img -}}
{{- end -}}
{{- end -}}
{{- end -}}
{{/* Filter collected files, store them as slice of dicts/maps */}}
{{- range $imgs_collect -}}
{{/* Only process files if they are recognised as an image */}}
{{- if in $img_exts (lower (path.Ext .)) -}}
{{/* Create a dict holding path and optional metadata */}}
{{- $imgdict := dict "src" . -}}
{{/* If metadata for this image path found, add all of it to dict */}}
{{- $img_metadata := where $metadata "src" . -}}
{{- with $img_metadata -}}
{{- $imgdict = merge $imgdict (index . 0) -}}
{{- end -}}
{{/* Add final dict to slice */}}
{{- $imgs = $imgs | append $imgdict -}}
{{- end -}}
{{- end -}}
{{/* Define cursor when hovering over images, depending on lightbox status */}}
{{- $lightbox := (default true .Params.lightbox) -}}
{{- $cursor := "auto" -}}
{{- if $lightbox }}{{ $cursor = "zoom-in" }}{{ end -}}
{{/* Visible images in separate modes */}}
{{- $mode := default "gallery" .Params.mode -}}
{{/* Gallery mode */}}
{{- if eq $mode "gallery" -}}
{{- partial "gallery" (dict "columns" .Params.columns "minwidth" .Params.minwidth "imgs" $imgs "galno" $galno "cursor" $cursor "aspectratio" .Params.aspectratio) -}}
{{/* Slideshow mode */}}
{{- else if eq $mode "slideshow" -}}
{{- partial "slideshow" (dict "imgs" $imgs "galno" $galno "width" .Params.slideshowwidth "cursor" $cursor "aspectratio" .Params.aspectratio) -}}
{{/* Set autorotate timer for slideshow, if configured (default: yes) */}}
{{- if (default true .Params.slideshowrotate) -}}
<script>const autoSlideshow = setInterval(moveSlideshowItem, {{ default 5000 .Params.slideshowrotate_timer }}, {{ $galno }}, 1, "auto");</script>
{{- end -}}
{{- end -}}
{{/* The Modal/Lightbox */}}
{{ if $lightbox -}}
{{- partial "lightbox" (dict "galno" $galno "imgs" $imgs) -}}
{{- end -}}