| 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; |