page loading code
Matt S Trout [Thu, 3 Feb 2011 20:40:14 +0000 (20:40 +0000)]
lib/SCSite/PageSet.pm [new file with mode: 0644]
t/pages.t [new file with mode: 0644]
t/pages/index.html [new file with mode: 0644]
t/pages/one/two.md [new file with mode: 0644]

diff --git a/lib/SCSite/PageSet.pm b/lib/SCSite/PageSet.pm
new file mode 100644 (file)
index 0000000..d2d440a
--- /dev/null
@@ -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 (file)
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+<p>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{<html>
+  <head>
+    <title>--TITLE--</title>
+    <meta name="description" content="--DESCRIPTION--" />
+    <meta name="keywords" content="--KW1-- --KW2--" />
+  </head>
+  <body>
+    <p>Some markdown here.</p>
+  </body>
+</html>};
+
+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 (file)
index 0000000..26f557a
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+  <head>
+    <title>--TITLE--</title>
+    <meta name="description" content="--DESCRIPTION--" />
+    <meta name="keywords" content="--KW1-- --KW2--" />
+  </head>
+  <body>
+    <p>Some markdown here.</p>
+  </body>
+</html>
diff --git a/t/pages/one/two.md b/t/pages/one/two.md
new file mode 100644 (file)
index 0000000..f56d3de
--- /dev/null
@@ -0,0 +1,5 @@
+Title: --TITLE--
+description: --DESCRIPTION--
+keywords: --KW1-- --KW2--
+
+Some markdown here.