process SCS_PAGES_DIR etc. env vars equivalently to --pages_dir config option
[scpubgit/SCS.git] / lib / SCSite.pm
old mode 100644 (file)
new mode 100755 (executable)
index ffa9cb2..a6b1abf
@@ -1,3 +1,5 @@
+#!/usr/bin/env perl
+
 package SCSite;
 
 use IO::All;
@@ -10,10 +12,19 @@ has filters => (is => 'lazy');
 
 has _layout_zoom => (is => 'lazy');
 
+has _feed_configs => (is => 'lazy');
+
+has _feed_generator => (
+  is => 'lazy',
+  handles => { _feed_http_response => 'feed_http_response' },
+);
+
 sub default_config {
   (
-    pages_dir => 'share/content',
-    template_dir => 'share/skin',
+    pages_dir => 'share/pages',
+    template_dir => 'share/templates',
+    static_dir => 'share/static',
+    feed_id_prefix => 'http://shadow.cat',
   )
 }
 
@@ -25,13 +36,51 @@ sub _build_pages {
 sub _build_filters {
   my ($self) = @_;
   require SCSite::SubListFilter;
-  +{ SubList => SCSite::SubListFilter->new }
+  require SCSite::SidebarFilter;
+  +{
+    map +($_ => "SCSite::${_}Filter"->new_from_site($self)),
+      qw(SubList Sidebar)
+  }
+}
+
+sub _build__feed_configs {
+  my $f = +{
+    'blog' => {
+      title => 'All Shadowcat blogs',
+      entries => { min_depth => 2, max_depth => 3 },
+    },
+    'blog/matt-s-trout' => {
+      title => q{Matt S Trout (mst)'s blog},
+      entries => { at_depth => 1 },
+    },
+    'blog/mark-keating' => {
+      title => q{Mark Keating (mdk)'s blog},
+      entries => { min_depth => 1, max_depth => 2 },
+    },
+    'news' => {
+      title => 'Shadowcat News',
+      entries => { at_depth => 4 },
+    },
+  };
+  $f->{$_}{base} ||= $_ for keys %$f;
+  $f;
+}
+
+sub _build__feed_generator {
+  my ($self) = @_;
+  require SCSite::FeedGenerator;
+  SCSite::FeedGenerator->new(
+    pages => $self->pages,
+    id_prefix => $self->config->{feed_id_prefix},
+  );
 }
 
 sub dispatch_request {
   my $self = shift;
   sub (/feed/**/) {
-    $self->_http_response(500 => 'text/plain' => 'Not implemented');
+    if (my $conf = $self->_feed_configs->{$_[1]}) {
+      $self->_feed_http_response(200 => $conf);
+    }
   },
   sub (/) {
     $self->_page_http_response(200 => $self->_find_page('index'));
@@ -70,13 +119,29 @@ sub _page_http_response {
 sub _render_page {
   my ($self, $page) = @_;
   my $zoom = $self->_layout_zoom;
-  $zoom->select('.title')->replace_content($page->title)
-       ->select('meta[name=description]')->replace_content($page->description)
-       ->select('meta[name=keywords]')->replace_content($page->keywords)
-       ->select('.main')->replace_content(\$page->body)
-       ->select('.SubList')->collect({
-           filter => $self->filters->{SubList}->callback_for($page),
-           passthrough => 1,
+  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('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);
+             $_ = $_->select(".${fname}")->collect({
+                        filter => $cb, passthrough => 1
+                      });
+           }
+           $_
          })
        ->to_fh
 }
@@ -93,7 +158,7 @@ sub run_if_script {
   my $class = shift;
   my @config_keys = keys %{{$class->default_config}};
   require Getopt::Long;
-  my %config;
+  my %config = map +($_ => $ENV{"SCS_${\uc $_}"}), @config_keys;
   Getopt::Long::GetOptions(
     map +("$_=s" => \$config{$_}), @config_keys
   );
@@ -102,4 +167,14 @@ sub run_if_script {
   $new->run(@_)
 }
 
+around _run_cli => sub {
+  my ($orig, $self) = (shift, shift);
+  if (@_ >= 2 and $_[0] eq 'dev' and $_[1] eq 'server') {
+    require SCSite::DevMode;
+    Moo::Role->apply_roles_to_object($self, 'SCSite::DevMode');
+    return $self->_run_dev_server(@_[2..$#_]);
+  }
+  return $self->$orig(@_);
+};
+
 __PACKAGE__->run_if_script;