diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml index 5ea23f5..87654ef 100644 --- a/.forgejo/workflows/deploy.yml +++ b/.forgejo/workflows/deploy.yml @@ -26,7 +26,7 @@ jobs: set ftp:ssl-allow no open -u $USERNAME,$PASSWORD $PRODUCTION_HOST mirror --reverse --verbose --ignore-time --parallel=10 -x local/ assets assets - mirror --reverse --verbose --ignore-time --parallel=10 -x accounts/ -x cache/ -x sessions/ -x header.php site site + mirror --reverse --verbose --ignore-time --parallel=10 -x accounts/ -x cache/ -x sessions/ site site mirror --reverse --verbose --ignore-time --parallel=10 kirby kirby mirror --reverse --verbose --ignore-time --parallel=10 vendor vendor quit diff --git a/assets/js/product-loader.js b/assets/js/product-loader.js index b8c54bf..a8c348d 100644 --- a/assets/js/product-loader.js +++ b/assets/js/product-loader.js @@ -22,6 +22,7 @@ } renderProduct(product, isEnglish); + updateMetaTags(product, isEnglish); loadingState.style.display = "none"; contentState.removeAttribute("style"); @@ -224,4 +225,57 @@ } } } + + function updateMetaTags(product, isEnglish) { + // Update title and description + const title = isEnglish && product.titleEn?.value + ? product.titleEn.value + : product.title; + const description = isEnglish && product.descriptionEn?.value + ? product.descriptionEn.value + : product.description; + + // Update Open Graph title + const ogTitle = document.getElementById('og-title'); + if (ogTitle) { + ogTitle.setAttribute('content', title); + } + + // Update Open Graph description + const ogDescription = document.getElementById('og-description'); + if (ogDescription && description) { + const excerpt = description.substring(0, 160); + ogDescription.setAttribute('content', excerpt); + } + + // Update Open Graph image + const ogImage = document.getElementById('og-image'); + if (ogImage && product.images.edges.length > 0) { + ogImage.setAttribute('content', product.images.edges[0].node.url); + } + + // Update product price + const ogPrice = document.getElementById('og-price'); + if (ogPrice) { + const price = parseFloat(product.priceRange.minVariantPrice.amount).toFixed(2); + ogPrice.setAttribute('content', price); + } + + // Update availability + const ogAvailability = document.getElementById('og-availability'); + if (ogAvailability) { + const availability = product.availableForSale ? 'in stock' : 'out of stock'; + ogAvailability.setAttribute('content', availability); + } + + // Update page title + document.title = `${title} | Index.ngo`; + + // Update meta description + let metaDescription = document.querySelector('meta[name="description"]'); + if (metaDescription && description) { + const excerpt = description.substring(0, 160); + metaDescription.setAttribute('content', excerpt); + } + } })(); diff --git a/site/config/config.php b/site/config/config.php index 6d46858..3c9969a 100644 --- a/site/config/config.php +++ b/site/config/config.php @@ -14,6 +14,17 @@ return [ ], 'routes' => [ + // Sitemap + [ + 'pattern' => 'sitemap.xml', + 'action' => function() { + $sitemap = page('home'); + return new Kirby\Cms\Response( + snippet('sitemap', ['page' => $sitemap], true), + 'application/xml' + ); + } + ], // French products (default) [ 'pattern' => '(:any)', diff --git a/site/snippets/header.php b/site/snippets/header.php index 57257c8..f25287e 100644 --- a/site/snippets/header.php +++ b/site/snippets/header.php @@ -1,11 +1,7 @@
- - - -