Many plugins define their own unique set of objects and classes for manipulating data. Often that data needs to be stored in a database. Instead of requiring developers to write their own SQL code, or having to understand the idiosyncrasies of each of the databases Movable Type supports, Movable Type provides a very nice abstraction layer that keeps developers from every having to write SQL ever. Hallelujah.
There are two components to defining a custom object:
- registering the object in the registry
- defining the properties of the object so that the database binding can be created
Once the object is defined, Movable Type will automatically create the database table(s) for you, and will keep its definition in sync with the properties you have defined.
Registering the Object in the Registry
First let's look at how you register a new object type.
sub init_registry {
my $plugin = shift;
$plugin->registry({
object_types => {
'happyvideo' => 'TestPlugin::SuperHappyVideo',
}
});
}
The code above will define a new object that is intended to be stored in a database. The object is called "happyvideo" and the properties of the object are defined in the perl module TestPlugin::SuperHappyVideo.
Note: If you define any custom objects, your plugin must also define a schema_version in order to signal to Movable Type that it has tables to install and maintain.
Defining the Object's Properties
Now, let's define the object's properties in a file and perl module called SuperHappyVideo.pm. This file should be placed in the following directory:
MT_HOME (where mt.cgi is located)
plugins/
TestPlugin/
lib/
TestPlugin/
Code from TestPlugin::SuperHappyVideo.pm
package TestPlugin::SuperHappyVideo;
use strict;
__PACKAGE__->install_properties({
column_defs => {
'id' => 'integer not null auto_increment',
'blog_id' => 'integer not null',
'title' => 'string(255)',
'description' => 'text',
'length' => 'integer',
},
});
The code above will instruct Movable Type to build out and maintain database tables with five different columns.
Movable Type provides great flexibility in defining the structure and behavior of an object is stores and manages for you in the database. For a complete guide on the syntax of defining the structure of a custom data type read the MT::Object man page.
Getting and Storing Data for a Custom Data Type
Once you have registered and defined your custom object type. You can easily save instances of the object, or retrieve and/or delete them from the database. Here are some very simple code samples which cover the basics of retrieving and storing these custom objects from the database:
Inserting Data
my $object = TestPlugin::SuperHappyVideo->new;
$object->blog_id(1);
$object->title("My latest video");
$object->length(120);
$object->description("The best video in the world.");
$object->save;
Loading and Updating Data
my $object = TestPlugin::SuperHappyVideo->load({ id => 4 });
$object->title("My latest HAPPY video!");
$object->save;
Deleting Data
my $object = TestPlugin::SuperHappyVideo->load({ id => 4 });
$object->remove;
There are a number of different functions Movable Type makes available to you to make it easier to query and manipulate data in the database. Some of these functions are:
loadload_iterget_by_keyremoveremove_allremove_childrensaveset_by_keyinitjoinuniquecountcount_group_byexists
For complete documentation on creating custom objects, please consult the MT::Object man page.
5 User Contributed Notes
I'm sure this is covered in another document, but it'd be convenient to have it here I think. Which is to say, I stumbled on this point :)
schema_version gets defined in the plugin constructor (and not, as I fruitlessly tried, the init_registry() profile).
[Ed: This has been fixed]
A typo:
The last part should read "TestPlugin::SuperHappyVideo" instead of "MT::SuperHappyVideo"
To chiggins comment above, the plugin constructor is the thing described here. So you would add schema_version to the following:
my $plugin = MT::Plugin::TestPlugin->new({ id => 'TestPlugin', key => 'test-plugin', name => 'Test Plugin', description => "My first plugin", version => $VERSION, author_name => "[your name]", author_link => "[URL to your homepage]", plugin_link => "[link to plugin's homepage]", });So that you have this:
my $plugin = MT::Plugin::TestPlugin->new({ id => 'TestPlugin', key => 'test-plugin', name => 'Test Plugin', schema_version => 1.0001, description => "My first plugin", version => $VERSION, author_name => "[your name]", author_link => "[URL to your homepage]", plugin_link => "[link to plugin's homepage]", });My question (and actually this may not be any different than with MT 3 but I'm uncertain even in that case) is what happens if your plugin defines multiple objects. You can only have one schema_version. Does a change in that schema_version do upgrades for all defined objects?
[Ed: This has been fixed]
There are three object functions above which are misspelled (and partially italicized) due to Markdown escaping. The correct function names are:
[Ed: This has been fixed]
Under the section above entitled "Defining the Object's Properties", the TestPlugin should be indented further to indicate that it is installed underneath the "plugins" folder. That is: