File Coverage

blib/lib/HiD/Role/IsPost.pm
Criterion Covered Total %
statement 50 61 81.9
branch 10 18 55.5
condition 0 3 0.0
subroutine 16 20 80.0
pod 3 3 100.0
total 79 105 75.2


line stmt bran cond sub pod time code
1             # ABSTRACT: Role for blog posts
2              
3              
4             package HiD::Role::IsPost;
5             our $AUTHORITY = 'cpan:GENEHACK';
6             $HiD::Role::IsPost::VERSION = '1.991';
7 12     12   8362 use Moose::Role;
  12         28  
  12         101  
8 12     12   60416 use namespace::autoclean;
  12         28  
  12         92  
9              
10 12     12   1021 use 5.014; # strict, unicode_strings
  12         40  
11 12     12   69 use utf8;
  12         34  
  12         75  
12 12     12   283 use autodie;
  12         20  
  12         79  
13 12     12   55190 use warnings qw/ FATAL utf8 /;
  12         29  
  12         557  
14 12     12   66 use open qw/ :std :utf8 /;
  12         24  
  12         90  
15 12     12   1612 use charnames qw/ :full /;
  12         28  
  12         82  
16              
17 12     12   2793 use DateTime;
  12         335873  
  12         394  
18 12     12   4614 use Date::Parse qw/ str2time /;
  12         44855  
  12         779  
19              
20 12     12   86 use HiD::Types;
  12         26  
  12         16601  
21              
22              
23             has author => (
24             is => 'ro' ,
25             isa => 'Str' ,
26             lazy => 1 ,
27             builder => '_build_author' ,
28             );
29              
30             sub _build_author {
31 0     0   0 my $self = shift;
32              
33 0         0 my $author = $self->get_metadata( 'author' );
34 0 0       0 return $author if defined $author;
35              
36 0         0 my $default_author = $self->get_config( 'default_author' );
37 0 0       0 return $default_author if defined $default_author;
38              
39 0         0 die "Need author for " . $self->basename . "\n"
40             }
41              
42              
43             has categories => (
44             is => 'ro' ,
45             isa => 'ArrayRef' ,
46             lazy => 1 ,
47             default => sub {
48             my $self = shift;
49              
50             if ( my $category = $self->get_metadata( 'category' )) {
51             return [ $category ];
52             }
53             elsif ( my $categories = $self->get_metadata( 'categories' )) {
54             if ( ref $categories ) {
55             return [ @$categories ];
56             }
57             else {
58             my @categories = split /\s/ , $categories;
59             return [ @categories ];
60             }
61             }
62             else { return [] }
63             },
64             );
65              
66              
67             has date => (
68             is => 'ro' ,
69             isa => 'DateTime' ,
70             lazy => 1,
71             handles => {
72             day => 'day' ,
73             month => 'month' ,
74             strftime => 'strftime' ,
75             year => 'year' ,
76             },
77             default => sub {
78             my $self = shift;
79              
80             if ( $self->get_config( 'publish_drafts' )){
81             return DateTime->now if $self->is_draft;
82             }
83              
84             my( $year , $month , $day );
85             if ( my $date = $self->get_metadata( 'date' )) {
86             return DateTime->from_epoch(
87             epoch => str2time( $date ),
88             time_zone => 'local' ,
89             );
90             }
91             else {
92             ( $year , $month , $day ) = $self->input_filename
93             =~ m|^.*?/([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})-|;
94             return DateTime->new(
95             year => $year ,
96             month => $month ,
97             day => $day ,
98             time_zone => 'UTC' ,
99             );
100             }
101             },
102             );
103              
104              
105             has description => (
106             is => 'ro' ,
107             isa => 'Maybe[Str]' ,
108             lazy => 1 ,
109             builder => '_build_description' ,
110             );
111 0     0   0 sub _build_description { shift->get_metadata( 'description' ) }
112              
113              
114             has excerpt => (
115             is => 'ro',
116             isa => 'Str',
117             lazy => 1,
118             builder => '_build_excerpt',
119             );
120              
121             sub _build_excerpt {
122 10     10   18 my $self = shift;
123              
124 10         208 my $content = $self->content;
125              
126 10 50       30 return unless defined $content;
127              
128 10         200 my $sep = $self->hid->excerpt_separator;
129              
130 10 100       88 if($content =~ /^$sep/mp) {
131 1         32 return ${^PREMATCH};
132             }
133              
134 9         206 return $content;
135             }
136              
137              
138             has tags => (
139             is => 'ro' ,
140             isa => 'ArrayRef',
141             traits => [ qw/ Array / ] ,
142             handles => { join_tags => 'join' } ,
143             default => sub {
144             my $self = shift;
145              
146             if ( my $tag = $self->get_metadata( 'tag' )) {
147             return [ $tag ];
148             }
149             elsif ( my $tags = $self->get_metadata( 'tags' )) {
150             if ( ref $tags ) {
151             return [ @$tags ];
152             }
153             else {
154             my @tags = split /\s/ , $tags;
155             return [ @tags ];
156             }
157             }
158             else { return [] }
159             } ,
160             );
161              
162              
163             has title => (
164             is => 'ro' ,
165             isa => 'Str' ,
166             lazy => 1 ,
167             builder => '_build_title' ,
168             );
169              
170             sub _build_title {
171 38     38   72 my $self = shift;
172              
173 38         1099 my $title = $self->get_metadata( 'title' );
174              
175 38 100       261 return $self->basename unless defined $title;
176              
177 30 50       626 return ( ref $title ) ? $$title : $title;
178             }
179              
180              
181             has twitter_handles => (
182             is => 'ro' ,
183             isa => 'ArrayRef[Str]' ,
184             lazy => 1 ,
185             builder => '_build_twitter_handles' ,
186             traits => [ 'Array' ],
187             handles => {
188             has_twitter_handles => 'count',
189             all_twitter_handles => 'elements',
190             },
191             );
192              
193             sub _build_twitter_handles {
194 3     3   4 my $self = shift;
195              
196 3         91 my $t = $self->get_metadata('twitter');
197              
198 3 100       84 return ref $t ? $t : [ $t ? $t : () ];
    100          
199             }
200              
201              
202 3     3 1 100 sub twitter { ($_[0]->all_twitter_handles)[0] }
203              
204              
205             around BUILDARGS => sub {
206             my $orig = shift;
207             my $class = shift;
208              
209             my %args = ( ref $_[0] and ref $_[0] eq 'HASH' ) ? %{ $_[0] } : @_;
210              
211             if ( my $input = $args{input_filename} ) {
212             if ( my $source = $args{source} ) {
213             $input =~ s|$source/?||;
214             }
215              
216             if ( my( $cat ) = $input =~ m|^(.+?)/?_posts/| ) {
217             $args{categories} = [ split '/' , $cat ];
218             }
219             }
220              
221             return $class->$orig( \%args );
222             };
223              
224              
225 0     0 1   sub all_tags { shift->join_tags(',') }
226              
227              
228             my $drafts_dir;
229             sub is_draft {
230 0     0 1   my $self = shift;
231              
232 0   0       $drafts_dir //= $self->get_config( 'drafts_dir' );
233 0 0         return ( $self->input_filename =~ /^$drafts_dir/ ) ? 1 : 0;
234             }
235              
236 12     12   108 no Moose::Role;
  12         32  
  12         123  
