Jump to content

images and thumbnails


Marty Walker
 Share

Recommended Posts

Hi,

I'm trying to get my head around something I know should be simple. I'm working on an a site for an artist who'd like to upload a custom thumbnail for each of his images. I've added a second field called 'artist_thumbnail'. In my template I want to test to see if there's a custom thumbnail and if not get processwire to generate one automatically.

PHP isn't my strong point. Am I even close with this code?

foreach($page->children("limit=32") as $folio_item) {

if($folio_item->artist_thumbnail) {
        $img = "<li><a rel='lightbox' title='{$folio_item->title}' href='{$image->url}'><img title='{$folio_item->title}' src='{$thumb->url}' alt='{$folio_item->title}'></a></li>";
} else if($folio_item->artist_image) {
        $thumb = $folio_item->artist_image->size(100, 100);
        $image = $folio_item->artist_image;
        $img = "<li><a rel='lightbox' title='{$folio_item->title}' href='{$image->url}'><img title='{$folio_item->title}' src='{$thumb->url}' alt='{$folio_item->title}'></a></li>";
    } 
// Output the image
echo "$img";
}

  • Like 1
Link to comment
Share on other sites

You are very close! The main issue that I see is that you are referencing $image in a context where it doesn't exist. See my comment in your code:

<?php
foreach($page->children("limit=32") as $folio_item) {
    if($folio_item->artist_thumbnail) {
        $img = "<li><a rel='lightbox' title='{$folio_item->title}' href='{$image->url}'><img title='{$folio_item->title}' src='{$thumb->url}' alt='{$folio_item->title}'></a></li>";
        // $image is an uninitialized variable in the line above. Did you mean it to be $folio_item->image?
    } else if($folio_item->artist_image) {
        $thumb = $folio_item->artist_image->size(100, 100);
        // you could also solve it by just moving this line below above the "if" statement:
        $image = $folio_item->artist_image; 
        $img = "<li><a rel='lightbox' title='{$folio_item->title}' href='{$image->url}'><img title='{$folio_item->title}' src='{$thumb->url}' alt='{$folio_item->title}'></a></li>";
    } 
    // Output the image
    echo "$img";
}

Here's how I might recode it:

<?php
foreach($page->children("limit=32") as $folio_item) {
    $image = $folio_item->image;
    $thumb = $folio_item->artist_thumbnail; 
    if(!$thumb) $thumb = $image;
    $thumb = $thumb->size(100, 100); 
    echo "<li><a rel='lightbox' title='{$folio_item->title}' href='{$image->url}'><img src='{$thumb->url}' alt='{$folio_item->title}'></a></li>";
}
Link to comment
Share on other sites

Thanks Ryan,

I get all sorts of errors if I try that code.

Exception: Method Pageimages::size does not exist or is not callable in this context (in /Users/me/Sites/ProcessWire/ryancramerdesign-ProcessWire-TEST/wire/core/Wire.php line 205)

#0 [internal function]: Wire->__call('size', Array)
#1 /Users/me/Sites/ProcessWire/ryancramerdesign-ProcessWire-TEST/site/templates/template.php(90): Pageimages->size(100, 100)
#2 /Users/me/Sites/ProcessWire/ryancramerdesign-ProcessWire-TEST/wire/core/TemplateFile.php(88): require('/Users/me/S...')
#3 /Users/me/Sites/ProcessWire/ryancramerdesign-ProcessWire-TEST/wire/core/Wire.php(241): TemplateFile->___render()
#4 /Users/me/Sites/ProcessWire/ryancramerdesign-ProcessWire-TEST/wire/core/Wire.php(203): Wire->runHooks(Array, Array)
#5 [internal function]: Wire->__call('render', Array)
#6 /Users/martin/Sites/ProcessWire/ryancramerdesign-ProcessWire-TEST/wire/modules/PageRender.module(144): TemplateFile->render('render', Array)
#7 /Users/martin/Sites/ProcessWire/ryancramerdesign-ProcessWire-TEST/wire/core/Wire.php
Link to comment
Share on other sites

