line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
3
|
|
|
3
|
|
3487481
|
use 5.006; # our |
|
3
|
|
|
|
|
10
|
|
2
|
3
|
|
|
3
|
|
14
|
use strict; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
69
|
|
3
|
3
|
|
|
3
|
|
12
|
use warnings; |
|
3
|
|
|
|
|
12
|
|
|
3
|
|
|
|
|
234
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
package Statocles::AppRole::ExtraFeeds; |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = '0.001003'; |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
# ABSTRACT: Generate additional feed sets for apps |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
our $AUTHORITY = 'cpan:KENTNL'; # AUTHORITY |
12
|
|
|
|
|
|
|
|
13
|
3
|
|
|
3
|
|
418
|
use Moo::Role qw( has around ); |
|
3
|
|
|
|
|
14036
|
|
|
3
|
|
|
|
|
23
|
|
14
|
3
|
|
|
3
|
|
875
|
use Carp qw( croak ); |
|
3
|
|
|
|
|
4
|
|
|
3
|
|
|
|
|
186
|
|
15
|
3
|
|
|
3
|
|
502
|
use Statocles::App 0.070 (); # 0.70 required for ->template |
|
3
|
|
|
|
|
1123886
|
|
|
3
|
|
|
|
|
67
|
|
16
|
3
|
|
|
3
|
|
514
|
use Statocles::Page::List (); |
|
3
|
|
|
|
|
258257
|
|
|
3
|
|
|
|
|
76
|
|
17
|
3
|
|
|
3
|
|
17
|
use namespace::autoclean; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
31
|
|
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
has 'extra_feeds' => ( |
20
|
|
|
|
|
|
|
is => 'ro', |
21
|
|
|
|
|
|
|
lazy => 1, |
22
|
|
|
|
|
|
|
default => sub { {} }, |
23
|
|
|
|
|
|
|
); |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
|
29
|
3
|
|
|
3
|
|
496
|
use constant PATH_INDEX_PREFIX => qr{ \A (.*) / index [.](\w+) \z}sx; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
433
|
|
30
|
3
|
|
|
3
|
|
35
|
use constant PATH_GENERIC_PREFIX => qr{ \A (.*) / ([^/.]+) [.](\w+) \z}sx; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
1525
|
|
31
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
# This separation is to help Coverage tools not lie to me that I did a perfect job |
33
|
|
|
|
|
|
|
around pages => \&_around_pages; |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
sub _around_pages { |
36
|
2
|
|
|
2
|
|
561492
|
my ( $orig, $self, @rest ) = @_; |
37
|
2
|
|
|
|
|
30
|
my (@pages) = $self->$orig(@rest); |
38
|
|
|
|
|
|
|
|
39
|
2
|
50
|
|
|
|
139020
|
return @pages unless @pages; |
40
|
|
|
|
|
|
|
|
41
|
2
|
|
|
|
|
4
|
my %feed_cache; |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
my @out_pages; |
44
|
|
|
|
|
|
|
|
45
|
2
|
|
|
|
|
10
|
while (@pages) { |
46
|
18
|
|
|
|
|
422
|
my $page = shift @pages; |
47
|
|
|
|
|
|
|
|
48
|
18
|
|
|
|
|
23
|
push @out_pages, $page; |
49
|
|
|
|
|
|
|
|
50
|
18
|
|
|
|
|
238
|
my (@existing_feeds) = $page->links('feed'); |
51
|
|
|
|
|
|
|
|
52
|
18
|
100
|
|
|
|
1292
|
next if not @existing_feeds; |
53
|
|
|
|
|
|
|
|
54
|
6
|
|
|
|
|
7
|
for my $feed_id ( sort keys %{ $self->extra_feeds } ) { |
|
6
|
|
|
|
|
83
|
|
55
|
6
|
|
|
|
|
108
|
my $feed = $self->extra_feeds->{$feed_id}; |
56
|
6
|
|
|
|
|
23
|
my $feed_path; |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
{ |
59
|
6
|
|
|
|
|
7
|
my $reference_path = $existing_feeds[0]->href; |
|
6
|
|
|
|
|
69
|
|
60
|
6
|
|
33
|
|
|
40
|
my $feed_suffix = $feed->{name} || $feed_id; |
61
|
|
|
|
|
|
|
|
62
|
6
|
100
|
|
|
|
36
|
if ( $reference_path =~ PATH_INDEX_PREFIX ) { |
|
|
50
|
|
|
|
|
|
63
|
3
|
|
|
|
|
11
|
$feed_path = "$1/$feed_suffix"; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
elsif ( $reference_path =~ PATH_GENERIC_PREFIX ) { |
66
|
3
|
|
|
|
|
17
|
$feed_path = "$1/$2.$feed_suffix"; |
67
|
|
|
|
|
|
|
} |
68
|
|
|
|
|
|
|
else { |
69
|
0
|
|
|
|
|
0
|
croak "Don't know how to derive feed path from $reference_path for $feed_suffix"; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
6
|
100
|
|
|
|
14
|
if ( not exists $feed_cache{$feed_path} ) { |
74
|
|
|
|
|
|
|
my $feed_page = $feed_cache{$feed_path}{feed_page} = Statocles::Page::List->new( |
75
|
|
|
|
|
|
|
app => $self, |
76
|
|
|
|
|
|
|
pages => $page->pages, |
77
|
|
|
|
|
|
|
path => $feed_path, |
78
|
|
|
|
|
|
|
template => $self->template( $feed->{template} || $feed->{name} || $feed_id ), |
79
|
|
|
|
|
|
|
links => { |
80
|
|
|
|
|
|
|
alternate => [ |
81
|
|
|
|
|
|
|
$self->link( |
82
|
|
|
|
|
|
|
href => $page->path, |
83
|
4
|
|
33
|
|
|
12
|
title => ( $feed->{'index_title'} || $page->title || 'Web Index' ), |
|
|
|
50
|
|
|
|
|
84
|
|
|
|
|
|
|
type => $page->type, |
85
|
|
|
|
|
|
|
), |
86
|
|
|
|
|
|
|
], |
87
|
|
|
|
|
|
|
}, |
88
|
|
|
|
|
|
|
); |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
$feed_cache{$feed_path}{feed_link} = $self->link( |
91
|
|
|
|
|
|
|
text => $feed->{text}, |
92
|
4
|
|
|
|
|
4771
|
href => $feed_page->path->stringify, |
93
|
|
|
|
|
|
|
type => $feed_page->type, |
94
|
|
|
|
|
|
|
); |
95
|
|
|
|
|
|
|
} |
96
|
6
|
|
|
|
|
643
|
$page->links( feed => $feed_cache{$feed_path}{feed_link} ); |
97
|
|
|
|
|
|
|
} |
98
|
|
|
|
|
|
|
} |
99
|
2
|
|
|
|
|
10
|
return @out_pages, map { $feed_cache{$_}{feed_page} } sort keys %feed_cache; |
|
4
|
|
|
|
|
71
|
|
100
|
|
|
|
|
|
|
} |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
1; |
103
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
__END__ |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=pod |
107
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=encoding UTF-8 |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
=head1 NAME |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
Statocles::AppRole::ExtraFeeds - Generate additional feed sets for apps |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
=head1 VERSION |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
version 0.001003 |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
=head1 EXPERIMENTAL |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
This module is very new and it comes with the following present caveats: |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=over 4 |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
=item * Application outside C<Statocles::App::Blog> untested. |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
Feedback welcome though, and it might work by magic! |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
=item * Implementation details a bit sketchy |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
The code works. I kinda feel like it shouldn't, and its like I've performed some magic |
131
|
|
|
|
|
|
|
trick and the gods have smiled on me for a moment. |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=item * You're on your own with templates |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
This at present is a glorified lump of glue on top of existing C<Statocles> behavior. |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
As such, if you want this to work, you'll probably want to copy some templates and modify them. |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
This module does nothing for you in terms of the actual formatting, it just pumps the right |
140
|
|
|
|
|
|
|
glue so that the same code that generates the existing feeds will be invoked a few more times |
141
|
|
|
|
|
|
|
but with the file names and templates you chose ( instead of the ones provided by default by the app ) |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
Basically, you're going to want to copy C<blog/index.rss.ep> to C<blog/fulltext.rss.ep> and tweak |
144
|
|
|
|
|
|
|
it a bit, or something. |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
=back |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=head1 DESCRIPTION |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
This module is a role that can be applied to any C<Statocles::App> in a C<Statocles>'s C<Beam::Wire> |
151
|
|
|
|
|
|
|
configuration. |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
... |
154
|
|
|
|
|
|
|
blog_app: |
155
|
|
|
|
|
|
|
class: 'Statocles::App::Blog' |
156
|
|
|
|
|
|
|
with: 'Statocles::AppRole::ExtraFeeds' |
157
|
|
|
|
|
|
|
args: |
158
|
|
|
|
|
|
|
url_root: '/blog' |
159
|
|
|
|
|
|
|
# ... more Statocles::App::Blog args |
160
|
|
|
|
|
|
|
extra_feeds: |
161
|
|
|
|
|
|
|
fulltext.rss: |
162
|
|
|
|
|
|
|
text: "RSS FullText" |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
This example creates a feed called C</blog/fulltext.rss> containing the contents of C<theme/blog/fulltext.rss.ep> |
165
|
|
|
|
|
|
|
after template application, and is linked from every C<index> listing. |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
It also creates a feed called C<< /blog/tag/<%= tagname %>.fulltext.rss >> for each tag, provisioned from the same template. |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=for Pod::Coverage PATH_INDEX_PREFIX PATH_GENERIC_PREFIX |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
=head1 PARAMETERS |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
=head2 C<extra_feeds> |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
This Role provides one tunable parameter on its applied class, C<extra_feeds>, which contains a |
176
|
|
|
|
|
|
|
mapping of |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
id => spec |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=head3 C<extra_feeds> spec. |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
{ |
183
|
|
|
|
|
|
|
text => required |
184
|
|
|
|
|
|
|
name => default( id ) |
185
|
|
|
|
|
|
|
template => default( id ) |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=head4 C<text> |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
This is the name of the feed when shown in links on both C<index> and C<tag index> pages. |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
=head4 C<template> |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
This is the name of the template to render the feeds content into. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
Defaults to taking the same value as the key in the C<extra_fields> hash. |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=head4 C<name> |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
This is the name of the file/file suffix that is generated. |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
It defaults to the same value as the key in the C<extra_feeds> |
203
|
|
|
|
|
|
|
hash. |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
So: |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
extra_feeds: |
208
|
|
|
|
|
|
|
fulltext.rss: |
209
|
|
|
|
|
|
|
text: "My FullText RSS" |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
And |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
extra_feeds: |
214
|
|
|
|
|
|
|
genericlabel: |
215
|
|
|
|
|
|
|
text: "My FullText RSS" |
216
|
|
|
|
|
|
|
name: 'fulltext.rss' # output name |
217
|
|
|
|
|
|
|
template: 'fulltext.rss' # source template |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
Should both generate the same result. |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
=head1 AUTHOR |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
Kent Fredric <kentnl@cpan.org> |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=head1 COPYRIGHT AND LICENSE |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
This software is copyright (c) 2017 by Kent Fredric <kentfredric@gmail.com>. |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
This is free software; you can redistribute it and/or modify it under |
230
|
|
|
|
|
|
|
the same terms as the Perl 5 programming language system itself. |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
=cut |