Skip to content

Instantly share code, notes, and snippets.

@svale
Created August 20, 2022 16:33
Show Gist options
  • Save svale/9b681c976d1c2ce2ad3c9296120ff525 to your computer and use it in GitHub Desktop.
Save svale/9b681c976d1c2ce2ad3c9296120ff525 to your computer and use it in GitHub Desktop.
A reusable image twig component
{# Image
This is an image component template for echoing image tags in a twig template.
Output:
<figure>
<img />
<figcaption></figcaption>
</figure
It takes the following props:
image object Craft image element, i.e "entry.image.one()"
transform string Handle of optimised image field
sizes string For Responsive images. Set on sizes attribute on the img tag
altText string Text for the alt-attibute on the img tag
caption string Text for the figcaption tag (image caption)
lazy boolean Load lazy or eager
outerClasses string Classes added to the figure tag
innerClasses string Classes added to the img tag
debug boolean To debug responsive sizes. See btm of file.
#}
{# props #}
{% set image = image ?? null %}
{% set transform = transform ?? 'optimisedImage' %} {# `optimisedImage` is the default transform #}
{% set sizes = sizes ?? null %}
{% set altText = altText ?? '' %}
{% set caption = caption ?? '' %}
{% set lazy = lazy ?? true %}
{% set debug = debug ?? false %}
{% set outerClasses = outerClasses ?? '' %}
{% set innerClasses = innerClasses ?? '' %}
{# variables #}
{% set useWebP = true %}
{% set optimizedImages = image[transform] ?? null %} {# Get optimized images if available #}
{% if optimizedImages and (optimizedImages.optimizedWebPImageUrls|length or optimizedImages.optimizedImageUrls|length) %}
{% set src = optimizedImages.src() %}
{% set srcset = useWebP and optimizedImages.optimizedWebPImageUrls|length ? optimizedImages.srcsetWebP() : optimizedImages.srcset() %}
{% set width = optimizedImages.variantHeights|keys|last %}
{% set height = optimizedImages.variantHeights|last %}
{% else %}
{% set src = image.url %}
{% set srcset = null %}
{% set sizes = null %}
{% set width = image.width %}
{% set height = image.height %}
{% endif %}
{# figure tag attributes #}
{% set outerAttributes = { class: outerClasses }|merge(outerAttributes ?? {}) %}
{# image tag attributes #}
{% set innerAttributes =
{
src,
srcset,
sizes,
width,
height,
loading: lazy ? 'lazy' : 'eager',
alt: altText,
class: debug ? "#{innerClasses} debugimage" : innerClasses
}|merge(innerAttributes ?? {})
%}
{# output #}
<figure {{ attr(outerAttributes) }}>
<img {{ attr(innerAttributes) }} />
{% if caption %}
<figcaption>
{{ caption }}
</figcaption>
{% endif %}
</figure>
{# Debug srcset / sizes
# Prints image real size vs calculated size in the console
# if debug prop is true and in devMode.
# Ref: https://medium.com/unsplash/how-we-test-responsive-images-at-unsplash-4fb940caee72
#}
{# prettier-ignore-start #}
{% if debug and devMode %}
{% js %}
const image = document.querySelector('.debugimage')
if(image) {
import('https://unpkg.com/responsive-image-test@0.0.1/target/index.js').then((module) => {
// Whilst we debug image sizes, we want to hide scroll bars as they may not be accounted for in our `sizes` attribute.
// module.hideBodyScrollBars();
module.observeSizes(image);
});
}
{% endjs %}
{% endif %}
{# prettier-ignore-end #}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment