From: Matt S Trout Date: Thu, 3 Feb 2011 20:40:14 +0000 (+0000) Subject: page loading code X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=95148a72537d655421a86802a83117edce57d70b;p=scpubgit%2FSCS.git page loading code --- 95148a72537d655421a86802a83117edce57d70b diff --git a/lib/SCSite/PageSet.pm b/lib/SCSite/PageSet.pm new file mode 100644 index 0000000..d2d440a --- /dev/null +++ b/lib/SCSite/PageSet.pm @@ -0,0 +1,64 @@ +package SCSite::PageSet; + +{ package SCSite::Page; use Moo; + has $_ => (is => 'ro') for qw(title description keywords body); +} + +use IO::All; +use Text::MultiMarkdown 'markdown'; +use HTML::Zoom; +use Moo; + +has base_dir => (is => 'ro', required => 1); + +sub get { + my ($self, $spec) = @_; + $spec->{path} or die "path is required to get"; + my ($dir, $file) = $spec->{path} =~ m{^(?:(.*)/)?([^/]+)$}; + my $type; + my @poss = io($self->base_dir)->${\sub { + my $io = shift; + defined($dir) ? $io->catdir($dir) : $io + }}->filter(sub { $_->filename =~ /\Q${file}\E\.(html|md)/ and $type = $1 }) + ->all_files; + die "multiple files found for ${\$spec->{path}}:\n".join "\n", @poss + if @poss > 1; + $self->${\"_inflate_${type}"}($poss[0]->all); +} + +sub _new_page { + SCSite::Page->new($_[1]) +} + +sub _inflate_html { + my ($self, $html) = @_; + $self->_new_page($self->_extract_from_html($html)); +} + +sub _extract_from_html { + my ($self, $html) = @_; + HTML::Zoom->from_html($html) + ->select('title')->collect_content({ into => \my @title }) + ->select('meta[name=description]')->collect({ into => \my @description }) + ->select('meta[name=keywords]')->collect({ into => \my @keywords }) + ->select('body')->collect_content({ into => \my @body }) + ->run; + +{ + title => $title[0]->{raw}, + description => $description[0]->{attrs}{content}, + keywords => $keywords[0]->{attrs}{content}, + body => HTML::Zoom->from_events(\@body)->to_html, + } +} + +sub _inflate_md { + my ($self, $md) = @_; + $self->_new_page($self->_extract_from_md($md)); +} + +sub _extract_from_md { + my ($self, $md) = @_; + $self->_extract_from_html(markdown($md, { document_format => 'complete' })); +} + +1; diff --git a/t/pages.t b/t/pages.t new file mode 100644 index 0000000..adb1d44 --- /dev/null +++ b/t/pages.t @@ -0,0 +1,48 @@ +use strictures 1; +use Test::More; +use SCSite::PageSet; + +sub check_structure { + my ($s) = @_; + $s = { %$s }; + my $body = delete $s->{body}; + like($body, qr/^\s+

Some markdown here.<\/p>\s+$/sm, 'Body correct'); + is_deeply($s, + { + title => '--TITLE--', + description => '--DESCRIPTION--', + keywords => '--KW1-- --KW2--' + }, + 'Metadata ok' + ); +} + +my $ps = SCSite::PageSet->new(base_dir => 't/pages'); + +my $test_html = q{ + + --TITLE-- + + + + +

Some markdown here.

+ +}; + +check_structure($ps->_extract_from_html($test_html)); + +my $test_md = q{Title: --TITLE-- +description: --DESCRIPTION-- +keywords: --KW1-- --KW2-- + +Some markdown here. +}; + +check_structure($ps->_extract_from_md($test_md)); + +check_structure($ps->get({ path => 'index' })); + +check_structure($ps->get({ path => 'one/two' })); + +done_testing; diff --git a/t/pages/index.html b/t/pages/index.html new file mode 100644 index 0000000..26f557a --- /dev/null +++ b/t/pages/index.html @@ -0,0 +1,10 @@ + + + --TITLE-- + + + + +

Some markdown here.

+ + diff --git a/t/pages/one/two.md b/t/pages/one/two.md new file mode 100644 index 0000000..f56d3de --- /dev/null +++ b/t/pages/one/two.md @@ -0,0 +1,5 @@ +Title: --TITLE-- +description: --DESCRIPTION-- +keywords: --KW1-- --KW2-- + +Some markdown here.