Idea for simple <picture> responsive image solution


#1

Hi kirby community,

i started to use kriby 2 days ago and i already like it.
Before i worked years with Redaxo, i wanted to find a more simple and small Solution and Kirby is perfect.

I could not figure out where to post this so excuse me if its at the wrong place O:)

i wanted to render a responsive image solution the plugins seems to be nice, but i could not install it.
Do my time is to short to find the problems i tried to make it plain PHP.

The solution is not ideal and its to much code for sure, but it works for me (quick and dirty).
Its based on the idea that for Optimization reasons i always want to compress the image as hell with tools like tinypng (website) and so on.
I made 3 versions of the image: image–small.jpg 420w, image–mid.jpg 820w and a large one.
Uploaded them into the page file: section.
I limited the function to a template and the image count of 3 for this specific case.
I assembly the markup into one string for output.

I’am not the master Coder but always eager to find out how to make it better.
If you have ideas and suggestions how it could be done smarter, i appreciate every idea.

  foreach($pages->children() as $item) {

    if($item->hasFiles()) {

      //make a array with the url strings inside
        foreach($item->images() as $image) {
          $imageStrings[] = $image->url();
        }

         if(count($imageStrings) == 3) {

           for($img=0; $img<count($imageStrings); $img++) {

                 switch($img) {
                   case 0:
                   $sectionWrapImages.= '<div class="scrollable__white__layout__images"><picture><source srcset="'. $imageStrings[$img] .' 2048w,';
                   break;

                   case 1:
                  $sectionWrapImages.= ' '. $imageStrings[$img] .' 820w,';
                  break;

                   case 2:
                   $sectionWrapImages.= ' '. $imageStrings[$img] .' 420w" type="image/jpeg" sizes="(min-width: 75em), (min-width: 51.250em), (min-width: 26.250em)">';
                   $sectionWrapImages.= '<img src="'. $imageStrings[$img] .'" alt="image alt text here"></picture></div>';
                   break;
               }

           }
             $imageStrings = [];

           } else {
             $imageStrings = [];
             $sectionWrapImages = '';
           }
    }

    $sectionWrapMarkup.= '<section class="scrollable__white__layout__base">';
      $sectionWrapMarkup.= $sectionWrapImages;
      $sectionWrapMarkup.= '<h4>'. $item->title()->html(). '</h4>';
      $sectionWrapMarkup.= '<p class="white__layout__text">'. $item->text()->html() .'</p>';
    $sectionWrapMarkup.= '</section>';
    // empty images string
    $sectionWrapImages = '';
  }

the result is a nice markup:

<picture>
<source srcset="http://localhost/kirby-project/content/1-production-infrastructure/1-audio/image-large.jpg 2048w,
 http://localhost/kirby-project/content/1-production-infrastructure/1-audio/image-mid.jpg 820w, 
http://localhost/kirby-project/content/1-production-infrastructure/1-audio/image-small.jpg 420w" 
type="image/jpeg" sizes="(min-width: 75em), (min-width: 51.250em), (min-width: 26.250em)">
<img src="http://localhost/kirby-project/content/1-production-infrastructure/1-audio/image-small.jpg" alt="image alt text here">
</picture>

best pascal


#2

Hm, I think this code can be easily messed up since there is no real mapping between the images and their sizes, you just check if there are three images, but these images can be anything and in any order.


#3

If the different image versions are based on the same image and just differ in sizes, you can upload only the biggest and use the thumb method to create the others automatically. I would also use hasImages() instead of hasFiles().

Finally, this would end up in something like this (untested!):

<?php foreach ($pages->children() as $item): ?>
  <section class="scrollable__white__layout__base">

    <!-- Images -->
    <?php if ($item->hasImages()): ?>
      <?php foreach ($item->images() as $image): ?>
        <picture>
          
          <!-- Use the original image for the large version and create a thumb for the smaller ones -->
          <source srcset="<?php echo $image->url(); ?> 2048w,
            <?php echo thumb($image, array('width' => 820))->url(); ?> 820w, 
            <?php echo thumb($image, array('width' => 420))->url(); ?> 420w" 
            type="image/jpeg" sizes="(min-width: 75em), (min-width: 51.250em), (min-width: 26.250em)">
            <?php echo thumb($image, array('width' => 420)); ?>
        </picture>
      <?php endforeach; ?>
    <?php endif; ?>

    <!-- Headline and text -->
    <h4><?php echo $item->title()->html() ?></h4>
    <p class="white__layout__text"><?php echo $item->text()->html() ?></p>
  
  </section>
<?php endforeach; ?>



#4

If image optimization is the reason why you went for your solution, you might want check out the ImageKit plugin: ImageKit - An Asynchronous Thumbs API

It’s a commercial plugin ($25), but you can test it for free. It can also be combined with the ImageSet plugin for responsive image support (bundle of the two plugins is $40).


#5

super community feedback!

@flokosiol thanks for the idea, i will use hasImages, makes perfect sense!

@texnixe the plugin looks nice and it would be the a alternative. My problem is that i can’t run those plugins yet.
I still don’t get how they work and i get so many error when i install them.
But when the site so far is implemented i will learn how to use plugins and update my stuff. Right now i don’t have the time to learn this.
Thank you for the tipp!

thank folks!
best, pascal


#6

If you need help with installing plugins, let us know. To do so, we would need to know what sort of errors you get, your Kirby and PHP version and the plugin that does not work as expected.

In general, plugins live in the /site/plugins folder, and the name of the plugin folders must match the name of its main file, e.g.

/site/plugins/feed/feed.php (for the feed plugin)


#7

@texnixe i know that this code is not perfect.
In this case i’am the content editor (lucky) and i can hande it with simply sorting them in the backend so they get used in the correct order.
also naming them manually and make proper (BEM) naming of the file with suffix --mid --small --large by hand.
I could also sort them before outputting, this is a temporary solution and must be better in the future.

best, pascal


#8

@texnixe
okey i give it another try, and post if something crashes.

thanks for the support!