+#!/usr/bin/env perl
+
package SCSite;
use IO::All;
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',
)
}
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'));
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
}
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
);
$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;