blib/lib/XML/RSS/JavaScript.pm | |||
---|---|---|---|
Criterion | Covered | Total | % |
statement | 15 | 68 | 22.0 |
branch | 0 | 12 | 0.0 |
condition | 0 | 9 | 0.0 |
subroutine | 5 | 12 | 41.6 |
pod | 4 | 4 | 100.0 |
total | 24 | 105 | 22.8 |
line | stmt | bran | cond | sub | pod | time | code |
---|---|---|---|---|---|---|---|
1 | package XML::RSS::JavaScript; | ||||||
2 | |||||||
3 | 7 | 7 | 64511 | use strict; | |||
7 | 14 | ||||||
7 | 282 | ||||||
4 | 7 | 7 | 41 | use warnings; | |||
7 | 13 | ||||||
7 | 244 | ||||||
5 | |||||||
6 | 7 | 7 | 39 | use base qw( XML::RSS ); | |||
7 | 15 | ||||||
7 | 4251 | ||||||
7 | |||||||
8 | 7 | 7 | 44 | use Carp; | |||
7 | 12 | ||||||
7 | 563 | ||||||
9 | 7 | 7 | 8519 | use HTML::Entities (); | |||
7 | 55329 | ||||||
7 | 6494 | ||||||
10 | |||||||
11 | our $VERSION = '0.65'; | ||||||
12 | |||||||
13 | =head1 NAME | ||||||
14 | |||||||
15 | XML::RSS::JavaScript - serialize your RSS as JavaScript | ||||||
16 | |||||||
17 | =head1 SYNOPSIS | ||||||
18 | |||||||
19 | use XML::RSS::JavaScript; | ||||||
20 | my $rss = XML::RSS::JavaScript->new(); | ||||||
21 | $rss->channel( | ||||||
22 | title => 'My Channel', | ||||||
23 | link => 'http://my.url.com', | ||||||
24 | description => 'My RSS Feed.' | ||||||
25 | ); | ||||||
26 | |||||||
27 | $rss->add_item( | ||||||
28 | title => 'My item #1', | ||||||
29 | link => 'http://my.item.com#1', | ||||||
30 | description => 'My first news item.' | ||||||
31 | ); | ||||||
32 | |||||||
33 | $rss->add_item( | ||||||
34 | title => 'My item #2', | ||||||
35 | link => 'http://my.item.com#2', | ||||||
36 | description => 'My second news item.' | ||||||
37 | ); | ||||||
38 | |||||||
39 | # save rss | ||||||
40 | $rss->save( '/usr/local/apache/htdocs/myfeed.xml' ); | ||||||
41 | |||||||
42 | # save identical content as javascript | ||||||
43 | $rss->save_javascript( '/usr/local/apache/htdocs/myfeed.js'); | ||||||
44 | |||||||
45 | =head1 DESCRIPTION | ||||||
46 | |||||||
47 | Perhaps you use XML::RSS to generate RSS for consumption by RSS parsers. | ||||||
48 | Perhaps you also get requests for how to use the RSS feed by people who | ||||||
49 | have no idea how to parse XML, or write Perl programs for that matter. | ||||||
50 | |||||||
51 | Enter XML::RSS::JavaScript, a simple subclass of XML::RSS which writes your | ||||||
52 | RSS feed as a sequence of JavaScript print statements. This means you | ||||||
53 | can then write the JavaScript to disk, and a users HTML can simply | ||||||
54 | I |
||||||
55 | |||||||
56 | |||||||
57 | |||||||
58 | What's more the javascript emits HTML that can be fully styled with | ||||||
59 | CSS. See the CSS examples included with the distribution in the css directory. | ||||||
60 | |||||||
61 | |||||||
62 | |||||||
63 | |||||||
64 | |||||||
65 | |||||||
66 | Your content here... | ||||||
67 | |||||||
68 | |||||||
69 | |||||||
70 | |||||||
71 | =head1 INSTALLATION | ||||||
72 | |||||||
73 | perl Makefile.PL | ||||||
74 | make | ||||||
75 | make test | ||||||
76 | make install | ||||||
77 | |||||||
78 | =head1 METHODS | ||||||
79 | |||||||
80 | =head2 save_javascript() | ||||||
81 | |||||||
82 | Pass in the path to a file you wish to write your javascript in. Optionally | ||||||
83 | you can pass in the maximum amount of items to include from the feed and a | ||||||
84 | boolean value to switch descriptions on or off (default: on). | ||||||
85 | |||||||
86 | # save all the content | ||||||
87 | save_javascript( '/usr/local/apache/htdocs/rss/myfeed.js' ); | ||||||
88 | |||||||
89 | # no more than 10 items: | ||||||
90 | save_javascript( '/usr/local/apache/htdocs/rss/myfeed.js', 10 ); | ||||||
91 | |||||||
92 | # save all items without descriptions: | ||||||
93 | save_javascript( '/usr/local/apache/htdocs/rss/myfeed.js', undef, 0 ); | ||||||
94 | |||||||
95 | =cut | ||||||
96 | |||||||
97 | sub save_javascript { | ||||||
98 | 0 | 0 | 1 | my ( $self, $file, @options ) = @_; | |||
99 | 0 | $self->_save( 'as_javascript', $file, @options ); | |||||
100 | } | ||||||
101 | |||||||
102 | =head2 as_javascript() | ||||||
103 | |||||||
104 | as_javascript will return a string containing javascript suitable for | ||||||
105 | generating text for your RSS object. You can pass in the maximum amount of | ||||||
106 | items to include by passing in an integer as an argument and a boolean value | ||||||
107 | to switch descriptions on or off (default: on). If you pass in no argument | ||||||
108 | you will get the contents of the entire object. | ||||||
109 | |||||||
110 | $js = $rss->as_javascript(); | ||||||
111 | |||||||
112 | =cut | ||||||
113 | |||||||
114 | sub as_javascript { | ||||||
115 | 0 | 0 | 1 | my ( $self, $max, $descriptions ) = @_; | |||
116 | 0 | my $items = scalar @{ $self->{ items } }; | |||||
0 | |||||||
117 | 0 | 0 | 0 | if ( not $max or $max > $items ) { $max = $items; } | |||
0 | |||||||
118 | |||||||
119 | ## open javascript section | ||||||
120 | 0 | my $output = _js_print( ' ' ); |
|||||
121 | 0 | $output .= _js_print( | |||||
122 | ' ' |
||||||
123 | . HTML::Entities::encode_entities_numeric( | ||||||
124 | $self->channel( 'title' ) | ||||||
125 | ) | ||||||
126 | . '' | ||||||
127 | ); | ||||||
128 | |||||||
129 | ## open our list | ||||||
130 | 0 | $output .= _js_print( '
|
|||||
131 | |||||||
132 | ## generate content for each item | ||||||
133 | 0 | foreach my $item ( ( @{ $self->{ items } } )[ 0 .. $max - 1 ] ) { | |||||
0 | |||||||
134 | 0 | my $link = HTML::Entities::encode_entities_numeric( $item->{ link } ); | |||||
135 | my $title | ||||||
136 | 0 | = HTML::Entities::encode_entities_numeric( $item->{ title } ); | |||||
137 | my $desc = HTML::Entities::encode_entities_numeric( | ||||||
138 | 0 | $item->{ description } ); | |||||
139 | 0 | my $data = <<"JAVASCRIPT_TEXT"; | |||||
140 | |
||||||
141 | $title | ||||||
142 | JAVASCRIPT_TEXT | ||||||
143 | 0 | 0 | 0 | $data .= " $desc" | |||
144 | if $descriptions | ||||||
145 | or not defined( $descriptions ); | ||||||
146 | 0 | $data .= ''; | |||||
147 | 0 | $output .= _js_print( $data ); | |||||
148 | } | ||||||
149 | |||||||
150 | ## close our item list, and return | ||||||
151 | 0 | $output .= _js_print( '' ); | |||||
152 | 0 | $output .= _js_print( '' ); | |||||
153 | 0 | return $output; | |||||
154 | |||||||
155 | } | ||||||
156 | |||||||
157 | =head2 save_json( ) | ||||||
158 | |||||||
159 | Pass in the path to a file you wish to write your javascript in. Optionally | ||||||
160 | you can pass in any options that would normally get passed to C |
||||||
161 | |||||||
162 | =cut | ||||||
163 | |||||||
164 | sub save_json { | ||||||
165 | 0 | 0 | 1 | my ( $self, $file, @options ) = @_; | |||
166 | 0 | $self->_save( 'as_json', $file, @options ); | |||||
167 | } | ||||||
168 | |||||||
169 | =head2 as_json( ) | ||||||
170 | |||||||
171 | as_json will return a string containing json suitable for | ||||||
172 | generating text for your RSS object. You can pass in the maximum amount of | ||||||
173 | items to include by passing in an integer as an argument. If you pass in no argument | ||||||
174 | you will get the contents of the entire object. You can also pass in | ||||||
175 | the name of the JSON object (default: RSSJSON). | ||||||
176 | |||||||
177 | =cut | ||||||
178 | |||||||
179 | sub as_json { | ||||||
180 | 0 | 0 | 1 | my ( $self, $max, $object_name ) = @_; | |||
181 | 0 | my $items = scalar @{ $self->{ items } }; | |||||
0 | |||||||
182 | 0 | 0 | $object_name = 'RSSJSON' unless defined $object_name; | ||||
183 | 0 | 0 | 0 | if ( not $max or $max > $items ) { $max = $items; } | |||
0 | |||||||
184 | |||||||
185 | 0 | my $output | |||||
186 | = "if(typeof($object_name) == 'undefined') $object_name = {}; $object_name.posts = ["; | ||||||
187 | |||||||
188 | 0 | my @entries; | |||||
189 | 0 | foreach my $item ( ( @{ $self->{ items } } )[ 0 .. $max - 1 ] ) { | |||||
0 | |||||||
190 | 0 | my $link = $item->{ link }; | |||||
191 | 0 | my $title = _js_escape( $item->{ title } ); | |||||
192 | |||||||
193 | 0 | push @entries, qq({u:"$link",d:"$title"}); | |||||
194 | } | ||||||
195 | |||||||
196 | 0 | $output .= join( ',', @entries ); | |||||
197 | 0 | $output .= ']'; | |||||
198 | |||||||
199 | 0 | return $output; | |||||
200 | } | ||||||
201 | |||||||
202 | =head1 MORE EXAMPLES | ||||||
203 | |||||||
204 | Perhaps you want to get an existing RSS feed, suck it in, and write it out | ||||||
205 | as JavaScript for easy consumption. | ||||||
206 | |||||||
207 | use XML::RSS::JavaScript; | ||||||
208 | use LWP::Simple; | ||||||
209 | |||||||
210 | my $xml = get( 'http://slashdot.org/slashdot.rss' ); | ||||||
211 | my $rss = XML::RSS::JavaScript->new(); | ||||||
212 | |||||||
213 | $rss->parse( $xml ); | ||||||
214 | print $rss->as_javascript(); | ||||||
215 | |||||||
216 | =head1 SEE ALSO | ||||||
217 | |||||||
218 | =over 4 | ||||||
219 | |||||||
220 | =item * XML::RSS | ||||||
221 | |||||||
222 | =back | ||||||
223 | |||||||
224 | =head1 AUTHORS | ||||||
225 | |||||||
226 | Brian Cassidy E |
||||||
227 | |||||||
228 | Ed Summers E |
||||||
229 | |||||||
230 | =head1 COPYRIGHT AND LICENSE | ||||||
231 | |||||||
232 | Copyright 2003-2013 by Brian Cassidy and Ed Summers | ||||||
233 | |||||||
234 | This library is free software; you can redistribute it and/or modify | ||||||
235 | it under the same terms as Perl itself. | ||||||
236 | |||||||
237 | =cut | ||||||
238 | |||||||
239 | sub _save { | ||||||
240 | 0 | 0 | my ( $self, $method, $file, @options ) = @_; | ||||
241 | 0 | 0 | if ( !$file ) { | ||||
242 | 0 | croak "You must pass in a filename"; | |||||
243 | } | ||||||
244 | 0 | 0 | open( my $fh, ">$file" ) || croak "Cannot open file $file for write: $!"; | ||||
245 | 0 | print $fh $self->$method( @options ); | |||||
246 | 0 | close( $fh ); | |||||
247 | } | ||||||
248 | |||||||
249 | sub _js_print { | ||||||
250 | 0 | 0 | my $string = _js_escape( shift ); | ||||
251 | 0 | return ( "document.write('$string');\n" ); | |||||
252 | } | ||||||
253 | |||||||
254 | sub _js_escape { | ||||||
255 | 0 | 0 | my $string = shift; | ||||
256 | 0 | $string =~ s/"/\\"/g; | |||||
257 | 0 | $string =~ s/'/\\'/g; | |||||
258 | 0 | $string =~ s/\n//g; | |||||
259 | 0 | return $string; | |||||
260 | } | ||||||
261 | |||||||
262 | 1; |