Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

[Solved] Image Thumbnails in Gridfield


Go to End
Reply


23 Posts   6555 Views

Avatar
tmkp

Community Member, 42 Posts

27 June 2012 at 3:51am

Edited: 27/06/2012 4:00am

Hi everybody,
currently playing around with the gridfield on 3.0.0rc2 on a local xampp, but I can't figure out how to get image thumbnails to show up in the list view.

The custom getter method that used to work for DOM gives me a "Image_Cached" instead of an actual image, and the other solutions i found around the web will print out an image tag with "<" and ">" translated to html entities "&lt;" and "&gt;"

Thumbnail generation and image resizing is working fine otherwise.

Anybody else have problems with this?

Here's the code, based on [url=http://www.inforbiro.com/blog-eng/silverstripe-gridfield-tutorial/]this example[/url]

<?php

class Contact extends DataObject {

// Contact object's fields
public static $db = array(
'Name' => 'Varchar(255)',
'Description' => 'Text',
'Website' => 'Varchar(255)'
);

// One-to-one relationship with profile picture and contact list page
public static $has_one = array(
'ProfilePicture' => 'Image',
'ContactListPage' => 'ContactListPage'
);

// Summary fields
public static $summary_fields = array(
   'Thumbnail' => 'DOMThumbnail',
'Name' => 'Name',
'Description' => 'Description',
'Website' => 'Website URL'
);

public function getCMSFields_forPopup() {

// Profile picture field
$thumbField = new UploadField('ProfilePicture', 'Profile picture');
$thumbField->allowedExtensions = array('jpg', 'png', 'gif');

// Name, Description and Website fields
return new FieldList(
new TextField('Name', 'Name'),
new TextareaField('Description', 'Contact description'),
new TextField('Website', 'Website URL (including http://)'),
$thumbField
);
}

public function getThumbnail() {
if ($Image = $this->ProfilePicture()->ID) {
return $this->ProfilePicture()->SetWidth(80)->Tag;
} else {
return '(No Image)';
}
}

}

<?php

class ContactListPage extends Page {

// One to many relationship with Contact object
public static $has_many = array(
'Contacts' => 'Contact'
);

// Create Grid Field
public function getCMSFields() {
$fields = parent::getCMSFields();

$gridFieldConfig = GridFieldConfig::create()->addComponents(
new GridFieldToolbarHeader(),
new GridFieldAddNewButton('toolbar-header-right'),
new GridFieldSortableHeader(),
new GridFieldDataColumns(),
new GridFieldPaginator(10),
new GridFieldEditButton(),
new GridFieldDeleteAction(),
new GridFieldDetailForm()
);

$gridField = new GridField("Contacts", "Contact list:", $this->Contacts(), $gridFieldConfig);
$fields->addFieldToTab("Root.Contacts", $gridField);

return $fields;
}
}

class ContactListPage_Controller extends Page_Controller {

public static $allowed_actions = array (
);

public function init() {
parent::init();
}
}

Thanks in advance!
Andi

Avatar
Fuzz10

Community Member, 787 Posts

27 June 2012 at 9:01pm

Edited: 27/06/2012 9:01pm

Yeah, I also noticed custom getters in $summary_fields do not seem to work anymore in SS3. Subscribing.

Avatar
martimiz

Forum Moderator, 1132 Posts

28 June 2012 at 5:10am

Experimenting wth ModelAdmin - the custom getter is called, but the gridfield seems to want to treat the return value as string(???). And if you return the tag, as in something I tried here:

return $this->WhiskyImage()->getFormattedImage('SetSize', 50, 50)->forTemplate();

It displays the litteral image tag using "&lt;" and "&gt;" as you mention. Subscribing as well :-)

Avatar
jak

Community Member, 46 Posts

28 June 2012 at 7:08am

Edited: 30/07/2012 12:06am

EDIT 20120729: This bug will be fixed in 3.0.1. This workaround is only needed if you are running 3.0.0.

One way to get around the escaping that GridField does by default, is to use setFieldFormatting. I had a slightly different problem, adapting my solution to your example should look something like:

$gridField = new GridField(...)
$gridField->getConfig()->getComponentByType('GridFieldDataColumns')->setFieldFormatting(array(
   'DOMThumbnail' => function($val, $obj) { //if this does not work try Thumbnail instead
      if($obj instanceof Contact){
         return $obj->getThumbnail();
      } else {
         return $obj;
      }
   },
));

I am not sure if this is the most elegant solution (it is probably possible to do this without the inline function) but it should work.

BTW: You can also just use the builtin CMSThumbnail():

return $obj->ProfilePicture()->CMSThumbnail();


