package App::CPANIDX::Renderer;
use strict;
use warnings;
use YAML::Tiny;
use JSON::XS;
use XML::Simple;
use HTML::Tiny;
use vars qw[$VERSION];
$VERSION = '0.40';
my %types = (
'yaml', 'application/x-yaml; charset=utf-8',
'json', 'application/json; charset=utf-8',
'xml', 'application/xml; charset=utf-8',
'html', 'text/html',
);
my %renderers = (
'yaml', sub {
my $ref = shift;
my $string;
eval { $string = YAML::Tiny::Dump( $ref ); };
return $string;
},
'json', sub {
my $ref = shift;
my $string;
eval { $string = JSON::XS->new->utf8(1)->pretty(1)->encode( $ref ); };
return $string;
},
'xml', sub {
my $ref = shift;
my $type = shift || 'opt';
my %data;
$data{$type} = $ref;
my $string;
eval { $string = XMLout(\%data, RootName => 'results' ); };
return $string;
},
'html', sub {
my $ref = shift;
return _gen_html( @{ $ref } );;
},
);
sub renderers {
return sort keys %renderers;
}
sub new {
my $package = shift;
my $data = shift;
return unless $data and ref $data eq 'ARRAY';
my $format = shift || 'yaml';
$format = lc $format;
return unless exists $types{ $format };
bless { _data => $data, _format => $format }, $package;
}
sub render {
my $self = shift;
my $type = shift;
my $contype = $types{ $self->{_format} };
my $content = $renderers{ $self->{_format} }->( $self->{_data}, $type );
return ($contype, $content) if wantarray;
return [ $contype, $content ];
}
sub _gen_html {
my @results = @_;
my $h = HTML::Tiny->new();
my $data;
if ( !scalar @results ) {
$data = $h->p('There were no results, sorry');
}
else {
my @th = sort keys %{ $results[0] };
$data = $h->table( { border => 1, cellspacing => 0, width => '100%' },
[
\'tr',
[ \'th', @th ],
map { my $href = $_;
[ \'td', map { $href->{$_} } sort keys %$href ] } @results,
]
);
}
return $h->html(
[
$h->head( $h->title( 'Results' ) ),
$h->body(
[
$data
]
)
]
);
}
1;
__END__
=head1 NAME
App::CPANIDX::Renderer - Generates web content for App::CPANIDX
=head1 SYNOPSIS
my @types = App::CPANIDX::Renderer->renderers;
my $ren = App::CPANIDX::Renderer->new( \@data, 'yaml' );
my ($content_type, $content) = $ren->render();
=head1 DESCRIPTION
App::CPANIDX::Renderer renders web content for L<App::CPANIDX>.
=head1 CONSTRUCTOR
=over
=item C<new>
Returns a new App::CPANIDX::Renderer object. Takes two parameters, an arrayref of
data to be rendered, which is required, and the format, either C<yaml>, C<json>, C<xml>
or C<html>, to render to, which defaults to C<yaml>.
=back
=head1 CLASS METHODS
=over
=item C<renderers>
Returns a list of the supported renderers.
my @types = App::CPANIDX::Renderer->renderers;
=back
=head1 METHODS
=over
=item C<render>
Renders the previously supplied data to the format specified. Optionally takes one parameter,
which mainly has utility with the C<xml> format.
=back
=head1 AUTHOR
Chris C<BinGOs> Williams <chris@bingosnet.co.uk>
=head1 LICENSE
Copyright E<copy> Chris Williams
This module may be used, modified, and distributed under the same terms as Perl itself. Please see the license that came with your Perl distribution for details.
=head1 SEE ALSO
L<App::CPANIDX>
=cut