subtitle handling, prettified dates. bugfixes and better errors
Matt S Trout [Fri, 25 Feb 2011 06:43:36 +0000 (06:43 +0000)]
lib/SCSite.pm
lib/SCSite/Filter.pm
lib/SCSite/LatestPageSet.pm
lib/SCSite/Page.pm
lib/SCSite/PageSet.pm
lib/SCSite/SubListFilter.pm
share/templates/layout.html

index 43efb3f..7f6577b 100644 (file)
@@ -119,11 +119,19 @@ sub _render_page {
   my $zoom = $self->_layout_zoom;
   my %filters = %{$self->filters};
   $zoom->select('.page.title')->replace_content($page->title)
+       ->select('.page.subtitle')->${\sub {
+           $page->subtitle
+             ? $_[0]->replace_content($page->subtitle)
+             : $_[0]->replace('')
+         }}
+       ->select('.page.published_at')->replace_content($page->published_at)
        ->select('meta[name=description]')
          ->set_attribute(content => $page->description)
        ->select('meta[name=keywords]')
          ->set_attribute(content => $page->keywords)
-       ->select('.main')->replace_content(\$page->body)
+       ->select('meta[name=created]')
+         ->set_attribute(content => $page->created)
+       ->select('.page.body')->replace_content(\$page->body)
        ->apply(sub {
            foreach my $fname (sort keys %filters) {
              my $cb = $filters{$fname}->callback_for($page);
index 6897fc7..16e9896 100644 (file)
@@ -18,7 +18,10 @@ sub callback_for {
 sub _parse_config {
   my ($self, $evt) = @_;
   my %config = ( # adapted from CSS::Tiny, extracts -scs- prefix.
-    map /^\s*-scs-([\w._-]+)\s*:\s*(.*?)\s*$/,
+    map {        # converts -scs-foo-bar: to foo_bar
+      /^\s*-scs-([\w._-]+)\s*:\s*(.*?)\s*$/;
+      (join('_', split '-', $1), $2);
+    }
       grep { /\S/ } split /\;/, ($evt->{attrs}{style}||'')
   );
   s/^'(.*)'$/$1/ for values %config;
index dbeca56..c8fd13f 100644 (file)
@@ -11,7 +11,7 @@ sub flatten {
     $b->created cmp $a->created
   } $self->_parent->flatten;
   my $max = $self->_max_entries||0;
-  @sorted > $max ? @sorted[0..$max-1] : @sorted;
+  $max && @sorted > $max ? @sorted[0..$max-1] : @sorted;
 }
 
 sub map {
index b1b7e6f..7d09627 100644 (file)
@@ -1,9 +1,20 @@
 package SCSite::Page;
 
 use IO::All;
+use Time::Local qw(timelocal);
 use Moo;
 
-has $_ => (is => 'ro') for qw(title description keywords body created path);
+has $_ => (is => 'ro') for qw(
+  title subtitle description keywords body created path
+);
+
+sub published_at {
+  $_[0]->created
+    ? scalar localtime timelocal
+        map +(@{$_}[0..3], $_->[4]-1, $_->[5]-1900),
+          [ reverse split '\D+', $_[0]->created ]
+    : ''
+}
 
 has "_$_" => (is => 'ro', init_arg => $_) for qw(page_set);
 
index 0e0aedd..f55a868 100644 (file)
@@ -7,6 +7,7 @@ use Sub::Quote;
 use Syntax::Keyword::Gather;
 use SCSite::Page;
 use Moo;
+use Try::Tiny;
 
 has top_dir => (is => 'ro', lazy => 1, builder => 'base_dir');
 has base_dir => (is => 'ro', required => 1);
@@ -36,11 +37,19 @@ sub get {
   die "multiple files found for ${\$spec->{path}}:\n".join "\n", @poss
     if @poss > 1;
   return undef unless @poss;
-  $self->${\"_inflate_${type}"}(
-    $self->rel_path->catdir($spec->{path}), $poss[0]->all
+  $self->_inflate(
+    $type, $self->rel_path->catdir($spec->{path}), $poss[0]->all
   );
 }
 
+sub _inflate {
+  my ($self, $type, $path, $data) = @_;
+  try { $self->${\"_inflate_${type}"}($path, $data) }
+  catch {
+    die "Error inflating ${path} as ${type}: $_\n\nData was: ${data}";
+  }
+}
+
 sub map {
   my ($self, $mapper) = @_;
   [ map $mapper->($_), $self->flatten ]
@@ -59,7 +68,8 @@ sub flatten {
   my $min = $self->min_depth;
   map {
     my ($path, $type) = $_->name =~ /^(.*)${\$self->_types_re}$/;
-    $self->${\"_inflate_${type}"}(
+    $self->_inflate(
+      $type,
       $slash->catdir(File::Spec->abs2rel($path, $self->top_dir->name)),
       $_->all
     );
@@ -100,6 +110,7 @@ sub _extract_from_html {
   my ($self, $html) = @_;
   HTML::Zoom->from_html($html)
     ->select('title')->collect_content({ into => \my @title })
+    ->select('meta[name=subtitle]')->collect({ into => \my @subtitle })
     ->select('meta[name=description]')->collect({ into => \my @description })
     ->select('meta[name=keywords]')->collect({ into => \my @keywords })
     ->select('meta[name=created]')->collect({ into => \my @created })
@@ -107,6 +118,7 @@ sub _extract_from_html {
     ->run;
   +{
     title => $title[0]->{raw}||'',
+    subtitle => $subtitle[0]->{attrs}{content}||'',
     description => $description[0]->{attrs}{content}||'',
     keywords => $keywords[0]->{attrs}{content}||'',
     created => $created[0]->{attrs}{content}||'',
index 4246bd6..53489f3 100644 (file)
@@ -7,13 +7,17 @@ with 'SCSite::Filter';
 sub _filter_stream {
   my ($self, $stream, $config, $page) = @_;
   my $max = $config->{max_entries}||undef; # explicit undef (not 0)
+  my %child =
+    map +(exists $config->{$_} ? ($_ => $config->{$_}) : ()),
+      qw(min_depth max_depth at_depth);
   $stream->select('.SubList')
-         ->repeat_content($page->children->latest($max)->map(sub {
+         ->repeat_content($page->children(%child)->latest($max)->map(sub {
              my $o = shift;
              sub {
                $_->select('.entry.title')->replace_content($o->title)
+                 ->select('.entry.subtitle')->replace_content($o->subtitle)
                  ->select('.entry.description')->replace_content($o->description)
-                 ->select('.entry.created')->replace_content($o->created)
+                 ->select('.entry.published_at')->replace_content($o->published_at)
                  ->select('.entry.link')->set_attribute(href => $o->path);
              }
           }));
index 5efd444..996ab13 100644 (file)
@@ -7,6 +7,7 @@
     <meta name="author" content="Mark Keating, Matthew Trout, Chris Jackson, Eden Cardim, Wallace Reis" />
     <meta name="description" />
     <meta name="keywords" />
+    <meta name="created" />
     <meta name="copyright" content="2005-08 Shadowcat Systems Limited" />
     <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
 
           </table>
         </div>
 
-        <div id="maincontent" class="main">
+        <div id="maincontent">
+          <h3 class="page subtitle"></h3>
+          <p class="page published_at"></p>
+          <div class="page body"></div>
+
         </div>
 
         <div id="footer">