Files
addlivephoto/views/templates/hook/displayProductPriceBlock.tpl
2025-11-24 17:26:43 +02:00

228 lines
8.6 KiB
Smarty

{*
* 2007-2023 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author Your Name <your@email.com>
* @copyright 2007-2023 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*}
{if isset($live_photos) && !empty($live_photos)}
<div id="addlivephoto-container" class="mt-3">
<h6 class="h6">{l s='Freshness Guaranteed: See Today\'s Stock' d='Modules.Addlivephoto.Shop'}</h6>
<div class="d-flex flex-wrap gap-2">
{foreach from=$live_photos item=photo name=livephotoloop}
<a href="{$photo.url|escape:'htmlall':'UTF-8'}" class="live-photo-thumb" data-bs-toggle="modal"
data-bs-target="#livePhotoModal" data-photo-index="{$smarty.foreach.livephotoloop.index}"
title="{$photo.title|escape:'htmlall':'UTF-8'}">
<img src="{$photo.url|escape:'htmlall':'UTF-8'}" alt="{$photo.alt|escape:'htmlall':'UTF-8'}" class="img-thumbnail"
width="80" height="80" loading="lazy">
</a>
{/foreach}
</div>
</div>
{* --- MODAL --- *}
<div class="modal fade" id="livePhotoModal" tabindex="-1" aria-labelledby="livePhotoModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="livePhotoModalLabel">{l s='Live Product Photo' d='Modules.Addlivephoto.Shop'}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"
aria-label="{l s='Close' d='Shop.Theme.Actions'}"></button>
</div>
<div class="modal-body">
<div class="position-relative">
<img id="livePhotoModalImage" src="" alt="" class="img-fluid w-100">
<button id="livePhotoPrevBtn" class="btn btn-light modal-nav-btn prev">&lt;</button>
<button id="livePhotoNextBtn" class="btn btn-light modal-nav-btn next">&gt;</button>
</div>
<div class="text-muted text-wrap small mb-0">
{l s='Please Note: This is a live photo of a randomly selected package from our current stock to show its freshness. The expiry date on the product you receive will be the same or newer, but the lot number may differ.' d='Modules.Addlivephoto.Shop'}
</div>
</div>
<div class="modal-footer justify-content-start">
{* This caption is visible to the user and good for accessibility *}
<p id="livePhotoModalCaption" class="text-muted text-wrap small mb-0"></p>
{*
This hidden block provides rich metadata for SEO and AI crawlers (e.g., Google Images).
It uses schema.org microdata to describe the image.
*}
<div class="visually-hidden" itemprop="image" itemscope itemtype="https://schema.org/ImageObject">
<meta itemprop="contentUrl" id="livePhotoMetaUrl" content="">
<meta itemprop="description" id="livePhotoMetaDesc" content="">
<span itemprop="author" itemscope itemtype="https://schema.org/Organization">
<meta itemprop="name" content="{$shop.name|escape:'htmlall':'UTF-8'}">
</span>
</div>
</div>
</div>
</div>
</div>
{* --- STYLES AND SCRIPTS --- *}
<style>
.live-photo-thumb img {
object-fit: cover;
cursor: pointer;
transition: transform 0.2s ease-in-out;
}
.live-photo-thumb:hover img {
transform: scale(1.05);
border-color: var(--bs-primary);
}
.modal-nav-btn {
position: absolute;
top: 50%;
transform: translateY(-50%);
background-color: rgba(255, 255, 255, 0.7);
border: 1px solid #ccc;
z-index: 10;
}
.modal-nav-btn.prev {
left: 10px;
}
.modal-nav-btn.next {
right: 10px;
}
</style>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', () => {
// Data passed directly from Smarty to JavaScript
const photos = {$live_photos|json_encode nofilter};
let currentIndex = 0;
const modalElement = document.getElementById('livePhotoModal');
if (!modalElement) return;
const modalImage = document.getElementById('livePhotoModalImage');
const modalCaption = document.getElementById('livePhotoModalCaption');
const prevBtn = document.getElementById('livePhotoPrevBtn');
const nextBtn = document.getElementById('livePhotoNextBtn');
// SEO meta tags
const metaUrl = document.getElementById('livePhotoMetaUrl');
const metaDesc = document.getElementById('livePhotoMetaDesc');
const thumbnailLinks = document.querySelectorAll('.live-photo-thumb');
// Function to update the modal's content based on the current index
const updateModalContent = (index) => {
if (!photos[index]) return;
const photo = photos[index];
modalImage.src = photo.url;
modalImage.alt = photo.alt;
modalCaption.textContent = photo.alt; // Use the descriptive alt text as a caption
// Update hidden SEO metadata
metaUrl.setAttribute('content', photo.url);
metaDesc.setAttribute('content', photo.alt);
// Show/hide navigation buttons
prevBtn.style.display = (index === 0) ? 'none' : 'block';
nextBtn.style.display = (index === photos.length - 1) ? 'none' : 'block';
};
// Add click listeners to each thumbnail
thumbnailLinks.forEach(link => {
link.addEventListener('click', (e) => {
e.preventDefault();
currentIndex = parseInt(e.currentTarget.dataset.photoIndex, 10);
updateModalContent(currentIndex);
});
});
// Add click listeners for modal navigation
prevBtn.addEventListener('click', () => {
if (currentIndex > 0) {
currentIndex--;
updateModalContent(currentIndex);
}
});
nextBtn.addEventListener('click', () => {
if (currentIndex < photos.length - 1) {
currentIndex++;
updateModalContent(currentIndex);
}
});
// Add keyboard navigation for accessibility
modalElement.addEventListener('keydown', (e) => {
if (e.key === 'ArrowLeft') {
prevBtn.click();
} else if (e.key === 'ArrowRight') {
nextBtn.click();
}
});
});
</script>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', () => {
// Check if the gtag function is available to avoid errors
if (typeof gtag !== 'function') {
console.log('addLivePhoto GA4: gtag function not found.');
return;
}
// --- 1. Event for viewing the thumbnails ---
// This event is sent once the thumbnails are rendered on the page.
try {
gtag('event', 'view_live_photo_thumbnail', {
'event_category': 'product_page_engagement',
'event_label': '{$product.name|escape:'javascript':'UTF-8'}',
'product_id': '{$product.id|escape:'javascript':'UTF-8'}',
'photo_count': {$live_photos|count}
});
console.log('addLivePhoto GA4: Fired event "view_live_photo_thumbnail" for product ID {$product.id}.');
} catch (e) {
console.error('addLivePhoto GA4: Error firing view event.', e);
}
// --- 2. Event for clicking a thumbnail ---
const thumbnailLinks = document.querySelectorAll('#addlivephoto-container .live-photo-thumb');
thumbnailLinks.forEach(link => {
link.addEventListener('click', () => {
try {
gtag('event', 'click_live_photo', {
'event_category': 'product_page_engagement',
'event_label': '{$product.name|escape:'javascript':'UTF-8'}',
'product_id': '{$product.id|escape:'javascript':'UTF-8'}',
'photo_count': {$live_photos|count}
});
console.log('addLivePhoto GA4: Fired event "click_live_photo" for product ID {$product.id}.');
} catch (e) {
console.error('addLivePhoto GA4: Error firing click event.', e);
}
});
});
});
</script>
{/if}