Page Section: Thumbnail Preview from URL

The Image block allows you to upload an image OR use a public url.

The Page Section query option lets me pull in whatever image I’d like but if the block image uses a URL instead of an uploaded file, no preview is shown.

How would I got about creating a simple preview image for use with Page Section from only an URL?

I don’t think this is possible out of the box because the image property expects a file object. I also tried with creating a file object or assets from a url, but that didn’t work either (does work on the frontend though), that’s probably because the Panel always creates thumbs instead of using a file. But even a File::version component that return the file didn’t help.

I guess you would have to overwrite the pages section, unless someone else has a better idea.

Oh, that stinks. I figured that since it was built to use external URLs, there’s got to be a way to preview those images too. :frowning: Perhaps it’s relatively easy for the Kirby Devs to add something for this? Could make it a feature request.

Could you post the query you are using please? I think the issue I had was related to something else

Here’s the page method I’m using:

Here’s the query in the blueprint:
CleanShot 2022-05-04 at 14.37.42@2x

That doesn’t make sense. Your method returns a lot of different things, sometimes an file object, sometimes a string, but in your query you try to convert it to a file object. And apart from that, the code has far too many unnecessary if-else statement.

I suppose

  • $this->page_thumbnail() is files field?
  • What is $this->cover() and why do you call the image() method on it?
  • then we have a block that can return either a file url or an image object
  • and then the background block where I have no idea what sort of field this contains

Could you please post the code snippets as code, not screenshots?

Leaving out the background stuff for the moment, your method should look look something like this:

 'panel_thumbnail' => function () {

      if ($image = $this->page_thumbnail()->toFile()) {
        return $image;
      }
      if ($cover = $this->cover()) {
        return $cover;
      }
      $imageBlock = $this->text()->toBlocks()->filterBy('type', 'image')->first();
      if ($imageBlock && $image = $imageBlock->image()->toFile()) {
        return $image;
      }
      if ($imageBlock && $image = new Kirby\Cms\File([
            'filename' => 'panel.png',
            'parent'   => $this,
            'url'      => $imageBlock->src()
          ])) {
        return $image;
      }
    }

Since we return early, there is no need for all the if-else statements.

Good feedback. Thanks for clarifying. The page_thumbnail and cover are file fields that are used on certain pages and should override other thumbnails. The background block is basically a customized image block.

Using Ray() I can see it creates a file as expected, but the thumbnail is blank:

CleanShot 2022-05-04 at 16.48.00@2x

I tried using query: page.panel_thumbnail.toFile() and query: page.panel_thumbnail.

I can call $page->panel_thumbnail() in my template and it outputs the image as expected:

Not sure if this helps but here’s the URL i’m testing with: https://picsum.photos/seed/1342897788/800/600/

If cover is also a files field, then the cover part should be

  if ($cover = $this->cover()->toFile()) {
        return $cover;
      }

Ah, I think I mentioned it before. The problem in the Panel is that the Panel needs a thumbnail, not the full image and the reason it worked in my testcode is that I had a file::version component in place that returns the full file object in these cases.

    'components' => [
      'file::version' => function ( $kirby, $file, array $options = []) {

        static $original;

        if ($file->filename() === 'panel.png') {
          return $file;
        }
        if ($original === null) {
          $original = $kirby->nativeComponent('file::version');
        }

        // and return it with the given options
        return $original($kirby, $file, $options);
      }

    ]
1 Like

@texnixe that worked to get the url based image working! Thanks!

A side effect I’m seeing now is all of the normal images are show up a solid color:

CleanShot 2022-05-05 at 07.17.14@2x

Can you explain how the file::version code works? I guess something is not working with…

if ($original === null) {
    $original = $kirby->nativeComponent('file::version');
}

I think it has something to do with some other CDN code. Investigating.

Probably, because the code should actually work otherwise.

Yeah it was something with our CDN code causing the other images not to work. Here’s the final result:

'pageMethods' => [
    'panel_thumbnail' => function () {
        // Get Page Thumbnail
        if ($thumb = $this->page_thumbnail()->toFile()) {
            return $thumb;
        }
        // Get Cover Image
        if ($cover = $this->cover()->toFile()) {
            return $cover;
        }   

        // Get Image from Image Block
        if ($this->page_content()) {
            $blocks = $this->page_content()->toBlocks();

            $imageBlock = $blocks->filterBy('type', 'image')->first();
            // Image Block as File
            if ($imageBlock && $imageBlock->location() == 'kirby' && $imageBlock->image() && $image = $imageBlock->image()->toFile()) {
                return $image;
            }
            // Image Block as URL
            if ($imageBlock && $imageBlock->location() == 'web' && $imageBlock->src() && $image = new File([
                'filename' => 'panel.png',
                'parent'   => $this,
                'url'      => $imageBlock->src()
                ])) {
                return $image;
            }
        }

        // Get Image from Background Block
        $backgroundBlock = $blocks->filterBy('type', 'background')->first();
        if ($backgroundBlock && $backgroundBlock->image() && $bg = $backgroundBlock->image()->toFile()) {
            return $bg;
        }

        // Give every page an image for testing purposes
        return new File([
            'filename' => 'panel.png',
            'parent'   => $this,
            'url'      => "https://picsum.photos/seed/{$this->id()}/400/300/"
        ]);
    }
],
'components' => [
    'file::version' => function ( $kirby, $file, array $options = []) {

        static $original;

        if ($file->filename() === 'panel.png') {
        return $file;
        }

        // Is this a custom-cdn image?
        $url = CustomCDN::getFileUrl($file);
        
        // If not...
        if ($url === false) {
            if ($original === null) {
                $original = $kirby->nativeComponent('file::version');
            }

            // Return it with the given options
            return $original($kirby, $file, $options);
        }

        // Just like we do in custom-cdn/index.php
        return new FileVersion([
        'modifications' => $options,
        'original'      => $file,
        'root'          => $file->root(),
        'url'           => $url,
        ]);
    }  
],

Thanks @texnixe!

This will always return true (because a field object is always true even if it has an empty value) and is therefore useless.

Same for these:

1 Like