From: Matt S Trout Date: Tue, 31 Jul 2012 20:49:45 +0000 (+0000) Subject: wrap and replace for templating X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=scpubgit%2FApp-SCS.git;a=commitdiff_plain;h=485da0adf26fc195c28b8e9997f1014bbb964e72 wrap and replace for templating --- diff --git a/lib/App/SCS/Plugin/Core/PagePlugin/Template.pm b/lib/App/SCS/Plugin/Core/PagePlugin/Template.pm index 6bac9fe..0587b80 100644 --- a/lib/App/SCS/Plugin/Core/PagePlugin/Template.pm +++ b/lib/App/SCS/Plugin/Core/PagePlugin/Template.pm @@ -1,5 +1,6 @@ package App::SCS::Plugin::Core::PagePlugin::Template; +use List::Util qw(reduce); use Moo; with 'App::SCS::Role::PagePlugin'; @@ -14,14 +15,46 @@ sub filter_html_zoom { or die "No such template ${\$self->name}"; my $template_zoom = HTML::Zoom->from_html($template_page->html); my @ev; - $template_zoom->select('*[data-replace]') + my %wrap; + $template_zoom->select('*[data-wrap]') ->collect({ into => \@ev, passthrough => 1 }) ->then - ->replace(sub { - my $sel = $ev[0]->{attrs}{'data-replace'}; - $zoom->collect($sel, { into => \my @replace })->run; - HTML::Zoom::ArrayStream->new({ array => \@replace }) - }); + ->collect({ filter => sub { + my %attrs = %{$ev[0]->{attrs}}; + my $select = delete $attrs{'data-wrap'}; + $ev[0] = { + %{$ev[0]}, + raw => undef, raw_attrs => undef, + attrs => \%attrs, + attr_names => [ + grep $_ ne 'data-wrap', @{$ev[0]->{attr_names}} + ] + }; + $wrap{$select} = \@ev; + return $_[0]; + } }) + ->run; + reduce { + my @orig; + my $sel = $b; + $a->select($sel) + ->collect({ into => \@orig, passthrough => 1 }) + ->then + ->replace(sub { + my $orig = HTML::Zoom->from_events(\@orig); + my $wrap = HTML::Zoom->from_events(\@{$wrap{$sel}}); + my @to_replace; + $wrap->select('*[data-replace]') + ->collect({ into => \@to_replace, passthrough => 1 }) + ->then + ->replace(sub { + my $sel = $to_replace[0]->{attrs}{'data-replace'}; + $orig->collect($sel, { into => \my @replace_with })->run; + HTML::Zoom::ArrayStream->new({ array => \@replace_with }) + }) + ->to_stream; + }); + } $zoom, keys %wrap; } 1;