вторник, 11 ноября 2008 г.

file_column и ImageMagick в XSLT-шаблонах

Решил предоставить пользователю выбор размеров изображении в шаблоне XSLT.

Исходные: К любому сообщению пользователь может прикрепить одно изображение. Само изображение хранится в разных версиях (используем file_column + ImageMagick). И вот и решил я: раз уж юзер может использовать собственные XSLT-шаблоны, нужно дать ему возможность выбирать и размеры изображений (версию).
Вот примерно так у меня хранятся изображения.

Модель image.rb


class Image < ActiveRecord::Base
belongs_to :imageable, :polymorphic => true
VALID_EXTENSIONS = ["gif", "jpeg", "jpg", "png"]
file_column :name,
:magick => {:versions => {
:pic => {:crop => "1:1", :size => "33x33!", :attributes => {:quality => 90 },
:transformation => Proc.new { |image| image.strip! }},
:mini => {:crop => "1:1", :size => "50x50!", :attributes => {:quality => 90 },
:transformation => Proc.new { |image| image.strip! }},
:middle => {:size => "500x375>",:attributes => {:quality => 90 },
:transformation => Proc.new { |image| image.strip! }},
:thumb => {:crop => "148:111", :size => "148x111!", :attributes => {:quality => 90 },
:transformation => Proc.new { |image| image.strip! }}
}
}
validates_file_format_of :name, :in => ["gif", "png", "jpg", "GIF", "PNG", "JPG"]
end


Модель post.rb


class Post < ActiveRecord::Base
...
has_one :image, :as => :imageable, :dependent => :destroy
...
end

Ну это так... были вводные данные. Теперь перейдём непосредственно к XML/XSLT.

XML: blog.rxml


xml.tag!("posts") do
@posts.each do |post|
xml.tag!("post", :id => post.id){
xml.tag!("title") do
xml << link_to(post.title, :controller => "blog", :action => "post", :id => post.id)
end
xml.tag!( "created_at", post.created_at.strftime("%b %d, %Y") )
if @image = post.image
xml.tag!("image"){
xml.tag!("src-wide", url_for_file_column("image", "name", "wide") )
xml.tag!("src-thumb", url_for_file_column("image", "name", "thumb") )
xml.tag!("src-middle", url_for_file_column("image", "name", "middle") )
}
end #image
xml.message(post.message)
}
end
end

Ну и, собственно XSLT-темплейт

XSLT: blog.xsl


<xsl:template match="posts">
<xsl:apply-templates select="post" />
</xsl:template>

<xsl:template match="post">
<div class="blog-post" id="blog-post{@id}">
<h2><xsl:copy-of select="title/*" /></h2>
<span class="highcolor2"><xsl:value-of select="created_at" /></span><br />
<div class="blog-body">
<xsl:apply-templates select="image" />
<p><xsl:value-of select="message" /></p>
</div>
</div>
</xsl:template>

<xsl:template match="post/image">
<xsl:element name="img">
<xsl:attribute name="src">
<xsl:value-of select="src-thumb" />
</xsl:attribute>
<xsl:attribute name="class">thumb</xsl:attribute>
</xsl:element>
</xsl:template>

Вуа-ля! Теперь если пользователь захочет отображать изображения другого размера, ему просто нужно будет заменить <xsl:value-of select="src-thumb" /> например на <xsl:value-of select="src-middle" />.

0 Комментариев :

Отправить комментарий

Жги!