| blib/lib/HTML/SocialMedia.pm | |||
|---|---|---|---|
| Criterion | Covered | Total | % |
| statement | 7 | 9 | 77.7 |
| branch | n/a | ||
| condition | n/a | ||
| subroutine | 3 | 3 | 100.0 |
| pod | n/a | ||
| total | 10 | 12 | 83.3 |
| line | stmt | bran | cond | sub | pod | time | code | |||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | package HTML::SocialMedia; | |||||||||||||
| 2 | ||||||||||||||
| 3 | 1 | 1 | 86184 | use warnings; | ||||||||||
| 1 | 2 | |||||||||||||
| 1 | 26 | |||||||||||||
| 4 | 1 | 1 | 3 | use strict; | ||||||||||
| 1 | 1 | |||||||||||||
| 1 | 16 | |||||||||||||
| 5 | 1 | 1 | 511 | use CGI::Lingua; | ||||||||||
| 0 | ||||||||||||||
| 0 | ||||||||||||||
| 6 | ||||||||||||||
| 7 | =head1 NAME | |||||||||||||
| 8 | ||||||||||||||
| 9 | HTML::SocialMedia - Put social media links onto your website | |||||||||||||
| 10 | ||||||||||||||
| 11 | =head1 VERSION | |||||||||||||
| 12 | ||||||||||||||
| 13 | Version 0.27 | |||||||||||||
| 14 | ||||||||||||||
| 15 | =cut | |||||||||||||
| 16 | ||||||||||||||
| 17 | our $VERSION = '0.27'; | |||||||||||||
| 18 | ||||||||||||||
| 19 | =head1 SYNOPSIS | |||||||||||||
| 20 | ||||||||||||||
| 21 | Many websites these days have links and buttons into social media sites. | |||||||||||||
| 22 | This module eases links into Twitter, Facebook and Google's PlusOne. | |||||||||||||
| 23 | ||||||||||||||
| 24 | use HTML::SocialMedia; | |||||||||||||
| 25 | my $sm = HTML::SocialMedia->new(); | |||||||||||||
| 26 | # ... | |||||||||||||
| 27 | ||||||||||||||
| 28 | The language of the text displayed will depend on the client's choice, making | |||||||||||||
| 29 | HTML::SocialMedia ideal for running on multilingual sites. | |||||||||||||
| 30 | ||||||||||||||
| 31 | Takes optional parameter logger, an object which is used for warnings and | |||||||||||||
| 32 | traces. | |||||||||||||
| 33 | This logger object is an object that understands warn() and trace() messages, | |||||||||||||
| 34 | such as a L |
|||||||||||||
| 35 | ||||||||||||||
| 36 | Takes optional parameter cache, an object which is used to cache country | |||||||||||||
| 37 | lookups. | |||||||||||||
| 38 | This cache object is an object that understands get() and set() messages, | |||||||||||||
| 39 | such as an L |
|||||||||||||
| 40 | ||||||||||||||
| 41 | Takes optional parameter lingua, which is a L |
|||||||||||||
| 42 | ||||||||||||||
| 43 | =head1 SUBROUTINES/METHODS | |||||||||||||
| 44 | ||||||||||||||
| 45 | =head2 new | |||||||||||||
| 46 | ||||||||||||||
| 47 | Creates a HTML::SocialMedia object. | |||||||||||||
| 48 | ||||||||||||||
| 49 | use HTML::SocialMedia; | |||||||||||||
| 50 | my $sm = HTML::SocialMedia->new(twitter => 'example'); | |||||||||||||
| 51 | # ... | |||||||||||||
| 52 | ||||||||||||||
| 53 | =head3 Optional parameters | |||||||||||||
| 54 | ||||||||||||||
| 55 | twitter: twitter account name | |||||||||||||
| 56 | twitter_related: array of 2 elements - the name and description of a related account | |||||||||||||
| 57 | cache: This object will be an instantiation of a class that understands get and | |||||||||||||
| 58 | set, such as L |
|||||||||||||
| 59 | info: Object which understands host_name messages, such as L |
|||||||||||||
| 60 | ||||||||||||||
| 61 | =cut | |||||||||||||
| 62 | ||||||||||||||
| 63 | sub new { | |||||||||||||
| 64 | my $proto = shift; | |||||||||||||
| 65 | ||||||||||||||
| 66 | my $class = ref($proto) || $proto; | |||||||||||||
| 67 | return unless(defined($class)); | |||||||||||||
| 68 | ||||||||||||||
| 69 | my %params = (ref($_[0]) eq 'HASH') ? %{$_[0]} : @_; | |||||||||||||
| 70 | ||||||||||||||
| 71 | my $lingua = $params{lingua}; | |||||||||||||
| 72 | unless(defined($lingua)) { | |||||||||||||
| 73 | my %args; | |||||||||||||
| 74 | if($params{twitter}) { | |||||||||||||
| 75 | # Languages supported by Twitter according to | |||||||||||||
| 76 | # https://twitter.com/about/resources/tweetbutton | |||||||||||||
| 77 | $args{supported} = ['en', 'nl', 'fr', 'fr-fr', 'de', 'id', 'il', 'ja', 'ko', 'pt', 'ru', 'es', 'tr'], | |||||||||||||
| 78 | } else { | |||||||||||||
| 79 | # TODO: Google plus only supports the languages listed at | |||||||||||||
| 80 | # http://www.google.com/webmasters/+1/button/index.html | |||||||||||||
| 81 | require I18N::LangTags::Detect; | |||||||||||||
| 82 | ||||||||||||||
| 83 | # Facebook supports just about everything | |||||||||||||
| 84 | my @l = I18N::LangTags::implicate_supers_strictly(I18N::LangTags::Detect::detect()); | |||||||||||||
| 85 | ||||||||||||||
| 86 | if(@l) { | |||||||||||||
| 87 | $args{supported} = [$l[0]]; | |||||||||||||
| 88 | } else { | |||||||||||||
| 89 | $args{supported} = []; | |||||||||||||
| 90 | } | |||||||||||||
| 91 | } | |||||||||||||
| 92 | if($params{cache}) { | |||||||||||||
| 93 | $args{cache} = $params{cache}; | |||||||||||||
| 94 | } | |||||||||||||
| 95 | if($params{logger}) { | |||||||||||||
| 96 | $args{logger} = $params{logger}; | |||||||||||||
| 97 | } | |||||||||||||
| 98 | $lingua = $params{lingua} || CGI::Lingua->new(%args); | |||||||||||||
| 99 | if((!defined($lingua)) && scalar($args{supported})) { | |||||||||||||
| 100 | $args{supported} = []; | |||||||||||||
| 101 | $lingua = CGI::Lingua->new(%args); | |||||||||||||
| 102 | } | |||||||||||||
| 103 | } | |||||||||||||
| 104 | ||||||||||||||
| 105 | return bless { | |||||||||||||
| 106 | _lingua => $lingua, | |||||||||||||
| 107 | _twitter => $params{twitter}, | |||||||||||||
| 108 | _twitter_related => $params{twitter_related}, | |||||||||||||
| 109 | _cache => $params{cache}, | |||||||||||||
| 110 | _logger => $params{logger}, | |||||||||||||
| 111 | _info => $params{info}, | |||||||||||||
| 112 | # _alpha2 => undef, | |||||||||||||
| 113 | }, $class; | |||||||||||||
| 114 | } | |||||||||||||
| 115 | ||||||||||||||
| 116 | =head2 as_string | |||||||||||||
| 117 | ||||||||||||||
| 118 | Returns the HTML to be added to your website. | |||||||||||||
| 119 | HTML::SocialMedia uses L |
|||||||||||||
| 120 | in the language of the user. | |||||||||||||
| 121 | ||||||||||||||
| 122 | use HTML::SocialMedia; | |||||||||||||
| 123 | my $sm = HTML::SocialMedia->new( | |||||||||||||
| 124 | twitter => 'mytwittername', | |||||||||||||
| 125 | twitter_related => [ 'someonelikeme', 'another twitter feed' ] | |||||||||||||
| 126 | ); | |||||||||||||
| 127 | ||||||||||||||
| 128 | print "Content-type: text/html\n\n"; | |||||||||||||
| 129 | ||||||||||||||
| 130 | print ''; | |||||||||||||
| 131 | print ''; | |||||||||||||
| 132 | ||||||||||||||
| 133 | print $sm->as_string( | |||||||||||||
| 134 | twitter_follow_button => 1, | |||||||||||||
| 135 | twitter_tweet_button => 1, # button to tweet this page | |||||||||||||
| 136 | facebook_like_button => 1, | |||||||||||||
| 137 | facebook_share_button => 1, | |||||||||||||
| 138 | linkedin_share_button => 1, | |||||||||||||
| 139 | google_plusone => 1, | |||||||||||||
| 140 | reddit_button => 1, | |||||||||||||
| 141 | align => 'right', | |||||||||||||
| 142 | ); | |||||||||||||
| 143 | ||||||||||||||
| 144 | print ''; | |||||||||||||
| 145 | print "\n"; | |||||||||||||
| 146 | ||||||||||||||
| 147 | =head3 Optional parameters | |||||||||||||
| 148 | ||||||||||||||
| 149 | twitter_follow_button: add a button to follow the account | |||||||||||||
| 150 | ||||||||||||||
| 151 | twitter_tweet_button: add a button to tweet this page | |||||||||||||
| 152 | ||||||||||||||
| 153 | facebook_like_button: add a Facebook like button | |||||||||||||
| 154 | ||||||||||||||
| 155 | facebook_share_button: add a Facebook share button | |||||||||||||
| 156 | ||||||||||||||
| 157 | linkedin_share_button: add a LinkedIn share button | |||||||||||||
| 158 | ||||||||||||||
| 159 | google_plusone: add a Google +1 button | |||||||||||||
| 160 | ||||||||||||||
| 161 | reddit_button: add a Reddit button | |||||||||||||
| 162 | ||||||||||||||
| 163 | align: argument to HTML tag |
|||||||||||||
| 164 | ||||||||||||||
| 165 | =cut | |||||||||||||
| 166 | ||||||||||||||
| 167 | sub as_string { | |||||||||||||
| 168 | my $self = shift; | |||||||||||||
| 169 | ||||||||||||||
| 170 | my %params = (ref($_[0]) eq 'HASH') ? %{$_[0]} : @_; | |||||||||||||
| 171 | ||||||||||||||
| 172 | if($self->{_logger}) { | |||||||||||||
| 173 | $self->{_logger}->trace('Entering as_string'); | |||||||||||||
| 174 | } | |||||||||||||
| 175 | my $lingua = $self->{_lingua}; | |||||||||||||
| 176 | ||||||||||||||
| 177 | unless($self->{_alpha2}) { | |||||||||||||
| 178 | my $alpha2 = $lingua->language_code_alpha2(); | |||||||||||||
| 179 | my $locale = $lingua->locale(); # Locale::Object::Country | |||||||||||||
| 180 | ||||||||||||||
| 181 | if($self->{_logger}) { | |||||||||||||
| 182 | if(defined($alpha2)) { | |||||||||||||
| 183 | $self->{_logger}->debug("language_code_alpha2: $alpha2"); | |||||||||||||
| 184 | } else { | |||||||||||||
| 185 | $self->{_logger}->debug('language_code_alpha2 returned undef'); | |||||||||||||
| 186 | } | |||||||||||||
| 187 | } | |||||||||||||
| 188 | if($alpha2) { | |||||||||||||
| 189 | my $salpha2 = $lingua->sublanguage_code_alpha2(); | |||||||||||||
| 190 | if((!defined($salpha2)) && defined($locale)) { | |||||||||||||
| 191 | $salpha2 = $locale->code_alpha2(); | |||||||||||||
| 192 | } | |||||||||||||
| 193 | if($salpha2) { | |||||||||||||
| 194 | $salpha2 = uc($salpha2); | |||||||||||||
| 195 | $alpha2 .= "_$salpha2"; | |||||||||||||
| 196 | } elsif($locale) { | |||||||||||||
| 197 | my @l = $locale->languages_official(); | |||||||||||||
| 198 | $alpha2 = lc($l[0]->code_alpha2()) . '_' . uc($locale->code_alpha2()); | |||||||||||||
| 199 | } else { | |||||||||||||
| 200 | # Can't determine the area, i.e. is it en_GB or en_US? | |||||||||||||
| 201 | if($self->{_logger}) { | |||||||||||||
| 202 | $self->{_logger}->debug('Clearing the value of alpha2'); | |||||||||||||
| 203 | } | |||||||||||||
| 204 | $alpha2 = undef; | |||||||||||||
| 205 | } | |||||||||||||
| 206 | } | |||||||||||||
| 207 | ||||||||||||||
| 208 | unless($alpha2) { | |||||||||||||
| 209 | if($locale) { | |||||||||||||
| 210 | my @l = $locale->languages_official(); | |||||||||||||
| 211 | if(scalar(@l) && defined($l[0]->code_alpha2())) { | |||||||||||||
| 212 | $alpha2 = lc($l[0]->code_alpha2()) . '_' . uc($locale->code_alpha2()); | |||||||||||||
| 213 | } else { | |||||||||||||
| 214 | @l = $locale->languages(); | |||||||||||||
| 215 | if(scalar(@l) && defined($l[0]->code_alpha2())) { | |||||||||||||
| 216 | $alpha2 = lc($l[0]->code_alpha2()) . '_' . uc($locale->code_alpha2()); | |||||||||||||
| 217 | } | |||||||||||||
| 218 | } | |||||||||||||
| 219 | } | |||||||||||||
| 220 | unless($alpha2) { | |||||||||||||
| 221 | $alpha2 = 'en_GB'; | |||||||||||||
| 222 | if($self->{_logger}) { | |||||||||||||
| 223 | $self->{_logger}->info("Can't determine country, falling back to en_GB"); | |||||||||||||
| 224 | } | |||||||||||||
| 225 | } | |||||||||||||
| 226 | } | |||||||||||||
| 227 | if($self->{_logger}) { | |||||||||||||
| 228 | $self->{_logger}->debug("alpha2: $alpha2"); | |||||||||||||
| 229 | } | |||||||||||||
| 230 | $self->{_alpha2} = $alpha2; | |||||||||||||
| 231 | } | |||||||||||||
| 232 | ||||||||||||||
| 233 | my $rc; | |||||||||||||
| 234 | ||||||||||||||
| 235 | if($params{facebook_like_button} || $params{facebook_share_button}) { | |||||||||||||
| 236 | if(!defined($self->{_country})) { | |||||||||||||
| 237 | # Grab the Facebook preamble and put it as early as we can | |||||||||||||
| 238 | ||||||||||||||
| 239 | # See if Facebook supports our wanted language. If not then | |||||||||||||
| 240 | # I suppose we could enuerate through other requested languages, | |||||||||||||
| 241 | # but that is probably not worth the effort. | |||||||||||||
| 242 | ||||||||||||||
| 243 | my $country = $self->{_alpha2} || 'en_US'; | |||||||||||||
| 244 | my $res; | |||||||||||||
| 245 | if($self->{_cache}) { | |||||||||||||
| 246 | $res = $self->{_cache}->get($country); | |||||||||||||
| 247 | } | |||||||||||||
| 248 | ||||||||||||||
| 249 | if(defined($res)) { | |||||||||||||
| 250 | unless($res) { | |||||||||||||
| 251 | $country = 'en_US'; | |||||||||||||
| 252 | } | |||||||||||||
| 253 | } else { | |||||||||||||
| 254 | # Resposnse is of type HTTP::Response | |||||||||||||
| 255 | require LWP::UserAgent; | |||||||||||||
| 256 | ||||||||||||||
| 257 | my $response; | |||||||||||||
| 258 | ||||||||||||||
| 259 | eval { | |||||||||||||
| 260 | $response = LWP::UserAgent->new(timeout => 10)->request( | |||||||||||||
| 261 | HTTP::Request->new(GET => "http://connect.facebook.com/$country/sdk.js") | |||||||||||||
| 262 | ); | |||||||||||||
| 263 | }; | |||||||||||||
| 264 | if($@) { | |||||||||||||
| 265 | if($self->{_logger}) { | |||||||||||||
| 266 | $self->{_logger}->info($@); | |||||||||||||
| 267 | } | |||||||||||||
| 268 | $response = undef; | |||||||||||||
| 269 | } | |||||||||||||
| 270 | if(defined($response) && $response->is_success()) { | |||||||||||||
| 271 | # If it's not supported, Facebook doesn't return an HTTP | |||||||||||||
| 272 | # error such as 404, it returns a string, which no doubt | |||||||||||||
| 273 | # will get changed at sometime in the future. Sigh. | |||||||||||||
| 274 | if($response->decoded_content() =~ /is not a valid locale/) { | |||||||||||||
| 275 | # TODO: Guess more appropriate fallbacks | |||||||||||||
| 276 | $country = 'en_US'; | |||||||||||||
| 277 | if($self->{_cache}) { | |||||||||||||
| 278 | $self->{_cache}->set($country, 0, '10 minutes'); | |||||||||||||
| 279 | } | |||||||||||||
| 280 | } elsif($self->{_cache}) { | |||||||||||||
| 281 | $self->{_cache}->set($country, 1, '10 minutes'); | |||||||||||||
| 282 | } | |||||||||||||
| 283 | } else { | |||||||||||||
| 284 | $country = 'en_US'; | |||||||||||||
| 285 | if($self->{_cache}) { | |||||||||||||
| 286 | $self->{_cache}->set($country, 0, '10 minutes'); | |||||||||||||
| 287 | } | |||||||||||||
| 288 | } | |||||||||||||
| 289 | } | |||||||||||||
| 290 | $self->{_country} = $country; | |||||||||||||
| 291 | } | |||||||||||||
| 292 | ||||||||||||||
| 293 | $rc = << "END"; | |||||||||||||
| 294 | ||||||||||||||
| 295 | ||||||||||||||
| 303 | END | |||||||||||||
| 304 | } | |||||||||||||
| 305 | ||||||||||||||
| 306 | my $paragraph; | |||||||||||||
| 307 | if($params{'align'}) { | |||||||||||||
| 308 | $paragraph = " "; |
|||||||||||||
| 309 | } else { | |||||||||||||
| 310 | $paragraph = ' '; |
|||||||||||||
| 311 | } | |||||||||||||
| 312 | ||||||||||||||
| 313 | my $protocol; | |||||||||||||
| 314 | if($self->{_info}) { | |||||||||||||
| 315 | $protocol = $self->{_info}->protocol() || 'http'; | |||||||||||||
| 316 | } else { | |||||||||||||
| 317 | require CGI::Info; | |||||||||||||
| 318 | $protocol = CGI::Info->protocol() || 'http'; | |||||||||||||
| 319 | } | |||||||||||||
| 320 | ||||||||||||||
| 321 | if($self->{_twitter}) { | |||||||||||||
| 322 | if($params{twitter_follow_button}) { | |||||||||||||
| 323 | my $language = $lingua->language(); | |||||||||||||
| 324 | if(($language eq 'English') || ($language eq 'Unknown')) { | |||||||||||||
| 325 | $rc .= 'Follow @' . $self->{_twitter} . ''; | |||||||||||||
| 326 | } else { | |||||||||||||
| 327 | my $langcode = substr($self->{_alpha2}, 0, 2); | |||||||||||||
| 328 | $rc .= 'Follow \@" . $self->{_twitter} . ''; | |||||||||||||
| 329 | } | |||||||||||||
| 330 | if($params{twitter_tweet_button}) { | |||||||||||||
| 331 | $rc .= $paragraph; | |||||||||||||
| 332 | } | |||||||||||||
| 333 | } | |||||||||||||
| 334 | if($params{twitter_tweet_button}) { | |||||||||||||
| 335 | $rc .= << 'END'; | |||||||||||||
| 336 | ||||||||||||||
| 354 | 355 | END | ||||||||||||
| 356 | $rc =~ s/\n$//; | |||||||||||||
| 357 | $rc .= $self->{_twitter} . '"'; | |||||||||||||
| 358 | if($self->{_twitter_related}) { | |||||||||||||
| 359 | my @related = @{$self->{_twitter_related}}; | |||||||||||||
| 360 | $rc .= ' data-related="' . $related[0] . ':' . $related[1] . '"'; | |||||||||||||
| 361 | } | |||||||||||||
| 362 | $rc .= '>Tweet'; | |||||||||||||
| 363 | } | |||||||||||||
| 364 | } | |||||||||||||
| 365 | ||||||||||||||
| 366 | if($params{facebook_like_button}) { | |||||||||||||
| 367 | if($params{twitter_tweet_button} || $params{twitter_follow_button}) { | |||||||||||||
| 368 | $rc .= $paragraph; | |||||||||||||
| 369 | } | |||||||||||||
| 370 | ||||||||||||||
| 371 | my $host_name; | |||||||||||||
| 372 | unless($self->{info}) { | |||||||||||||
| 373 | require CGI::Info; | |||||||||||||
| 374 | ||||||||||||||
| 375 | $self->{info} = CGI::Info->new(); | |||||||||||||
| 376 | } | |||||||||||||
| 377 | $host_name = $self->{info}->host_name(); | |||||||||||||
| 378 | ||||||||||||||
| 379 | $rc .= ""; | |||||||||||||
| 380 | ||||||||||||||
| 381 | if($params{google_plusone} || $params{linkedin_share_button} || $params{reddit_button} || $params{'facebook_share_button'}) { | |||||||||||||
| 382 | $rc .= $paragraph; | |||||||||||||
| 383 | } | |||||||||||||
| 384 | } | |||||||||||||
| 385 | if($params{'facebook_share_button'}) { | |||||||||||||
| 386 | if($params{twitter_tweet_button} || $params{twitter_follow_button}) { | |||||||||||||
| 387 | $rc .= $paragraph; | |||||||||||||
| 388 | } | |||||||||||||
| 389 | ||||||||||||||
| 390 | my $host_name; | |||||||||||||
| 391 | unless($self->{info}) { | |||||||||||||
| 392 | require CGI::Info; | |||||||||||||
| 393 | ||||||||||||||
| 394 | $self->{info} = CGI::Info->new(); | |||||||||||||
| 395 | } | |||||||||||||
| 396 | $host_name = $self->{info}->host_name(); | |||||||||||||
| 397 | ||||||||||||||
| 398 | $rc .= ""; | |||||||||||||
| 399 | ||||||||||||||
| 400 | if($params{google_plusone} || $params{linkedin_share_button} || $params{reddit_button}) { | |||||||||||||
| 401 | $rc .= $paragraph; | |||||||||||||
| 402 | } | |||||||||||||
| 403 | } | |||||||||||||
| 404 | ||||||||||||||
| 405 | if($params{linkedin_share_button}) { | |||||||||||||
| 406 | $rc .= << 'END'; | |||||||||||||
| 407 | ||||||||||||||
| 408 | ||||||||||||||
| 409 | END | |||||||||||||
| 410 | if($params{google_plusone} || $params{reddit_button}) { | |||||||||||||
| 411 | $rc .= $paragraph; | |||||||||||||
| 412 | } | |||||||||||||
| 413 | } | |||||||||||||
| 414 | if($params{google_plusone}) { | |||||||||||||
| 415 | # $rc .= << 'END'; | |||||||||||||
| 416 | # |
|||||||||||||
| 417 | # | |||||||||||||
| 420 | # | |||||||||||||
| 421 | # | |||||||||||||
| 422 | # | |||||||||||||
| 425 | # | |||||||||||||
| 426 | # END | |||||||||||||
| 427 | $rc .= ' |
|||||||||||||
| 428 | $rc .= ' | |||||||||||||
| 442 | END | |||||||||||||
| 443 | if($params{reddit_button}) { | |||||||||||||
| 444 | $rc .= $paragraph; | |||||||||||||
| 445 | } | |||||||||||||
| 446 | } | |||||||||||||
| 447 | if($params{reddit_button}) { | |||||||||||||
| 448 | $rc .= ''; | |||||||||||||
| 449 | } | |||||||||||||
| 450 | ||||||||||||||
| 451 | return $rc; | |||||||||||||
| 452 | } | |||||||||||||
| 453 | ||||||||||||||
| 454 | =head2 render | |||||||||||||
| 455 | ||||||||||||||
| 456 | Synonym for as_string. | |||||||||||||
| 457 | ||||||||||||||
| 458 | =cut | |||||||||||||
| 459 | ||||||||||||||
| 460 | sub render { | |||||||||||||
| 461 | my ($self, %params) = @_; | |||||||||||||
| 462 | ||||||||||||||
| 463 | return $self->as_string(%params); | |||||||||||||
| 464 | } | |||||||||||||
| 465 | ||||||||||||||
| 466 | =head1 AUTHOR | |||||||||||||
| 467 | ||||||||||||||
| 468 | Nigel Horne, C<< |
|||||||||||||
| 469 | ||||||||||||||
| 470 | =head1 BUGS | |||||||||||||
| 471 | ||||||||||||||
| 472 | When adding a FaceBook like button, you may find performance improves a lot if | |||||||||||||
| 473 | you use L |
|||||||||||||
| 474 | ||||||||||||||
| 475 | Please report any bugs or feature requests to C |
|||||||||||||
| 476 | the web interface at L |
|||||||||||||
| 477 | automatically be notified of progress on your bug as I make changes. | |||||||||||||
| 478 | ||||||||||||||
| 479 | Would be good to have | |||||||||||||
| 480 | my ($head, $body) = $sm->onload_render(); | |||||||||||||
| 481 | ||||||||||||||
| 482 | =head1 SEE ALSO | |||||||||||||
| 483 | ||||||||||||||
| 484 | ||||||||||||||
| 485 | =head1 SUPPORT | |||||||||||||
| 486 | ||||||||||||||
| 487 | You can find documentation for this module with the perldoc command. | |||||||||||||
| 488 | ||||||||||||||
| 489 | perldoc HTML::SocialMedia | |||||||||||||
| 490 | ||||||||||||||
| 491 | You can also look for information at: | |||||||||||||
| 492 | ||||||||||||||
| 493 | =over 4 | |||||||||||||
| 494 | ||||||||||||||
| 495 | =item * RT: CPAN's request tracker | |||||||||||||
| 496 | ||||||||||||||
| 497 | L |
|||||||||||||
| 498 | ||||||||||||||
| 499 | =item * AnnoCPAN: Annotated CPAN documentation | |||||||||||||
| 500 | ||||||||||||||
| 501 | L |
|||||||||||||
| 502 | ||||||||||||||
| 503 | =item * CPAN Ratings | |||||||||||||
| 504 | ||||||||||||||
| 505 | L |
|||||||||||||
| 506 | ||||||||||||||
| 507 | =item * Search CPAN | |||||||||||||
| 508 | ||||||||||||||
| 509 | L |
|||||||||||||
| 510 | ||||||||||||||
| 511 | =back | |||||||||||||
| 512 | ||||||||||||||
| 513 | ||||||||||||||
| 514 | =head1 ACKNOWLEDGEMENTS | |||||||||||||
| 515 | ||||||||||||||
| 516 | ||||||||||||||
| 517 | =head1 LICENSE AND COPYRIGHT | |||||||||||||
| 518 | ||||||||||||||
| 519 | Copyright 2011-2016 Nigel Horne. | |||||||||||||
| 520 | ||||||||||||||
| 521 | This program is released under the following licence: GPL | |||||||||||||
| 522 | ||||||||||||||
| 523 | =cut | |||||||||||||
| 524 | ||||||||||||||
| 525 | 1; # End of HTML::SocialMedia |