File Coverage

blib/lib/HTML/Latemp/News.pm
Criterion Covered Total %
statement 16 29 55.1
branch 0 2 0.0
condition n/a
subroutine 6 8 75.0
pod n/a
total 22 39 56.4


line stmt bran cond sub pod time code
1             package HTML::Latemp::News;
2              
3 1     1   28549 use warnings;
  1         2  
  1         46  
4 1     1   5 use strict;
  1         2  
  1         38  
5              
6 1     1   31 use 5.008;
  1         8  
  1         103  
7              
8             =head1 NAME
9              
10             HTML::Latemp::News - News Maintenance Module for Latemp (and possibly other
11             web frameworks)
12              
13             =cut
14              
15             our $VERSION = '0.1.8';
16              
17             =head1 SYNOPSIS
18              
19             #!/usr/bin/perl
20              
21             use strict;
22             use warnings;
23              
24             use MyManageNews;
25              
26             my @news_items =
27             (
28             .
29             .
30             .
31             {
32             'title' => "Changes of 18-April-2005",
33             'id' => "changes-2005-04-18",
34             'description' => q{Around 18 April, 2005, Jane's Site has seen a
35             lot of changes. Click the link for details on them.},
36             'date' => "2005-04-18",
37             'author' => "Jane Smith",
38             'category' => "Jane's Site",
39             },
40             .
41             .
42             .
43             );
44              
45             my $news_manager =
46             HTML::Latemp::News->new(
47             'news_items' => \@news_items,
48             'title' => "Better SCM News",
49             'link' => "http://janes-site.tld/",
50             'language' => "en-US",
51             'copyright' => "Copyright by Jane Smith, (c) 2005",
52             'webmaster' => "Jane Smith ",
53             'managing_editor' => "Jane Smith ",
54             'description' => "News of Jane's Site - a personal site of " .
55             "Jane Smith",
56             );
57              
58             $news_manager->generate_rss_feed(
59             'output_filename' => "dest/rss.xml"
60             );
61              
62             1;
63             =cut
64              
65             package HTML::Latemp::News::Base;
66              
67 1     1   6 use base 'Class::Accessor';
  1         3  
  1         1907  
68 1     1   5365 use CGI;
  1         21991  
  1         9  
69              
70             sub new
71             {
72 0     0     my $class = shift;
73 0           my $self = {};
74 0           bless $self, $class;
75 0           $self->initialize(@_);
76 0           return $self;
77             }
78              
79             package HTML::Latemp::News::Item;
80              
81             our @ISA=(qw(HTML::Latemp::News::Base));
82              
83             __PACKAGE__->mk_accessors(qw(index title id description author date
84             category text));
85              
86             sub initialize
87             {
88 0     0     my $self = shift;
89              
90 0           my (%args) = (@_);
91              
92 0           foreach my $k (keys(%args))
93             {
94 0 0         if (! $self->can($k))
95             {
96 0           die "Unknown property for HTML::Latemp::News::Item - \"$k\"!";
97             }
98 0           $self->set($k, $args{$k});
99             }
100             }
101              
102             package HTML::Latemp::News;
103              
104             our @ISA=(qw(HTML::Latemp::News::Base));
105              
106             __PACKAGE__->mk_accessors(qw(copyright description docs generator items
107             language link managing_editor rating title ttl webmaster));
108              
109 1     1   848 use XML::RSS;
  0            
  0            
