hacking movable type
DESCRIPTION
An introduction to plugin development for Movable TypeTRANSCRIPT
“Movable Type 3.2 is the premier weblog publishing
platform for businesses, organizations, developers,
and web designers”
MT
Articoli,
template
________
________
________
Le funzioni di MT
Le funzioni di MT<MTEntries> <$MTEntryTrackbackData$>...<a id="a<$MTEntryID pad="1"$>"></a><div class="entry" id="entry-<$MTEntryID$>"> <h3 class="entry-header"><$MTEntryTitle$></h3> <div class="entry-content"> <div class="entry-body"> <$MTEntryBody$> <MTEntryIfExtended> ... </div> </div></div></MTEntries>
Le caratteristiche di MT
• Interfaccia web completa ma affidabile
• Sistema di gestione degli autori (con abbozzo di gestione di ruoli e permessi)
• Sistema potente per la gestione dei template
Inoltre...
MT dal punto di vista del programmatore
• Espone una API sofisticata e documentata
• Incoraggia lo sviluppo di plug-in per estenderne le funzionalità
• È scritto in Perl :-)
MT
Articoli,
template
________
________
________
Plugin
Estendere MT
Esempi di realizzazioni
Esempi di realizzazioni
maketitle.plmy $plugin;
require MT::Plugin;
$plugin = MT::Plugin->new( { name => 'Maketitle', description => q{Costruisce titoli grafici}, doc_link => '',} );
MT->add_plugin($plugin);
maketitle.pl /2
# ... continua
MT::Template::Context->add_tag( MakeGraphicTitle => \&make_graphic_title );
maketitle.pl /2
...<center> <$MTMakeGraphicTitle$></center>...
nel template...
maketitle.pl /2sub make_graphic_title{ my $context = shift; my $params = shift;
my $entry = $context->stash('entry');
my $title = $entry->title(); my $dirified_title = dirify( $title ); ... return qq{<img src="$imageurl">};}
maketitle.pl /2
...<center> <img src=”...”></center>...
nel file HTML risultante...
statwatch
statwatch
schemas mysql.dump
tmpl
list.tmpl
swfooter.tmpl
swheader.tmpl
view.tmpl
statwatch
statwatch
lib
Stats.pm
StatWatch Visit.pm
StatWatch.pm
StatWatchConfig.pm
statvisit.cgi
statwatch.cgi
statwatch.pl
statwatch
...
MT::Template::Context->add_tag('Stats' => sub{&staturl});
sub staturl { my $ctx = shift; my $blog = $ctx->stash('blog');
my $cfg = MT::ConfigMgr->instance; my $script = '<script type="text/javascript"> '.'<!-- '. qq|document.write('<img src="| . $cfg->CGIPath . "plugins/statwatch/statvisit.cgi?blog_id=" . $blog->id ... |.'// -->'.' </script>'; return $script;}
1;
statwatch.pl
statwatch
lib
Stats.pm
StatWatch Visit.pm
StatWatch.pm
StatWatchConfig.pm
statvisit.cgi
statwatch.cgi
statwatch.pl
statwatch
# StatWatch - lib/StatWatch/Visit.pm # Nick O'Neill (http://www.raquo.net/statwatch/)
package StatWatch::Visit;use strict;
use MT::App;@StatWatch::Visit::ISA = qw( MT::App );
use Stats;my $VERSION = '1.2';my $DEBUG = 0;
Visit.pm
MT::App
MT::App::CMS MT::App::Comments MT::App::Search
MT
MT::ErrorHandler
MT::Plugin
sub init { my $app = shift; $app->SUPER::init(@_) or return; $app->add_methods( visit => \&visit, ); $app->{default_mode} = 'visit'; $app->{user_class} = 'MT::Author';
$app->{charset} = $app->{cfg}->PublishCharset; my $q = $app->{query};
$app;}
Visit.pm /2
sub visit { my $app = shift; my $q = $app->{query}; my $blog_id; if ($blog_id = $q->param('blog_id')) { require MT::Blog; my $blog = MT::Blog->load({ id => $blog_id }) or die "Error loading blog from blog_id $blog_id";
my $stats = Stats->new;
# ...
Visit.pm /2
statwatch
lib
Stats.pm
StatWatch Visit.pm
StatWatch.pm
StatWatchConfig.pm
statvisit.cgi
statwatch.cgi
statwatch.pl
statwatch
package Stats;use strict;
use MT::Object;@Stats::ISA = qw( MT::Object );__PACKAGE__->install_properties({ columns => [ 'id', 'blog_id', 'url', 'referrer', 'ip', ], indexes => { ip => 1, blog_id => 1, created_on => 1, }, audit => 1, datasource => 'stats', primary_key => 'id',});
1;
Visit.pm /2
MT::ObjectDriver
MT::ObjectDriver::DBI MT::ObjectDriver::DBM
MT::Object
MT::Entry MT::Author MT::Config
MT::ErrorHandler
# ...
$stats->ip($app->remote_ip); $stats->referrer($referrer); $stats->blog_id($blog_id); $stats->url($url); &compileStats($blog_id,$app->remote_ip);
$stats->save or die "Saving stats failed: ", $stats->errstr; } else { die "No blog id"; }}
Visit.pm /2
statwatch
lib
Stats.pm
StatWatch Visit.pm
StatWatch.pm
StatWatchConfig.pm
statvisit.cgi
statwatch.cgi
statwatch.pl
statwatch
sub init { my $app = shift; $app->SUPER::init(@_) or return; $app->add_methods( list => \&list, view => \&view, ); $app->{default_mode} = 'list'; $app->{user_class} = 'MT::Author';
$app->{requires_login} = 1; $app->{charset} = $app->{cfg}->PublishCharset; my $q = $app->{query};
$app;}
Visit.pm /2
sub list { my $app = shift; my %param; my $q = $app->{query}; $param{debug} = ($DEBUG || $q->param('debug')); $param{setup} = $q->param('setup');
( $param{script_url} , $param{statwatch_base_url} , $param{statwatch_url} , my $static_uri) = parse_cfg();
require MT::PluginData; unless (MT::PluginData->load({ plugin => 'statwatch', key => 'setup_'.$VERSION })) { &setup; $app->redirect($param{statwatch_url}."?setup=1"); }
require MT::Blog; my @blogs = MT::Blog->load; my $data = []; ...
Visit.pm /2
... ### Listing the blogs on the main page ### for my $blog (@blogs) { if (Stats->count({ blog_id => $blog->id })) { # [... colleziona i dati da mostrare ...] # Row it my $row = { ... }; push @$data, $row; } } $param{blog_loop} = $data; $param{gen_time} = " | ".$now." seconds";
$param{version} = $VERSION; $app->build_page('tmpl/list.tmpl', \%param);}
Visit.pm /2
Riepilogo?
• Inserire nuovi tag speciale all’interno dei template
• Aggiungere pannelli (applicazioni)
• ...
BigPAPI
• Big Plugin API
• Permette di agganciarsi all’interfaccia esistente di MT, estendendo le funzionalità dei pannelli esistenti
Perchè?
RightFieldsMT->add_callback( 'bigpapi::template::edit_entry::top', 9, $rightfields, \&edit_entry_template );
MT->add_callback( 'bigpapi::param::edit_entry', 9, $rightfields, \&edit_entry_param );
MT->add_callback( 'bigpapi::param::preview_entry', 9, $rightfields, \&preview_entry_param);
RightFields
Approfondimenti
• Six Apart Developer Wikihttp://www.lifewiki.net/sixapart/
• Seedmagazine.com — Lookin’ Goodhttp://o2b.net/archives/seedmagazine
• Beyond the bloghttp://a.wholelottanothing.org/features/2003/07/beyond_the_blog
• http://del.icio.us/slr/movabletype :-)
Grazie :)
Stefano [email protected]