basic porting work for SCSite
[scpubgit/App-SCS.git] / lib / App / SCS / Plugin / Core / PagePlugin / Template.pm
1 package App::SCS::Plugin::Core::PagePlugin::Template;
2
3 use List::Util qw(reduce);
4 use Moo;
5
6 with 'App::SCS::Role::PagePlugin';
7
8 has templates => (is => 'ro', required => 1);
9
10 has name => (is => 'ro', required => 1);
11
12 sub filter_html_zoom {
13   my ($self, $zoom) = @_;
14   my $template_page = $self->templates->get({ path => $self->name })
15     or die "No such template ${\$self->name}";
16   my $template_zoom = HTML::Zoom->from_html($template_page->html);
17   my @ev;
18   my %wrap;
19   $template_zoom->select('*[data-wrap]')
20                 ->collect({ into => \@ev, passthrough => 1 })
21                 ->then
22                 ->collect({ filter => sub {
23                     my %attrs = %{$ev[0]->{attrs}};
24                     my $select = delete $attrs{'data-wrap'};
25                     $ev[0] = {
26                       %{$ev[0]},
27                       raw => undef, raw_attrs => undef,
28                       attrs => \%attrs,
29                       attr_names => [
30                         grep $_ ne 'data-wrap', @{$ev[0]->{attr_names}}
31                       ]
32                     };
33                     $wrap{$select} = \@ev;
34                     return $_[0];
35                   } })
36                 ->run;
37   reduce {
38     my @orig;
39     my $sel = $b;
40     $a->select($sel)
41       ->collect({ into => \@orig, passthrough => 1 })
42       ->then
43       ->replace(sub {
44           my $orig = HTML::Zoom->from_events(\@orig);
45           my $wrap = HTML::Zoom->from_events(\@{$wrap{$sel}});
46           my @to_replace;
47           $wrap->select('*[data-replace]')
48                ->collect({ into => \@to_replace, passthrough => 1 })
49                ->then
50                ->replace(sub {
51                    my $sel = $to_replace[0]->{attrs}{'data-replace'};
52                    my $content = $sel =~ s/^content-of:\s*//;
53                    $orig->collect($sel, {
54                      into => \my @replace_with,
55                      content => $content
56                    })->run;
57                    HTML::Zoom::ArrayStream->new({ array => \@replace_with })
58                  })
59                ->to_stream;
60         });
61   } $zoom, keys %wrap;
62 }
63
64 1;