# A plugin for converting '[map:address-description]' string into an # embeded map provided by mapping services. # # $Id$ # # This software is provided as-is. You may use it for commercial or # personal use. If you distribute it, please keep this notice intact. # # Copyright (c) 2006 Hirotaka Ogawa package MT::Plugin::Mapper; use strict; use MT; use MT::Template::Context; use MT::ConfigMgr; use base 'MT::Plugin'; sub BEGIN { our $VERSION = '0.12'; my $plugin = MT::Plugin::Mapper->new({ name => 'Mapper', version => $VERSION, description => 'This plugin enables MTMapper container tag, which converts "[map:address-description]" string into an embeded map provided by mapping services such as Google Maps.', doc_link => 'http://code.as-is.net/wiki/Mapper_Plugin', author_name => 'Hirotaka Ogawa', author_link => 'http://profile.typekey.com/ogawa/', blog_config_template => \&blog_config_template, settings => new MT::PluginSettings([ ['google_maps_key', { Default => '' }] ]), }); MT->add_plugin($plugin); MT::Template::Context->add_container_tag(Mapper => sub { $plugin->mapper(@_) }); } sub mapper { my $plugin = shift; my ($ctx, $args, $cond) = @_; my $blog = $ctx->stash('blog') or return; my $config = $plugin->get_config_hash('blog:' . $blog->id) or return; %$config = (%$config, %$args); $config->{unique} = $ctx->stash('entry')->id if defined $ctx->stash('entry'); my $cfg = MT::ConfigMgr->instance; $config->{language} ||= $cfg->DefaultLanguage; $config->{charset} ||= $cfg->PublishCharset; my $mapper_class = __PACKAGE__ . '::' . ($args->{method} || 'Google'); my $mapper = $mapper_class->new($config); defined(my $html = $ctx->stash('builder')->build($ctx, $ctx->stash('tokens'), $cond)) or return; $html =~ s!(?:<(?:div|p)\s+[^<>]*class="adr"[^<>]*>\s*([^<>]+)\s*)|(?:<(?:div|p)[^<>]*>\s*\[map:([^]]+)\]\s*)!$mapper->generate($1||$2)!ge; $html; } sub blog_config_template { my $tmpl = <<'EOT';

This plugin enables MTMapper container tag, which converts "[map:address-description]" string into an embeded map provided by mapping services such as Google Maps.

For more details, see "Mapper Plugin".

EOT } package MT::Plugin::Mapper::Google; use strict; use MT::Util qw(encode_url); use LWP::Simple; use HTML::Template; sub new { my $class = shift; my($config) = @_; $config->{count} = 0; $config->{unique} ||= int(rand(65536)); bless $config, $class; } sub DESTROY { } sub generate { my $this = shift; my($s) = @_; $s =~ s/^\s+//; $s =~ s/\s+$//; my($str, $opt) = split(/:/, $s); my $adr = $str; $adr =~ s/\(.*\)//ge; $adr =~ s/^\s+//; $adr =~ s/\s+$//; my($lat, $lon); if ($adr =~ m!^x([-.\d]+)y([-.\d]+)$!) { # map:xy ($lat, $lon) = ($2, $1); } elsif ($adr =~ m!^([-.\d]+),\s*([-.\d]+)$!) { # map:, ($lat, $lon) = ($1, $2); } else { ($lat, $lon) = eval { $this->resolve_address($adr) }; return "
$adr (Sorry, this address cannot be resolved.)
" if $@; } my $res = ''; $res .= $this->preamble unless $this->{count}; $res .= $this->body($lat, $lon, $str); $this->{count}++; $res; } sub resolve_address { my $this = shift; my($adr) = @_; my $geo_url = $this->{language} eq 'ja' ? 'http://maps.google.co.jp/maps?q=' : 'http://maps.google.com/maps?q='; $geo_url .= encode_url($adr) . '&output=kml'; $geo_url .= '&ie=' . $this->{charset} . '&oe=' . $this->{charset}; my $res = get($geo_url); if ($res && $res =~ /coordinates>([-.\d]+),([-.\d]+),/is) { return ($2, $1); } else { die "Cannot obtain the coordinates for this address."; } } my $preamble_tmpl = <<'EOT'; EOT sub preamble { my $this = shift; my $tmpl = HTML::Template->new(scalarref => \$preamble_tmpl); $tmpl->param( google_maps_key => $this->{google_maps_key}, language => $this->{language} || '' ); $tmpl->output; } my $body_tmpl = <<'EOT';
" style="width:;height:;" class="adr">
EOT sub body { my $this = shift; my($lat, $lon, $adr) = @_; my $tmpl = HTML::Template->new(scalarref => \$body_tmpl); $tmpl->param( mapid => "MTPluginMapperGoogle-" . $this->{unique} . '-' . $this->{count}, width => $this->{width} || '400px', height => $this->{height} || '300px', latitude => $lat, longitude => $lon, address => $adr, maptype => $this->{maptype} || 'G_NORMAL_MAP', zoom => (defined $this->{zoom}) ? $this->{zoom} : 15 ); $tmpl->output; } sub postamble { '' } package MT::Plugin::Mapper::Alps; use strict; use MT::Util qw(encode_url); use MT::I18N; sub new { my $class = shift; my($config) = @_; bless $config, $class; } sub DESTROY { } sub generate { my $this = shift; my($s) = @_; $s =~ s/^\s+//; $s =~ s/\s+$//; my($str, $opt) = split(/:/, $s); my $adr = $str; $adr =~ s/\(.*\)//ge; $adr =~ s/^\s+//; $adr =~ s/\s+$//; my $pos = ''; if ($adr =~ m!^x([-.\d]+)y([-.\d]+)$!) { # map:xy $pos = "$2,$1"; } elsif ($adr =~ m!^([-.\d]+),\s*([-.\d]+)$!) { # map:, $pos = $adr; } if ($pos) { return qq[

$str

]; } $adr = MT::I18N::encode_text($adr, '', 'euc-jp') || ''; $adr = MT::Util::encode_url($adr); qq[

$str

]; }