DTL-Fast

 view release on metacpan or  search on metacpan

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

package DTL::Fast::Template;
use parent 'DTL::Fast::Parser';
use strict;
use utf8;
use warnings FATAL => 'all';

use DTL::Fast qw(get_template);
use DTL::Fast::Context;
use DTL::Fast::Tags;
use DTL::Fast::Filters;
use Scalar::Util qw/weaken/;

our $CURRENT_TEMPLATE;      # global variable for linking  modules
our $CURRENT_TEMPLATE_LINE; # global variable for source line number

#@Override
sub new
{
    my ( $proto, $template, %kwargs ) = @_;
    $template //= '';

    $kwargs{raw_chunks} = _get_raw_chunks($template);
    $kwargs{dirs} //= [ ];             # optional dirs to look up for includes or parents
    $kwargs{file_path} //= 'inline';
    $kwargs{perl} = $];
    $kwargs{blocks} = { };
    $kwargs{modules} //= {
        'DTL::Fast' => $DTL::Fast::VERSION,
    };

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

    return $self;
}

#@Override self-linking
sub remember_template
{
    my ($self) = @_;

    $self->{_template} = $self;
    $self->{_template_line} = 1;
    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
{
    my ( $template ) = @_;

    my $result = [ split $reg, $template ];

    return $result;
}

#@Override
sub render
{
    my ( $self, $context ) = @_;

    $context //= { };

    if (ref $context eq 'HASH')
    {
        $context = DTL::Fast::Context->new($context);
    }
    elsif (
        defined $context
            and ref $context ne 'DTL::Fast::Context'
    )
    {
        die  "Context must be a DTL::Fast::Context object or a HASH reference";
    }

    $context->push_scope();

    $context->{ns}->[- 1]->{_dtl_ssi_dirs} = $self->{ssi_dirs} if ($self->{ssi_dirs});
    $context->{ns}->[- 1]->{_dtl_url_source} = $self->{url_source} if ($self->{url_source});

    my $template_path = $self->{file_path};

    if (not exists $context->{ns}->[- 1]->{_dtl_include_path})  # entry point
    {
        $context->{ns}->[- 1]->{_dtl_include_path} = [ ];
        $context->{ns}->[- 1]->{_dtl_include_files} = { };
    }
    else    # check for recursion, shouldn't this be in the include tag?
    {
        if (exists $context->{ns}->[- 1]->{_dtl_include_files}->{$template_path})
        {
            # recursive inclusion
            die sprintf("Recursive inclusion detected:\n%s\n"
                    , join( "\n includes ", @{$context->{ns}->[- 1]->{_dtl_include_path}}, $template_path)
                );
        }
    }



( run in 0.929 second using v1.01-cache-2.11-cpan-39bf76dae61 )