Hacking Movable Type

24,390 views

Published on

An introduction to plugin development for Movable Type

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
24,390
On SlideShare
0
From Embeds
0
Number of Embeds
72
Actions
Shares
0
Downloads
61
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Hacking Movable Type

  1. 1. Hacking Movable Type Italian Perl Workshop 2006 Stefano Rodighiero - stefano.rodighiero@dada.net
  2. 2. “Movable Type 3.2 is the premier weblog publishing platform for businesses, organizations, developers, and web designers”
  3. 3. Le funzioni di MT MT ________ ________ Articoli, ________ template
  4. 4. Le funzioni di MT <MTEntries> <$MTEntryTrackbackData$> ... <a id=quot;a<$MTEntryID pad=quot;1quot;$>quot;></a> <div class=quot;entryquot; id=quot;entry-<$MTEntryID$>quot;> <h3 class=quot;entry-headerquot;><$MTEntryTitle$></h3> <div class=quot;entry-contentquot;> <div class=quot;entry-bodyquot;> <$MTEntryBody$> <MTEntryIfExtended> ... </div> </div> </div> </MTEntries>
  5. 5. 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
  6. 6. Inoltre...
  7. 7. 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 :-)
  8. 8. Estendere MT MT ________ ________ Articoli, ________ template Plugin
  9. 9. Esempi di realizzazioni
  10. 10. Esempi di realizzazioni
  11. 11. maketitle.pl my $plugin; require MT::Plugin; $plugin = MT::Plugin->new( { name => 'Maketitle', description => q{Costruisce titoli grafici}, doc_link => '', } ); MT->add_plugin($plugin);
  12. 12. maketitle.pl /2 # ... continua MT::Template::Context->add_tag( MakeGraphicTitle => &make_graphic_title );
  13. 13. maketitle.pl /2 nel template... ... <center> <$MTMakeGraphicTitle$> </center> ...
  14. 14. maketitle.pl /2 sub 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=quot;$imageurlquot;>}; }
  15. 15. maketitle.pl /2 nel file HTML risultante... ... <center> <img src=”...”> </center> ...
  16. 16. statwatch
  17. 17. statwatch schemas mysql.dump list.tmpl statwatch swfooter.tmpl tmpl swheader.tmpl view.tmpl
  18. 18. statwatch Stats.pm lib StatWatch Visit.pm statvisit.cgi StatWatch.pm statwatch statwatch.cgi StatWatchConfig.pm statwatch.pl
  19. 19. statwatch.pl ... 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=quot;text/javascriptquot;> '.'<!-- '. qq|document.write('<img src=quot;| . $cfg->CGIPath . quot;plugins/statwatch/statvisit.cgi?blog_id=quot; . $blog->id ... |.'// -->'.' </script>'; return $script; } 1;
  20. 20. statwatch Stats.pm lib StatWatch Visit.pm statvisit.cgi StatWatch.pm statwatch statwatch.cgi StatWatchConfig.pm statwatch.pl
  21. 21. Visit.pm # 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;
  22. 22. MT::ErrorHandler MT::Plugin MT MT::App MT::App::CMS MT::App::Comments MT::App::Search
  23. 23. Visit.pm /2 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; }
  24. 24. 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 quot;Error loading blog from blog_id $blog_idquot;; my $stats = Stats->new; # ...
  25. 25. statwatch Stats.pm lib StatWatch Visit.pm statvisit.cgi StatWatch.pm statwatch statwatch.cgi StatWatchConfig.pm statwatch.pl
  26. 26. Visit.pm /2 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;
  27. 27. MT::ErrorHandler MT::Object MT::ObjectDriver MT::ObjectDriver::DBI MT::ObjectDriver::DBM MT::Entry MT::Author MT::Config
  28. 28. Visit.pm /2 # ... $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 quot;Saving stats failed: quot;, $stats->errstr; } else { die quot;No blog idquot;; } }
  29. 29. statwatch Stats.pm lib StatWatch Visit.pm statvisit.cgi StatWatch.pm statwatch statwatch.cgi StatWatchConfig.pm statwatch.pl
  30. 30. Visit.pm /2 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; }
  31. 31. 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}.quot;?setup=1quot;); } require MT::Blog; my @blogs = MT::Blog->load; my $data = []; ...
  32. 32. 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} = quot; | quot;.$now.quot; secondsquot;; $param{version} = $VERSION; $app->build_page('tmpl/list.tmpl', %param); }
  33. 33. Riepilogo? • Inserire nuovi tag speciale all’interno dei template • Aggiungere pannelli (applicazioni) • ...
  34. 34. BigPAPI • Big Plugin API • Permette di agganciarsi all’interfaccia esistente di MT, estendendo le funzionalità dei pannelli esistenti
  35. 35. Perchè?
  36. 36. RightFields MT->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);
  37. 37. RightFields
  38. 38. Approfondimenti • Six Apart Developer Wiki http://www.lifewiki.net/sixapart/ • Seedmagazine.com — Lookin’ Good http://o2b.net/archives/seedmagazine • Beyond the blog http://a.wholelottanothing.org/features/2003/07/beyond_the_blog • http://del.icio.us/slr/movabletype :-)
  39. 39. Grazie :) Stefano Rodighiero stefano.rodighiero@dada.net

×