Fazendo thumbnails de tamanho fixo com attachment_fu
O plugin attachment_fu é quase que o plugin padrão para tratar do upload de arquivos em aplicações Rails. Ele suporta também o resize de imagens mantendo as proporções, mas não suporta crop. Sempre precisamos criar avatar ou coisas semelhantes. E em geral o avatar tem um tamanho fixo, como 80x80. Para isso é necessário fazer o crop da imagem. Adicione o método resize_image, como abaixo, no seu modelo:
class Photo < ActiveRecord::Base
belongs_to :owner, :class_name => "Person"
has_attachment :content_type => :image,
:processor => :rmagick,
:storage => :file_system,
:resize_to => '600>',
:thumbnails => {
:album => 'crop: 150x150',
:icon => '72>' }
protected
def resize_image(img, size)
# resize_image take size in a number of formats, we just want
# Strings in the form of "crop: WxH"
reg = /^crop: (\d*)x(\d*)/i
if (size.is_a?(String) && size =~ reg) ||
(size.is_a?(Array) && size.first.is_a?(String) &&
size.first =~ reg)
img.crop_resized!($1.to_i, $2.to_i)
# We need to save the resized image in the same way the
# orignal does.
self.temp_path = write_to_temp_file(img.to_blob)
else
super # Otherwise let attachment_fu handle it
end
end
end
Assim você sobrescreve o método original do attachment_fu para suportar uma sintaxe especial. Então quando você quiser um thumbnail ou até mesmo a imagem principal cortada de um tamanho específico, basta usar a string ‘crop: WxH’. Bom lembrar que isso só irá funcionar com o Rmagick. Eu dei uma olhada sobre como fazer usando o image_science, mas era um pouco mais chato. É bom setar: :processor => :rmagick na definição do has_attachment.
Eu também fiz um teste para garantir que os meus thumbnails estão sendo gerados no tamanho correto:
describe "photo resize" do
it "should create thumbnails with correct size" do
photo = new_photo
photo.save!
full, album, icon = *Magick::ImageList.new(
photo.full_filename,
photo.full_filename('album'),
photo.full_filename('icon')
)
full.columns.should == 50
full.rows.should == 64
album.columns.should == 150
album.rows.should == 150
icon.columns.should == 50
icon.rows.should == 64
end
end
PS1: Sim, eu sou paranóico com testes e você também deveria ser!
PS2: Essa dica foi adaptada daqui.
3 comentários : 17.03.2009 07:04 PM
acts_as_taggable_on_steroids e will_paginate
Num dos projetos que trabalho utilizo o plugin acts_as_taggable_on_steroids. Pela primeira vez fui fazer paginação de elementos com tags utilizando o will_paginate. O acts_as_taggable_on_steroids fornece o método de classe find_tagged_with que serve para buscar por items com uma determinada tag:
Post.find_tagged_with('rails')
E é possível fazer paginação utilizando o método paginate_tagged_with, mas o problema é que ele não funciona como deveria. Apesar de fazer a paginação funcionar corretamente, a sql que ele gera para fazer o count dos elementos não é correta. Se usado sem conditions, ele gera o número de páginas considerando todos os elementos da base. Eu escrevi o seguinte monkey patch, que coloquei no /lib do projeto:
module ActiveRecord
module Acts
module Taggable
module SingletonMethods
def paginate_tagged_with(tags, args = {})
options = find_options_for_find_tagged_with(tags, :match_all => true)
options.merge!(args)
paginate(options.merge(:count => { :select => options[:select].gsub("#{table_name}.*", "#{table_name}.id") }))
end
end
end
end
end
Para usar basta colocar no seu controller algo como:
@posts = Post.paginate_tagged_with(params[:tag_id], :page => params[:page] || 1)
Também escrevi uma spec para testar o funcionamento. Ela só faz sentido dentro do contexto do meu projeto, mas basta você modificar as fixtures, os modelos, etc, de acordo com seu projeto.
describe Post do
it "should return the correct total_pages to will_paginate" do
post = posts(:blog_post)
5.times do
new_post = BlogPost.new(post.attributes)
new_post.tag_list = 'global'
new_post.save
end
paginator = BlogPost.paginate_tagged_with('global', :page => 1, :per_page => 2)
paginator.total_entries.should == 6
paginator.total_pages.should == 3
end
end
2 comentários : 21.01.2009 12:09 AM
Syntax Highlight Mephisto plugin
UPDATE: Atualizado localização do repositório svn!
Já havia um tempo que eu queria adicionar syntax highlight nos códigos que escrevo aqui no blog. Resolvi pesquisar se já hávia algum plugin para Mephisto, mas não encontrei nenhum que utilizasse o dp.SyntaxHighlighter.
Utilizei como base o plugin do Dan Webb e fiz as modificações necessárias para utilizar o dp.SyntaxHighlighter. Para instalar:
script/plugin install http://mergulhao.info/svn/mephisto_plugins/filtered_column_better_code_highlighter/trunk/
Agora é só seguir as instruções do README e já poderá fazer isso:
class CreateContas < ActiveRecord::Migration
def self.up
create_table :contas do |t|
t.string :codigo, :limit => 8, :null => false
t.integer :parent_id
t.integer :lft
t.integer :rgt
t.timestamps
end
end
def self.down
drop_table :contas
end
end
A vantagem de utilizar um syntax highlighter client-side como o dp.SyntaxHighlighter é que o seu código original fica limpo, fácil de editar novamente. Uma possível desvantagem é que pode ficar lento caso tenha muito código para fazer a sintaxe, já que ele usa javascript.
1 comentário : 24.02.2008 12:41 PM




