Simplify Image Sizing With a Macro
Problem
You want to display images without writing lots of code or repeating yourself.
Solution
Create a basic macro to handle it. We’re passing the following variables to the macro:
- The image object
- Alt text
- The transform (you need to define this in Craft under Settings > Assets)
- The declared width and height. This is what will be output in the tag. You may want it to be different than the actual image size.
- URL, if you want to link the image
- Class
You can easily add you own items to the macro, like title, onClick, whatever you like.
{% macro sizedImage(img, alt, transform, declaredWidth, declaredHeight, link, class) %}
{% if link|length %}
<a href="{{ link }}">
<img
src="{{ img.getUrl(transform) }}"
alt="{{ alt }}"
width="{{ declaredWidth }}"
height="{{ declaredWidth }}"
class="{{ class }}"
>
</a>
{% else %}
<img
src="{{ img.getUrl(transform) }}"
alt="{{ alt }}"
width="{{ declaredWidth }}"
height="{{ declaredWidth }}"
class="{{ class }}"
>
{% endif %}
{% endmacro %}
Now we include the macro, and call it from within an entries loop. This assumed our image field is called image, and we want to link it to the entry’s URL, and add myAwesomeClass to it
{% import 'macros/imageSizer' as macros %}
{% for entry in craft.entries.section('mySection') %}
{% set image = entry.image.first() %}
{{ macros.sizedImage(image, entry.title, 'myTransform', 200, 300, entry.url, myAwesomeClass) }}
{% endfor %}
Our output should look like this (line breaks added for readability):
<a href="/mysection/mypage">
<img src="/images/myImage.jpg"
width="200"
height="300"
alt="My entry title"
class="myAwesomeClass">
</a>
Discussion
At Versa Studio, we’ve used this to standardize how we display images. With a set of transforms and guidelines for our clients on image sizing and cropping (pre-Craft), combined with our image macros, we save a lot of coding time.
Submitted by Ben Seigel on 4th March, 2017