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 )