Commit | Line | Data |
221c4151 |
1 | package SCSite::FeedGenerator; |
2 | |
3 | use Moo; |
4 | no warnings 'once'; |
5 | |
6 | has id_prefix => (is => 'ro', required => 1); |
7 | has pages => (is => 'ro', required => 1); |
8 | |
9 | sub feed_http_response { |
10 | my ($self, $code, $feed_config) = @_; |
11 | $self->_feed_response( |
12 | $code, $self->_config_to_data($feed_config) |
13 | ); |
14 | } |
15 | |
16 | sub _config_to_data { |
17 | my ($self, $config) = @_; |
18 | my $base_page = $self->pages->get({ path => $config->{base} }); |
19 | my @entry_pages = $base_page->children(%{$config->{entries}}) |
20 | ->latest(10)->flatten; |
21 | +{ |
22 | %$config, |
23 | id => $self->_id_for($base_page->path), |
24 | web_url => $base_page->path, |
25 | feed_url => "/feed/${\$config->{base}}", |
26 | entries => [ map +{ |
27 | title => $_->title, |
28 | summary_html => do { |
29 | use HTML::Tags; |
30 | HTML::Tags::to_html_string(<p>, $_->description, </p>) |
31 | }, |
32 | content_html => $_->body, |
33 | created => $_->created, |
34 | web_url => $_->path, |
35 | }, @entry_pages ], |
36 | } |
37 | } |
38 | |
39 | sub _id_for { |
40 | my ($self, $for) = @_; |
41 | join '', $self->id_prefix, $for; |
42 | } |
43 | |
44 | sub _feed_response { |
45 | my ($self, $code, $data) = @_; |
46 | [ $code, |
47 | [ 'Content-type' => 'application/atom+xml' ], |
48 | [ $self->_feed_string($data) ] |
49 | ] |
50 | } |
51 | |
52 | sub _feed_string { |
53 | my ($self, $data) = @_; |
54 | XML::Tags::to_xml_string( |
55 | $self->_feed_data_to_tags($data) |
56 | ); |
57 | } |
58 | |
59 | sub _feed_data_to_tags { |
60 | my ($self, $data) = @_; |
61 | use XML::Tags qw( |
62 | feed title subtitle link id |
63 | ); |
64 | my ($web_url, $feed_url) = @{$data}{qw(web_url feed_url)}; |
8509b33b |
65 | (\'<?xml version="1.0" encoding="UTF-8"?>', "\n", |
66 | <feed xmlns="http://www.w3.org/2005/Atom">, "\n", |
67 | ' ', <title type="text">, $data->{title}, </title>, "\n", |
221c4151 |
68 | ($data->{subtitle} |
8509b33b |
69 | ? (' ', <subtitle type="text">, $data->{subtitle}, </subtitle>, "\n",) |
221c4151 |
70 | : ()), |
8509b33b |
71 | ' ', <link rel="alternate" type="text/html" href="${web_url}" />, "\n", |
72 | ' ', <link rel="self" type="application/atom+xml" href="${feed_url}" />, "\n", |
73 | ' ', <id>, $data->{id}, </id>, "\n", |
221c4151 |
74 | (map $self->_entry_data_to_tags($_), @{$data->{entries}}), |
75 | </feed>); |
76 | } |
77 | |
78 | sub _entry_data_to_tags { |
79 | my ($self, $data) = @_; |
80 | use XML::Tags qw(entry title link id published updated summary content); |
81 | my $web_url = $data->{web_url}; |
8509b33b |
82 | ' ', <entry>, "\n", |
83 | ' ', <title>, $data->{title}, </title>, "\n", |
84 | ' ', <link href="${web_url}" />, "\n", |
85 | ' ', <id>, $self->_id_for($data->{web_url}), </id>, "\n", |
86 | ' ', <published>, $data->{created}, </published>, "\n", |
87 | ' ', <updated>, ($data->{created}||$data->{updated}), </updated>, "\n", |
221c4151 |
88 | ($data->{summary_html} |
8509b33b |
89 | ? (' ', <summary type="html">, \($data->{summary_html}), </summary>, "\n") |
221c4151 |
90 | : () |
91 | ), |
8509b33b |
92 | ' ', <content type="html">, \($data->{body_html}), </content>, "\n", |
93 | ' ', </entry>, "\n"; |
221c4151 |
94 | } |
95 | |
96 | 1; |