Add image gallery shortcode with lightbox support

This commit is contained in:
gribse 2025-04-17 20:28:24 +02:00
parent 42b3553ada
commit cd2a02b65e

View file

@ -0,0 +1,284 @@
<!--
trouvé ici : https://github.com/thisdev/hugo-gallery-shortcode
modifié pour accepter les images dans le répertoire de la page
ne supporte que 5 images max (pourquoi ?)
-->
<style>
/* Gallery Grid */
.image-gallery {
overflow: auto;
margin-left: -1% !important;
}
.image-gallery li {
float: left;
display: block;
margin: 0 0 1% 1%;
}
/* Dynamic widths based on image count */
.image-gallery[data-count="2"] li {
width: 49%;
}
.image-gallery[data-count="3"] li {
width: 32%;
}
.image-gallery[data-count="4"] li {
width: 24%;
}
.image-gallery[data-count="5"] li {
width: 19%;
}
/* Override PaperMod theme link styles */
.post-content .image-gallery a {
box-shadow: none;
box-decoration-break: none;
-webkit-box-decoration-break: none;
}
.image-gallery li a {
text-align: center;
text-decoration: none;
color: #777;
display: block;
}
.image-gallery li a span {
display: block;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
padding: 3px 0;
}
.image-gallery li a img {
width: 100%;
aspect-ratio: 1 / 1;
display: block;
border-radius: 8px;
object-fit: cover;
background: #f5f5f5;
transition: transform 0.3s ease;
}
.image-gallery li a:hover img {
transform: scale(1.01);
}
/* Simple Lightbox */
.simple-lightbox {
display: none;
position: fixed;
z-index: 999;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.9);
}
.simple-lightbox.active {
display: flex;
justify-content: center;
align-items: center;
}
.lightbox-content {
position: relative;
max-width: 90%;
max-height: 90vh;
}
.lightbox-content img {
max-width: 100%;
max-height: 90vh;
object-fit: contain;
}
.lightbox-caption {
position: absolute;
bottom: -60px;
left: 0;
right: 0;
color: white;
text-align: center;
padding: 10px;
}
.lightbox-close {
position: absolute;
top: 20px;
right: 20px;
color: white;
font-size: 30px;
cursor: pointer;
width: 30px;
height: 30px;
line-height: 30px;
text-align: center;
}
.lightbox-nav {
position: absolute;
top: 50%;
transform: translateY(-50%);
color: white;
font-size: 30px;
cursor: pointer;
padding: 20px;
user-select: none;
}
.lightbox-prev {
left: 20px;
}
.lightbox-next {
right: 20px;
}
</style>
{{ $dir := .Get "gallery_dir" }}
<div class="simple-lightbox">
<div class="lightbox-content">
<img src="" alt="">
<div class="lightbox-caption"></div>
</div>
<div class="lightbox-close">&times;</div>
<div class="lightbox-nav lightbox-prev">&lt;</div>
<div class="lightbox-nav lightbox-next">&gt;</div>
</div>
<ul class="image-gallery">
{{ $localPath := string (.Get "gallery_dir") }}
{{ $displayTitle := ne (.Get "disp_title") "no" }}
<!-- Get images from page resources, looking in the specified directory -->
{{ $files := .Page.Resources.Match (printf "%s/*" $localPath) }}
<!-- For debugging
{{ $count := len $files }}
<div style="color: #666; font-size: 0.8em; margin-bottom: 10px;">
Found {{ $count }} images in "{{ $localPath }}" directory
</div>
-->
{{ $imageFiles := slice }}
{{ range $files }}
{{- $ext := path.Ext .Name | lower -}}
{{- if in (slice ".jpg" ".jpeg" ".png" ".gif" ".webp") $ext -}}
{{ $imageFiles = $imageFiles | append . }}
{{ end }}
{{ end }}
{{ if and (ge (len $imageFiles) 2) (le (len $imageFiles) 5) }}
{{ range $imageFiles }}
{{- $imagetitle := index (split .Name ".") 0 -}}
<li>
<a href="{{ .RelPermalink }}" title="{{ $imagetitle }}" class="gallery-image"
data-caption="{{ $imagetitle }}">
<img src="{{ .RelPermalink }}" alt="{{ $imagetitle }}" title="{{ $imagetitle }}">
{{ if $displayTitle }}
<span>{{ $imagetitle }}</span>
{{ end }}
</a>
</li>
{{ end }}
{{ else if eq (len $imageFiles) 0 }}
<div style="background: #fff3cd; color: #856404; padding: 10px; border-radius: 5px;">
<strong>Note:</strong> No images found in "{{ $localPath }}" directory. Make sure your images are in the correct location.
</div>
{{ else if eq (len $imageFiles) 1 }}
<div style="background: #fff3cd; color: #856404; padding: 10px; border-radius: 5px;">
<strong>Note:</strong> Only one image found in "{{ $localPath }}" directory. Gallery needs at least 2 images.
</div>
{{ else }}
<div style="background: #fff3cd; color: #856404; padding: 10px; border-radius: 5px;">
<strong>Note:</strong> Too many images found ({{ len $imageFiles }}). Maximum supported is 5 images.
</div>
{{ end }}
</ul>
<script>
document.addEventListener('DOMContentLoaded', function () {
const lightbox = document.querySelector('.simple-lightbox');
const lightboxImg = lightbox.querySelector('img');
const lightboxCaption = lightbox.querySelector('.lightbox-caption');
const gallery = document.querySelector('.image-gallery');
let currentIndex = 0;
let images = [];
// Set data-count attribute for CSS styling
const imageCount = gallery.querySelectorAll('.gallery-image').length;
gallery.setAttribute('data-count', imageCount.toString());
// collect all images
gallery.querySelectorAll('.gallery-image').forEach((link, index) => {
images.push({
src: link.href,
title: link.getAttribute('data-caption')
});
// click event for each image
link.addEventListener('click', (e) => {
e.preventDefault();
currentIndex = index;
showImage(currentIndex);
});
});
// show image in lightbox
function showImage(index) {
lightboxImg.src = images[index].src;
lightboxCaption.textContent = images[index].title;
lightbox.classList.add('active');
}
// close button
lightbox.querySelector('.lightbox-close').addEventListener('click', () => {
lightbox.classList.remove('active');
});
// navigation
lightbox.querySelector('.lightbox-prev').addEventListener('click', () => {
currentIndex = (currentIndex - 1 + images.length) % images.length;
showImage(currentIndex);
});
lightbox.querySelector('.lightbox-next').addEventListener('click', () => {
currentIndex = (currentIndex + 1) % images.length;
showImage(currentIndex);
});
// keyboard navigation
document.addEventListener('keydown', (e) => {
if (!lightbox.classList.contains('active')) return;
if (e.key === 'Escape') {
lightbox.classList.remove('active');
} else if (e.key === 'ArrowLeft') {
currentIndex = (currentIndex - 1 + images.length) % images.length;
showImage(currentIndex);
} else if (e.key === 'ArrowRight') {
currentIndex = (currentIndex + 1) % images.length;
showImage(currentIndex);
}
});
// click anywhere to close lightbox
lightbox.addEventListener('click', (e) => {
if (e.target === lightbox) {
lightbox.classList.remove('active');
}
});
});
</script>