Add image gallery shortcode with lightbox support
This commit is contained in:
parent
42b3553ada
commit
cd2a02b65e
1 changed files with 284 additions and 0 deletions
284
layouts/shortcodes/image-gallery.html
Normal file
284
layouts/shortcodes/image-gallery.html
Normal 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">×</div>
|
||||
<div class="lightbox-nav lightbox-prev"><</div>
|
||||
<div class="lightbox-nav lightbox-next">></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>
|
Loading…
Add table
Add a link
Reference in a new issue