Compare commits

...

2 commits

Author SHA1 Message Date
isUnknown
f69d990349 cart drawer : close button strokes to black
All checks were successful
Deploy / Deploy to Production (push) Successful in 7s
2026-01-16 16:41:46 +01:00
isUnknown
f4ecdcf947 Fix multilingual routing for virtual product pages
Use site()->visit() to properly set language context for virtual pages.
This ensures UI translations and language-specific content work correctly
on both /slug (French) and /en/slug (English) routes.

Changes:
- Add site()->visit($page, $lang) in routes to set page language
- Create product controller for language detection
- Fix add-to-cart button to update text in .txt div instead of button
- Remove broken hooks approach

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-16 16:40:10 +01:00
8 changed files with 48 additions and 20 deletions

View file

@ -10,7 +10,8 @@
"Bash(grep:*)",
"Bash(npm run build:*)",
"Bash(php test-shopify.php:*)",
"WebFetch(domain:getkirby.com)"
"WebFetch(domain:getkirby.com)",
"WebFetch(domain:forum.getkirby.com)"
]
}
}

View file

@ -76,6 +76,10 @@
&:hover {
opacity: 0.7;
}
svg {
stroke: #000;
}
}
&__content {

View file

@ -83,6 +83,7 @@
}
.header-cart-btn {
font-family: var(--font);
background: none;
border: none;
cursor: pointer;
@ -109,11 +110,11 @@
}
&:not(:empty)::before {
content: '(';
content: "(";
}
&:not(:empty)::after {
content: ')';
content: ")";
}
}
}

View file

@ -559,6 +559,7 @@ main {
color: var(--color-txt);
}
#site-header .header-cart-btn {
font-family: var(--font);
background: none;
border: none;
cursor: pointer;
@ -1431,6 +1432,9 @@ body.is-fullscreen {
.cart-drawer__close:hover {
opacity: 0.7;
}
.cart-drawer__close svg {
stroke: #000;
}
.cart-drawer__content {
flex: 1;
overflow-y: auto;

File diff suppressed because one or more lines are too long

View file

@ -10,6 +10,13 @@
return;
}
const buttonTextDiv = addToCartBtn.querySelector('.txt[data-button-text]');
if (!buttonTextDiv) {
console.error('Button text div not found');
return;
}
const texts = {
add: addToCartBtn.dataset.textAdd || 'Add to cart',
adding: addToCartBtn.dataset.textAdding || 'Adding...',
@ -28,13 +35,13 @@
}
addToCartBtn.disabled = true;
const originalText = addToCartBtn.textContent;
addToCartBtn.textContent = texts.adding;
const originalText = buttonTextDiv.textContent;
buttonTextDiv.textContent = texts.adding;
try {
const cartResult = await cart.addToCart(variantId, 1);
addToCartBtn.textContent = texts.added;
buttonTextDiv.textContent = texts.added;
addToCartBtn.classList.add('success');
document.dispatchEvent(new CustomEvent('cart:updated', {
@ -43,19 +50,19 @@
setTimeout(() => {
addToCartBtn.disabled = false;
addToCartBtn.textContent = originalText;
buttonTextDiv.textContent = originalText;
addToCartBtn.classList.remove('success');
}, 1500);
} catch (error) {
console.error('Error adding to cart:', error);
addToCartBtn.textContent = texts.error;
buttonTextDiv.textContent = texts.error;
addToCartBtn.classList.add('error');
setTimeout(() => {
addToCartBtn.disabled = false;
addToCartBtn.textContent = originalText;
buttonTextDiv.textContent = originalText;
addToCartBtn.classList.remove('error');
}, 2000);
}

View file

@ -14,11 +14,10 @@ return [
],
'routes' => [
// French product pages (default)
// French products (default)
[
'pattern' => '(:any)',
'action' => function($slug) {
// Skip known pages
if (in_array($slug, ['home', 'error', 'thanks'])) {
return null;
}
@ -27,28 +26,28 @@ return [
foreach ($products as $product) {
if ($product['handle'] === $slug) {
return Page::factory([
$page = Page::factory([
'slug' => $product['handle'],
'template' => 'product',
'parent' => site()->homePage(),
'content' => [
'title' => $product['title'],
'shopifyHandle' => $product['handle'],
'uuid' => $product['id']
]
]);
site()->visit($page, 'fr');
return $page;
}
}
// Not a product, let Kirby handle normally
return null;
}
],
// English product pages
// English products
[
'pattern' => 'en/(:any)',
'action' => function($slug) {
// Skip known pages
if (in_array($slug, ['home', 'error', 'thanks'])) {
return null;
}
@ -57,20 +56,21 @@ return [
foreach ($products as $product) {
if ($product['handle'] === $slug) {
return Page::factory([
$page = Page::factory([
'slug' => $product['handle'],
'template' => 'product',
'parent' => site()->homePage(),
'content' => [
'title' => $product['title'],
'shopifyHandle' => $product['handle'],
'uuid' => $product['id']
]
]);
site()->visit($page, 'en');
return $page;
}
}
// Not a product, let Kirby handle normally
return null;
}
]

View file

@ -0,0 +1,11 @@
<?php
return function ($page, $kirby) {
$shopifyHandle = $page->shopifyHandle()->or($page->slug())->value();
$language = $kirby->language()->code();
return [
'shopifyHandle' => $shopifyHandle,
'language' => $language
];
};