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.