-
Notifications
You must be signed in to change notification settings - Fork 9
En dev listing framework overview
The listing Framework provides a common listing user interface for objects that inherits MT::Object
. The framework includes various functions such as filtering and sorting the list. A plugin author can use this framework to generate a list of custom objects as well as adding custom columns or filters to the existing MT objects.
In the past, the listing function used mtapp:listing
template tag, to render the list in the template. In the new listing framework we don’t use it anymore, but instead use a customizable template to render lists.
However, mtapp:listing
is still supported for the backward compatibility, but it does not provide new functions such as filtering or sorting.
Existing list_actions
and URL links ( such as http://example.com/mt.cgi?__mode=list&_type=entry&filter=status&filter_val=2
) should work fine in most cases.
Suppose that you have a new object in your plugin, named MyPlugin::Sunrise, who is recording the sunrise times in different cities around the world. It have a few fields: country, city, date, sunrise time, and a small boolean “was I there or not”, which we will shorten to “witon”. For the object itself, we choose the descriptive model name “sunrise”.
Of course, we want to create a listing for this object. (the creation of new objects of this kind is left as an exercise to the reader, but should probably include another form)
The object’s Perl module will be something like this:
package MyPlugin::Sunrise;
use strict;
use warnings;
use base qw( MT::Object );
__PACKAGE__->install_properties({
column_defs => {
id => 'integer not null auto_increment',
country => 'string(2)',
city => 'string(20)',
time => 'datetime',
witon => 'boolean not null',
},
datasource => 'sunrise',
primary_key => 'id',
});
The following code goes to the config.yaml file of the plugin
object_types:
sunrise: MyPlugin::Sunrise
listing_screens:
sunrise:
object_label: Sunrise Listing
primary: city
default_sort_key: id
condition: |
sub {
my ($app) = @_;
return $app->user->is_superuser();
}
list_properties:
sunrise:
country:
label: Country
html: $MyPlugin::MyPlugin::Sunrise::country_name
city: City
date:
label: Date
html: |
sub {
my ($prop, $obj, $app, $options) = @_;
return substr($obj->time, 0, 8);
}
time:
label: Time
html: |
sub {
my ($prop, $obj, $app, $options) = @_;
return substr($obj->time, 8);
}
witon: Was I There
First we told MT to register a new object class, (with object_types) and informed it that we want a listing screen for it. (listing_screens) and that only a superuser is allowed to see it.
Then we specify (in list_properties) which fields should be in the listing.
Of these fields, City and witon are the easiest: we just let MT handle everything.
Country is a bit more difficult: we store in the database just the shortcut, but want to display the full country name. So we use a handler to generate the name. um, maybe we should actually write it: (in Sunrise.pm)
my %country_names = ( US => "United State", JP => "Japan", IL => "Israel");
sub country_name {
my ($prop, $obj, $app, $options) = @_;
my $cc = $obj->country();
return $country_names{$cc} || $cc;
}
There. and we already handled all the important cases. (Or maybe it will be better use a module like Locale::Country)
The last two fields, date and time, are not a real fields in the object, that just keep one time field containing both day and time. we need to extract the info in both cases, and do it with inline subroutine inside the YAML.
Let’s inject some values to the database, if you still haven’t entered new objects to the system:
insert into mt_sunrise
(sunrise_city, sunrise_country, sunrise_time, sunrise_witon)
values ('Haifa', 'IL', NOW(), 0);
now use the URL:
mt.cgi?__mode=list&_type=sunrise
… and you see an empty list. before you start cursing, go to “display options” and mark all the columns. ah, now we can see a list!
You probably either want to make it a menu item, or put it as a link in other page.
Now you can customize the listing. You probably want to set the order of fields, and tell the listing to display some fields by default. Add action buttons, filters and some CSS to make it pretty. all the details are here:
- Registry: listing-screens – Define the overall behavior of the list
- Registry: list_properties – Add columns and filters to the list
- Registry: system_filters – Add built-in filters to the list
- Registry: list_actions – Add actions for the objects in the list
- Registry: content_actions – Add links to related pages above the list
See Listing Calbacks
If listing/foo_list_header.tmpl
exists in the template search path, it will be included automatically before the header. You can customize listing screens or add JavaScript code by accessing MTML variables in the included template.
See Template Special Variables
The event listReady
will be called when the list is loaded.
jQuery(window).bind('listReady', function() {
// Do something after the List table was rendered.
})
When MT receives a request like mt.cgi?__mode=list&_type=foo
and if corresponding method applications/cms/methods/list_foo
does not exist, the listing framework generate a list automatically from the information written in the registry ( listing_screens/foo
and list_properties/foo
) .
The listing framework calls XHR (XMLHttpRequest) to get listing data, and render HTML to display the listing screen. You can use various callbacks to customize either the listing data, the listing screen, or both.
The listing screen consists of HTML and JavaScript to render the list, the available filters and the actions. When the listing screen is loaded, or a user changes the filter settings, the listing screen calls XHR to get the data. The XHR contains parameters such as the filter type, the number of rows, and the requested columns. Based on the request, Movable Type loads objects from the database, convert them to proper HTML snippets, and then return the listing data in JSON format. The listing screen receives the JSON response and render it as the list.