{# Reusable lazy loading image component with progressive enhancement. Parameters: - image_url: The URL of the image to load - alt_text: Alt text for accessibility (required) - css_classes: Additional CSS classes (optional) - width: Image width (optional) - height: Image height (optional) - loading: "lazy" (default) or "eager" for above-fold images - placeholder: Custom placeholder URL (optional, defaults to inline SVG) - srcset: Responsive image srcset (optional) - sizes: Responsive image sizes (optional) - full_src: Full-size image URL for lightbox (optional) Usage: {% include "components/lazy_image.html" with image_url=park.image_url alt_text=park.name %} {% include "components/lazy_image.html" with image_url=ride.thumbnail alt_text=ride.name loading="eager" %} {% include "components/lazy_image.html" with image_url=photo.url alt_text=photo.caption css_classes="rounded-lg shadow" %} Cloudflare Images responsive example: {% include "components/lazy_image.html" with image_url=photo.url|add:"?width=800" srcset=photo.url|add:"?width=400 400w, "|add:photo.url|add:"?width=800 800w, "|add:photo.url|add:"?width=1200 1200w" sizes="(max-width: 640px) 400px, (max-width: 1024px) 800px, 1200px" alt_text=photo.caption %} #} {% load static %} {# Default placeholder: inline SVG with aspect ratio preservation #} {% with placeholder_default="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 9'%3E%3Crect fill='%23f3f4f6' width='16' height='9'/%3E%3C/svg%3E" %} {{ alt_text|default:'' }} {% endwith %}