Optional crop for image

How to allow user to crop the image, but not make him to do that? Mostly they don’t need to crop, just use original pic, so we don’t open cropper automatically.

For example when crop is not defined template is like this:
<img src="[[+url]]" width="[[+width]]">
But when user defines crop (named Free), template should be:
<img src="[[+crops.Free.url]]" width="[[+crops.Free.targetWidth]]">

If crop is not defined we need to resize using phpthumbof, when crop is defined we can use it directly.

I tried:
<img src="[[+crops.Free.url:default=`[[+url]]`]]" width="[[+crops.Free.targetWidth:default=`[[+width]]`]]">

While crops.Free placeholders are empty, they go into resource content field and break further processing, like phpthumbof.

Is there a way in template to tell if crop is defined and use different code?
Or at least can undefined crop receive default values (url, width,height) from image itself (though not really solving all issues)

Try out:

<img src="[[+crops.Free.url:isnot=``:then=`[[+crops.Free.url]]`:else=`[[+url]]`]]" width="[[+crops.Free.targetWidth:isnot=``:then=`[[+crops.Free.targetWidth]]`:else=`[[+width]]`]]">

Sometimes it works.

Thanks Stefan, but any combination of placeholders and output filters won’t work. Problem is that CB on save won’t process output filters and fill only placeholders with value.
So for example, you don’t create crop and original image is image.jpg (no path for simplicity), this goes to resource content:
[[+crops.Free.url:isnot=``:then=`[[+crops.Free.url]]`:else=`image.jpg`]]
If we don’t need any further processing, MODX will process this correctly on page render. But we need to use phpthumof to rescale image to some maximum size, so we call phpthumbof where image path is entire string above. This is obviously not working. Not saying that we need to use phthumbof only when user didn’t created crop, otherwise we use crop directly.

It would be best if CB creates automatically all crops from entire image without opening cropper. If user is not satisfied with result, he or she can open cropper and adjust it later.
When user mostly want to use uncropped images, it’s annoying to open cropper uatomatically. User then needs to stretch crop rectangle to entire image (it’s not by default) and save crop. It’s several extra clicks per image, customers are complaining.

Logged as feature request #756.

As we’re working on ContentBlocks v2 and any time we spend on v1 ends up requiring duplicate time to also bring that to v2, there’s no guarantee we’ll get this added in v1 but it is a logical thing for it to do.

1 Like

Hi @hrabovec, which MODX Version are you using?

Hi, we are using latest stable 3.1.2pl. MODX works as intended, we need change in CB behaviour to create default crops automatically, so we can rely on their existence.

Yes, I think understand. I was thinking, that you are maybe hitting the same (or similar) bug, as I do/did in MODX 2.x with CB 1.14.x;
for me similar/complex cases with output modifiers started to fail.

My temporary solution is to wrap the part inside the output modifier in a chunk and call that, like this - Before:

(everything red just got omitted in the FE output)

After:

So you could try to either put your whole template code in a chunk,
and then call it in the cb-field template like this:

[[$myImageTpl? 
    &crop=`[[+crops.Free.url]]` 
    &cropWidth=`[[+crops.Free.targetWidth]]` 
    &url=`[[+url]]`
    &urlWidth=`[[+width]]`
    &alt=`[[+crops.Free.title]]`
]]

And inside your $myImageTpl (just an example name),
you put your template and adapt the “if” logic - maybe this works.

Or you could try something like this:

<img 
     src="[[$myImageSource? &crop=`[[+crops.Free.url]]` &url=`[[+url]]` ]]" 
     width="[[+crops.Free.targetWidth:default=`[[+width]]`]]"
     alt="[[+crops.Free.title]]">

And again, inside your $myImageSource chunk, you try to use your logic.

Another thing, that just comes to mind, is making sure that your upper templates/chunks, that include your image, also are cached. Because mixing cached/uncached chunks can in many cases lead to issues or inconsistencies.

If none of the two ideas work, the last resort - only if the page(s) don’t have tooo many images, probably - could be to try to use the placeholders uncached, something like this:

<img 
     src="[[!+crops.Free.url:default=`[[!+url]]`]]" 
     width="[[+crops.Free.targetWidth:default=`[[+width]]`]]"
     alt="[[+crops.Free.title]]">

I wish you good luck, and hope one of this helps you solve this.

Please let us know your results :slight_smile:

Hello Sebastian,
thanks for your ideas, but any combination of chunks and output filters won’t work. As I have mentioned, we are using output filter on [[*content]] field. This is moment when not all placeholders are parsed, so you are working with unparsed strings instead of parsed values.

But I have found quite an elegant way using newly added CB events.
Consider this field template (simplified use case):

<img class="mx-cb-field-image-cropped" src="[[+crops.Free.url]]" width="[[+crops.Free.targetWidth]]" height="[[+crops.Free.targetHeight]]">

If “Free” crop is not defined, you need to switch to a different template. So I used plugin for ContentBlocks_BeforeParse:

<?php
$tpl = $scriptProperties['tpl'];
$phs = $scriptProperties['phs'];
if (strpos($tpl, 'mx-cb-field-image-cropped') !== false) {
  if(!$phs["crops"] || !$phs["crops"]["free"]) {
    $modx->log(modX::LOG_LEVEL_ERROR, "changing template");
    $modx->event->output('<img src="[[+url]]" width="[[+width]]" height="[[+height]]">');
  }
}
return null;

We have it more complicated than this, rescaling with phpthumbof etc, but the basic idea work just fine.

Unfortunately this doesn’t solve bugs mentioned here: Bugs with Image input type