DTL-Fast

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN


1.04 - 2015-01-14
    - Taken date function from Dotiac::DTL to DTL::Fast::Utils::time2str_php
    - `now` tag and `date` filter now works with time2str_php function (like Django itself)
    - Implemented strftime filter, which works with Date::Format str2time.
    - Added Russian version of pluralize filter:

        use DTL::Fast;
        use DTL::Fast::Filter::Ru::Pluralize; # this will override default pluralize with Russian version.
        
    - Refactored strings backup and parametrized filters.
    - `block` and `extends` tags now works as tags.
    - New dependency added: Storable

1.03 - 2015-01-13
    - Tested with CentOS & Perl 5.10
    - Lowered Perl version requirement to 5.10
    - Changed implicit split to explicit in wordcount filter (v5.10 considers it depricated).
    - Added exception on missing parent template in extends tag.
    - Added exception on missing included template in include tag.
    - Added exception on recursive inheritance (extends tag).

lib/DTL/Fast/Cache.pm  view on Meta::CPAN

    return $template;
}

sub put
{
    my ( $self, $key, $template, %kwargs ) = @_;

    if (defined $template)
    {
        my @keys = ('cache', 'url_source');
        my @backup = @{$template}{@keys};
        delete @{$template}{@keys};
        $self->write_data($key, $template, %kwargs);
        @{$template}{@keys} = @backup;
    }
    return $self;
}

sub read_data
{
    my ( $self, $key ) = @_;
    die "read_data method was not defined in ".(ref $self);
}

lib/DTL/Fast/Expression.pm  view on Meta::CPAN

    }
    else
    {
        $kwargs{expression} = $expression;
        $kwargs{level} //= 0;

        my $self = $proto->SUPER::new(%kwargs);

        $self->{expression} = $self->_parse_expression(
            $self->_parse_brackets(
                $self->backup_strings($expression)
            )
        );

        $EXPRESSION_CACHE{$expression} = $result = $self->{expression};
    }

    return $result;
}

sub _parse_brackets
{
    my ( $self, $expression ) = @_;

    $expression =~ s/\s+/ /xgsi;
    while( $expression =~ s/
        \(\s*([^()]+)\s*\)
        /
        $self->backup_expression($1)
        /xge ){};

    die $self->get_parse_error('unpaired brackets in expression')
        if ($expression =~ /[()]/);

    return $expression;
}

sub get_parse_error
{

lib/DTL/Fast/Expression.pm  view on Meta::CPAN

            while( defined ( my $token = shift @source) )
            {
                next if ($token eq '');

                if ($token =~ /^$operators$/six) # operation
                {
                    push @result, $token;
                }
                else
                {
                    push @result, $self->get_backup_or_expression($token, $level);
                }
            }

            # processing operators
            while( my $token = shift @result )
            {
                if (ref $token) # operand
                {
                    $result = $token;
                }

lib/DTL/Fast/Expression.pm  view on Meta::CPAN

                            );
                    }
                }
            }
            last if ($result);    # parsed level
        }

    }
    return
        $result
            // $self->get_backup_or_variable($expression)
    ;
}

1;

lib/DTL/Fast/Filter/Dictsort.pm  view on Meta::CPAN


use Scalar::Util qw(looks_like_number);
use locale;

#@Override
sub parse_parameters
{
    my $self = shift;
    die $self->get_parse_error("no sorting key specified")
        if (not scalar @{$self->{parameter}});
    $self->{key} = [ split /\./, $self->{parameter}->[0]->render() ]; # do we need to backup strings here ?
    return $self;
}

#@Override
sub filter
{
    my ($self, $filter_manager, $value, $context) = @_;

    die $self->get_render_error("dictsort works only with array of hashes")
        if (ref $value ne 'ARRAY');

lib/DTL/Fast/FilterManager.pm  view on Meta::CPAN

        $self->add_filter($filter_name);
    }
    return $self;
}

