Skip to content

Instantly share code, notes, and snippets.

@stenvdb
Last active July 4, 2022 10:49
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save stenvdb/be8224ca6620404b2229871f28e69c22 to your computer and use it in GitHub Desktop.
Save stenvdb/be8224ca6620404b2229871f28e69c22 to your computer and use it in GitHub Desktop.
Macro collection for Imager in Craft CMS
{#
# USAGE:
# (transform can either be an object, or an array of objects, aka srcset)
#
# {{ macro.regular(entry.image.one(), { width: 50, height: 50 }, 'class="block"') }}
# ➡️ <img src="..." width="50" height="50" alt="..." class="block" />
#
# {{ macro.url(entry.image.one(), { width: 50, height: 50 }) }}
# ➡️ /uploads_c/../{...}.jpg
#
# {{ macro.srcWidthHeight(entry.image.one(), { width: 50, height: 50 }) }}
# ➡️ src="/uploads_c/../{...}.jpg" width="50" height="50"
#}
{# Returns an img element #}
{% macro regular(image, transform, attributes = '') %}
{% if transform|first is not iterable %}
<img {{ _self.src(image, transform, true) }} alt="{{ (image is iterable) ? image.title : '' }}" {{ attributes|raw }} />
{% else %}
{# Do some magic to transform our string into an array #}
{% set helper = create('craft\\helpers\\StringHelper') %}
{% set string = _self.src(image, transform) %}
{% set array = helper.splitOnWords(string) %}
<img src="{{ array[array|length // 2]|split(' ')[0] }}"
sizes="100vw"
srcset="{{ string }}"
alt="{{ (image is iterable) ? image.title : '' }}" {{ attributes|raw }} />
{% endif %}
{% endmacro %}
{# Returns a plain url #}
{% macro url(image, transform) %}{% spaceless %}
{{ _self.src(image, transform) }}
{% endspaceless %}{% endmacro %}
{# Returns src, width & height attributes as a string #}
{% macro srcWidthHeight(image, transform) %}{% spaceless %}
{{ _self.src(image, transform, true) }}
{% endspaceless %}{% endmacro %}
{#
#
# This is the one
# All of the transform logic is done here!
#
#}
{% macro src(image, transform, withSizeAttrs = false) %}{% spaceless %}
{% if image %}
{% if image.size|default < craft.app.config.general.maxUploadFileSize %}
{# Set some good transfrom defaults, but don't override the transform passed! #}
{% if transform is iterable %}
{# Defaults: #}
{% set mergeThisIn = {
position: ((image.focalPoint.x|default(0.5) * 100)) ~ '% ' ~ (image.focalPoint.y|default(0.5) * 100) ~ '%',
effects: { sharpen: true },
interlace: true,
mode: 'crop'
} %}
{# Check if there is 1 or more transforms #}
{% if transform|first is iterable %}
{# Array of transforms (srcset) =>
create a new transform array with the defaults added for each item #}
{% set tempArr = [] %}
{% for i in 0..transform|length-1 %}
{% set tempArr = tempArr|merge({ (i): mergeThisIn|merge(transform[i])}) %}
{% endfor %}
{# We can't update the transform array because
merge doesn't work with numeric keys.. so replace it #}
{% set transform = tempArr %}
{% else %}
{# Single transform => simple merge #}
{% set transform = mergeThisIn|merge(transform) %}
{% endif %}
{% endif %}
{# Do the transform #}
{% set transformed = craft.imager.transformImage(image, transform) %}
{% if transform|first is not iterable %}
{# Return the transform #}
{{ withSizeAttrs ? 'src="' }}{{ transformed.url }}{{ withSizeAttrs ? '"' }} {{ withSizeAttrs ? "width='#{transformed.width}' height='#{transformed.height}'"|raw }}
{% else %}
{# We can only return strings with macros, this will be transformed into array later on #}
{{ transformed|map(x => "#{x.url} #{x.width}w")|join(',')|raw }}
{% endif %}
{% endif %}
{% endif %}
{% endspaceless %}{% endmacro %}
@wihodges
Copy link

Hey awesome macro and article.

Question, do you know why line 23
'{% set array = helper.toArray(string) %}'
is returning a deprecation error:
"Passing a string to ArrayHelper::toArray() has been deprecated. Use StringHelper::split() instead."
Usually these craft messages are helpful but changing to .split(string) does not work.

@stenvdb
Copy link
Author

stenvdb commented Sep 27, 2020

@wihodges Thanks for pointing this out. I have updated to gist to fix the deprecation error. In particular line 21 & 23 have been updated.

@wihodges
Copy link

wihodges commented Oct 6, 2020

Yes that solved it!

@wihodges
Copy link

wihodges commented Oct 8, 2020

So now it seems on line the 24, img src="imager" is not splitting the string. Intersting locally it shows <img src="imager" .... and on production <img src="8094" ... ~which I believe is the asset ID.

@rogerdawkins
Copy link

So now it seems on line the 24, img src="imager" is not splitting the string. Intersting locally it shows <img src="imager" .... and on production <img src="8094" ... ~which I believe is the asset ID.

The issue is on line 23. The code uses splitOnWords() but that appears to be incorrect. It should be split() so the line should read:
{% set array = helper.split(string) %}

splitOnWords will split on a variety of characters including '/' whereas split will correctly split on commas only.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment