Image field type not working properly
Created 6 years ago by emergingdzns

I've added an image field type to the posts -> field section and called it "infographic". I then assigned it in the posts -> types to my one and only type. In the post I've added a jpg to the infographic field. In my module I'm fetching the posts collection like this:

$categoryPosts = $posts->findManyByCategory($category);
return view('my.module.content::posts')->with('posts',$categoryPosts);

In the posts.twig file when it echos the list of posts I added <img class="img-thumbnail" src="{{ post.infographic.make.url }}"> and it works just fine. However, I'm trying to do something a bit different because (for reasons I won't get into here) I'm starting to use some handlebar templates and need to pass in the URL to the template where I can't pass in an object. So, in the controller I'm trying to do this:

$items = [];
$categoryPosts = $posts->findManyByCategory($category);
foreach($categoryPosts as $post) {
    $thisItem = [
        'id' => $post->id,
        'title' => $post->title,
        'image_url' => $post->infographic->make()->url(),
        'excerpt' => $post->summary,
    ];
    $items[] = $item;
}

But this throws an error Call to a member function make() on null. So when NOT using twig, the very same call to make() on $post->infographic is giving me an error saying the $post->infographic is null. To debug I just did a print_r of the $post object and it does show the infographic assignment, that it's an image field type and even the data for the image with x/y sizes etc. I then tried doing print_r of $post->infographic and it's blank. So I tried $post->infographic_id. Again it's blank. Nothing I try seems to work in the controller. But if I simply pass the same collection data to the view the twig presenter calls work fine.

emergingdzns  —  6 years ago

For giggles, I created an image.twig view that has JUST this line it it: {{ post.infographic.make.url }}. I then modified the array shown above to change the image_url line to the following:

'image_url' => $view->make('my.module.content::image',['post'=>$post])->render(),

And now I get the URL. A very hack way of working around the problem. But clearly the $post->infographic isn't actually null or this would return nothing at all.

ryanthompson  —  6 years ago

In your controller - what is the output of dd($post->infographic);?

ryanthompson  —  6 years ago

Also the URL method will not return any cropped information (if you indeed mean image field type and not file field type). For that you will need the equivalent of {{ post.infographic.cropped.path }} or url but path is safer generally a better habit I think?

emergingdzns  —  6 years ago

output of dd($post->infographic) is "null"; Doesn't make sense when twig sees the object relationship just fine...

According to the documentation path returns something like local:// which is the file path not the url right? Or am I misunderstanding this? I'm not concerned about the cropping as we aren't forcing any crop on these images. But I could try using path instead if it's going to give the url back for the img tag.

ryanthompson  —  6 years ago

Cropped returns an Image instance. So it'll be the path to the output file. path off of the file instance/presenter will indeed return the file path. You're thinking of location I think. Using url off of the file instance is handy though for things like S3 files where you want the S3 source to be used.

Null.. that's interesting. The field slug is infographic then? You can use loadRelations or whatever it is to load all the relations and perhaps that will help. OR you can simply use post->entry->infographic that will force the entry object. Idk why it'd be missing maybe it's cause the _id suffix in that particular case. Very odd. There are numerous other ways you can grab the value if need be too - I'll have to see if I can replicate maybe something is wrong there.

emergingdzns  —  6 years ago

Here's the dd($post) result: https://pastecode.xyz/view/d012d941 (ignore the html at the top and bottom. it's added by their system) Notice that it does show the infographic relationship and it's json data. but dd($post->infographic) comes back null. It's really odd.

ryanthompson  —  6 years ago

You could also try decorating it - that will give it more of a Twig-like behavior:

$post = (new Decorator)->decorate($post);

I think $post = $post->decorated will do it too. So you could use that inline if need be: $post->decorated->infographic->cropped->path

I've gotta scoot - hope this helps!

emergingdzns  —  6 years ago

oooh interesting. I always thought the "decorated" just referred to an object that was already decorated.. Duh. So the documentation is LITERAL. 😄 I just did dd($post->entry->infographic->make()->url()); and it does return the url. So adding the ->entry bit did in fact force it to work. Thanks for that help!

ryanthompson  —  6 years ago

Sure thing! So what we were seeing here (idk why I didn't think of it prior) is that the presenter is responsible for passing it through automatically to the entry object. No presenter - no magic 😛