feat(gallery): tambah CPT Galeri, template page-galeri, filter interaktif, dan native lightbox zoom
This commit is contained in:
+234
@@ -0,0 +1,234 @@
|
||||
<?php
|
||||
/**
|
||||
* Template Name: Galeri & Fasilitas
|
||||
* Deskripsi: Menampilkan grid foto galeri dengan filter kategori dan efek Zoom/Lightbox interaktif.
|
||||
*/
|
||||
get_header();
|
||||
?>
|
||||
|
||||
<main id="primary" class="site-main edukarsa-gallery-page" style="padding: 60px 0 80px; background-color: var(--bg-light-blue); min-height: 75vh;">
|
||||
<div class="container">
|
||||
|
||||
<!-- Header Seksi Galeri -->
|
||||
<div class="section-header text-center" style="margin-bottom: 40px;">
|
||||
<span class="badge-title">FASILITAS & DOKUMENTASI KAMI</span>
|
||||
<h1 class="section-title">Galeri Kampus</h1>
|
||||
<hr class="title-underline">
|
||||
<p style="color: #64748b; max-width: 600px; margin: 0 auto; line-height: 1.7; font-size: 15px;">
|
||||
Jelajahi berbagai fasilitas pendukung belajar, laboratorium, sarana olahraga, dan lingkungan inspiratif di institusi kami.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Tombol Filter Kategori -->
|
||||
<div class="gallery-filters text-center" style="margin-bottom: 40px;">
|
||||
<button class="gallery-filter-btn active" data-filter="all">Semua Foto</button>
|
||||
<?php
|
||||
$terms = get_terms( array( 'taxonomy' => 'kategori_galeri', 'hide_empty' => true ) );
|
||||
foreach ( $terms as $term ) {
|
||||
echo '<button class="gallery-filter-btn" data-filter="' . esc_attr( $term->slug ) . '">' . esc_html( $term->name ) . '</button>';
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<!-- Grid Foto Galeri -->
|
||||
<div class="gallery-grid" id="edukarsa-gallery-grid">
|
||||
<?php
|
||||
$query_galeri = new WP_Query( array( 'post_type' => 'galeri', 'posts_per_page' => -1 ) );
|
||||
if ( $query_galeri->have_posts() ) :
|
||||
$idx = 0;
|
||||
while ( $query_galeri->have_posts() ) : $query_galeri->the_post();
|
||||
// Ambil kategori untuk filter class
|
||||
$terms = get_the_terms( get_the_ID(), 'kategori_galeri' );
|
||||
$term_slugs = '';
|
||||
$term_names = '';
|
||||
if ( $terms && ! is_wp_error( $terms ) ) {
|
||||
$slugs = array();
|
||||
$names = array();
|
||||
foreach ( $terms as $term ) {
|
||||
$slugs[] = $term->slug;
|
||||
$names[] = $term->name;
|
||||
}
|
||||
$term_slugs = implode( ' ', $slugs );
|
||||
$term_names = implode( ', ', $names );
|
||||
}
|
||||
|
||||
// Ambil URL gambar dan deskripsi
|
||||
$img_full = has_post_thumbnail() ? get_the_post_thumbnail_url( get_the_ID(), 'full' ) : '';
|
||||
$img_thumb = has_post_thumbnail() ? get_the_post_thumbnail_url( get_the_ID(), 'large' ) : '';
|
||||
|
||||
// Prioritaskan Excerpt, jika kosong ambil paragraf pertama dari Content
|
||||
$desc = wp_strip_all_tags( get_the_excerpt() );
|
||||
if ( empty($desc) ) {
|
||||
$desc = wp_trim_words( wp_strip_all_tags( get_the_content() ), 25, '...' );
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="gallery-item-card <?php echo esc_attr( $term_slugs ); ?>"
|
||||
data-src="<?php echo esc_url( $img_full ); ?>"
|
||||
data-title="<?php echo esc_attr( get_the_title() ); ?>"
|
||||
data-desc="<?php echo esc_attr( $desc ); ?>"
|
||||
data-cat="<?php echo esc_attr( $term_names ); ?>">
|
||||
|
||||
<div class="gallery-img-wrapper">
|
||||
<?php if ( $img_thumb ) : ?>
|
||||
<img src="<?php echo esc_url( $img_thumb ); ?>" alt="<?php the_title(); ?>" loading="lazy">
|
||||
<?php else: ?>
|
||||
<div class="img-placeholder" style="height: 100%;"><i>📸</i></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<div class="gallery-overlay">
|
||||
<span class="gallery-zoom-icon">🔍</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gallery-item-info">
|
||||
<h4><?php the_title(); ?></h4>
|
||||
<?php if($term_names): ?>
|
||||
<span class="gallery-cat-badge"><?php echo esc_html( $term_names ); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<?php
|
||||
$idx++;
|
||||
endwhile;
|
||||
wp_reset_postdata();
|
||||
else :
|
||||
echo '<div style="grid-column: 1 / -1; text-align: center; padding: 40px; background: #fff; border-radius: 12px; border: 1px dashed #cbd5e1; color: #64748b;">Belum ada foto galeri yang dipublikasikan.</div>';
|
||||
endif;
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- VANILLA JS LIGHTBOX (ZOOM EFFECT OVERLAY) -->
|
||||
<div id="ek-lightbox" class="ek-lightbox">
|
||||
<span class="ek-lb-close" id="ek-lb-close" title="Tutup">×</span>
|
||||
<div class="ek-lb-content">
|
||||
<div class="ek-lb-img-container">
|
||||
<img id="ek-lb-img" src="" alt="">
|
||||
</div>
|
||||
<div class="ek-lb-caption">
|
||||
<span id="ek-lb-cat" class="ek-lb-cat"></span>
|
||||
<h3 id="ek-lb-title"></h3>
|
||||
<p id="ek-lb-desc"></p>
|
||||
</div>
|
||||
</div>
|
||||
<button class="ek-lb-nav ek-lb-prev" id="ek-lb-prev" title="Sebelumnya">❮</button>
|
||||
<button class="ek-lb-nav ek-lb-next" id="ek-lb-next" title="Selanjutnya">❯</button>
|
||||
</div>
|
||||
|
||||
<!-- Logika Interaktif Native JS -->
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
// 1. LOGIKA FILTER KATEGORI (SMOOTH FADE)
|
||||
const filterBtns = document.querySelectorAll('.gallery-filter-btn');
|
||||
const galleryItems = document.querySelectorAll('.gallery-item-card');
|
||||
|
||||
filterBtns.forEach(btn => {
|
||||
btn.addEventListener('click', () => {
|
||||
// Hapus status aktif dari semua tombol
|
||||
filterBtns.forEach(b => b.classList.remove('active'));
|
||||
btn.classList.add('active');
|
||||
|
||||
const filterValue = btn.getAttribute('data-filter');
|
||||
|
||||
galleryItems.forEach(item => {
|
||||
// Sembunyikan dengan fade out
|
||||
item.style.opacity = '0';
|
||||
item.style.transform = 'scale(0.95)';
|
||||
|
||||
setTimeout(() => {
|
||||
if (filterValue === 'all' || item.classList.contains(filterValue)) {
|
||||
item.style.display = 'block';
|
||||
// Beri jeda sedikit agar display block dirender sebelum mengubah opacity
|
||||
setTimeout(() => {
|
||||
item.style.opacity = '1';
|
||||
item.style.transform = 'scale(1)';
|
||||
}, 50);
|
||||
} else {
|
||||
item.style.display = 'none';
|
||||
}
|
||||
}, 300); // 300ms sesuaikan dengan durasi CSS transition
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// 2. LOGIKA LIGHTBOX / ZOOM SLIDER
|
||||
const lightbox = document.getElementById('ek-lightbox');
|
||||
const lbImg = document.getElementById('ek-lb-img');
|
||||
const lbTitle = document.getElementById('ek-lb-title');
|
||||
const lbDesc = document.getElementById('ek-lb-desc');
|
||||
const lbCat = document.getElementById('ek-lb-cat');
|
||||
const closeBtn = document.getElementById('ek-lb-close');
|
||||
const prevBtn = document.getElementById('ek-lb-prev');
|
||||
const nextBtn = document.getElementById('ek-lb-next');
|
||||
|
||||
let currentIndex = 0;
|
||||
let visibleItems = [];
|
||||
|
||||
// Fungsi untuk memperbarui daftar item yang sedang tidak disembunyikan oleh filter
|
||||
function updateVisibleItems() {
|
||||
visibleItems = Array.from(galleryItems).filter(item => item.style.display !== 'none');
|
||||
}
|
||||
|
||||
function openLightbox(index) {
|
||||
if(visibleItems.length === 0) return;
|
||||
currentIndex = index;
|
||||
const item = visibleItems[currentIndex];
|
||||
|
||||
lbImg.src = item.getAttribute('data-src');
|
||||
lbTitle.textContent = item.getAttribute('data-title');
|
||||
lbDesc.textContent = item.getAttribute('data-desc');
|
||||
lbCat.textContent = item.getAttribute('data-cat');
|
||||
|
||||
lightbox.classList.add('show');
|
||||
document.body.style.overflow = 'hidden'; // Kunci scroll halaman belakang
|
||||
}
|
||||
|
||||
function closeLightbox() {
|
||||
lightbox.classList.remove('show');
|
||||
document.body.style.overflow = ''; // Kembalikan scroll
|
||||
setTimeout(() => lbImg.src = '', 300); // Bersihkan gambar setelah animasi tutup
|
||||
}
|
||||
|
||||
function showNext() {
|
||||
currentIndex = (currentIndex + 1) % visibleItems.length;
|
||||
openLightbox(currentIndex);
|
||||
}
|
||||
|
||||
function showPrev() {
|
||||
currentIndex = (currentIndex - 1 + visibleItems.length) % visibleItems.length;
|
||||
openLightbox(currentIndex);
|
||||
}
|
||||
|
||||
// Pasang Event Klik pada setiap foto di Grid
|
||||
galleryItems.forEach(item => {
|
||||
item.addEventListener('click', function() {
|
||||
updateVisibleItems();
|
||||
const idx = visibleItems.indexOf(this);
|
||||
if(idx !== -1) openLightbox(idx);
|
||||
});
|
||||
});
|
||||
|
||||
// Event Navigasi Lightbox
|
||||
closeBtn.addEventListener('click', closeLightbox);
|
||||
nextBtn.addEventListener('click', showNext);
|
||||
prevBtn.addEventListener('click', showPrev);
|
||||
|
||||
// Tutup jika mengklik area kosong di luar konten
|
||||
lightbox.addEventListener('click', function(e) {
|
||||
if (e.target === lightbox) closeLightbox();
|
||||
});
|
||||
|
||||
// Dukungan Navigasi Keyboard
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (!lightbox.classList.contains('show')) return;
|
||||
if (e.key === 'Escape') closeLightbox();
|
||||
if (e.key === 'ArrowRight') showNext();
|
||||
if (e.key === 'ArrowLeft') showPrev();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<?php get_footer(); ?>
|
||||
Reference in New Issue
Block a user