Double check what you're calling size() on. This sort of error happens [mostly], when:

  • You have an error in your code – chance is, your field is called 'images' and you're calling 'image'
  • You have another type of error in your code – calling image function on ImageArray, for example [rather than $images->size, you want something like $images->eq(0)->size()
  • There is nothing uploaded yet. This happens, when your code is okay, but isn't prepared to receive no data, and, in fact, does receive no data

Also, there might be problem with what Ryan posted, but if history taught us anything, it's that Ryan's code is mostly ok. :D

  • Like 2
Link to comment
Share on other sites

Hi,

Thanks for your help. I've started from scratch. I have two fields, artist_image & artist_thumbnail. I get the same errors.

<?php
foreach($page->children as $artist_item) {
    $image = $artist_item->artist_image;
    $thumb = $artist_item->artist_thumbnail; 
    if(!$thumb) $thumb = $image;
    $thumb = $thumb->size(100, 100);
    echo "<li><a rel='lightbox' title='{$artist_item->title}' href='{$image->url}'><img src='{$thumb->url}' alt='{$artist_item->title}'></a></li>";
}
Link to comment
Share on other sites

You're welcome!

Just so you understood: As I suspected, $thumb was giving you ImageArray [or WireArray, or whatever the class is], rather than one image, thus giving error (WireArray doesn't have size() method). By putting eq(0) there, we selected first image (in null-based array) to be resized.

Link to comment
Share on other sites

Thank you again. Your explanation goes some way in helping me learn PW better and I appreciated it.

If I don't upload a thumbnail and get PW to generate a thumb I get the below error.

Call to a member function size() on a non-object 

<?php
foreach($page->children as $artist_item) {
    $image = $artist_item->artist_image;
    $thumb = $artist_item->artist_thumbnail; 
    if(!$thumb) $thumb = $image;
    $thumb = $thumb->eq(0)->size(100,100);
    echo "<li><a rel='lightbox' title='{$artist_item->title}' href='{$image->url}'><img src='{$thumb->url}' alt='{$artist_item->title}'></a></li>";
}
Link to comment
Share on other sites

Sorry my code example assumed we were dealing with a single image (due to the field name being 'image' rather than 'images'). I should have thought to post an example for both.

If your 'image' and 'artist_image' fields are designed just to hold a single image, I would recommend converting them to that to reduce confusion. To do this, edit those fields, and set the "maximum files allowed" to 1. After you do that, the API will reference it as a single image rather than an array of images. Following that, the original code example I posted should work.

If you want to keep them as multi-image fields, then you'd want to change that code example to this:

<?php
foreach($page->children("limit=32") as $folio_item) {
    $image = $folio_item->image->first(); 
    $thumb = $folio_item->artist_thumbnail->first(); 
    if(!$thumb) $thumb = $image;
    $thumb = $thumb->size(100, 100); 
    echo "<li><a rel='lightbox' title='{$folio_item->title}' href='{$image->url}'><img src='{$thumb->url}' alt='{$folio_item->title}'></a></li>";
}

The only difference between the above example and the original are the first two lines in the foreach(). They grab a single image out of the array, like this: $folio_item->image->first(), rather than just $folio_item->image. This is the same as doing eq(0) as in Adam's example, so use whatever syntax you prefer.

@adamkiss: thanks for your replies here!

Link to comment
Share on other sites

Where is this code going? Is it part of a template or used somewhere else? In templates, PW has something called outputFormatting turned on (unless you turn it off). Internally, all file/image fields are stored as arrays. But the file/image fieldtypes use this output formatting to convert a file array to a single file when you set the max files to 1. This is provided as a convenience for your templates. It's so that you don't have to think about arrays when they aren't relevant to your intended use. I've been assuming you are using this code in a template, but if you are using it somewhere else (like via bootstrapping PW separately) then that outputFormatting isn't going to be on by default. So I figured I should double check that we are talking about code in a template, just to make sure we're talking about the same thing? :)

The other thing to look at is that the file/image field is actually populated. I didn't do that in the example, but here's how you would:

<?php
foreach($page->children as $artist_item) {
    $image = $artist_item->artist_image;
    if(!$image) continue; // no image, so abort
    $thumb = $artist_item->artist_thumbnail; 
    if(!$thumb) $thumb = $image;
    $thumb = $thumb->size(100, 100);
    echo "<li><a rel='lightbox' title='{$artist_item->title}' href='{$image->url}'><img src='{$thumb->url}' alt='{$artist_item->title}'></a></li>";
}
Link to comment
Share on other sites

Hi Ryan,

It's in a template called artist_list. My pages are:

Portfolio - uses template artist_list.php

- artwork - child page uses template 'artist_work' with two fields - artist_image & artist_thumbnail

- artwork - etc

- artwork - etc

All I'd like to do is generate a thumbnail from the larger image if the thumbnail image isn't present. The child pages won't be viewed as such as I'm calling the larger image into Fancybox.

Link to comment
Share on other sites

Are these examples still not working? You may want to double check that your copy of PW is relatively up to date with the current source. If in doubt, you can always replace the /wire/ directory with a new one (along with /index.php and /.htaccess). Also, you may want to edit /site/config.php and set the line that says "$config->debug = false;" to be "$config->debug = true;". That will turn on stronger error reporting that can help a lot during development.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...