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