#!/usr/bin/perl
package Catalyst::Plugin::Images;
use strict;
use warnings;
use Image::Size ();
use HTML::Entities ();
use Path::Class ();
use MRO::Compat;
our $VERSION = "0.02";
sub setup {
my $app = shift;
my $ret = $app->next::method( @_ );
$app->config->{images}{paths} ||= [
$app->path_to(qw/root static/),
$app->path_to(qw/root images/),
$app->path_to(qw/root static images/),
];
$app->config->{images}{uri_base} ||= $app->path_to("root");
$ret;
}
sub image_tag {
my ( $c, $basename, @attrs ) = @_;
my %attrs = (@attrs == 1) ? %{ $attrs[0] } : @attrs;
my $info = $c->get_image_info( $basename );
foreach my $attr (qw/width height alt/) {
next if exists $attrs{$attr};
next unless exists $info->{$attr};
$attrs{$attr} = $info->{$attr};
}
$attrs{src} = $info->{uri}->as_string;
foreach my $tag ( keys %attrs ) {
$attrs{$tag} = HTML::Entities::encode_entities( $attrs{$tag} )
if $attrs{$tag} =~ /\D/;
}
return join(" ",
'
'
);
}
sub get_image_info {
my ( $c, $basename ) = @_;
if ( my $cached = $c->get_cached_image_info( $basename ) ) {
return $cached;
}
my $path = $c->find_image_file( $basename );
my $info = { ( $path ? $c->read_image_info( $path ) : () ) };
$info->{path} = $path || Path::Class::file( $basename );
$info->{uri} = $c->image_path_to_uri( $path, $basename );
$c->set_cached_image_info( $basename, $info );
return $info;
}
sub get_cached_image_info {
my ( $c, $basename ) = @_;
return;
}
sub set_cached_image_info {
my ( $c, $basename, $info ) = @_;
return;
}
sub image_path_to_uri {
my ( $c, $path, $basename ) = @_;
$c->uri_for( "/" . ( $path ? $path->relative( $c->config->{images}{uri_base} ) : $basename ) );
}
sub find_image_file {
my ( $c, $basename ) = @_;
foreach my $path ( map { Path::Class::dir($_) } @{ $c->config->{images}{paths} } ) {
$path = $c->path_to( $path ) unless $path->is_absolute;
my $file = $path->file( $basename );
return $file if -f $file->stringify;
}
$c->log->debug("Couldn't find an image by the name of '$basename' in any of the search paths")
if $c->debug;
return;
}
sub read_image_info {
my ( $self, $path ) = @_;
my ( $width, $height ) = eval { Image::Size::imgsize( $path->stringify ) };
return ( width => $width || '', height => $height || '' );
}
__PACKAGE__;
__END__
=pod
=head1 NAME
Catalyst::Plugin::Images - Generate image tags for static files.
=head1 SYNOPSIS
use Catalyst qw/
Images
/;
# ... somewhere in your templates
[% c.image_tag("foo.png", alt => "alt text") %];
=head1 DESCRIPTION
This plugin provides a quick and easy way to include your images on the page,
automatically extracting and caching image metadata. It's automatically
extendable, just pass whatever attribute you require as a key/value pair, and
it will be added to the image tag. It will also look through a preset of folders
so that you don't have to specify the full address to your image.
=head1 METHODS
=over 4
=item image_tag $basename, %attrs
This method generates an image tag for the image named $basename, with the
extra tags %attr automatically added to the resulting HTML tag. If you don't
specify height/width, it will be autodetected from the image.
=item get_image_info $basename
Retrieve the information about the image either from the cache or by searching
for it.
=item find_image_file $basename
Look inside all the search paths (see L) for an image named
$basename, and return the full path to it, as a object..
=item read_image_info $path
Given the full path, as a L object, return the attributes to
be added to the image. This returns a list with C and C, using
C.
=item image_path_to_uri $path, $basename
Generates a URI using L, with the absolute path C<$path>
relativized to C. See L.
=item get_cached_image_info
=item set_cached_image_info
see L below.
=item setup
Overridden to seed configuration defaults.
=back
=head1 CONFIGURATION
All configuration information is stored under the C key.
=over 4
=item paths
This should be an array reference of L objects (easily
generated with L) in which to search for images.
It defaults to C, C, C by
default.
=item uri_base
This is the "base" prefix path for URI generation. For example, if an image was
found at C and C is C then the
L generated with C will be for
C.
=back
=head1 CACHING IMAGE DATA
The code will call C and C when
appropriate. Currently both these operations are no op. You should override
this if you care.
C receives the base name, and should return the info
hash.
C receives the base name, and the info hash. It can use
this data to expire the cache based on mtime, etc. The info hash contains the
keys C, C, C, and C.
=head1 SEE ALSO
L, L, L
=head1 AUTHOR
Yuval Kogman, C
Last released by Tomas Doran, C
=head1 LICENSE
This library is free software, you can redistribute it and/or modify it under
the same terms as Perl itself.
=cut