sub add_filter
{
    my $self = shift;
    my $filter_name = shift;

    my @arguments = split /\s*\:\s*/x, $self->backup_strings($filter_name);
    $filter_name = shift @arguments;

    if (
        not exists $DTL::Fast::FILTER_HANDLERS{$filter_name}
            and exists $DTL::Fast::KNOWN_FILTERS{$filter_name}
    )
    {
        require Module::Load;
        Module::Load::load($DTL::Fast::KNOWN_FILTERS{$filter_name});
        $DTL::Fast::LOADED_MODULES{$DTL::Fast::KNOWN_FILTERS{$filter_name}} = time;
    }

    if (exists $DTL::Fast::FILTER_HANDLERS{$filter_name})
    {
        my $args = [ ];

        foreach my $argument (@arguments)
        {
            push @$args, $self->get_backup_or_variable($argument) // $argument;
        }

        push @{$self->{filters}}, $DTL::Fast::FILTER_HANDLERS{$filter_name}->new($args);

        $self->{filters_number}++;
    }
    else
    {
        warn $self->get_parse_error( "unknown filter $filter_name" );
    }

lib/DTL/Fast/Replacer.pm  view on Meta::CPAN

use strict;
use utf8;
use warnings FATAL => 'all';
use parent 'DTL::Fast::Entity';

use DTL::Fast::Replacer::Replacement;
use DTL::Fast::Variable;

our $VERSION = '1.00';

sub backup_strings
{
    my ( $self, $expression ) = @_;

    $self->clean_replacement($expression)
        if (not $self->{replacement}
            or not $self->{replacement}->isa('DTL::Fast::Replacer::Replacement'));

    $expression =~ s/(?<!\\)(["'])(.*?)(?<!\\)\1/$self->backup_value($1.$2.$1)/ge;

    return $expression;
}

sub backup_value
{
    my ( $self, $value ) = @_;

    return $self->{replacement}->add_replacement(
        DTL::Fast::Variable->new($value)
    );
}

sub backup_expression
{
    my ( $self, $expression ) = @_;

    return $self->{replacement}->add_replacement(
        DTL::Fast::Expression->new(
            $expression
            , replacement => $self->{replacement}
            , level       => 0
        )
    );
}

sub get_backup
{
    return shift->{replacement}->get_replacement(shift);
}


sub get_backup_or_variable
{
    my ( $self, $token ) = @_;

    my $result = $self->get_backup($token)
        // DTL::Fast::Variable->new( $token, replacement => $self->{replacement} );

    return $result;
}

sub get_backup_or_expression
{
    my ( $self, $token, $current_level ) = @_;
    $current_level //= - 1;

    my $result = $self->get_backup($token)
        // DTL::Fast::Expression->new(
        $token
        , replacement => $self->{replacement}
        , level       => $current_level + 1
    );

    return $result;
}

sub clean_replacement

lib/DTL/Fast/Replacer.pm  view on Meta::CPAN

{
    my ( $self, $replacement ) = @_;
    $self->{replacement} = $replacement;
    return $self;
}

sub parse_sources
{
    my ( $self, $source ) = @_;

    my $sources = $self->backup_strings($source);

    warn $self->get_parse_warning(
            sprintf(
                "comma-separated source values in %s tag are DEPRICATED, please use spaces:\n\t%s"
                , ref $self
                , $source
            )
        ) if ($sources =~ /,/);

    my $result = [ ];

    foreach my $source (split /[,\s]+/, $sources)
    {
        if ($source =~ /^(__BLOCK_.+?)\|(.+)$/)   # filtered static variable
        {
            push @$result, $self->get_backup_or_variable($1);
            $result->[- 1]->{filter_manager}->parse_filters($2);
        }
        else
        {
            push @$result, $self->get_backup_or_variable($source)
        }
    }

    return $result;
}

1;

lib/DTL/Fast/Tag/Regroup.pm  view on Meta::CPAN


#@Override
sub parse_parameters
{
    my $self = shift;

    if ($self->{parameter} =~ /^\s*(.+)\s+by\s+(.+?)\s+as\s+(.+?)\s*$/si)
    {
        @{$self}{qw( source grouper target_name)} = (
            DTL::Fast::Variable->new($1)
            , [ (split /\./, $2) ] # do we need to backup strings here ?
            , $3
        );

        die $self->get_parse_error("traget variable can't be traversable: $3") if ($3 =~ /\./);
    }
    else
    {
        die $self->get_parse_error("do not understand condition: $self->{parameter}");
    }

lib/DTL/Fast/Tag/Url.pm  view on Meta::CPAN

use DTL::Fast::Utils;

#@Override
sub parse_parameters
{
    my ( $self ) = @_;

    if ($self->{parameter} =~ /^\s*(.+?)(?:\s+as\s+([^\s]+))?\s*$/s)
    {
        $self->{target_name} = $2;
        my @params = split /\s+/, $self->backup_strings($1);

        $self->{model_path} = $self->get_backup_or_variable(shift @params);
        if (scalar @params)
        {
            if ($params[0] =~ /\=/)
            {
                $self->parse_named_parameters(\@params);
            }
            else
            {
                $self->parse_positional_parameters(\@params);
            }

lib/DTL/Fast/Tag/Url.pm  view on Meta::CPAN


sub parse_named_parameters
{
    my ( $self, $params ) = @_;

    my $result = { };
    foreach my $param (@$params)
    {
        if ($param =~ /^(.+)\=(.+)$/)
        {
            $result->{$1} = $self->get_backup_or_variable($2);
        }
        else
        {
            die $self->get_parse_error("you can't mix positional and named arguments in url tag: $self->{parameter}");
        }
    }
    $self->{arguments} = $result;
    return $self;
}

sub parse_positional_parameters
{
    my ( $self, $params ) = @_;

    my $result = [ ];
    foreach my $param (@$params)
    {
        die $self->get_parse_error("you can't mix positional and named arguments in url tag: $self->{parameter}")
            if ($param =~ /\=/);

        push @$result, $self->get_backup_or_variable($param);
    }
    $self->{arguments} = $result;
    return $self;
}

1;

lib/DTL/Fast/Tag/With.pm  view on Meta::CPAN

    my $self = shift;

    $self->{mappings} = { };
    if ($self->{parameter} =~ /^\s*(.+?)\s+as\s+(.+)\s*$/s)  # legacy
    {
        $self->{mappings}->{$2} = DTL::Fast::Expression->new($1);
    }
    else    # modern
    {
        my @parts = ();
        my $string = $self->backup_strings($self->{parameter});

        while ( $string =~ s{^
            \s*
            ([^\s\=]+)
            \s*\=\s*
            ([^\s\=]+)
            \s*
            }{}x
        )
        {
            $self->{mappings}->{$1} = $self->get_backup_or_variable($2);
        }

        if ($string) {
            die $self->get_parse_error(
                    "there is an error in `with` parameters"
                    , 'Passed parameters' => $self->{parameter}
                );
        }
    }

lib/DTL/Fast/Template.pm  view on Meta::CPAN

    weaken $self->{_template};

    return $self;
}

#@Override
sub parse_chunks
{
    my ( $self ) = @_;

    my ( $current_template_backup, $current_template_line_backup ) = ($CURRENT_TEMPLATE, $CURRENT_TEMPLATE_LINE);
    ($CURRENT_TEMPLATE, $CURRENT_TEMPLATE_LINE) = ($self, 1);

    $self->SUPER::parse_chunks();

    ($CURRENT_TEMPLATE, $CURRENT_TEMPLATE_LINE) = ($current_template_backup, $current_template_line_backup);
    return $self;
}

my $reg = qr/(
    \{\#.+?\#\}
    |\{\%.+?\%\}
    |\{\{.+?\}\}
    )/xs;

sub _get_raw_chunks



( run in 1.463 second using v1.01-cache-2.11-cpan-49f99fa48dc )