diff --git a/shop/static/shop/images/products/noir_hat.png.avif b/shop/static/shop/images/products/noir_hat.png.avif new file mode 100644 index 0000000..b451e1d Binary files /dev/null and b/shop/static/shop/images/products/noir_hat.png.avif differ diff --git a/shop/templates/shop/product_item.html b/shop/templates/shop/product_item.html index e00c05e..84c6eb9 100644 --- a/shop/templates/shop/product_item.html +++ b/shop/templates/shop/product_item.html @@ -1,7 +1,11 @@ +{% load shop_extras %}
{% if product.image %} - {{ product.title }} + {{ product.title }} {% else %}
No Image Available
{% endif %} @@ -33,6 +37,7 @@ title="{{ color.name }}" data-color-id="{{ color.id }}" data-color-name="{{ color.name }}" + data-color-image="{{ product.image|color_image_url:color.name }}" onclick="selectColor('{{ product.id }}', '{{ color.id }}', '{{ color.name }}', this)">
{% endfor %}
@@ -123,6 +128,16 @@ function selectColor(productId, colorId, colorName, element) { // Add selected class to clicked color element.classList.add('selected'); + + // Update product image based on selected color + const productImage = document.getElementById(`product-image-${productId}`); + + if (productImage) { + const colorImage = element.getAttribute('data-color-image'); + if (colorImage) { + productImage.src = colorImage; + } + } } diff --git a/shop/templatetags/__init__.py b/shop/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/shop/templatetags/shop_extras.py b/shop/templatetags/shop_extras.py new file mode 100644 index 0000000..c6f6406 --- /dev/null +++ b/shop/templatetags/shop_extras.py @@ -0,0 +1,82 @@ +from django import template +import os + +register = template.Library() + +@register.filter +def color_image_url(product_image, color_name): + """ + Returns color-specific image URL with any supported extension. + Falls back to the original image if no color variant exists. + """ + if not product_image or not color_name: + return product_image + + # Generate color suffix + suffix = generate_color_suffix(color_name) + + # Split path + directory, filename = os.path.split(product_image) + base_name, original_ext = os.path.splitext(filename) + + # List of supported image extensions to check + supported_extensions = ['.png.avif', '.jpg', '.jpeg', '.png', '.gif', '.webp', '.avif'] + + # Check for the color image with original extension first + color_filename = f"{suffix}_{base_name}{original_ext}" + color_image = os.path.join(directory, color_filename) + + # Extract the path after /static/ + static_prefix = '/static/' + if color_image.startswith(static_prefix): + rel_path = color_image[len(static_prefix):] + else: + rel_path = color_image.lstrip('/') + + # Check if file with original extension exists + from django.conf import settings + app_static_path = os.path.join(settings.BASE_DIR, 'shop', 'static', rel_path) + + if os.path.exists(app_static_path): + return color_image + + # If not found with original extension, try other extensions + for ext in supported_extensions: + if ext == original_ext: + continue # Skip the original extension as we already checked it + + color_filename = f"{suffix}_{base_name}{ext}" + color_image = os.path.join(directory, color_filename) + + if color_image.startswith(static_prefix): + rel_path = color_image[len(static_prefix):] + else: + rel_path = color_image.lstrip('/') + + app_static_path = os.path.join(settings.BASE_DIR, 'shop', 'static', rel_path) + + if os.path.exists(app_static_path): + return color_image + + # If no color variant is found with any extension, return the original image + return product_image + +def generate_color_suffix(color_name): + """ + Generates a URL-friendly suffix from a color name + Example: "Noir / Gris Foncé Chiné" becomes "noir_gris_fonce_chine" + """ + import unicodedata + import re + + # Convert to lowercase and replace accents + value = color_name.lower() + value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore').decode('ascii') + + # Replace slashes and spaces with underscores + value = re.sub(r'[/\s]+', '_', value) + + # Remove any remaining non-alphanumeric characters + value = re.sub(r'[^\w_]', '', value) + + return value