Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Hacking
Movable
Type
    A
guide
for
developers




      Six
Apart
Ltd.

                             Page

Developing
for
Movable
Type
in
2
Days

• Day
1:
The
Basics
  – Plugin
Structure
  – The
Registry
  – ConfiguraEon
DirecEves...
Course
Prerequisites
• This
course
requires
that
you
have
access
to
a

  working
Movable
Type
installa:on.
• This
course
a...
About
Hacking
• What
makes
a
good
programmer?
• Use
the
source
Luke.
• Copy
and
paste
is
your
friend.




                ...
Developing
for
Movable
Type
in
2
Days

• Day
1:
The
Basics
  ➡ Plugin
Structure
  – The
Registry
  – ConfiguraEon
DirecEves...
Plugin
Structure
• Your
config
file
  – plugins/MyPlugin/config.yaml
• Your
library
files
  – plugins/MyPlugin/lib/*
• Your
t...
Plugin
Structure
• Other
important
files
and
directories
  –   MyPlugin-README.txt
  –   MyPlugin-LICENSE.txt
  –   plugins...
Plugin
Packaging
• Files
that
really
help
with
the
packaging
and

  distribuEon
of
an
enEre
plugin:
  – Makefile.PL
  – MAN...
Makefile.PL
use ExtUtils::MakeMaker;
WriteMakefile(
    NAME         => quot;My Plugin's Display Namequot;,
    VERSION    ...
MANIFEST.SKIP
# version control
bCVS
(^|/).

# CPAN chain files
^MANIFEST
^Makefile
^META.yml$
^blib/
~$

# packages
.zip$...
CreaEng
a
Plugin
Zip
File
These
simple
sequence
of
commands:
> perl Makefile.PL
> make manifest
> make zipdist


Will
prod...
Developing
for
Movable
Type
in
2
Days

• Day
1:
The
Basics
  – Plugin
Structure
  ➡ The
Registry
  – ConfiguraEon
DirecEves...
The
Movable
Type
Registry
• Movable
Type
is
a
config‐driven
applicaEon.
• The
“registry”
is
where
Movable
Type
stores
its

...
config.yaml
name: Fluid App
id: FluidApp
author_link: http://www.majordojo.com/
author_name: Byrne Reese
description: This ...
Yikes
What
is
all
that?




                    Page

A
YAML
Primer
•   YAML
==
“Yet
Another
Markup
Language”
•   XML
AlternaEve
•   Less
verbose
•   Human
readable
and
writabl...
XML
vs.
YAML
<?xml version=quot;1.0quot;>
<address>

 <first_name>Byrne</first_name>

 <last_name>Reese</last_name>

 <ema...
XML
vs.
YAML
address:

 
 first_name: Byrne

 
 last_name: Reese

 
 email: byrne@majordojo.com

 
 company:

 
 
 name: S...
Your
First
Plugin
Place
this
in:
plugins/Good4Nothing/config.yaml
  name: Good for Nothing Plugin for Movable Type
  id: Go...
Developing
for
Movable
Type
in
2
Days

• Day
1:
The
Basics
  – Plugin
Structure
  – The
Registry
  ➡ Configura:on
Direc:ves...
Adding
a
Config
DirecEve
• What
is
a
configuraEon
direcEve?
• When
should
you
use
a
config
direcEve?
• What
are
the
alternaEv...
Adding
a
Config
DirecEve
name: Good for Nothing Plugin for Movable Type
id: Good4Nothing
key: Good4Nothing
author_link: htt...
Config
DirecEve
ProperEes
• Registry
properEes:
  – path
  – handler
  – alias




                                 Page

Developing
for
Movable
Type
in
2
Days

• Day
1:
The
Basics
  – Plugin
Structure
  – The
Registry
  – ConfiguraEon
DirecEves...
Adding
a
Template
Tag
• What
is
a
template
tag?
• Where
are
template
tags
used?
• What
are
the
various
types
of
template
t...
Adding
a
Template
Tag
‐
config.yaml
name: Good for Nothing Plugin for Movable Type
id: Good4Nothing
key: Good4Nothing
autho...
Adding
a
Template
Tag
‐
Handler
#   Good for Nothing Plugin for Movable Type
#   Author: Your Name Here, your.email@addres...
More
about
Template
Tags
• Types
of
Tags
  – funcEon
  – block
  – modifiers
• CondiEonal
Tags
• Loops
• Template
Context

...
More
about
Template
Tags
tags:
  function:
    'SaySomething': $Example::Example::Plugin::SaySomething

    'SayWhatever':...
More
about
Template
Tags
# Example: <mt:SaySomething>
sub SaySomething {
  my ($ctx, $args) = @_;
  return quot;Somethingq...
More
about
Template
Tags
# Example: <mt:LoopTenTimes>...</mt:LoopTenTimes>
sub LoopTenTimes {
  my ($ctx, $args, $cond) = ...
Adding
a
Tag
Modifier
• What
is
a
tag
modifier?
• Example
modifiers:
  –   <mt:block capitalize=“1”>abc</block>
  –   <mt:blo...
Adding
a
Template
Tag
‐
config.yaml
name: Good for Nothing Plugin for Movable Type
id: Good4Nothing
key: Good4Nothing
autho...
Adding
a
Modifier
‐
Handler
#   Good for Nothing Plugin for Movable Type
#   Author: Your Name Here, your.email@address.com...
Developing
for
Movable
Type
in
2
Days

• Day
1:
The
Basics
  – Plugin
Structure
  – The
Registry
  – ConfiguraEon
DirecEves...
Objects
and
Data
Persistence
• An
overview
of
Movable
Type
Objects
  – MT::Entry
  – MT::Comment
  – Etc.
• Before
and
afe...
About
MT
Objects
• Movable
Type’s
Data
AbstracEon
Layer
  – Data::ObjectDriver
  – MT::ObjectDriver
  – MT::Object
• Memca...
InteracEng
with
MT::Objects
•   MT::MyObject‐>new()
•   $obj‐>save()
•   MT::MyObject‐>load($terms,
$arguments)
•   MT::My...
new()
and
save()
my $foo = MT::Foo->new;
$foo->first_name(’Byrne');
$foo->last_name(‘Reese’);
$foo->save()
    or die quot...
load()
my @objects = MT::Foo->load(

 
 {

 
 
 title => quot;Hello Worldquot;,

 
 
 foo => quot;barquot;,

 
 }, {

 
 
...
load_iter()
my $iter = MT::Foo->load_iter(

 
 {

 
 
 title => quot;Hello Worldquot;,

 
 
 foo => quot;barquot;,

 
 }, ...
load
and
load_iter
OpEons
•   sort
•   direcEon
•   limit
•   lastn
•   offset
•   start_val
•   range
•   range_incl
•   j...
CreaEng
Your
Own
Object
•   Schema
definiEon
•   Registering
database
indexes
•   Record
audiEng
•   Primary
keys
•   Meta
...
MT::MyObject
package Example::MyObject;

use strict;
use base qw( MT::Object );

__PACKAGE__->install_properties({

   col...
MT::Object
Database
Data
Types
•   string
•   integer
•   boolean
•   smallint
•   dateEme
•   blob
•   text
•   float



 ...
Extending
ExisEng
Objects
• Extending
exisEng
objects
• schema_version
registry
property




                             ...
Extending
ExisEng
Objects

name: Example Plugin for Movable Type
id: Example
key: Example
description: This plugin is an e...
Extending
ExisEng
Objects

• Which
then
let’s
you
do
this:

use MT::Entry;
my $entry = MT::Entry->load($id);
$entry->is_fe...
Developing
for
Movable
Type
in
2
Days

• Day
1:
The
Basics
  – Plugin
Structure
  – The
Registry
  – ConfiguraEon
DirecEves...
Movable
Type
Callbacks
• Nomenclature:
  – Event,
Callback,
Fire,
Listening
• Event
Types
  – Object
Level
  – ApplicaEon
...
Object‐Level
Callbacks
• Events:
  – MT::ObjectName::pre_save
  – MT::ObjectName::post_save
  – MT::ObjectName::pre_load
 ...
Adding
a
Callback
‐
config.yaml
name: Good for Nothing Plugin for Movable Type
id: Good4Nothing
key: Good4Nothing
author_li...
Adding
a
Callback
‐
Handler
package Example::Plugin;
use strict;

sub pre_save {
  my ($cb, $obj) = @_;
  # $cb - holds a ...
Exercise:
Add
a
Callback
• Your
Mission:
Add
a
record
to
the
Movable

  Type
AcEvity
Log,
just
afer
an
entry
is
saved.
• A...
End
Day
1
    Byrne
Reese
byrne@sixapart.com




                     Page

Upcoming SlideShare
Loading in …5
×

Hacking Movable Type Training - Day 1

14,823 views

Published on

A series of slides presented to developers wishing to learn how to build plugins using Movable Type.

Published in: Technology, Art & Photos

Hacking Movable Type Training - Day 1

  1. Hacking
Movable
Type A
guide
for
developers Six
Apart
Ltd. Page

  2. Developing
for
Movable
Type
in
2
Days • Day
1:
The
Basics – Plugin
Structure – The
Registry – ConfiguraEon
DirecEves – Template
Tags – Objects – Callbacks • Day
2:
Building
User
Interfaces – Menus – New
ApplicaEon
Screens – Dialogs – LisEng
Screens 2 Page

  3. Course
Prerequisites • This
course
requires
that
you
have
access
to
a
 working
Movable
Type
installa:on. • This
course
also
assumes
that
you
are
familiar
 with
basic
system
administra:on
tasks,
such
 as
copying
and
ediEng
files. • Finally,
this
course
requires
knowledge
of
the
 Perl
programming
language. Page

  4. About
Hacking • What
makes
a
good
programmer? • Use
the
source
Luke. • Copy
and
paste
is
your
friend. Page

  5. Developing
for
Movable
Type
in
2
Days • Day
1:
The
Basics ➡ Plugin
Structure – The
Registry – ConfiguraEon
DirecEves – Template
Tags – Objects – Callbacks • Day
2:
Building
User
Interfaces – Menus – New
ApplicaEon
Screens – Dialogs – LisEng
Screens 5 Page

  6. Plugin
Structure • Your
config
file – plugins/MyPlugin/config.yaml • Your
library
files – plugins/MyPlugin/lib/* • Your
templates – plugins/MyPlugin/tmpl/* • Your
staEc
images,
javascript
and
CSS
files – mt-static/plugins/MyPlugin/* Page

  7. Plugin
Structure • Other
important
files
and
directories – MyPlugin-README.txt – MyPlugin-LICENSE.txt – plugins/MyPlugin/t/* – plugins/MyPlugin/extlib/* – plugins/MyPlugin/php/* Page

  8. Plugin
Packaging • Files
that
really
help
with
the
packaging
and
 distribuEon
of
an
enEre
plugin: – Makefile.PL – MANIFEST.SKIP Page

  9. Makefile.PL use ExtUtils::MakeMaker; WriteMakefile( NAME => quot;My Plugin's Display Namequot;, VERSION => '1.1', DISTNAME => 'MyPlugin', ); Page

  10. MANIFEST.SKIP # version control bCVS (^|/). # CPAN chain files ^MANIFEST ^Makefile ^META.yml$ ^blib/ ~$ # packages .zip$ .tar.gz$ Page

  11. CreaEng
a
Plugin
Zip
File These
simple
sequence
of
commands: > perl Makefile.PL > make manifest > make zipdist Will
produce
the
perfect
MT
Plugin
zip
file: • MyPlugin‐1.1.zip Page

  12. Developing
for
Movable
Type
in
2
Days • Day
1:
The
Basics – Plugin
Structure ➡ The
Registry – ConfiguraEon
DirecEves – Template
Tags – Objects – Callbacks • Day
2:
Building
User
Interfaces – Menus – New
ApplicaEon
Screens – Dialogs – LisEng
Screens 12 Page

  13. The
Movable
Type
Registry • Movable
Type
is
a
config‐driven
applicaEon. • The
“registry”
is
where
Movable
Type
stores
its
 configuraEon. • Each
plugin
provides
a
mini‐registry
file,
config.yaml,
 that
defines
its
feature
set. • The
config.yaml
file
is
then
merged
into
Movable
 Type’s
main
registry. • Every
plugin
therefore
is
50%
configuraEon
and
50%
 code. Page

  14. config.yaml name: Fluid App id: FluidApp author_link: http://www.majordojo.com/ author_name: Byrne Reese description: This plugin provides enhanced support for Fluid. version: 0.90 plugin_link: http://www.majordojo.com/projects/mt-fluid-app.php applications: cms: methods: fluid_update: $FluidApp::FluidApp::Plugin::cms_update callbacks: MT::App::CMS::template_source.header: $FluidApp::…::Plugin::xfrm Page

  15. Yikes What
is
all
that? Page

  16. A
YAML
Primer • YAML
==
“Yet
Another
Markup
Language” • XML
AlternaEve • Less
verbose • Human
readable
and
writable Page

  17. XML
vs.
YAML <?xml version=quot;1.0quot;> <address> <first_name>Byrne</first_name> <last_name>Reese</last_name> <email>byrne@majordojo.com</email> <company> <name>Six Apart, Ltd.</name> <street_address> 548 4th Street, San Francisco, CA 94107 </street_address> </company> </address> Page

  18. XML
vs.
YAML address: first_name: Byrne last_name: Reese email: byrne@majordojo.com company: name: Six Apart, Ltd. street_address: 548 4th Street, San Francisco, CA 94107 Page

  19. Your
First
Plugin Place
this
in:
plugins/Good4Nothing/config.yaml name: Good for Nothing Plugin for Movable Type id: Good4Nothing key: Good4Nothing author_link: http://www.yourwebsite.com/ author_name: Your Name Here description: This plugin is an example plugin. version: 1.0 Page

  20. Developing
for
Movable
Type
in
2
Days • Day
1:
The
Basics – Plugin
Structure – The
Registry ➡ Configura:on
Direc:ves – Template
Tags – Objects – Callbacks • Day
2:
Building
User
Interfaces – Menus – New
ApplicaEon
Screens – Dialogs – LisEng
Screens 20 Page

  21. Adding
a
Config
DirecEve • What
is
a
configuraEon
direcEve? • When
should
you
use
a
config
direcEve? • What
are
the
alternaEves? Page

  22. Adding
a
Config
DirecEve name: Good for Nothing Plugin for Movable Type id: Good4Nothing key: Good4Nothing author_link: http://www.yourwebsite.com/ author_name: Your Name Here description: This plugin is an example plugin. version: 1.0 config_settings: MyImageURL: default: http://path.com/images/foo.jpg Page

  23. Config
DirecEve
ProperEes • Registry
properEes: – path – handler – alias Page

  24. Developing
for
Movable
Type
in
2
Days • Day
1:
The
Basics – Plugin
Structure – The
Registry – ConfiguraEon
DirecEves ➡ Template
Tags – Objects – Callbacks • Day
2:
Building
User
Interfaces – Menus – New
ApplicaEon
Screens – Dialogs – LisEng
Screens 24 Page

  25. Adding
a
Template
Tag • What
is
a
template
tag? • Where
are
template
tags
used? • What
are
the
various
types
of
template
tags? Page

  26. Adding
a
Template
Tag
‐
config.yaml name: Good for Nothing Plugin for Movable Type id: Good4Nothing key: Good4Nothing author_link: http://www.yourwebsite.com/ author_name: Your Name Here description: This plugin is an example plugin. version: 1.0 config_settings: MyImageURL: default: http://path.com/images/foo.jpg tags: function: MyImageURL: $Good4Nothing::Good4Nothing::Plugin::tag Page

  27. Adding
a
Template
Tag
‐
Handler # Good for Nothing Plugin for Movable Type # Author: Your Name Here, your.email@address.com # Copyright (C) 2008 Your Name Here # This file is licensed under the Artistic License, # or the same terms as Perl itself. package Good4Nothing::Plugin; use strict; sub tag { my ($ctx) = @_; my $cfg = $ctx->{config}; return $cfg->MyImageURL; } 1; # Every module must return true Page

  28. More
about
Template
Tags • Types
of
Tags – funcEon – block – modifiers • CondiEonal
Tags • Loops • Template
Context Page

  29. More
about
Template
Tags tags: function: 'SaySomething': $Example::Example::Plugin::SaySomething 'SayWhatever': $Example::Example::Plugin::SayWhatever block: 'LoopTenTimes': $Example::Example::Plugin::LoopTenTimes 'IfOdd?': $Example::Example::Plugin::IfOdd Page

  30. More
about
Template
Tags # Example: <mt:SaySomething> sub SaySomething { my ($ctx, $args) = @_; return quot;Somethingquot;quot;; } # Example: <mt:SayWhatever say=”Hello”> sub SayWhatever { my ($ctx, $args) = @_; # What the person passed in through the # argument 'say' my $input = $args->{'say'}; return $input; } Page

  31. More
about
Template
Tags # Example: <mt:LoopTenTimes>...</mt:LoopTenTimes> sub LoopTenTimes { my ($ctx, $args, $cond) = @_; my $out = quot;quot;; my $builder = $ctx->stash('builder'); my $tokens = $ctx->stash('tokens'); for (my $i = 1; $i <= 10; $i++) { $ctx->stash(quot;current_loop_numberquot;,$i); $out .= quot;$i * quot; . $builder->build($ctx,$tokens,$cond); } return $out; } # Example: <mt:IfOdd>do this</mt:IfOdd> sub IfOdd { my ($ctx, $args, $cond) = @_; my $num = $ctx->stash('current_loop_number'); if ($num % 2 == 0) { return 0; } else { return 1; } } Page

  32. Adding
a
Tag
Modifier • What
is
a
tag
modifier? • Example
modifiers: – <mt:block capitalize=“1”>abc</block> – <mt:block ltrim=“1”> foo</mt:block> – <mt:block regex_replace=“/foo/gi”,”bar”> foo </mt:block> – <mt:block count_words=“1”>Hello World</mt:block> Page

  33. Adding
a
Template
Tag
‐
config.yaml name: Good for Nothing Plugin for Movable Type id: Good4Nothing key: Good4Nothing author_link: http://www.yourwebsite.com/ author_name: Your Name Here description: This plugin is an example plugin. version: 1.0 config_settings: MyImageURL: default: http://path.com/images/foo.jpg tags: modifier: lolcats: $Good4Nothing::Good4Nothing::Plugin::lolcats Page

  34. Adding
a
Modifier
‐
Handler # Good for Nothing Plugin for Movable Type # Author: Your Name Here, your.email@address.com # Copyright (C) 2008 Your Name Here # This file is licensed under the Artistic License, # or the same terms as Perl itself. package Good4Nothing::Plugin; use strict; sub lolcats { my ($str, $val, $ctx) = @_; return quot;CAN I HAZ “. uc($str); } 1; # Every module must return true Page

  35. Developing
for
Movable
Type
in
2
Days • Day
1:
The
Basics – Plugin
Structure – The
Registry – ConfiguraEon
DirecEves – Template
Tags ➡ Objects – Callbacks • Day
2:
Building
User
Interfaces – Menus – New
ApplicaEon
Screens – Dialogs – LisEng
Screens 35 Page

  36. Objects
and
Data
Persistence • An
overview
of
Movable
Type
Objects – MT::Entry – MT::Comment – Etc. • Before
and
afer
a
record
is
modified
in
the
 Movable
Type
database,
an
event
is
fired. • Plugins
can
register
callbacks
for
those
events. Page

  37. About
MT
Objects • Movable
Type’s
Data
AbstracEon
Layer – Data::ObjectDriver – MT::ObjectDriver – MT::Object • Memcached
Support • Event
PropagaEon • Gegers/Segers Page

  38. InteracEng
with
MT::Objects • MT::MyObject‐>new() • $obj‐>save() • MT::MyObject‐>load($terms,
$arguments) • MT::MyObject‐>load_iter($terms,
$arguments) • $obj‐>remove($terms,
$arguments) • MT::MyObject‐>remove_all • MT::MyObject‐>count($terms) • MT::MyObject‐>exists($terms) • $obj‐>clone() Page

  39. new()
and
save() my $foo = MT::Foo->new; $foo->first_name(’Byrne'); $foo->last_name(‘Reese’); $foo->save() or die quot;Saving foo failed: quot;, $foo->errstr; Page

  40. load() my @objects = MT::Foo->load( { title => quot;Hello Worldquot;, foo => quot;barquot;, }, { sort => 'created_on', direction => 'ascend', } ); foreach my $obj (@objects) { print $obj->baz(); # do something } Page

  41. load_iter() my $iter = MT::Foo->load_iter( { title => quot;Hello Worldquot;, foo => quot;barquot;, }, { sort => 'created_on', direction => 'ascend', } ); while (my $obj = $iter->()) { print $obj->baz(); # do something } Page

  42. load
and
load_iter
OpEons • sort • direcEon • limit • lastn • offset • start_val • range • range_incl • join
 • unique Page

  43. CreaEng
Your
Own
Object • Schema
definiEon • Registering
database
indexes • Record
audiEng • Primary
keys • Meta
Data Page

  44. MT::MyObject package Example::MyObject; use strict; use base qw( MT::Object ); __PACKAGE__->install_properties({ column_defs => { 'id' => 'integer not null auto_increment', 'blog_id' => 'integer', 'some_property' => 'string(100) not null', }, audit => 1, indexes => { id => 1, }, datasource => 'myplugin_myobject', primary_key => 'id', }); Page

  45. MT::Object
Database
Data
Types • string • integer • boolean • smallint • dateEme • blob • text • float Page

  46. Extending
ExisEng
Objects • Extending
exisEng
objects • schema_version
registry
property Page

  47. Extending
ExisEng
Objects name: Example Plugin for Movable Type id: Example key: Example description: This plugin is an example plugin version: 1.0 schema_version: 2 object_types: entry: is_featured: smallint Page

  48. Extending
ExisEng
Objects • Which
then
let’s
you
do
this: use MT::Entry; my $entry = MT::Entry->load($id); $entry->is_featured(1); $entry->save; Page

  49. Developing
for
Movable
Type
in
2
Days • Day
1:
The
Basics – Plugin
Structure – The
Registry – ConfiguraEon
DirecEves – Template
Tags – Objects ➡ Callbacks • Day
2:
Building
User
Interfaces – Menus – New
ApplicaEon
Screens – Dialogs – LisEng
Screens 49 Page

  50. Movable
Type
Callbacks • Nomenclature: – Event,
Callback,
Fire,
Listening • Event
Types – Object
Level – ApplicaEon
Level – TransformaEon Page

  51. Object‐Level
Callbacks • Events: – MT::ObjectName::pre_save – MT::ObjectName::post_save – MT::ObjectName::pre_load – MT::ObjectName::post_load – MT::ObjectName::pre_remove – MT::ObjectName::pre_remove_all – MT::ObjectName::post_remove_all Page

  52. Adding
a
Callback
‐
config.yaml name: Good for Nothing Plugin for Movable Type id: Good4Nothing key: Good4Nothing author_link: http://www.yourwebsite.com/ author_name: Your Name Here description: This plugin is an example plugin. version: 1.0 callbacks: MT::Entry::pre_save: $Example::Example::Plugin::pre_save Page

  53. Adding
a
Callback
‐
Handler package Example::Plugin; use strict; sub pre_save { my ($cb, $obj) = @_; # $cb - holds a reference to the callback object # $obj - holds a reference to the object about # to be saved # do your thing if ($error) { return $cb->error(“Error Message”); } } Page

  54. Exercise:
Add
a
Callback • Your
Mission:
Add
a
record
to
the
Movable
 Type
AcEvity
Log,
just
afer
an
entry
is
saved. • About
Logging: MT->log({ message => quot;DemoPlugin: an object was saved.quot;, class => 'system', level => MT::Log::INFO() }); }); Page

  55. End
Day
1 Byrne
Reese byrne@sixapart.com Page


×