Sponsoring The Perl Toolchain Summit 2025: Help make this important event another success Learn more

use Carp;
attr paths => sub { [] };
attr encoding => 'UTF-8';
attr tt => sub { Template::Tiny->new };
sub process
{
my ($self, $template, $vars) = @_;
my $ref = ref $template;
# A GLOB or an IO object will be read and returned as a SCALAR template
# No reference means a file name
if (!$ref) {
$template = $self->_read_file($self->find_template($template));
}
elsif ($ref =~ /^IO/ || $ref eq 'GLOB') {
$template = $self->_read_file($template);
}
elsif ($ref ne 'SCALAR') {
croak "Template reference must be SCALAR, GLOB or an IO object";
}
my $output;
$self->tt->process($template, $vars, \$output);
return $output;
}
sub find_template
{
my ($self, $name) = @_;
my $file;
for my $p ('.', @{$self->paths}) {
$file = "$p/$name";
return $file if -e $file;
}
return undef;
}
sub _read_file
{
my ($self, $file) = @_;
my $text;
if (ref $file) {
# read the entire file
local $/ = undef;
# make sure to properly rewind the handle after we read from it
my $pos = tell $file;
$text = readline $file;
seek $file, $pos, 0;
}
else {
$text = path($file)->slurp(
{binmode => ':encoding(' . $self->encoding . ')'}
);
}
return \$text;
}
1;
__END__
=pod
=head1 NAME
Kelp::Template - A very minimal template rendering engine for Kelp
=head1 SYNOPSIS
my $t = Kelp::Template->new;
say $t->process('file.tt', { bar => 'foo' });
=head1 DESCRIPTION
This module provides basic template rendering using L<Template::Tiny>.
=head1 ATTRIBUTES
=head2 paths
An arrayref of paths to use when looking for template files.
=head2 encoding
Specifies the text encoding of the template files. The default value is C<UTF-8>.
=head1 METHODS
=head2 process( $template, \%vars )
Processes a template and returns the parsed text. The template may be a file name,
a reference to a text, a GLOB or an IO object.
say $t->process(\"Hello [% who %]", { who => 'you' });
=cut