Jump to content

How do I interact with the image field in processwire?


ryan
 Share

Recommended Posts

How do I interact with the image field in processwire? For instance, I have a Javascript gallery that takes a certain size image and it's thumbnail to make a browseable gallery. I know PW creates a thumbnail somewhere...but how do I configure the size and access it from the front end?

To interact with the images field. Create a new field (under Setup > Fields) and call it whatever you want, like "images" for example. Set the field type as "image". Add this field to a template (under Setup > Templates). Then edit a page using that template and upload some images.

In your template code:

ProcessWire will create your images at any size on the fly and then keep a cache of them. For instance, lets say we want to cycle through all the images, create a large image at 500 pixel width with proportional height, and a thumbnail at 100x100, and then have the thumbnail link to the large:

<?php
foreach($page->images as $image) {
$large = $image->width(500);
$thumb = $image->size(100, 100);
echo "<a href='{$large->url}'><img src='{$thumb->url}' alt='{$thumb->description}' /></a>";
}
  • Like 3
Link to comment
Share on other sites

  • 2 months later...

Hi ryan,

I have one question about the way images are managed in PW: if I understand, the resized images are cached in the same folder as the images used by a page (folder named by page ID, under the "site/assets/files" folder is that it ?); in case I've uploaded an image called "MyPhoto.jpg" and use it in my template as a 100 pixels wide thumbnail, I'll get a file called "MyPhoto.100x0.jpg"... But what if I now want to upload an image called "MyPhoto.100x0.jpg" ? Do you already manage this case ?

Or if I upload a new image called "MyPhoto.250x78.jpg", will it be erased if I delete the previous "MyPhoto.jpg" ?

Link to comment
Share on other sites

I believe, that the general idea is: why would you do such thing?

Just upload image/photo/artwork of maximum size and let the system create all needed size (because I believe that the only situation where you might upload image with size is if you have defined the size yourself…)

Link to comment
Share on other sites

I see it as a valid and possible scenario that client uploads file with similar name. This was also very quick to test and this was result:

I uploaded file "hyatt_interior9.0x100.jpg" to page 1 of demosite (which already had that file) and result was: "hyatt_interior9.0x1001.jpg". So it adds running number on filename.

Link to comment
Share on other sites

I believe, that the general idea is: why would you do such thing?

Just upload image/photo/artwork of maximum size and let the system create all needed size (because I believe that the only situation where you might upload image with size is if you have defined the size yourself…)

I didn't say that I wanted to upload the same image with another resolution, just that I wanted to upload another image with a similar filename. As Apeisa said, a client could upload such a file.

I see it as a valid and possible scenario that client uploads file with similar name. This was also very quick to test and this was result:

I uploaded file "hyatt_interior9.0x100.jpg" to page 1 of demosite (which already had that file) and result was: "hyatt_interior9.0x1001.jpg". So it adds running number on filename.

Ok so that answers the first part... But I believe there could be a problem with the second: in Pageimage.php there is a removeVariations function that "deletes all the alternate sizes associated with this Pageimage", based on a regular expression. So, still if I understand correctly, if you delete "hyatt_interior9.jpg", won't it delete "hyatt_interior9.0x1001.jpg" too ? (it's ok to delete "hyatt_interior9.0x100.jpg", but not "hyatt_interior9.0x1001.jpg" which is supposed to be a totally different image, not a variation !)

Link to comment
Share on other sites

The idea was that the cached filenames would be system-specific enough that it would be unlikely you'd choose the same filename as one already in the system using the same dimension format. But not so system specific that you could immediately identify what CMS it is based on the filenames. Given that, ProcessWire will assume these images are related and when the first is deleted, the other should be too:

hello.jpg

hello.[width]x[height].jpg

While it seems like an unlikely scenario, it's not impossible that someone would upload another image to the same page called hello.123x456.jpg ... especially if they had perhaps downloaded it from another site running ProcessWire. If they did, and it matched the filename already on the given page (but with .[width]x[height].jpg appended to it) then it would get deleted when they deleted hello.jpg. That would be an error.

In the latest commit, I fixed this by having ProcessWire filter out any extra dots in filenames during the upload or the $page->files->add("new file name") process. Without the extra dot there, ProcessWire isn't going to recognize it as being an image cache file, so this error should no longer be possible. Thanks for the finding this.

Ryan

Link to comment
Share on other sites

(which consisted in checking if the variations found were not also listed as page "main" images)

I was thinking about this option too, as it sounds like a good one. But then another thing occurred: what if they first uploaded hello.0x100.jpg and then later uploaded hello.jpg? Then we'd indirectly run into the same problem. I figured the safest bet is probably just to disallow uploading/adding images to PW that are in the same format that it's image cache generates, and removing any dots from the filename (other than the extension) seems to solve it. In that case, the uploaded hello.0x100.jpg becomes hello_0x100.jpg, which ProcessWire wouldn't recognize as one of it's cached images. I figured removing dots from the filename has other security benefits too, and your suggestion motivated the change.

Thanks,

Ryan

Link to comment
Share on other sites

Thank you, that's kind of you to say. But I think you are giving me too much credit. You deserve the credit here for discovering this issue here that I missed, so thanks for that.