237             1;
238              
239             __END__
240              
241             =pod
242              
243             =encoding UTF-8
244              
245             =head1 NAME
246              
247             HiD::Role::IsPost - Role for blog posts
248              
249             =head1 SYNOPSIS
250              
251             package HiD::ThingThatIsAPost;
252             use Moose;
253             with 'HiD::Role::IsPost';
254              
255             ...
256              
257             1;
258              
259             =head1 DESCRIPTION
260              
261             This role is consumed by objects that are blog posts and provides blog
262             post-specific attributes and methods.
263              
264             =head1 ATTRIBUTES
265              
266             =head2 author
267              
268             =head2 categories
269              
270             =head2 date
271              
272             DateTime object for this post.
273              
274             =head2 description
275              
276             A one-line synopsis of the post (used, e.g., for metadata information used by
277             Open Graph)
278              
279             =head2 excerpt
280              
281             It is generally useful to summarize or lead a post with a "read more" tag
282             added to the end of the post. This is ideal for a blog where we might not
283             want to list the full post on the front page.
284              
285             =head2 tags
286              
287             =head2 title
288              
289             =head2 twitter_handles
290              
291             Returns an arrayref of the twitter handles passed via
292             the C<twitter> parameter.
293              
294             =head1 METHODS
295              
296             =head2 has_twitter_handles
297              
298             Returns c<true> if the post has any twitter handles associated with it, C<false>
299             otherwise.
300              
301             =head2 all_twitter_handles
302              
303             Returns the list of the twitter handles associated with the post.
304              
305             =head2 twitter
306              
307             DEPRECATED: use <twitter_handles> instead.
308              
309             Returns the first twitter handle given to C<twitter>.
310              
311             =head2 all_tags
312              
313             Returns all tags for this post, joined together with commas
314              
315             =head2 is_draft
316              
317             Returns a boolean value indicating whether this post is coming from the drafts
318             folder or not.
319              
320             =head1 VERSION
321              
322             version 1.991
323              
324             =head1 AUTHOR
325              
326             John SJ Anderson <genehack@genehack.org>
327              
328             =head1 COPYRIGHT AND LICENSE
329              
330             This software is copyright (c) 2015 by John SJ Anderson.
331              
332             This is free software; you can redistribute it and/or modify it under
333             the same terms as the Perl 5 programming language system itself.
334              
335             =cut