From 5811e2f6469ab7303a2ef014f691df659f549cea Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Wed, 3 Oct 2012 17:06:55 -0500 Subject: mostly implement partials just need to get the auto-indenting behavior correct --- lib/Text/Handlebars.pm | 7 ++++++- lib/Text/Xslate/Syntax/Handlebars.pm | 30 ++++++++++++++++++++++++++++-- t/mustache-spec.t | 7 ++++--- 3 files changed, 38 insertions(+), 6 deletions(-) diff --git a/lib/Text/Handlebars.pm b/lib/Text/Handlebars.pm index c9a2e18..4cb1723 100644 --- a/lib/Text/Handlebars.pm +++ b/lib/Text/Handlebars.pm @@ -5,6 +5,7 @@ use warnings; use base 'Text::Xslate'; use Scalar::Util 'weaken'; +use Try::Tiny; sub default_functions { my $class = shift; @@ -76,7 +77,11 @@ sub _register_builtin_methods { my $to_render = $code->(@args); $to_render = "{{= $open_tag $close_tag =}}$to_render" if defined($open_tag) && defined($close_tag) && $close_tag ne '}}'; - return $self->render_string($to_render, $vars); + return $weakself->render_string($to_render, $vars); + }; + $funcs->{'(find_file)'} = sub { + my ($filename) = @_; + return try { $weakself->find_file($filename); 1 } catch { undef }; }; } diff --git a/lib/Text/Xslate/Syntax/Handlebars.pm b/lib/Text/Xslate/Syntax/Handlebars.pm index 6ec5769..1be7dff 100644 --- a/lib/Text/Xslate/Syntax/Handlebars.pm +++ b/lib/Text/Xslate/Syntax/Handlebars.pm @@ -68,7 +68,7 @@ sub split_tags { push @delimiters, [$tag_start, $tag_end]; } - my $autochomp = $code =~ m{^[!#^/=]}; + my $autochomp = $code =~ m{^[!#^/=>]}; if ($code =~ s/^=\s*([^\s]+)\s+([^\s]+)\s*=$//) { ($tag_start, $tag_end) = ($1, $2); @@ -80,11 +80,14 @@ sub split_tags { if ($autochomp && $standalone) { if ($input =~ /\A\s*(?:\n|\z)/) { $input =~ s/\A$nl//; - if (@chunks > 0 && $chunks[-1][0] eq 'text') { + if (@chunks > 0 && $chunks[-1][0] eq 'text' && $code !~ m{^>}) { $chunks[-1][1] =~ s/^(?:(?!\n)\s)*\z//m; } } } + else { + $standalone = 0; + } if (length($code)) { push @chunks, [ @@ -196,6 +199,8 @@ sub init_symbols { $self->symbol('^')->set_std($self->can('std_block')); $self->prefix('/', 0)->is_block_end(1); + $self->symbol('>')->set_std($self->can('std_partial')); + $self->prefix('&', 0)->set_nud($self->can('nud_mark_raw')); $self->prefix('..', 0)->set_nud($self->can('nud_uplevel')); } @@ -395,6 +400,27 @@ sub nud_uplevel { return $symbol->clone(arity => 'variable'); } +sub std_partial { + my $self = shift; + my ($symbol) = @_; + + my $partial = $self->token->clone(arity => 'literal'); + $self->advance; + + return $self->make_ternary( + $self->call('(find_file)', $partial->clone), + $symbol->clone( + arity => 'include', + id => 'include', + first => $partial, + ), + $symbol->clone( + arity => 'literal', + id => '', + ), + ); +} + sub define_function { my $self = shift; my (@names) = @_; diff --git a/t/mustache-spec.t b/t/mustache-spec.t index a97cb10..88f8560 100644 --- a/t/mustache-spec.t +++ b/t/mustache-spec.t @@ -9,15 +9,16 @@ use Test::Requires 'JSON', 'Path::Class'; for my $file (dir('t', 'mustache-spec', 'specs')->children) { next unless $file =~ /\.json$/; - next if $file->basename =~ /partials/; my $tests = decode_json($file->slurp); note("running " . $file->basename . " tests"); for my $test (@{ $tests->{tests} }) { local $TODO = "unimplemented" - if $file->basename eq 'delimiters.json' - && $test->{name} =~ /partial/i; + if $file->basename eq 'partials.json' + && $test->{name} =~ /standalone/i + && $test->{name} !~ /line endings/i; render_ok( + ($test->{partials} ? ({ path => [$test->{partials}] }) : ()), $test->{template}, fix_data($test->{data}), $test->{expected}, -- cgit v1.2.3-54-g00ecf