From: Matt S Trout Date: Tue, 31 Jul 2012 20:36:42 +0000 (+0000) Subject: html_zoom starts to work X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=0034f1516506431aeb0fd97f12c8087bdac9ef19;p=scpubgit%2FApp-SCS.git html_zoom starts to work --- diff --git a/lib/App/SCS.pm b/lib/App/SCS.pm index c8a3c07..56b393b 100644 --- a/lib/App/SCS.pm +++ b/lib/App/SCS.pm @@ -8,20 +8,45 @@ with 'App::SCS::Role::WithConfig'; has plugins => (is => 'ro', default => sub { [] }); +has root_dir => (is => 'lazy'); + +sub _build_root_dir { + my ($self) = @_; + io->dir(io->dir($self->config->{root_dir})->absolute); +} + +has share_dir => (is => 'lazy'); + +sub _build_share_dir { + my ($self) = @_; + io->dir($self->config->{share_dir}||$self->root_dir->catdir('share')); +} + +has page_plugin_config => (is => 'lazy'); + +sub _build_page_plugin_config { + my ($self) = @_; + return { + plugin_map => { + do { + my %map = map $_->page_plugins, reverse @{$self->plugins}; + ref($_) or $_ = { class => $_, config => sub {} } for values %map; + %map; + } + }, + defaults => [ + map $_->default_page_plugins, @{$self->plugins} + ], + }; +} + has pages => (is => 'lazy'); sub _build_pages { my ($self) = @_; return use_module('App::SCS::PageSet')->new( - base_dir => io->dir($self->config->{share_dir})->catdir('pages'), - plugin_config => { - plugin_map => { - map $_->page_plugins, reverse @{$self->plugins} - }, - defaults => [ - map $_->default_page_plugins, @{$self->plugins} - ], - } + base_dir => $self->share_dir->catdir('pages'), + plugin_config => $self->page_plugin_config, ); } diff --git a/lib/App/SCS/Page.pm b/lib/App/SCS/Page.pm index e6f78a4..a05c5e9 100644 --- a/lib/App/SCS/Page.pm +++ b/lib/App/SCS/Page.pm @@ -4,6 +4,7 @@ use IO::All; use Time::Local qw(timelocal); use Data::Pond qw(pond_read_datum pond_write_datum); use List::Util qw(reduce); +use Module::Runtime qw(use_module); use Moo; with 'App::SCS::Role::PageChildren'; @@ -42,15 +43,15 @@ has _page_plugins => (is => 'lazy'); sub _build__page_plugins { my ($self) = @_; my $plugin_config = $self->plugin_config; - my ($plugin_map, $defaults) = @{$self->_page_set}{qw(plugin_map defaults)}; - + my ($plugin_map, $defaults) = @{$self->_page_set->plugin_config} + {qw(plugin_map defaults)}; my @spec = (@$defaults, @$plugin_config); my @plugins; while (my ($name, $config) = splice @spec, 0, 2) { my $info = $plugin_map->{$name}; push @plugins, use_module($info->{class})->new( - %{$info->{config}||{}}, %$config, page => $self + ($info->{config}||sub{})->(), %$config, page => $self ); } return \@plugins; @@ -90,23 +91,27 @@ has _psgi_response => (is => 'lazy'); sub _build__psgi_response { my ($self) = @_; - my @plugins = @{$self->page_plugins}; - - my $html_zoom = reduce { - $b->filter_html_zoom($a) - } HTML::Zoom->from_html($self->html), @plugins; - - my $content_zoom = reduce { - $b->filter_content_zoom($a) - } $html_zoom, @plugins; - my $psgi_res = [ - 200, [ 'Content-type' => 'text/html' ], $content_zoom->to_fh + 200, [ 'Content-type' => 'text/html' ], $self->_content_zoom->to_fh ]; return reduce { $b->filter_psgi_response($a) - } $psgi_res, @plugins; + } $psgi_res, @{$self->_page_plugins}; +} + +sub _content_zoom { + my ($self) = @_; + return reduce { + $b->filter_content_zoom($a) + } $self->_html_zoom, @{$self->_page_plugins}; +} + +sub _html_zoom { + my ($self) = @_; + return reduce { + $b->filter_html_zoom($a) + } HTML::Zoom->from_html($self->html), @{$self->_page_plugins}; } no Moo; diff --git a/lib/App/SCS/PageSet.pm b/lib/App/SCS/PageSet.pm index b71c5d4..9dfc792 100644 --- a/lib/App/SCS/PageSet.pm +++ b/lib/App/SCS/PageSet.pm @@ -8,6 +8,7 @@ use App::SCS::Page; use IO::All; use Try::Tiny; use List::Util qw(reduce); +use Module::Runtime qw(use_module); use JSON; use Moo; @@ -131,15 +132,16 @@ sub _all_files { sub latest { my ($self, $max) = @_; - require SCSite::LatestPageSet; - SCSite::LatestPageSet->new( + use_module('App::SCS::LatestPageSet')->new( parent => $self, max_entries => $max, ); } sub _new_page { - SCSite::Page->new({ path => $_[1], page_set => $_[0], %{$_[2]} }) + use_module('App::SCS::Page')->new( + path => $_[1], page_set => $_[0], %{$_[2]} + ); } sub _types_re { qw/\.(html|md)/ } diff --git a/lib/App/SCS/Plugin/Core.pm b/lib/App/SCS/Plugin/Core.pm index f799f70..e6a943b 100644 --- a/lib/App/SCS/Plugin/Core.pm +++ b/lib/App/SCS/Plugin/Core.pm @@ -1,5 +1,7 @@ package App::SCS::Plugin::Core; +use Module::Runtime qw(use_module); +use IO::All; use Moo; no warnings::illegalproto; use Safe::Isa; @@ -11,7 +13,10 @@ has templates => (is => 'lazy'); sub _build_templates { my ($self) = @_; return use_module('App::SCS::PageSet')->new( - base_dir => io->dir($self->app->config->{share_dir})->catdir('templates'), + base_dir => io->dir($self->app->share_dir)->catdir('templates'), + plugin_config => { + plugin_map => $self->app->page_plugin_config->{plugin_map} + } ); } @@ -29,11 +34,11 @@ sub page_plugins { PageList => 'App::SCS::Plugin::Core::PagePlugin::PageList', Template => { class => 'App::SCS::Plugin::Core::PagePlugin::Template', - config => { templates => $self->templates }, + config => sub { templates => $self->templates }, }, Include => { class => 'App::SCS::Plugin::Core::PagePlugin::Include', - config => { includes => $self->includes }, + config => sub { includes => $self->includes }, }, PageData => 'App::SCS::Plugin::Core::PagePlugin::PageData', } diff --git a/lib/App/SCS/Plugin/Core/PagePlugin/Template.pm b/lib/App/SCS/Plugin/Core/PagePlugin/Template.pm index b1e47ce..6bac9fe 100644 --- a/lib/App/SCS/Plugin/Core/PagePlugin/Template.pm +++ b/lib/App/SCS/Plugin/Core/PagePlugin/Template.pm @@ -14,13 +14,14 @@ 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->collect('*[data-replace]', { into => \@ev }) + $template_zoom->select('*[data-replace]') + ->collect({ into => \@ev, passthrough => 1 }) ->then - ->${\sub { + ->replace(sub { my $sel = $ev[0]->{attrs}{'data-replace'}; - $zoom->collect($self, { into => \my @replace })->run; - shift->replace(\@replace); - }} + $zoom->collect($sel, { into => \my @replace })->run; + HTML::Zoom::ArrayStream->new({ array => \@replace }) + }); } 1; diff --git a/lib/App/SCS/Role/PagePlugin.pm b/lib/App/SCS/Role/PagePlugin.pm index f7b1055..ceee4cb 100644 --- a/lib/App/SCS/Role/PagePlugin.pm +++ b/lib/App/SCS/Role/PagePlugin.pm @@ -6,10 +6,10 @@ has 'page' => (is => 'ro', weak_ref => 1, required => 1); sub extra_pages { () } -sub filter_html_zoom { shift } +sub filter_html_zoom { $_[1] } -sub filter_content_zoom { shift } +sub filter_content_zoom { $_[1] } -sub filter_psgi_response { shift } +sub filter_psgi_response { $_[1] } 1; diff --git a/t/02simple.t b/t/02simple.t new file mode 100644 index 0000000..1854a8f --- /dev/null +++ b/t/02simple.t @@ -0,0 +1,46 @@ +use strictures 1; +use Test::More; +use App::SCS; +use IO::All; + +my $app = App::SCS->new( + config => { root_dir => 't/data' } +); + +my $simple1 = $app->pages->get({ path => 'simple/1' }); + +ok($simple1, 'Got a page object'); + +is( + $simple1->html, + io->file('t/data/share/pages/simple/1.html')->all, + "Correct file loaded" +); + +my @page_plugins = @{$simple1->_page_plugins}; + +is(scalar(@page_plugins), 2, 'Two plugins applied'); + +my ($tp, $pdp) = @page_plugins; + +ok( + $tp->isa('App::SCS::Plugin::Core::PagePlugin::Template'), + 'Template plugin' +); + +is($tp->name, 'layout', 'Template name'); + +ok( + $pdp->isa('App::SCS::Plugin::Core::PagePlugin::PageData'), + 'PageData plugin' +); + +like( + $simple1->_html_zoom->to_html, + qr{
.*

Hello world}s, + 'Layout woven correctly' +); + +warn $simple1->_content_zoom->to_html; + +done_testing; diff --git a/t/data/share/pages/simple/.htcache.1.html.json b/t/data/share/pages/simple/.htcache.1.html.json new file mode 100644 index 0000000..0c27fc5 --- /dev/null +++ b/t/data/share/pages/simple/.htcache.1.html.json @@ -0,0 +1 @@ +{"keywords":"","created":"","subtitle":"","plugins":"","html":"\n \n Simple 1\n \n \n

Hello world

\n \n\n","title":"Simple 1","description":""} \ No newline at end of file diff --git a/t/data/share/pages/simple/1.html b/t/data/share/pages/simple/1.html new file mode 100644 index 0000000..9116bed --- /dev/null +++ b/t/data/share/pages/simple/1.html @@ -0,0 +1,8 @@ + + + Simple 1 + + +

Hello world

+ + diff --git a/t/data/share/templates/.htcache.layout.html.json b/t/data/share/templates/.htcache.layout.html.json new file mode 100644 index 0000000..57e9c50 --- /dev/null +++ b/t/data/share/templates/.htcache.layout.html.json @@ -0,0 +1 @@ +{"keywords":"","created":"","subtitle":"","plugins":"","html":"\n \n \n
\n
\n
\n \n\n","title":"","description":""} \ No newline at end of file diff --git a/t/data/share/templates/layout.html b/t/data/share/templates/layout.html new file mode 100644 index 0000000..946c744 --- /dev/null +++ b/t/data/share/templates/layout.html @@ -0,0 +1,8 @@ + + + +
+
+
+ +