-
Notifications
You must be signed in to change notification settings - Fork 9
English plugin dev 4 2
Application, in MT, is a xxxx.cgi file, that the web server execute independantly. MT uses different application for different purposes.
For example, mt.cgi is the main CMS application. mt-comments.cgi is the application handling comments and commenters.
The rule-of-thumb is the if there is a need of a different authentication schema, use a different application. Otherwise, you can just add methods to an existing application, as we seen in previous chapters.
For this chapter, we will create an application for viewing / editing MT::Foo objects that we introduced later chapter.
We will use MyPlugin11 (where we added MT::Foo) as the basis of this chapter
- Should have three screens: view, edit and new, for creating, editing and listing MT::Foo objects
- Able to create and save new objects, as well as edit existing ones
- Encodes correctly while displaying the text parts of the MT::Foo objects, using
encode_html=1(we don’t want XSS attacks…) - For accessing the plugin we will use the URL
http://www.example.com/cgi-bin/mt504/plugins/MyPlugin12/newapp.cgi?blog_id=2(blog_id is required)
A config.yaml is not really necessary for adding an application, but adding one will make it appear in the plugin listing in the CMS, so nobody will forget that it is in place
id: MyPlugin12 key: MyPlugin12 name: <__trans phrase="Sample Plugin New Application"> version: 1.0 description: <__trans phrase="_PLUGIN_DESCRIPTION"> author_name: <__trans phrase="_PLUGIN_AUTHOR"> author_link: http://www.example.com/about/ doc_link: http://www.example.com/docs/ l10n_class: MyPlugin12::L10N
This is the CGI file that the server will run. As done in the mt-xxx.cgi files, we use MT::Bootstrap to start our application, that will be stored in the MyPlugin12::NewApp Perl module
#!/usr/bin/perl -w use strict; use lib '../../lib'; use lib '../../extlib'; use MT::Bootstrap App => 'MyPlugin12::NewApp';
If you are using Linux / OSX, be sure to make the file runnable
$ cd $MT_DIR/plugins/MyPlugin12/ $ sudo chmod +x newapp.cgi
The main body of the application. the init_request function is used for initize the application. The view, new, edit and save function provide the necessary functionality
package MyPlugin12::NewApp;
use strict;
use base qw( MT::App );
sub init_request {
my $app = shift;
$app->SUPER::init_request(@_);
$app->add_methods( main => \&view,
view => \&view,
new => \&foo_new,
edit => \&edit,
save => \&save,
);
$app->{ default_mode } = 'main';
$app->{ requires_login } = 1;
}
sub view {
my $app = shift;
my $q = $app->param;
my $blog_id = $q->param('blog_id');
my $blog = MT->model('blog')->load($blog_id);
my $class = $app->model('foo');
my ( $terms, $args );
$terms = { blog_id => $blog_id };
$args = { sort => 'created_on',
direction => 'descend',
limit => 10,
};
my @foos = $class->load( $terms, $args );
my $param;
$param = { blog_name => $blog->name,
foos => \@foos,
plugin_template_path => 'tmpl',
};
$app->build_page( 'view_foo.tmpl', $param );
}
sub edit {
my $app = shift;
my $q = $app->param;
my $blog_id = $q->param('blog_id');
my $blog = MT->model('blog')->load($blog_id);
my $id = $q->param('id');
my $class = $app->model('foo');
my $foo = $class->load( $id );
my $param;
$param = { blog_name => $blog->name,
id => $id,
blog_id => $blog_id,
title => $foo->title(),
bar => $foo->bar(),
plugin_template_path => 'tmpl',
};
$app->build_page( 'edit_foo.tmpl', $param );
}
sub save {
my $app = shift;
my $q = $app->param;
my $blog_id = $q->param('blog_id');
my $blog = MT->model('blog')->load($blog_id);
my $class = $app->model('foo');
my $foo;
my $id;
if ( $id = $q->param('id') ) {
$foo = $class->load($id);
} else {
$foo = $class->new();
$foo->blog_id($blog_id);
}
$foo->title($q->param('title'));
$foo->bar($q->param('bar'));
$foo->save()
or die $foo->errstr;
$app->redirect( $app->return_uri . "blog_id=$blog_id" );
}
sub foo_new {
my $app = shift;
my $q = $app->param;
my $blog_id = $q->param('blog_id');
my $blog = MT->model('blog')->load($blog_id);
my $param = { blog_name => $blog->name,
blog_id => $blog_id,
};
$app->build_page( 'new_foo.tmpl', $param );
}
1;
package MyPlugin12::NewApp; use strict; use base qw( MT::App );
- Declares the
MyPlugin12::NewAppPerl module - This module will inherit from
MT::App
sub init_request {
my $app = shift;
$app->SUPER::init_request(@_);
$app->add_methods( main => \&view,
view => \&view,
new => \&foo_new,
edit => \&edit,
save => \&save,
);
$app->{ default_mode } = 'main';
$app->{ requires_login } = 1;
}
- This function is for initializing the application
- Get
$app - Call parent class’s
init_request()for application-independent initializing -
$app->add_methods()is used to tell MT which modes this application supports, and which function to call for each mode- Ties main and view to the view function (
\&view) - Ties new to
\&foo_new, edit to\&editand save to\&save
- Ties main and view to the view function (
-
$app->{ default_mode } = 'main';if mode is not specified, use main -
$app->{ requires_login } = 1;Specify if a user need to be logged in to use this application-
1: Log-in is required. If the user is not logged in, he will be redirected to the login screen -
0: The user can be either logged in or not, he still can use the application
-
sub view {
my $app = shift;
my $q = $app->param;
my $blog_id = $q->param('blog_id');
my $blog = MT->model('blog')->load($blog_id);
my $class = $app->model('foo');
my ( $terms, $args );
$terms = { blog_id => $blog_id };
$args = { sort => 'created_on',
direction => 'descend',
limit => 10,
};
my @foos = $class->load( $terms, $args );
my $param;
$param = { blog_name => $blog->name,
foos => \@foos,
plugin_template_path => 'tmpl',
};
$app->build_page( 'view_foo.tmpl', $param );
}
- This function display the listing of MT::Foo objects
- Gets
$app– the application handle -
$qwill hold the collection of the request parameters - Get
$blog_idfrom the parameters - From
$blog_idload the blog object - Prepare the class of the
fooobject type - Prepare the
termsandargsfor loading the list offooobjects - Put all the needed data into
$param, and use it to build the output page with$app->build_page( 'view_foo.tmpl', $param );The template that will be used here isview_foo.tmpl(we will write it later)
sub edit {
my $app = shift;
my $q = $app->param;
my $blog_id = $q->param('blog_id');
my $blog = MT->model('blog')->load($blog_id);
my $id = $q->param('id');
my $class = $app->model('foo');
my $foo = $class->load( $id );
my $param;
$param = { blog_name => $blog->name,
id => $id,
blog_id => $blog_id,
title => $foo->title(),
bar => $foo->bar(),
plugin_template_path => 'tmpl',
};
$app->build_page( 'edit_foo.tmpl', $param );
}
- This function will output the edit screen for a MT::Foo object
- Gets
$app– the application handle -
$qwill hold the collection of the request parameters - Get
$blog_idfrom the parameters - From
$blog_idload the blog object - Get
$idfrom the parameters – the id of the MT::Foo object to edit - Prepare the class of the
fooobject type - Use
$idto load the relevant MT::Foo object to$foo - Push all the relevant data into
$param, and use it to build the page using$app->build_page( 'edit_foo.tmpl', $param );. the template file that will be used isedit_foo.tmpl
sub save {
my $app = shift;
my $q = $app->param;
my $blog_id = $q->param('blog_id');
my $blog = MT->model('blog')->load($blog_id);
my $class = $app->model('foo');
my $foo;
my $id;
if ( $id = $q->param('id') ) {
$foo = $class->load($id);
} else {
$foo = $class->new();
$foo->blog_id($blog_id);
}
$foo->title($q->param('title'));
$foo->bar($q->param('bar'));
$foo->save()
or die $foo->errstr;
$app->redirect( $app->return_uri . "blog_id=$blog_id" );
}
- This function handles saving an edited / new foo object
- Gets
$app– the application handle -
$qwill hold the collection of the request parameters - Get
$blog_idfrom the parameters - From
$blog_idload the blog object - If
idparameter is supplied, then this is an edit of existing object. Load the edited object - If there is not
idparameter, this is a new object. create a new object, and set itsblog_idusing$foo->blog_id($blog_id) - Set the
titleandbarproperties - Save
$foo, print an error on failure - After saving, redirect the user to the next page
sub foo_new {
my $app = shift;
my $q = $app->param;
my $blog_id = $q->param('blog_id');
my $blog = MT->model('blog')->load($blog_id);
my $param = { blog_name => $blog->name,
blog_id => $blog_id,
};
$app->build_page( 'new_foo.tmpl', $param );
}
- This function will output the screen for creating new foo objects
- Gets
$app– the application handle -
$qwill hold the collection of the request parameters - Get
$blog_idfrom the parameters - From
$blog_idload the blog object - Push all the relevant data into
$param, and use it to build the page using$app->build_page( 'new_foo.tmpl', $param );. the template file that will be used isnew_foo.tmpl
The template of the MT::Foo object listing screen
<html>
<head>
<title>MT::Foo View</title>
</head>
<body>
<h1><mt:var name="blog_name" encode_html=1/></h1>
<ul>
<mt:loop name="foos">
<li><a href="<mt:GetVar name="script_url" />?__mode=edit&id=<mt:GetVar name="id" />&blog_id=<mt:GetVar name="blog_id" />"><mt:GetVar name="title" encode_html=1/></a></li>
</mt:loop>
</ul>
<p><a href="<mt:GetVar name="script_url" />?__mode=new&blog_id=2">New</a></p>
</body>
</html>
The screen to edit an existing foo object
<html>
<head>
<title>MT::Foo Edit</title>
</head>
<body>
<h1><mt:var name="blog_name" /></h1>
<form method="post" action="<mt:GetVar name="script_url" escape_html=1 />">
<input type="hidden" name="__mode" value="save">
<input type="hidden" name="id" value="<mt:GetVar name="id">">
<input type="hidden" name="blog_id" value="<mt:GetVar name="blog_id">">
<table border="2">
<tr><td>id</td><td><mt:GetVar name="id"></td></tr>
<tr><td>blog_id</td><td><mt:GetVar name="blog_id"></td></tr>
<tr><td>title</td><td><input name="title" type="text" value="<mt:GetVar name="title" escape_html=1>"></td></tr>
<tr><td>bar</td><td><textarea name="bar"><mt:GetVar name="bar" escape_html=1></textarea></td></tr>
</table>
<br />
<input type="submit"><input type="reset">
</form>
<p><a href="<mt:GetVar name="script_url" />?__mode=main&blog_id=2">Back</a></p>
</body>
</html>
The screen for entering a new foo object
<html>
<head>
<title>MT::Foo New</title>
</head>
<body>
<h1><mt:var name="blog_name" /></h1>
<form method="post" action="<mt:GetVar name="script_url" />">
<input type="hidden" name="__mode" value="save">
<input type="hidden" name="blog_id" value="<mt:GetVar name="blog_id">">
<table border="2">
<tr><td>blog_id</td><td><mt:GetVar name="blog_id"></td></tr>
<tr><td>title</td><td><input name="title" type="text" value="<mt:GetVar name="title">"></td></tr>
<tr><td>bar</td><td><textarea name="bar"><mt:GetVar name="bar"></textarea></td></tr>
</table>
<br />
<input type="submit">
</form>
<p><a href="<mt:GetVar name="script_url" />?__mode=main&blog_id=2">Back</a></p>
</body>
</html>
$MT_DIR/
|__ plugins/
|__ MyPlugin12/
|__ config.yaml
|__ lib/
| |_ MyPlugin12/
| |__ L10N.pm
| |_ L10N/
| | |_ en_us.pm
| | |_ ja.pm
| |__ NewApp.pm
|__ newapp.cgi
|__ tmpl/
|_ edit_foo.tmpl
|_ new_foo.tmpl
|_ view_foo.tmpl
The independent application option gives us a very interesting ability to work outside of the regular MT framework, and you get to decide how far from the regular you want to be, by overriding selected functions of the MT::App class.
Of course, there are very few cases that I saw where it was used, and of them it was unnecessary in some, but still, better to have it in our toolbox…
Prev:Creating Your Own Objects << Index >> Next:Developing a transformer plug-in