Cms: Image transforms return error on first load

Created on 10 Jan 2018  Â·  12Comments  Â·  Source: craftcms/cms

Description

I've created some transforms in the Control Panel. I'm using them to generate responsive CSS background images in my template code. When I load the page for the first time, I get this error (and images don't load):

URL:

http://mywebsite.local/index.php?p=actions/assets/generate-transform&transformId=9

Error details:

Argument 1 passed to craft\services\Assets::getAssetById()
must be of the type integer, null given, called in 
C:\web\mywebsite\vendor\craftcms\cms\src\controllers\AssetsController.php on line 853

The same thing happens on production (Ubuntu 16.04) so it's not just a Windows issue.

TWIG template code:

{% if b.bgImage.one() is defined %}
    .block-{{b.id}} { background-image: url({{ b.bgImage[0].getUrl('t768x1024') }}); }
@media (min-width: {{g.lg}}) {
    .block-{{b.id}} { background-image: url({{ b.bgImage[0].getUrl('t1200x800') }}); }
}
@media (min-width: {{g.xl}}),
       (min-width: {{g.lg}}) and (-webkit-min-device-pixel-ratio: 1.5),
       (min-width: {{g.lg}}) and (min-resolution: 144dpi) {
    .block-{{b.id}} { background-image: url({{ b.bgImage[0].getUrl('t1800x1200') }}); }
}
{% endif %}

If I reload the page everything loads normally. This doesn't only happen before the first transforms get generated - even with transforms already done, when caches get cleared, I still get this error on first load.

I tried it with vanilla Craft transforms and also using ImageOptimize plugin - same result.

Steps to reproduce

  1. Create custom transforms in CP
  2. Use transforms in Twig template

Additional info

  • Craft version: 3.0.0-RC5
  • PHP version: PHP 7.1.10 (cli) (built: Oct 4 2017 08:54:01)
  • Database driver & version: MySQL 5.7.19

Most helpful comment

No I don’t think it would – &s should not be HTML-encoded when generating URLs in CSS, as far as I know.

Or should we just always use |raw when using asset.getUrl()?

Only when calling getUrl() within CSS or JavaScript code.

All 12 comments

Hi juresrpcic,
the problem is, that TWIG {{ ... }} automatically encodes the output of getUrl(...).
which transforms the & to & in the transformation URL.

Just add the TWIG raw filter to your output, e.g.

{{ b.bgImage[0].getUrl('t768x1024') | raw }}

Something seems to have changed here in one of the last RCs, as this problem did not occure before.

Thanks a lot @hiasl - that solved the issue. I did have this working before (might have been a C3 beta though), so it's a relatively recent change, possibly from updating Twig.

yeah, same for me, I also came from b34 to rc4 and it stopped working

We updated from Twig 2.3 to 2.4 in Beta 35, but I don’t see anything in the changelog related to escaping HTML, and I just tested outputting an asset transform generation URL in Beta 34 and got the same output as I do in RC5.

Here’s the template I’m testing with:

{% set asset = craft.assets.kind('image').one() %}
<style type="text/css">
    foo {
        background: url({{ asset.getUrl({ width: 100, height: 100 }) }});
    }
</style>

And here’s the output:

<style type="text/css">
    foo {
        background: url(http://happylager.dev/index.php?p=actions/assets/generate-transform&amp;transformId=1);
    }
</style>

Let me know if you can think of any other factors that might have affected this - happy to keep investigating.

Thanks Brandon - just want to check if your example works for you (that encoded &amp; in your output causes my issue on first load)? Or should we just always use |raw when using asset.getUrl()?

No I don’t think it would – &s should not be HTML-encoded when generating URLs in CSS, as far as I know.

Or should we just always use |raw when using asset.getUrl()?

Only when calling getUrl() within CSS or JavaScript code.

I have this issue as well; I suspect that it's a platform issue between Windows and Mac. The transform URLs have URL-safe &amp; in them which triggers the "Argument 1 passed to craft\services\Assets::getAssetById() must be of the type integer, null given" error. Removing the amp; portion and just leaving & fixes things entirely.

@proimage How is the URL being output in your template?

@proimage How is the URL being output in your template?

Inside a <style> block, just like everybody else. Adding the |raw filter fixes it.

Yeah that makes sense, for same reason explained by https://github.com/craftcms/cms/issues/2290#issuecomment-356585962. Twig escapes dynamic output for HTML by default, since that is generally what you are generating. If you are generating CSS code you need to use |raw. Or if you are generating JS code you need to use |e('js').

No worries; I'm fine with needing to use |raw to address the issue. I just thought that perhaps since both the OP and myself are on Windows, and since you didn't encounter the same issue, that perhaps it was something OS-specific that could be addressed. :)

Sorry for the confusion – I was specifically referring to whether Twig’s encoding behavior had changed in 2.4. I wasn’t saying it was working in a browser for me; just that both Twig 2.3 and 2.4 behaved identically for me – that they were both HTML-encoding the & into &amp;, thus in both cases |raw was needed.

Was this page helpful?
0 / 5 - 0 ratings