Dodaj dynamiczny opis kategorii na podstawie URL w szablonie listy produktów

This commit is contained in:
2025-10-03 00:19:00 +02:00
parent 48732777ad
commit ca5f85fa95
3 changed files with 352 additions and 21 deletions

View File

@@ -74,12 +74,6 @@
<div id="category-description" class="text-muted">{$category.description nofilter}</div>
{/if}
{/if}
{if $smarty.server.REQUEST_URI == '/60-koldry/s-1/rozmiar-160x200_cm/rodzaj-koldry'}
<div id="category-description" class="text-muted">Opis kategorii</div>
{/if}
{if $smarty.server.REQUEST_URI == '/60-koldry/s-1/rozmiar-220x200_cm/rodzaj-koldry'}
<div id="category-description" class="text-muted">Opis kategorii zmieniony</div>
{/if}
{else}
{include file='errors/not-found.tpl'}
@@ -88,6 +82,143 @@
</section>
</section>
{literal}
<script>
(function () {
// ============ KONFIG ============
var ENDPOINT = '/category-description.php'; // PHP, który zwróci HTML opisu
var SHOW_ONLY_FIRST_PAGE = false; // jeśli opis tylko na 1. stronie -> true
var DEBOUNCE_MS = 200;
// ============ NARZĘDZIA ============
var lastUrl = null;
var debounceTimer = null;
var inflightController = null;
function onReady(fn) {
if (document.readyState === 'complete' || document.readyState === 'interactive') {
setTimeout(fn, 0);
} else {
document.addEventListener('DOMContentLoaded', fn);
}
}
// Wywołuj "locationchange" przy każdej zmianie historii
function hookHistoryEvents() {
var wrap = function (type) {
var orig = history[type];
return function () {
var ret = orig.apply(this, arguments);
window.dispatchEvent(new Event('locationchange'));
window.dispatchEvent(new Event(type));
return ret;
};
};
history.pushState = wrap('pushState');
history.replaceState = wrap('replaceState');
window.addEventListener('popstate', function () {
window.dispatchEvent(new Event('locationchange'));
});
}
function isFirstPage(urlStr) {
if (!SHOW_ONLY_FIRST_PAGE) return true;
try {
var u = new URL(urlStr, window.location.origin);
var p = u.searchParams.get('page') || u.searchParams.get('p');
return !p || p === '1';
} catch (e) {
return true;
}
}
function ensureContainer() {
var el = document.getElementById('category-description');
if (el) return el;
var anchor = document.querySelector('#js-product-list-top') || document.querySelector('#js-product-list');
el = document.createElement('div');
el.id = 'category-description';
el.className = 'text-muted';
if (anchor && anchor.parentNode) {
anchor.parentNode.insertBefore(el, anchor.nextSibling);
} else {
document.body.appendChild(el);
}
return el;
}
function replaceDescriptionIfHasContent(html) {
if (typeof html !== 'string') return;
var clean = html.trim();
if (!clean) return; // <-- KLUCZOWA ZMIANA: tylko jeśli coś przyszło
var box = ensureContainer();
box.innerHTML = clean;
box.style.display = '';
}
function fetchDescriptionFor(urlStr) {
if (inflightController) {
inflightController.abort();
inflightController = null;
}
inflightController = new AbortController();
var endpointUrl = ENDPOINT + '?url=' + encodeURIComponent(urlStr);
return fetch(endpointUrl, {
method: 'GET',
credentials: 'same-origin',
signal: inflightController.signal,
headers: { 'X-Requested-With': 'XMLHttpRequest' }
})
.then(function (res) {
if (!res.ok) throw new Error('HTTP ' + res.status);
return res.text();
})
.then(function (html) {
replaceDescriptionIfHasContent(html); // <-- tylko podmiana, gdy niepuste
})
.catch(function () { /* cicho ignorujemy błąd */ })
.finally(function () {
inflightController = null;
});
}
function updateDescriptionDebounced() {
clearTimeout(debounceTimer);
debounceTimer = setTimeout(function () {
var currentUrl = window.location.href;
if (currentUrl === lastUrl) return;
lastUrl = currentUrl;
// Jeśli chcesz pokazywać opis tylko na 1. stronie nie ruszamy treści,
// po prostu nie robimy requestu na stronach > 1.
if (!isFirstPage(currentUrl)) return;
fetchDescriptionFor(currentUrl);
}, DEBOUNCE_MS);
}
function wirePrestashopEvents() {
if (window.prestashop && typeof window.prestashop.on === 'function') {
window.prestashop.on('updateProductList', updateDescriptionDebounced);
window.prestashop.on('updatedProductList', updateDescriptionDebounced);
window.prestashop.on('facets:changed', updateDescriptionDebounced);
}
document.addEventListener('updateProductList', updateDescriptionDebounced, true);
document.addEventListener('updatedProductList', updateDescriptionDebounced, true);
}
onReady(function () {
hookHistoryEvents();
wirePrestashopEvents();
window.addEventListener('locationchange', updateDescriptionDebounced);
updateDescriptionDebounced(); // start
});
})();
</script>
{/literal}
{hook h='displayApSC' sc_key=sc2450863744}
{/block}