Link to comment
Share on other sites

Thanks that's very generous of you. If you ever find parts that aren't smart (there always are some) please let me know too. I sometimes come across my code (whether on this project or others) where I look at it and think to myself "what the hell was I thinking?".  ;D I avoid coding at night for this reason.

Link to comment
Share on other sites

  • 9 months later...
  • 3 months later...

Is the general consensus here that it is preferable to declare width and height within the PHP?

I wanted to just output width and height without declaring another variable (ie: thumb or large) yet I couldn't seem to get it working so I reverted to good old HTML. Was just wondering what the standard way of declaring width and height would be within PW.

Think I've just figured this out:

$page->test_image->size(400,300)

Is that the right way?

Link to comment
Share on other sites

Off the top of my head I'd say that that looks correct. It should scale down until width or height hits one of those dimensions, then crop the other axis (so either a bit off the top and bottom, or a bit off either side) to become that exact size.

It works well for most things as photos usually have the focus of the image in the center. Where it can cause issues though is a portrait photo for example (as in a head and shoulders shot of a person, not talking about landscape/portrait in terms of image orientation ;). I've had one where it chopped the top of the person's head off since I wanted all images to be cropped to a specific width and height, so you have to be careful or instead use Apeisa's wonderful Thumbnails module so you can specify image crops and custom-crop images in the admin.

Link to comment
Share on other sites

Is the general consensus here that it is preferable to declare width and height within the PHP?

I wanted to just output width and height without declaring another variable (ie: thumb or large) yet I couldn't seem to get it working so I reverted to good old HTML. Was just wondering what the standard way of declaring width and height would be within PW.

Think I've just figured this out:

$page->test_image->size(400,300)

Is that the right way?

Not sure what you are after, but no matter have you resized the image or not, you can access it's width and height easily:

<?php
$img = $page->test_image;
?>
<img src="<?= $img->url; ?>" width="<?= $img->width(); ?>" height="<?= $img->height(); ?>" alt="" />

Also if you need images in specific width or height you can resize them like this:

$img = $page->test_image->width(200);
OR
$img = $page->test_image->height(200);
  • Like 1
Link to comment
Share on other sites

When I want a max-size i use images like this:

if($image->width > 500) $image = $image->width(500);
echo "<img src='$image->url' alt='$image->description'>";

and on the css:

img { max-width:500px; }
Link to comment
Share on other sites

Thanks guys, I'm running into a few problems setting image dimensions within the foreach loop.

If I want to set it, should it be before the loop is called or after?

<?php

$blog_entry = $page->children();

foreach ($blog_entry as $entry) {
$image = $entry->single_image->size(200,100);
   echo "<div class='blog_box'>";
   echo "<div class='blog_text'>";
   echo "<h3>$entry->title</h3>";
   echo "<p>$entry->body</p>";
   echo "</div>";
   echo "<img src='$image->url' alt='alt text' />";
   echo "<div class='clear'></div>";
   echo "</div>";
}

?>
Link to comment
Share on other sites

This is my new code but the page won't load :

foreach ($page->children as $entry)

{ 
// add classes to first and last boxes.
$class = 'blog_box';
if ($entry == $page->children->first()) { $class .= ' blog_box_first'; }
 elseif ($entry == $page->children->last()) { $class .= ' blog_box_last'; }
 else { $class .= ''; }

 // make blog images 200 X 150
 $image = $entry->single_image->size(200,150);

   echo "<div class='$class'>";
  echo "<div class='blog_text'>";
  echo "<h3>$entry->title</h3>";
  echo "<p>$entry->body</p>";
  echo "</div><!-- /.blog_text -->";
  echo "<img src='$image->url' alt='alt text' />";
  echo "<div class='clear'></div>";
  echo "</div><!-- /.blog_box -->";
}

If I leave out the resizing however, the image is called and the page works :

foreach ($page->children as $entry)

  {
   // add classes to first and last boxes.
   $class = 'blog_box';
   if ($entry == $page->children->first()) { $class .= ' blog_box_first'; }
   elseif ($entry == $page->children->last()) { $class .= ' blog_box_last'; }
   else { $class .= ''; }
   // make blog images 200 X 150
   $image = $entry->single_image;	  echo "<div class='$class'>";
  echo "<div class='blog_text'>";
  echo "<h3>$entry->title</h3>";
  echo "<p>$entry->body</p>";
  echo "</div><!-- /.blog_text -->";
  echo "<img src='$image->url' alt='alt text' />";
  echo "<div class='clear'></div>";
  echo "</div><!-- /.blog_box -->";
 }
Link to comment
Share on other sites

While developing, it is good practice to put debug mode on from /site/config.php - that way you see error messages directly on the screen.

Are you sure you are using image field and not file field? Because if ->url works but resize doesn't, then it seems to behave just like file field. So check that your fieldtype is set to image instead of file?

Link to comment
Share on other sites

While developing, it is good practice to put debug mode on from /site/config.php - that way you see error messages directly on the screen.

Are you sure you are using image field and not file field? Because if ->url works but resize doesn't, then it seems to behave just like file field. So check that your fieldtype is set to image instead of file?

Thanks Apeisa, I just checked and it is set to image, can ->size not be called in that way?

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...