110              
111             sub input_items
112             {
113             my $self = shift;
114              
115             my $items = shift;
116              
117             return
118             [
119             map
120             { $self->input_single_item($_, $items->[$_]) }
121             (0 .. $#$items)
122             ];
123             }
124              
125             sub input_single_item
126             {
127             my $self = shift;
128             my ($index, $inputted_item) = (@_);
129              
130             return
131             HTML::Latemp::News::Item->new(
132             %$inputted_item,
133             'index' => $index,
134             );
135             }
136              
137             sub initialize
138             {
139             my $self = shift;
140              
141             my %args = (@_);
142              
143             my $items = $args{'news_items'};
144              
145             $self->items(
146             $self->input_items($items)
147             );
148              
149             $self->title($args{'title'});
150             $self->link($args{'link'});
151             $self->language($args{'language'});
152             $self->rating($args{'rating'} || '(PICS-1.1 "http://www.classify.org/safesurf/" 1 r (SS~~000 1))');
153             $self->copyright($args{'copyright'} || "");
154             $self->docs($args{'docs'} || "http://blogs.law.harvard.edu/tech/rss");
155             $self->ttl($args{'ttl'} || "360");
156             $self->generator($args{'generator'} || "Perl and XML::RSS");
157             $self->webmaster($args{'webmaster'});
158             $self->managing_editor($args{'managing_editor'} || $self->webmaster());
159             $self->description($args{'description'});
160              
161             return 0;
162             }
163              
164             =head1 DESCRIPTION
165              
166             This is a module that maintains news item for a web-site. It can generate
167             an RSS feed, as well as a news page, and an HTML newsbox, all from the same
168             data.
169              
170             =head1 FUNCTION
171              
172             =head2 HTML::Latemp::News->new(...)
173              
174             This is the constructor for the news manager. It accepts the following named
175             parameters:
176              
177             =over 8
178              
179             =item 'news_items'
180              
181             This is a reference to a list of news_items. See below.
182              
183             =item 'title'
184              
185             The title of the RSS feed.
186              
187             =item 'link'
188              
189             The link to the homepage of the site.
190              
191             =item 'language'
192              
193             The language of the text.
194              
195             =item 'copyright'
196              
197             The copyright notice of the text.
198              
199             =item 'webmaster'
200              
201             The Webmaster.
202              
203             =item 'managing_editor'
204              
205             The managing editor.
206              
207             =item 'description'
208              
209             A description of the news feed as will be put in the RSS feed.
210              
211             =back
212              
213             =head3 Format of the news_items
214              
215             The news_items is a reference to an array, of which each element is a hash
216             reference. The hash may contain the following keys:
217              
218             =over 8
219              
220             =item 'title'
221              
222             The title of the item.
223              
224             =item 'id'
225              
226             The ID of the item. This will also be used to calculate URLs.
227              
228             =item 'description'
229              
230             A text description explaining what the item is all about.
231              
232             =item 'author'
233              
234             The author of the item.
235              
236             =item 'date'
237              
238             A string representing the daet.
239              
240             =item 'category'
241              
242             The cateogry of the item.
243              
244             =back
245              
246             =cut
247              
248             sub add_item_to_rss_feed
249             {
250             my $self = shift;
251             my %args = (@_);
252              
253             my $item = $args{'item'};
254             my $rss_feed = $args{'feed'};
255              
256             my $item_url = $self->get_item_url($item);
257              
258             $rss_feed->add_item(
259             'title' => $item->title(),
260             'link' => $item_url,
261             'permaLink' => $item_url,
262             'enclosure' => { 'url' => $item_url, },
263             'description' => $item->description(),
264             'author' => $item->author(),
265             'pubDate' => $item->date(),
266             'category' => $item->category(),
267             );
268             }
269              
270             sub get_item_url
271             {
272             my $self = shift;
273             my $item = shift;
274             return $self->link() . $self->get_item_rel_url($item);
275             }
276              
277             sub get_item_rel_url
278             {
279             my $self = shift;
280             my $item = shift;
281             return "news/" . $item->id() . "/";
282             }
283              
284             sub get_items_to_include
285             {
286             my $self = shift;
287             my $args = shift;
288              
289             my $num_items_to_include = $args->{'num_items'} || 10;
290              
291             my $items = $self->items();
292              
293             if (@$items < $num_items_to_include)
294             {
295             $num_items_to_include = scalar(@$items);
296             }
297              
298             return [ @$items[(-$num_items_to_include) .. (-1)] ];
299             }
300              
301             sub generate_rss_feed
302             {
303             my $self = shift;
304              
305             my %args = (@_);
306              
307             my $rss_feed = XML::RSS->new('version' => "2.0");
308             $rss_feed->channel(
309             'title' => $self->title(),
310             'link' => $self->link(),
311             'language' => $self->language(),
312             'description' => $self->description(),
313             'rating' => $self->rating(),
314             'copyright' => $self->copyright(),
315             'pubDate' => (scalar(localtime())),
316             'lastBuildDate' => (scalar(localtime())),
317             'docs' => $self->docs(),
318             'ttl' => $self->ttl(),
319             'generator' => $self->generator(),
320             'managingEditor' => $self->managing_editor(),
321             'webMaster' => $self->webmaster(),
322             );
323              
324             foreach my $single_item (@{$self->get_items_to_include(\%args)})
325             {
326             $self->add_item_to_rss_feed(
327             'item' => $single_item,
328             'feed' => $rss_feed,
329             );
330             }
331              
332             my $filename = $args{'output_filename'} || "rss.xml";
333              
334             $rss_feed->save($filename);
335             }
336              
337             =head2 $news_manager->generate_rss_feed('output_filename' => "rss.xml")
338              
339             This generates an RSS feed. It accepts two named arguments.
340             C<'output_filename'> is the name of the RSS file to write to. C<'num_items'>
341             is the number of items to include, which defaults to 10.
342              
343             =cut
344              
345             sub get_navmenu_items
346             {
347             my $self = shift;
348             my %args = (@_);
349              
350             my @ret;
351              
352             foreach my $single_item (reverse(@{$self->get_items_to_include(\%args)}))
353             {
354             push @ret,
355             {
356             'text' => $single_item->title(),
357             'url' => $self->get_item_rel_url($single_item),
358             };
359             }
360             return \@ret;
361             }
362              
363             =head2 $news_manager->get_navmenu_items('num_items' => 5)
364              
365             This generates navigation menu items for input to the navigation menu of
366             L. It accepts a named argument C<'num_items'> which
367             defaults to 10.
368              
369             =cut
370              
371             sub format_news_page_item
372             {
373             my $self = shift;
374             my (%args) = (@_);
375              
376             my $item = $args{'item'};
377             my $base_url = $args{'base_url'};
378              
379             return "

id() . "/\">" .

380             CGI::escapeHTML($item->title()) . "\n" .
381             "

\n" . $item->description() . "\n

\n";
382             }
383              
384             sub get_news_page_entries
385             {
386             my $self = shift;
387             my %args = (@_);
388              
389             my $html = "";
390              
391             my $base_url = exists($args{'base_url'}) ? $args{'base_url'} : "";
392              
393             foreach my $single_item (reverse(@{$self->get_items_to_include(\%args)}))
394             {
395             $html .=
396             $self->format_news_page_item(
397             'item' => $single_item,
398             'base_url' => $base_url,
399             );
400             }
401             return $html;
402             }
403              
404             =head2 $news_manager->get_news_page_entries('num_items' => 5, 'base_url' => "news/")
405              
406             This generates HTML for the news page. 'base_url' points to a URL to be
407             appended to each item's ID.
408              
409             =cut
410              
411             sub get_news_box_contents
412             {
413             my $self = shift;
414             my (%args) = (@_);
415              
416             my $html = "";
417             foreach my $item (reverse(@{$self->get_items_to_include(\%args)}))
418             {
419             $html .= "
  • 420             $self->get_item_rel_url($item) . "\">" .
    421             CGI::escapeHTML($item->title()) . "\n";
    422             }
    423             return $html;
    424             }
    425              
    426              
    427             sub get_news_box
    428             {
    429             my $self = shift;
    430              
    431             my $html = "";
    432              
    433             $html .= qq{
    \n};
    434             $html .= qq{

    News

    \n};
    435             $html .= qq{
      \n};
    436             $html .=
    437             $self->get_news_box_contents(
    438             @_
    439             );
    440             $html .= qq{
  • More…
  • };
    441             $html .= qq{\n};
    442             $html .= qq{\n};
    443             return $html;
    444             }
    445              
    446             =head2 $news_manager->get_news_box('num_items' => 5)
    447              
    448             This generates an HTML news box with the recent headlines.
    449              
    450             =cut
    451              
    452             1;
    453              
    454             __END__