diff --git a/shop/static/shop/images/products/PC001/blanc/PS_KP912-B_WHITE.png.avif b/shop/static/shop/images/products/PC001/blanc/PS_KP912-B_WHITE.png.avif new file mode 100644 index 0000000..52ba473 Binary files /dev/null and b/shop/static/shop/images/products/PC001/blanc/PS_KP912-B_WHITE.png.avif differ diff --git a/shop/static/shop/images/products/PC001/blanc/PS_KP912-S_WHITE.png.avif b/shop/static/shop/images/products/PC001/blanc/PS_KP912-S_WHITE.png.avif new file mode 100644 index 0000000..b713c00 Binary files /dev/null and b/shop/static/shop/images/products/PC001/blanc/PS_KP912-S_WHITE.png.avif differ diff --git a/shop/static/shop/images/products/PC001/blanc/PS_KP912_WHITE.png.avif b/shop/static/shop/images/products/PC001/blanc/PS_KP912_WHITE.png.avif new file mode 100644 index 0000000..c6d5cab Binary files /dev/null and b/shop/static/shop/images/products/PC001/blanc/PS_KP912_WHITE.png.avif differ diff --git a/shop/static/shop/images/products/PC001/bleu-sport/PS_KP912-B_NAVY.png.avif b/shop/static/shop/images/products/PC001/bleu-sport/PS_KP912-B_NAVY.png.avif new file mode 100644 index 0000000..773a218 Binary files /dev/null and b/shop/static/shop/images/products/PC001/bleu-sport/PS_KP912-B_NAVY.png.avif differ diff --git a/shop/static/shop/images/products/PC001/bleu-sport/PS_KP912-S_NAVY.png.avif b/shop/static/shop/images/products/PC001/bleu-sport/PS_KP912-S_NAVY.png.avif new file mode 100644 index 0000000..857968a Binary files /dev/null and b/shop/static/shop/images/products/PC001/bleu-sport/PS_KP912-S_NAVY.png.avif differ diff --git a/shop/static/shop/images/products/PC001/bleu-sport/PS_KP912_NAVY.png.avif b/shop/static/shop/images/products/PC001/bleu-sport/PS_KP912_NAVY.png.avif new file mode 100644 index 0000000..cbefe4d Binary files /dev/null and b/shop/static/shop/images/products/PC001/bleu-sport/PS_KP912_NAVY.png.avif differ diff --git a/shop/static/shop/images/products/PC001/noir/PS_KP912-B_BLACK.png.avif b/shop/static/shop/images/products/PC001/noir/PS_KP912-B_BLACK.png.avif new file mode 100644 index 0000000..c467628 Binary files /dev/null and b/shop/static/shop/images/products/PC001/noir/PS_KP912-B_BLACK.png.avif differ diff --git a/shop/static/shop/images/products/PC001/noir/PS_KP912-S_BLACK.png.avif b/shop/static/shop/images/products/PC001/noir/PS_KP912-S_BLACK.png.avif new file mode 100644 index 0000000..3956e54 Binary files /dev/null and b/shop/static/shop/images/products/PC001/noir/PS_KP912-S_BLACK.png.avif differ diff --git a/shop/static/shop/images/products/PC001/noir/noir_hat.png.avif b/shop/static/shop/images/products/PC001/noir/noir_hat.png.avif new file mode 100644 index 0000000..b451e1d Binary files /dev/null and b/shop/static/shop/images/products/PC001/noir/noir_hat.png.avif differ diff --git a/shop/templates/shop/product_item.html b/shop/templates/shop/product_item.html index 047ec50..75cef84 100644 --- a/shop/templates/shop/product_item.html +++ b/shop/templates/shop/product_item.html @@ -3,7 +3,7 @@
{% if product.image %} {{ product.title }} {% else %} @@ -37,7 +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 }}" + data-color-image="{% color_image_url product.image color.name product.sku %}" onclick="selectColor('{{ product.id }}', '{{ color.id }}', '{{ color.name }}', this)">
{% endfor %} diff --git a/shop/templatetags/shop_extras.py b/shop/templatetags/shop_extras.py index c6f6406..dcb40b9 100644 --- a/shop/templatetags/shop_extras.py +++ b/shop/templatetags/shop_extras.py @@ -2,69 +2,64 @@ from django import template import os register = template.Library() +from django.conf import settings -@register.filter -def color_image_url(product_image, color_name): +@register.simple_tag +def color_image_url(default_image, color_name, sku): """ - Returns color-specific image URL with any supported extension. - Falls back to the original image if no color variant exists. + Returns color-specific image URL from the color-specific folder structure. + Structure expected: + static/shop/images/products/ + ├── {sku}/ + │ ├── default.jpg (or any supported extension) + │ └── {color_name}/ + │ └── image.jpg (or any supported extension) """ - 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 + # List of supported image extensions 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): + # Base path for products + base_path = f'/static/shop/images/products/{sku}/' + physical_base_path = os.path.join(settings.BASE_DIR, 'shop', 'static', 'shop', 'images', 'products', sku) + + if color_name: + # Generate color folder name (sanitize the color name) + color_folder = generate_color_folder_name(color_name) + + # Check color-specific folder + color_path = os.path.join(physical_base_path, color_folder) + if os.path.exists(color_path): + # Get first image from color folder + files = [f for f in os.listdir(color_path) + if any(f.lower().endswith(ext) for ext in supported_extensions)] + + if files: + # Sort files to ensure consistent selection + files.sort(key=lambda x: ( + 1 if '-B_' in x else + 2 if '-S_' in x else + 0 + )) + + # Get the first image + first_file = files[0] + return f'{base_path}{color_folder}/{first_file}' + + # If no color-specific image found, look for default image in product folder + if os.path.exists(physical_base_path): + for file in os.listdir(physical_base_path): + if any(file.lower().endswith(ext) for ext in supported_extensions): + if os.path.isfile(os.path.join(physical_base_path, file)): # Make sure it's a file, not a directory + return f'{base_path}{file}' + + # If nothing found, return the default image from the database + return default_image + +def generate_color_folder_name(color_name): """ - Generates a URL-friendly suffix from a color name - Example: "Noir / Gris Foncé Chiné" becomes "noir_gris_fonce_chine" + Generates a folder-friendly name from a color name + Example: "Noir / Gris Foncé Chiné" becomes "noir-gris-fonce-chine" """ import unicodedata import re @@ -73,10 +68,10 @@ def generate_color_suffix(color_name): 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) + # Replace slashes and spaces with hyphens + value = re.sub(r'[/\s]+', '-', value) - # Remove any remaining non-alphanumeric characters - value = re.sub(r'[^\w_]', '', value) + # Remove any remaining non-alphanumeric characters except hyphens + value = re.sub(r'[^\w-]', '', value) return value