MVC-Neaf
view release on metacpan or search on metacpan
lib/MVC/Neaf/Route/Main.pm view on Meta::CPAN
Everything following the newline and until next such entry
is considered file content.
Options may include:
=over
=item * C<type=ext | mime/type>
=item * C<format=base64>
=item * C<view=view_name,view_name...> - specify a template for given view(s)
Leading slash will be stripped in this case.
=back
Entries with unknown options will be skipped with a warning.
B<[EXPERIMENTAL]> This method and exact format of data is being worked on.
=cut
# TODO split this sub & move to a separate file
my $INLINE_SPEC = qr/^(?:\[(\w+)\]\s+)?(\S+)((?:\s+\w+=\S+)*)$/;
my %load_resources_opt;
$load_resources_opt{$_}++ for qw( view format type );
sub load_resources {
my ($self, $file, $name) = @_;
if (!ref $file and defined $file) {
open my $fd, "<", $file
or $self->my_croak( "Failed to open(r) $file: $!" );
$name = $file;
$file = $fd;
};
# Don't load the same filename twice
return $self
if defined $name and $self->{load_resources}{$name}++;
my $content;
if (ref $file eq 'GLOB') {
local $/;
$content = <$file>;
defined $content
or $self->my_croak( "Failed to read from $file: $!" );
close $file;
# Die later
} elsif (ref $file eq 'SCALAR') {
$content = $$file;
} else {
$self->my_croak( "Argument must be a scalar, a scalar ref, or a file descriptor" );
};
defined $content
or $self->my_croak( "Failed load content" );
# TODO 0.40 The regex should be: ^@@\s+(/\S+(?:\s+\w+=\S+)*)\s*$
# but we must deprecate '[TT] foo.html' first
my @parts = split m{^@@\s+(\S.*?)\s*$}m, $content, -1;
shift @parts;
confess "NEAF load_resources failed unexpectedly, file a bug in MVC::Neaf"
if @parts % 2;
my %templates;
my %static;
while (@parts) {
# parse pseudo-file
my $spec = shift @parts;
my $content = shift @parts;
# process header
my ($dest, $name, $extra) = ($spec =~ $INLINE_SPEC);
$self->my_croak("Bad resource spec format @@ $spec")
unless defined $name;
my %opt = $extra =~ /(\w+)=(\S+)/g;
if ($dest) {
$opt{view} = $dest;
carp "DEPRECATED '@@ [$dest]' resource format,"
." use '@@ $name view=$dest' instead";
};
if ( my @unknown = grep { !$load_resources_opt{$_} } keys %opt ) {
carp "Unknown options (@unknown) in '@@ name' in $file, skipping";
next;
};
# process content
if (!$opt{format}) {
$content =~ s/^\n+//s;
$content =~ s/\s+$//s;
$content = Encode::decode_utf8( $content, 1 );
} elsif ($opt{format} eq 'base64') {
$content = decode_b64( $content );
} else {
# TODO 0.50 calculate line
$self->my_croak("Unknown format $opt{format} in '@@ $spec' in $file");
};
# store for loading
if (defined( my $view = $opt{view} )) {
# template
$self->my_croak("Duplicate template '@@ $spec' in $file")
if defined $templates{$view}{$name};
$templates{$view}{$name} = $content;
} else {
# static file
$self->my_croak("Duplicate static file '@@ $spec' in $file")
if $static{$name};
$static{$name} = [ $content, $opt{type} ];
};
}; # end while @parts
# now do the loading
foreach my $name( keys %templates ) {
my $view = $self->get_view( $name, 1 );
if (!$view) {
carp "NEAF: Unknown view $name mentioned in $file";
} elsif ($view->can("preload")) {
$view->preload( %{ $templates{$name} } );
( run in 1.452 second using v1.01-cache-2.11-cpan-71847e10f99 )