Adding a new thumbnail size

30 views
Skip to first unread message

Neil

unread,
Jul 9, 2009, 3:19:21 PM7/9/09
to Spree
Has anyone overwritten image attachment settings in a clean way? It
looks as though I'm going to need to set another thumbnail size in
image.rb (presuming that's where I should be making these changes),
and I was hoping I could use something like an alias_method_chain in
an extension rather than having to completely overwrite the image.rb.

Am I on the right track with this one? Does anyone have a fork with an
example of this?

Cheers

Paul Callaghan

unread,
Jul 9, 2009, 4:11:03 PM7/9/09
to spree...@googlegroups.com
The following in an extension activation works for me

Image.attachment_definitions[:attachment][:styles] = {:thumb =>
'60x60', :mini => '100x100', :small => '175x175', :product => '300',
:large => '500x500'}

Note that Image now stores the width and height of the original image,
from which you can calculate actual height for any of the styles -
including working out the height of the product style (which is
resized to a width of 300 and no restriction on height)

Paul

Neil

unread,
Jul 10, 2009, 6:54:23 AM7/10/09
to Spree
Thanks Paul

An extension activation is a new one to me; I can see a TODO on the
tutorial docs http://wiki.github.com/railsdog/spree/extension-tutorial,
how are they different from creating a new image.rb in my /vendor/
extensions/site/app/model/ ?

Also, are you overriding the [ render 'image' ] or [ render
'thumbnails' ] in the products/show.html.erb to get at the new size? I
haven't figured out how to override those yet, either.



On Jul 9, 9:11 pm, Paul Callaghan <paulcc....@googlemail.com> wrote:
> The following in an extension activation works for me
>
>        Image.attachment_definitions[:attachment][:styles] = {:thumb =>
> '60x60', :mini => '100x100', :small => '175x175', :product => '300',
> :large => '500x500'}
>
> Note that Image now stores the width and height of the original image,
> from which you can calculate actual height for any of the styles -
> including working out the height of the product style (which is
> resized to a width of 300 and no restriction on height)
>
> Paul
>

Paul Callaghan

unread,
Jul 10, 2009, 7:36:27 AM7/10/09
to spree...@googlegroups.com
Using my single line saves you the hassle of maintaining your own copy
of image.rb (eg what happens when the core version of it changes? will
you remember to update your copy etc?)

If using different image sizes, you will probably need to change
show.html, its partials, or some of the related style files - but this
is something that you will need to do to customize your site...

Paul

Neil

unread,
Jul 10, 2009, 9:19:42 AM7/10/09
to Spree
Thanks again. With regards to avoiding my own copy of image.rb; yes,
that is what I've been looking to achieve. Where do I put the single
line? I haven't worked out where this extension activation belongs in
the app.

Paul Callaghan

unread,
Jul 10, 2009, 9:43:28 AM7/10/09
to spree...@googlegroups.com
in the "activate" method of one of your project's extensions (eg SiteExtension)

Paul

Sean Schofield

unread,
Jul 10, 2009, 9:22:40 PM7/10/09
to spree...@googlegroups.com
Paul,

Are you still thinking about writing this up in the guides/blog post?
Ideally both. Documentation with snippets summary in blog post.

Sean

Paul Callaghan

unread,
Jul 11, 2009, 1:40:26 AM7/11/09
to spree...@googlegroups.com

> write up?

Of course - but was planning to get the new paperclip installed first and then write about that plus tips for image handling

Incidentally, how about making the core less "square"? there's a few places where the actual height of an image doesn't matter to the layout (key example: main image on product/show) so we can get paperclip to resize to width only and calculate the height of the bounding box dynamically. (Eg see http://www.parasolsdirect.co.uk/products/tradewind-parasol-2-6m-hexagonal). I'll ticket this if it doesn't get shot down instantly!

Paul

Sean Schofield

unread,
Jul 11, 2009, 9:28:18 AM7/11/09
to spree...@googlegroups.com
> Incidentally, how about making the core less "square"? there's a few places
> where the actual height of an image doesn't matter to the layout (key
> example: main image on product/show) so we can get paperclip to resize to
> width only and calculate the height of the bounding box dynamically. (Eg see
> http://www.parasolsdirect.co.uk/products/tradewind-parasol-2-6m-hexagonal).
> I'll ticket this if it doesn't get shot down instantly!

+1

> Paul

Sean

Michael Lang

unread,
Jul 11, 2009, 9:34:06 AM7/11/09
to spree...@googlegroups.com
+1

For what its worth, I changed my to percentages...

:styles => { :mini => '5x5%',
:small => '10x10%',
:product => '24x24%',
:large => '60x60%'
},

Works for rectangular and square images equally well. ;-)

Michael
--
http://codeconnoisseur.org

Neil

unread,
Jul 11, 2009, 10:53:35 AM7/11/09
to Spree
I hadn't spotted the 'activate' part before, thanks for the pointer.
I'm approaching this project with the intention of keeping as much as
possible in one extension, so as to keep it as closely aligned to the
way Rails apps are handled (plus I'm finding jumping from extension-to-
extension to be very confusing) - but hopefully the image.rb cropping
override is only one of a few 'activate' methods required at all, and
it shouldn't get too cluttered.

With regards to making the spree core less square; coming from someone
who has found this to be a tricky project to get in to, I'd say there
needs to be fewer decisions made with regards to the views and
rendering. Image sizes will be entirely dependent on the application
in question; views are the one part that will be unique to every Spree
app. Try to make any pre-defined thumb-nailing decisions as close to a
'universally applicable' image set as possible - otherwise you'll just
be creating more code which other people will only 'un-do' in their
activate methods.


On Jul 10, 2:43 pm, Paul Callaghan <paulcc....@googlemail.com> wrote:
> in the "activate" method of one of your project's extensions (eg SiteExtension)
>
> Paul
>

Michael Lang

unread,
Jul 11, 2009, 12:10:19 PM7/11/09
to spree...@googlegroups.com
Why not simply this problem by storing the Image properties in the
Spree::Config?

in other words:

11:54:35:shop >> script/console
Loading development environment (Rails 2.3.2)
>> Spree::Config.set(:image_styles => { :mini => '5x5%', :small => '10x10%', :product => '24x24%', :large => '60x60%' })
=> nil
>> Spree::Config[:image_styles]
=> "--- \n:mini: 5x5%\n:large: 60x60%\n:small: 10x10%\n:product: 24x24%\n"
>> YAML::Load(Spree::Config[:image_styles])
NoMethodError: undefined method `Load' for YAML:Module
from (irb):3
>> YAML::load(Spree::Config[:image_styles])
=> {:mini=>"5x5%", :large=>"60x60%", :small=>"10x10%", :product=>"24x24%"}
>> quit

Which means....

class Image < Asset
has_attached_file :attachment,
:styles => YAML::load(Spree::Config[:image_styles]),
:default_style => :product,
:url => "/assets/products/:id/:style/:basename.:extension",
:path => ":rails_root/public/assets/products/:id/:style/:basename.:extension"
end

If we extend this and store default_style, url, and path in
Spree::Config, then setting the values in an initializer file or
migration file is all that's needed for complete customization by
anyone.

Spree::Config.set(:image_styles => { :mini => '5x5%', :small =>
'10x10%', :product => '24x24%', :large => '60x60%' })
Spree::Config.set(:image_default_style => :product)
Spree::Config.set(:image_url =>
"/assets/products/:id/:style/:basename.:extension")
Spree::Config.set(:image_path =>
":rails_root/public/assets/products/:id/:style/:basename.:extension")

and the Image model then becomes:

class Image < Asset
has_attached_file :attachment,
:styles => YAML::load(Spree::Config[:image_styles]),
:default_style => Spree:Config[:image_default_style],
:url => Spree.Config[:image_url],
:path => Spree.Config[:image_path]
end

Michael
--
http://codeconnoisseur.org

Neil

unread,
Jul 11, 2009, 12:18:01 PM7/11/09
to Spree
That sounds super duper.

Paul Callaghan

unread,
Jul 11, 2009, 4:34:59 PM7/11/09
to spree...@googlegroups.com
On Sat, Jul 11, 2009 at 5:10 PM, Michael Lang<mwl...@cybrains.net> wrote:
>
> Why not simply this problem by storing the Image properties in the
> Spree::Config?

Image sizes are fairly fundamental to a site's design/layout, and I
don't think it's productive to allow too much flexibility to change
them. Plus, what happens when the admininstrator (not necessarily the
developer) chooses to change a size? or opts to choose a different
asset location? should all of the images be resized/recomputed?

IMHO, paperclip gives sufficient hooks to allow developers to change
what they need to change.

Note that we can now put initializers in extensions, so we can
probably put the styles changes there rather than in activate.

Paul

Michael Lang

unread,
Jul 14, 2009, 10:22:15 AM7/14/09
to spree...@googlegroups.com
> Image sizes are fairly fundamental to a site's design/layout, and  I
> don't think it's productive to allow too much flexibility to change

Every time I set up a new spree store, I'm going to have to tweak the
sizes...and its usually done at the outset when doing the site design
and layout. Seems to me the easier we make it to configure Spree w/o
having to resort to writing code, the better.

> IMHO, paperclip gives sufficient hooks to allow developers to change
> what they need to change.
>

Right. That's not the problem being solved, though. ;-) The problem
is what are those image sizes gonna be? It just seems to me that
writing an extension to change image sizes is overly complex compared
to a simple migration script (or initializer to specify the sizes),
not to mention easier to document.

Michael
--
http://codeconnoisseur.org

Eliot Sykes

unread,
Sep 10, 2009, 11:52:18 AM9/10/09
to Spree
Note to others who might try doing this in an extension's initializer
script, it didn't work for me.

I didn't take the time to investigate why, however if you put in the
activate method of an extension as stated earlier it will work.

e.g. adding an xl size:

class SiteExtension < Spree::Extension
def activate
Image.attachment_definitions[:attachment][:styles] =
{ :mini => '48x48>', :small => '100x100>', :product =>
'240x240>',
:large => '600x600>', :xl => '1200x1200>' }
end
end
Reply all
Reply to author
Forward
0 new messages