I'm using Paperclip with a Ruby on Rails to attach assets to a model, these assets can be any file type and currently thumbnails are only being generated if the asset is an image. I'd like to be able to display a different default image for other files, either by generating a thumbnail of the files on upload, or setting something up with the default_url but so far I can't find any resources to help with this and am getting no where on my own.
My model is as follows:
class Asset < ActiveRecord::Base
has_attached_file :media,
:storage => :s3,
:s3_credentials => "#{RAILS_ROOT}/config/s3.yml",
:path => ":attachment/:id/:style.:extension",
:bucket => S3_BUCKET,
:styles => {:thumb => "75x75>", :large => "600x800>",
:whiny => false,
:default_url => "/images/:attachment/missing.jpg"
Does anyone have any resources for generating custom thumbnails if generation fails, or fall back on something like :content_type in the default url? I've looked through the source and haven't been able to get anywhere.
Thanks!
I've actually implemented this very same feature. Paperclip generates thumbnails for all my images and PDFs, and I have added custom thumbnail icons for MS Word, Excel, HTML, TXT files etc.
My solution is fairly straightforward. In my model Attachment
(in your case Asset
) I have defined the following method:
def thumbnail_uri(style = :original)
if style == :original || has_thumbnail?
attachment.s3.interface.get_link(attachment.s3_bucket.to_s, attachment.path(style), EXPIRES_AFTER)
else
generic_icon_path style
end
end
This returns either a URL to a thumbnail stored on S3, or a local path to a generic PNG icon based on the assets content type (discussed below). The has_thumbnail?
method determines whether or not this asset has had a thumbnail generated for it. This is something I added in my own fork of Paperclip, but you can substitute in your own logic (I'm not sure of the 'standard' way to determine this, maybe comparing the path with your defined 'missing' path, or even just comparing the content type to a default list ["image/jpeg", "image/png"] etc).
Anyway, here's the method which passes back a path to a generic icon based on both the thumbnail style (in your case :thumb and :large) and the content type:
# Generates a path to the thumbnail image for the given content type
# and image size.
#
# e.g. a :small thumbnail with a content type of text/html, the file name
# would have the filename icon.small.text.html.png
#
# If no such thumbnail can be found a generic one is returned
def generic_icon_path(style = image.default_style)
url = "/images/attachments/icon.#{style.to_s}.#{attachment_content_type.sub('/', '.')}.png"
if File.exists? "#{RAILS_ROOT}/public/#{url}"
url
else
"/images/attachments/icon.#{style.to_s}.default.png"
end
end
Then, to add a new thumbnail I just add PNG files into /images/attachments/
with the correct file name convention. My thumbail style is called :small and I have defined styles for Word, Excel and plain text so at the present time I have:
icon.small.application.msword.png
icon.small.text.plain.png
icon.small.application.vnd.ms-excel.png
icon.small.application.vnd.openxmlformats-officedocument.spreadsheetml.sheet.png
icon.small.application.vnd.openxmlformats-officedocument.wordprocessingml.document.png
If the content type isn't supported, there's a generic 'catch all' icon which is displayed:
icon.small.default.png
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With