doy / text-handlebars

http://handlebarsjs.com/ for Text::Xslate
http://metacpan.org/release/Text-Handlebars
6 stars 9 forks source link

"each" does not work for hashrefs #9

Open rmesser opened 7 years ago

rmesser commented 7 years ago

"each" does not process hashes. For example, this test fails:

use Text::Handlebars;
use Test::More tests => 1;

my $hb = Text::Handlebars->new();
my $template = <<'END';
{{#each obj}}
key: {{@key}}, value: {{this}}
{{/each}}
END

my $output = $hb->render_string($template, {obj => {foo => 'bar', bingo => 'test'}});
my $expected = <<END;
key: bingo, value: test
key: foo, value: bar
END

is($output, $expected, 'each with hashref');

The error is: Text::Handlebars: Not an ARRAY reference at /home/intellisurvey/versions/7.0/isapps/lib/perl5/site_perl/5.22.1/Text/Handlebars.pm line 24.

This template does work on the javascript version, as tested on http://tryhandlebarsjs.com/.

This patch fixes the problem, and makes the above test pass, without causing any other failures:

---
 lib/perl5/site_perl/5.22.1/Text/Handlebars.pm | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/lib/perl5/site_perl/5.22.1/Text/Handlebars.pm b/lib/perl5/site_perl/5.22.1/Text/Handlebars.pm
index 0312fe7..1cf137d 100644
--- a/lib/perl5/site_perl/5.22.1/Text/Handlebars.pm
+++ b/lib/perl5/site_perl/5.22.1/Text/Handlebars.pm
@@ -20,8 +20,12 @@ sub default_helpers {
             return $options->{fn}->($new_context);
         },
         each => sub {
-            my ($context, $list, $options) = @_;
-            return join '', map { $options->{fn}->($_) } @$list;
+            my ($context, $ref, $options) = @_;
+            if (ref $ref eq 'HASH') {
+                return join '', map { $options->{fn}->( {'@key' => $_, '.' => $ref->{$_}} ) } sort keys %$ref;
+            } else {
+                return join '', map { $options->{fn}->($_) } @$ref;
+            }
         },
         if => sub {
             my ($context, $conditional, $options) = @_;
--
1.8.3.1
amit777 commented 7 years ago

Hi @rmesser, are you using this lib in production?

rmesser commented 7 years ago

Hi. We were using it for a while in production because we want to share templates between perl and javascript. But there were enough differences that it was difficult, so we switched to using more standard Text::Xslate on the back-end (perl) side. Regards,

Rob

On Aug 18, 2017, at 3:49 PM, amit777 notifications@github.com wrote:

Hi @rmesser https://github.com/rmesser, are you using this lib in production?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/doy/text-handlebars/issues/9#issuecomment-323477450, or mute the thread https://github.com/notifications/unsubscribe-auth/ABwSpAxkqGMgYi-YDBG4OlEUVCLhWkZ8ks5sZhTvgaJpZM4LSNYh.

amit777 commented 7 years ago

@rmesser , thanks Rob. We are looking to do the same exact thing. If you are using Text::Xslate in perl, what are you doing on the javascript side? I'm also considering just creating an nodejs for the perl code to call.

rmesser commented 7 years ago

@amit777, we went the other way and just let the front-end do a server-side call (via a websocket, but it could be ajax) to apply the data to the template. But yea I suppose you could let perl call nodejs to run some javascript and handle the template that way.

On Aug 18, 2017, at 4:22 PM, amit777 notifications@github.com wrote:

@rmesser https://github.com/rmesser , thanks Rob. We are looking to do the same exact thing. If you are using Text::Xslate in perl, what are you doing on the javascript side? I'm also considering just creating an nodejs for the perl code to call.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/doy/text-handlebars/issues/9#issuecomment-323481553, or mute the thread https://github.com/notifications/unsubscribe-auth/ABwSpKTH3RB17a5N7mPhVamEU5zSenGwks5sZhyrgaJpZM4LSNYh.