350 likes | 427 Views
Welcome to San Francisco Perl Mongers. Sponsored by. Wireless Network Info: SSID: melody No WEP, no keys, nada. Building on the. Byrne Reese Manager, Platform Technology Six Apart, Ltd. October 20, 2005. overview. Introductions About Six Apart Why Movable Type? Your First Plugin.
E N D
Welcome to San Francisco Perl Mongers • Sponsored by Wireless Network Info: SSID: melody No WEP, no keys, nada.
Building on the Byrne Reese Manager, Platform Technology Six Apart, Ltd. October 20, 2005
overview Introductions About Six Apart Why Movable Type? Your First Plugin
me Product Manager Open Source Hacker CPAN Contributor (SOAP::Lite) Movable Type Plugin Developer
six apart 10+ million bloggers using our software to share their lives, experiences and opinions with their friends, their families and the world. plus, a company of perl experts, hackers and enthusiasts
our modules XML::Feed XML::FOAF WWW::Blog::Metadata XML::Atom XML::Atom::Filter SOAP::Lite Net::OpenID LWP::ParanoidAgent Perlbal SWF::Chart Crypt::OpenSSL::DSA Text::Textile Email::Find Mac::MacBinary plus over a hundred more…
movabletype highly extensible plugin architecture large community of developers free! not a product… a platform
Simple Complex a platform Plugins can range from the very simple to the very complex.
Simple Complex a platform Template Tags Text Filters Examples: IfEmpty ModifiedOn Textile Markdown Ajaxify
Simple Complex a platform • StatWatch • Add one template tag and… • Get hit stats for your blog. • One template tag • A one-page user interface
Simple Complex a platform • StyleCatcher • MT Template Plugin Action • Complex Javascript UI • Support for multiple template libraries
Simple Complex a platform • SpamLookup • Complex set of plugin actions for filtering incoming comments • Expert use of MT’s plugin configuration framework
Simple Complex a platform • Media Manager • Third party integration • Dedicated User Interface • Alternative templates • Overloaded modes
Simple Complex a platform • Not to mention plugins for: • Feedburner plugin • PayPal Firewalls • Editorial Workflow • Podcasting • …you name it.
pronet you are not alone… hundreds of members strong articles, docs and mailing lists plugin directory a community of developers…
pronet …and professionals gig leads promote yourself deals on conferences free technical support
creating your plugin package MT::Plugin::MyPlugin; use MT; use base qw(MT::Plugin); use vars qw($VERSION); sub BEGIN { $VERSION = '1.0'; my $plugin; $plugin = new MT::Plugin::MyPlugin({ name => 'Photo Gallery', version => $VERSION, description => ‘A description.', doc_link => '', author_name => 'Byrne Reese', author_link => 'http://www.majordojo.com/', }); MT->add_plugin($plugin); }
registering your plugin place your plugin .pl file in the plugins directory your plugin will appear among the other plugins in MT’s Plugins Control Panel
a simple tag MT::Template::Context->add_tag(HelloWorld => \&helloworld); sub helloworld { my ($context, $args) = @_; my $who = $args->{who} || “World”; if ($who eq “Byrne”) { return $context->error(“Please don’t feed the animals”); } return “Hello $who”; } # <MTHelloWorld who=“Byrne”>
a container tag MT::Template::Context->add_container_tag(HelloWorld => \&helloworld); sub helloworld { my ($context, $args) = @_; my $who = $args->{who} || “World”; my $res; my $builder = $ctx->stash('builder'); my $tokens = $ctx->stash('tokens'); foreach my $p (split(“,”,$who) { $ctx->stash(‘who', $p); defined(my $out = $builder->build($context, $tokens)) or return $ctx->error($context->errstr); $res .= $out; } $res; }
a container tag (continued) MT::Template::Context->add_tag(Who => \&who); sub who { my ($context, $args) = @_; my $who = $context->stash(‘who’); return $who; } # <MTHelloWorld who=“byrne,ben,mark”> # <$MTWho$> # </MTHelloWorld
a conditional tag MT::Template::Context->add_conditional_tag(IfByrne => \&ifbyrne); sub ifbyrne { my ($context, $args) = @_; my $who = $context->stash(‘who’); return $who =~ /Byrne/i; } # <MTHelloWorld who=“byrne,ben,mark”> # <MTIfByrne> # Please don’t feed the animals. # <MTElse> # <$MTWho$> # </MTIfByrne> # </MTHelloWorld
a simple text filter MT->add_text_filter(‘bfil’, { label => "Byrne’s Filter", on_format => &filter, docs => ‘url’}); sub filter { my ($str, $context) = @_; $str =~ s#Byrne#<a href=“http://majordojo.com/”>\1</a>#gi return $str; }
MT::App your plugin == a tiny MT contains all of your application logic package MyPlugin::App; use strict; use MT::App; @MyPlugin::App::ISA = qw( MT::App ); sub init { my $app = shift; my %param = @_; $app->SUPER::init(%param) or return; $app->add_methods(‘hello’ => &hello); return $app; } sub hello { my $app = shift; $app->l10n_filter( “hello world” ); }
creating a cgi script dispatches requests to your MT::App MT::Bootstrap #!/usr/bin/perl # # My Movable Type Plugin use strict; use lib "lib", ($ENV{MT_HOME} ? "$ENV{MT_HOME}/lib" : "../../lib"); use MT::Bootstrap App => ‘MyPlugin::App'; __END__
MT::Object abstracts developer away from SQL and database package MediaManager::Entry; use strict; use MT::Object; @MediaManager::Entry::ISA = qw( MT::Object ); __PACKAGE__->install_properties({ column_defs => { 'id' => 'integer not null auto_increment', 'blog_id' => 'integer not null', 'title' => 'string(150) not null', 'catalog' => 'string(50) not null', 'isbn' => 'string(50) not null', 'entry_id' => 'integer' }, indexes => { blog_id => 1, }, audit => 1, datasource => 'mediamanager', primary_key => 'id', });
MT::Object methods count exists load and load_iter save remove my %constraints; $constraints{blog_id} = $blog_id; $constraints{status} = $show if $show ne 'all'; $constraints{catalog} = $catalog if $catalog ne 'all'; my %options; $options{sort} = $sort; $options{direction} = direction => $acs ? 'ascend' : 'descend'; $options{limit} = $limit if $limit ne 'none'; $options{offset} = $offset; my $iter = MediaManager::Entry->load_iter( \%constraints, \%options );
etcetera alt-templates junk filters callbacks advanced plugin actions integrated plugin settings interface BigPAPI