start of SubList filter code
[scpubgit/SCS.git] / lib / SCSite.pm
CommitLineData
5cc6d9e2 1package SCSite;
2
3use IO::All;
4use SCSite::PageSet;
5use Web::Simple;
6
5cc6d9e2 7has pages => (is => 'lazy');
8
ebd4c292 9has filters => (is => 'lazy');
10
5cc6d9e2 11has _layout_zoom => (is => 'lazy');
12
13sub default_config {
14 (
15 pages_dir => 'share/content',
16 template_dir => 'share/skin',
17 )
18}
19
20sub _build_pages {
21 my ($self) = @_;
ebd4c292 22 SCSite::PageSet->new(base_dir => io->dir($self->config->{pages_dir}))
23}
24
25sub _build_filters {
26 my ($self) = @_;
27 require SCSite::SubListFilter;
28 +{ SubList => SCSite::SubListFilter->new }
5cc6d9e2 29}
30
31sub dispatch_request {
32 my $self = shift;
33 sub (/feed/**/) {
34 $self->_http_response(500 => 'text/plain' => 'Not implemented');
35 },
36 sub (/) {
37 $self->_page_http_response(200 => $self->_find_page('index'));
38 },
39 sub (/**) {
40 [ 302, [ 'Location' => "/$_[1]/" ], [] ]
41 },
42 sub (/**/) {
43 my ($code, $page) = map {
44 $_ ? (200, $_) : (404, $self->_error_page(404))
45 } $self->_find_page($_[1]);
46 $self->_page_http_response($code => $page);
47 }
48}
49
50sub _error_page {
51 my ($self, $code) = @_;
52 $self->_find_page("error_${code}");
53}
54
55sub _find_page {
56 my ($self, $path) = @_;
57 $self->pages->get({ path => $path });
58}
59
60sub _http_response {
61 my ($self, $code, $type, $content) = @_;
62 [ $code, [ 'Content-type' => $type ], [ $content ] ];
63}
64
65sub _page_http_response {
66 my ($self, $code, $page) = @_;
67 [ $code, [ 'Content-type' => 'text/html' ], $self->_render_page($page) ];
68}
69
70sub _render_page {
71 my ($self, $page) = @_;
72 my $zoom = $self->_layout_zoom;
73 $zoom->select('.title')->replace_content($page->title)
74 ->select('meta[name=description]')->replace_content($page->description)
75 ->select('meta[name=keywords]')->replace_content($page->keywords)
5cc6d9e2 76 ->select('.main')->replace_content(\$page->body)
ebd4c292 77 ->select('.SubList')->collect({
78 filter => $self->filters->{SubList}->callback_for($page),
79 passthrough => 1,
80 })
5cc6d9e2 81 ->to_fh
82}
83
84sub _build__layout_zoom {
85 my ($self) = @_;
86 HTML::Zoom->from_file(
87 io->dir($self->config->{template_dir})->catfile('layout.html')
88 )->memoize;
89}
90
91sub run_if_script {
92 return $_[0]->to_psgi_app if caller(1);
93 my $class = shift;
94 my @config_keys = keys %{{$class->default_config}};
95 require Getopt::Long;
96 my %config;
97 Getopt::Long::GetOptions(
98 map +("$_=s" => \$config{$_}), @config_keys
99 );
100 delete $config{$_} for grep !defined($config{$_}), keys %config;
101 my $new = $class->new(config => \%config);
102 $new->run(@_)
103}
104
105__PACKAGE__->run_if_script;