Edit 20120729: I removed a call to Tag() since this might break in 3.0.1

Avatar
tmkp

Community Member, 42 Posts

28 June 2012 at 7:50pm

That seems to do the trick, although it's kind of a long way to go for a thumbnail : )

Working example below, I also implemented UndefinedOffset's [url=https://github.com/UndefinedOffset/SortableGridField]Sortable Gridfield Module[/url] for giggles.

Thanks for the help!

<?php

class Contact extends DataObject {

   // Contact object's fields
   public static $db = array(
      'Name' => 'Varchar(255)',
      'Description' => 'Text',
      'Website' => 'Varchar(255)',
      'SortID' => 'Int'
   );

   // One-to-one relationship with profile picture and contact list page
   public static $has_one = array(
      'ProfilePicture' => 'Image',
      'ContactListPage' => 'ContactListPage'
   );

   // Summary fields
   public static $summary_fields = array(
      'Thumbnail' => 'Thumbnail',
      'Name' => 'Name',
      'Description' => 'Description',
      'Website' => 'Website URL'
   );

   public function getCMSFields_forPopup() {

      // Profile picture field
      $thumbField = new UploadField('ProfilePicture', 'Profile picture');
      $thumbField->allowedExtensions = array('jpg', 'png', 'gif');

      // Name, Description and Website fields
      return new FieldList(
         new TextField('Name', 'Name'),
         new TextareaField('Description', 'Contact description'),
         new TextField('Website', 'Website URL (including http://)'),
         $thumbField
      );
   }

   public function getThumbnail() {
      if ($Image = $this->ProfilePicture()->ID) {
         return $this->ProfilePicture()->SetWidth(80)->Tag;
      } else {
         return '(No Image)';
      }
   }

}

<?php

class ContactListPage extends Page {

   // One to many relationship with Contact object
   public static $has_many = array(
      'Contacts' => 'Contact'
   );

   // Create Grid Field
   public function getCMSFields() {

      $fields = parent::getCMSFields();

      $gridFieldConfig = GridFieldConfig::create()->addComponents(
         new GridFieldToolbarHeader(),
         new GridFieldAddNewButton('toolbar-header-right'),
         //new GridFieldSortableHeader(),
         new GridFieldDataColumns(),
         //new GridFieldPaginator(10),
         new GridFieldEditButton(),
         new GridFieldDeleteAction(),
         new GridFieldDetailForm(),
         new GridFieldSortableRows('SortID')
      );

      $gridField = new GridField("Contacts", "Contact list:", $this->Contacts(), $gridFieldConfig);

      $gridField->getConfig()->getComponentByType('GridFieldDataColumns')->setFieldFormatting(array(
         'Thumbnail' => function($val, $obj) {
            if($obj instanceof Contact){
               return $obj->getThumbnail();
            } else {
               return $obj;
            }
         },
      ));

      $fields->addFieldToTab("Root.Contacts", $gridField);

      return $fields;
   }
}

class ContactListPage_Controller extends Page_Controller {

   public static $allowed_actions = array (
   );

   public function init() {
      parent::init();
   }
}

Avatar
martimiz

Forum Moderator, 1132 Posts

29 June 2012 at 1:16am

Edited: 29/06/2012 1:17am

I think I just stumbled on what might be the right wy to do this, and it works in ModelAdmin:

class MyObject extends DataObject {

   static $has_one = array(
      'MyImage' => 'Image'
   );

   static $summary_fields = array(
      'MyImage.StripThumbnail' => '',
      'Name' => 'Name'
   );
}

Or, if you want a custom imagesize:

class MyObject extends DataObject {

   static $has_one = array(
      'MyImage' => 'CustomImage'
   );

   static $summary_fields = array(
      'MyImage.CustomThumbnail' => '',
      'Name' => 'Name'
   );
}

class CustomImage extends Image {
   public function generateCustomThumbnail(GD $gd) {
      return $gd->croppedResize(50, 50);
   }
}

Only thing is - for me this works on MAMP, but not on my DEBIAN/PHP5.3/Lighttpd install, where I just get an empty cell - this happens in the Files section as well, so the solution should be right, and my Lighttpd setup cause problems... aaargh)

Avatar
tmkp

Community Member, 42 Posts

29 June 2012 at 1:22am

Hi martimiz,
i remember trying this approach on a xampp a couple days ago, but empty cells for me as well.
It is the way it's supposed to work though, i guess.

Avatar
Fuzz10

Community Member, 787 Posts

29 June 2012 at 1:23am

Can someone change the thread's title again ? This is not solved yet. ;-)

Go to Top