return to $self by following the upgrade instructions in the docs
[catagits/Web-Simple.git] / examples / bloggery / bloggery.cgi
CommitLineData
89166c1b 1#!/usr/bin/perl
2
5c33dda5 3use FindBin;
4use lib $FindBin::Bin.'/code';
5use Web::Simple 'Bloggery';
6
7package Bloggery::PostList;
8
9use File::stat;
10
11sub from_dir {
12 my ($class, $dir) = @_;
13 bless ({ dir => $dir }, $class);
14}
15
16sub all {
17 my ($self) = @_;
18 map { Bloggery::Post->from_file($_) }
19 sort { stat($a)->mtime <=> stat($b)->mtime }
20 grep { !/\.summary\.html$/ }
21 glob($self->{dir}.'/*.html');
22}
23
24sub post {
25 my ($self, $name) = @_;
26 my $file = $self->{dir}."/${name}.html";
27 return unless $file && -f $file;
28 return Bloggery::Post->from_file($file);
29}
30
d2a1d0c7 31sub map {
32 my ($self, $code) = @_;
33 map $code->($_), $self->all;
34}
35
5c33dda5 36package Bloggery::Post;
37
38sub from_file {
39 my ($class, $file) = @_;
40 bless({ file => $file }, $class);
41}
42
43sub name {
44 my $name = shift->{file};
45 $name =~ s/.*\///;
46 $name =~ s/\.html$//;
47 $name;
48}
49
50sub title {
51 my $title = shift->name;
52 $title =~ s/-/ /g;
53 $title;
54}
55
56sub html {
57 \do { local (@ARGV, $/) = shift->{file}; <> };
58}
59
60sub summary_html {
61 my $file = shift->{file};
62 $file =~ s/\.html$/.summary.html/;
63 return \'<p>No summary</p>' unless -f $file;
64 \do { local (@ARGV, $/) = $file; <> };
65}
66
67package Bloggery;
68
69default_config(
70 title => 'Bloggery',
71 posts_dir => $FindBin::Bin.'/posts',
72);
73
74sub post_list {
75 my ($self) = @_;
76 $self->{post_list}
77 ||= Bloggery::PostList->from_dir(
78 $self->config->{posts_dir}
79 );
80}
81
82sub post {
83 my ($self, $post) = @_;
84 $self->post_list->post($post);
85}
86
7274da22 87sub dispatch_request {
48cab33d 88 my $self = shift;
5c33dda5 89 sub (GET + /) {
48cab33d 90 redispatch_to '/index.html';
5c33dda5 91 },
4ed4fb42 92 sub (.html) {
48cab33d 93 response_filter { $self->render_html($_[1]) },
4ed4fb42 94 },
5c33dda5 95 sub (GET + /index) {
48cab33d 96 $self->post_list
5c33dda5 97 },
98 sub (GET + /*) {
48cab33d 99 $self->post($_[1])
5c33dda5 100 },
101 sub (GET) {
102 [ 404, [ 'Content-type', 'text/plain' ], [ 'Not found' ] ]
103 },
104 sub {
105 [ 405, [ 'Content-type', 'text/plain' ], [ 'Method not allowed' ] ]
106 },
92e23550 107};
5c33dda5 108
109sub render_html {
110 my ($self, $data) = @_;
111 use HTML::Tags;
112 return $data if ref($data) eq 'ARRAY';
113 return [
114 200,
115 [ 'Content-type', 'text/html' ],
116 [
117 HTML::Tags::to_html_string(
118 <html>,
119 <head>,
120 <title>, $self->title_for($data), </title>,
121 </head>,
122 <body>,
123 <h1>, $self->title_for($data), </h1>,
124 <div id="main">,
125 $self->main_html_for($data),
126 </div>,
127 </body>,
128 </html>
129 )
130 ]
131 ];
132}
133
134sub title_for {
135 my ($self, $data) = @_;
136 if ($data->isa('Bloggery::Post')) {
137 return $data->title;
138 }
139 return $self->config->{title};
140}
141
142sub main_html_for {
143 my ($self, $data) = @_;
144 use HTML::Tags;
145 if ($data->isa('Bloggery::Post')) {
146 $data->html
147 } elsif ($data->isa('Bloggery::PostList')) {
148 <ul>,
d2a1d0c7 149 $data->map(sub {
89166c1b 150 my $path = $_->name.'.html';
5c33dda5 151 <li>,
152 <h4>, <a href="$path">, $_->title, </a>, </h4>,
153 <span class="summary">, $_->summary_html, </span>,
154 </li>;
d2a1d0c7 155 }),
5c33dda5 156 </ul>;
157 } else {
158 <h2>, "Don't know how to render $data", </h2>;
159 }
160}
161
162Bloggery->run_if_script;