#!/usr/bin/perl =head1 NAME Comment Map Movable Type plugin =head1 DESCRIPTION Show your comments on a Google Map =head1 COPYRIGHT Copyright (c) 2006 Antoine Imbert All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut package MT::Plugin::CommentMap; use strict; use warnings; use Data::Dumper; use MT; use vars qw( $VERSION $plugin); $VERSION = 0.01; eval { require MT::Plugin; $plugin = MT::Plugin->new({ name => 'Comment Map', description => "Show your comments on a Google Map", doc_link => 'http://blog.ant0ine.com/2006/11/mt_comment_map_plugin.html', author_name => 'Antoine Imbert', author_link => 'http://blog.ant0ine.com', version => $VERSION, config_template => \&template, settings => new MT::PluginSettings([ ['google_api_key', { Default => '' }], ]), }); MT->add_plugin($plugin); MT::Template::Context->add_tag( CommentMapHead => \&comment_map_head); MT::Template::Context->add_tag( CommentMapDiv => \&comment_map_div); MT::Template::Context->add_tag( CommentMapScript => \&comment_map_script); }; sub make_map { my ($args) = @_; require Geo::IP::PurePerl; require HTML::GoogleMaps; require MT::Comment; require HTML::Template; my $gi = Geo::IP::PurePerl->new(Geo::IP::PurePerl::GEOIP_STANDARD()); my $map_key = $plugin->get_config_value('google_api_key') or die 'You must provide a Google Maps API key'; my $map = HTML::GoogleMaps->new( key => $map_key, height => $args->{height}, width => $args->{width} ); $map->v2_zoom($args->{zoom}); $map->dragging(0); $map->controls('small_map_control'); $map->map_type($args->{type}); my $markers = {}; my $iter = MT::Comment->load_iter( { junk_status => 1, blog_id => $args->{blog_id} }, { 'sort' => 'created_on', direction => 'descend', limit => $args->{lastn} } ); while (my $comment = $iter->()) { my $h = $gi->get_city_record_as_hash($comment->ip) or next; next unless $h->{longitude} && $h->{latitude} && $h->{city}; my $key = $h->{country_code}.$h->{city}; $markers->{$key} = $h unless $markers->{$key}; next if $markers->{$key}->{comments} && @{$markers->{$key}->{comments}} > $args->{max_comments_per_bubble}; push @{$markers->{$key}->{comments}}, { comment_author => $comment->author, comment_permalink => $comment->entry->permalink.'#comment-'.$comment->id, entry_title => $comment->entry->title, entry_permalink => $comment->entry->permalink, }; } for my $key (keys %{$markers}) { my $tmpl = &bubble; my $tmpl_obj = HTML::Template->new(scalarref => \$tmpl); $tmpl_obj->param( city => $markers->{$key}->{city}, comments => $markers->{$key}->{comments} ); my $html = $tmpl_obj->output; $html =~ s/"/\\"/g; $html =~ s/\n//g; $map->add_marker( point => [$markers->{$key}->{longitude}, $markers->{$key}->{latitude}], html => $html, noformat => 1); } return $map->render or die 'failed to render the map'; } sub comment_map_head { my ($ctx, $args, $cond) = @_; $args->{blog_id} ||= $ctx->stash('blog')->id; $args->{height} ||= 400; $args->{width} ||= 600; $args->{zoom} ||= 1; $args->{type} ||= 'normal'; $args->{lastn} ||= 10; $args->{max_comments_per_bubble} ||= 8; my $data = {}; eval { ($data->{head}, $data->{div}, $data->{script}) = &make_map($args); }; return $ctx->error($@) if $@; $ctx->stash('comment_map', $data); return $data->{head}; } sub comment_map_div { return $_[0]->stash('comment_map')->{div}; } sub comment_map_script { return $_[0]->stash('comment_map')->{script}; } sub template { my $tmpl = <<'EOT';

You can get a key at http://maps.google.com/apis/maps/signup.html

EOT } sub bubble { my $tmpl = <<'EOT';

on
EOT } 1;