Resizing images inside structure field

Hi guys,

I’m currently outputting my images from my structure field inside my blueprints like this:

<?php foreach($page->pagelink()->yaml() as $pagelink) {

           $title = $pagelink['pagetitle'];
           $image = $pagelink['pageimage'];
           $link = $pagelink['link'];

          echo html('<div class="third page"><a href="'.$link.'">
          <h3>'.$title.'</h3>
          <img src="'.$image.'" alt="'.$title.'">
          </a>

But that just loads whatever image was uploaded from the panel. The problem now is that the images are not resized accordingly and the full 100% of the image is loading which is making the site quite slow.

I want to resize the images and ive been trying width(100) and resize(100) but im not sure how to implement this in the above code without breaking the site.

Any help would be most appreciated, thank you

Your image is just a string, not an image object:

$image = $page->image($pagelink['pageimage']);

$image->resize(300);

When im also adding the variable into the img src tag, how would i position it?

Like this?
<img src="'.$image->resize(300);.'" alt="'.$title.'">

Like this

<img src="<?= $image->resize(300)->url() ?>" alt="<?= $title ?>">

Its still not working.

Heres my full div of code.

 <div class="full">
        <?php foreach($page->collectionImages()->yaml() as $collection) {

            $title = $collection['featuretitle'];
            $featureimage = $page->image($collection['featureimage']);

           
           echo html("<div class='third product'>
                                <img src="<?= $image->resize()->url() ?>" alt="<?= $title ?>">
                           </div>"); 
          }

        ?>
   </div>

Where am i going wrong?

Oh, sorry, I forgot to add the size …

And, you have changed your variable from $image to $featureimage, so you gotta change that as well.

Yeah sorry about that, i have a few of them on the page.

$featureimage = $page->image($collection['featureimage']);

      echo html("<div class='third product'>
             <img src="<?= $featureimage->resize(200)->url() ?>" alt="<?= $title ?>">
      </div>"); 

This doesnt work either. It actually breaks the page.

I also tried

      ?>
        <div class="third product">
              <img src="<?php $featureimage->resize(200)->url() ?>" alt="<?php $title ?>">
        </div>
     <?php

Breaks the page aswell.

Yo can try:


<?php foreach($page->pagelink()->toStructure() as $pagelink) {

           $title = $pagelink->title();
           $image = $pagelink->pageimage()->toFile();
           $link = $pagelink->link();

          echo html('<div class="third page"><a href="'.$link.'">
          <h3>'.$title.'</h3>
          <img src="'.$image->resize(200)->url().'" alt="'.$title.'">

Pls. turn on debug in your config, I think you have an error in your php syntax. You open a new php tag inside php, because you echo your html tags, which is in fact not good practice.

<div class="full">
      <?php foreach($page->collectionImages()->yaml() as $collection):

        $title = $collection['featuretitle'];
        $featureimage = $page->image($collection['featureimage']); 
     ?>

       <div class='third product'>
            <img src="<?= $image->resize()->url() ?>" alt="<?= $title ?>">
       </div>")
 <?php endforeach ?>
   </div>

Let me make this clearer because none of those suggestions seemed to work. I reverted back to my current working code to show you exactly how I’m laying it out and to make sure there are no errors.

     <div class="full">
        <?php foreach($page->collectionImages()->yaml() as $collection) {

            $title = $collection['featuretitle'];
            $featureimage = $collection['featureimage'];
            
              echo html('<div class="third product">
                            <img src="'.$featureimage.'" alt="'.$title.'">
                         </div>'); 

        } ?>
    </div>

This code is spitting out the images perfectly without error. But as above, I want to resize the images to a certain size so the images load faster etc…

Here is the collectionImages blueprint

collectionImages:
    label: Featured Images Collection
    type: structure
    entry: >
      <h2 style="font-size: 21px; margin-top: 10px;">{{featuretitle}}</h2><br>
      <img src="{{featureimage}}" height=300px/></br></br>
    fields:
      featuretitle:
        label: Image Title
        type: text
      featureimage:
        label: Collection Image
        type: select
        options: query
      jquery:
        fetch: files
        value: '{{url}}'
        text: '{{filename}}

Oh, I see the problem, you save the url to the content file, not the filename; then it can’t possibly work.

You can try to use the new Asset class then:

 $featureimage = new Asset($collection['featureimage']);

Okay so I rewrote my code a bit,

  <div class="full">
      <?php foreach($page->collectionImages()->toStructure() as $collection): ?>
              <div class="third product">
                <img src="<?php echo $collection->featureimage()->width(20);?>">
              </div>  
      <?php endforeach ?>
  </div>

Is it possible for me to use resize() or width() now?

No, the toStructure() method does not help here (although you can use it).

As I said above, you have an URL in your content file and you need an image object. The way to transform your URL into an image object should be by using the code I posted above. Have you tried that?

Or change what you are saving to your content file, use the filename instead of the URL and you can use the code I first posted above.

Okay so I went back and rewrote the code using the asset function you provided.

    <?php foreach($page->collectionImages()->yaml() as $collection): ?>
           
           <?php    
           $title = $collection['featuretitle'];
           $image = new Asset($collection['featureimage']);
           $featureimage = $image->resize(100)->url();
            ?>
        
        <div class="third product">
          <img src="<?php echo $featureimage; ?>">
          
        </div>

      <?php endforeach; ?>

The images are showing up, but they are ignoring the resize function?

I have also tried to write it like this:

   <?php foreach($page->collectionImages()->yaml() as $collection) {
           
            
           $title = $collection['featuretitle'];
           $image = new Asset($collection['featureimage']);
           $featureimage = $image->width(50)->url();
          
        
        echo html('<div class="third product">
          <img src="'.$featureimage.'"> 
        </div>');

      } ?>

Still no luck, Do you see where I am going wrong?

Hm, too bad, maybe the new Asset class only works for images in the assets folder (as its name seems to imply). I thought it could maybe be used for all sorts of images.

Why do you need to use the url instead of just the filename? Would really make things so much easier …

It would mean me going back and rewriting pretty much the entire site, as all the images are based on urls instead of file names.

All I want to do is optimize the images so the full 100% isn’t loading.

How should my blueprint look if I wanted to save the filename?

collectionImages:
    label: Featured Images Collection
    type: structure
    entry: >
      <h2 style="font-size: 21px; margin-top: 10px;">{{featuretitle}}</h2><br>
      <img src="{{featureimage}}" height="300px"/></br></br>
    fields:
      featuretitle:
        label: Image Title
        type: text
      featureimage:
        label: Collection Image
        type: select
        options: query
      query:
        fetch: files
        value: '{{url}}'
        text: '{{filename}}'

Should value: {{url}} be changed to value: {{filename}}?
Then if so, do i output the images like normal?

Cheers for all your help

I’m really sorry that it does not work. Yes, changing it to filename would do the job. But maybe someone else here comes up with another idea how to work with the url instead, @lukasbestle?

If you use the filename instead of the URL, you could use this code to fetch the images:

<?php foreach($page->collectionImages()->yaml() as $collection): ?>
      
      <?php
      $title = $collection['featuretitle'];
      $image = $page->image($collection['featureimage']);
      ?>
      
      <div class="third product">
        <img src="<?php echo $image->resize(100)->url() ?>">
        
      </div>
      
    <?php endforeach; ?>

If you want to keep using the URL, use the code posted in the last post by @texnixe, but replace the code to get the image with this:

$image = $page->images()->findBy('url', $collection['featureimage']);
1 Like

So like this?

    <div class="full">
      
      <?php foreach($page->collectionImages()->yaml() as $collection): ?>
  
    <?php
      $title = $collection['featuretitle'];
      $image = $page->images()->findBy('url', $collection['featureimage']);
    ?>
  
   <div class="third product">
    <img src="<?php echo $image->resize(100)->url(); ?>">
    
  </div>
<?php endforeach; ?>

Still no luck :frowning:

Getting this error :
#6 C:\Users\DazdLaptop\Desktop\work\sites#\app\index.php(16): K in C:\Users\DazdLaptop\Desktop\work\sites#\app\site\templates\home.php on line 25
[Fri Jun 3 14:44:18 2016] 127.0.0.1:64207 [500]: / - Uncaught Error: Call to a member function resize() on null in C:\Users\DazdLaptop\Desktop\work\sites#\app\site\templates\home.php:25

This is line 25:
<img src="<?php echo $image->resize(100)->url(); ?>">

Are all the fields filled with image urls? If not, you should always check if the image exists before trying to use a method on it.