first commit
This commit is contained in:
228
views/templates/hook/displayProductPriceBlock.tpl
Normal file
228
views/templates/hook/displayProductPriceBlock.tpl
Normal file
@@ -0,0 +1,228 @@
|
||||
{*
|
||||
* 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"><</button>
|
||||
<button id="livePhotoNextBtn" class="btn btn-light modal-nav-btn next">></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}
|
||||
Reference in New Issue
Block a user