Skip to content

Creating new plugins

Akron edited this page Nov 14, 2011 · 3 revisions

Creating new Plugins

Plugins are powerful in Mojolicious. You can add and change provided functionality by nearly all means.

In Mojolicious Lite they are started by using ...

plugin 'MyPlugin', foo => 'bar;

... and in Mojolicious by using ...

$app->plugin('MyPlugin', foo => 'bar');

... whereas (foo => 'bar') are the parameters the MyPlugin is initialized.

They have nearly always a similar structure:

package Mojolicious::Plugin::MyPlugin;
use Mojo::Base 'Mojolicious::Plugin';

sub register {
  my ($self, $app, $param) = @_;
  # This stuff is executed, when the plugin is loaded
};

1;

Helper

The most common way to provide additional functionality is by establishing helper methods for your Mojolicious app. Inside the register method of your plugin, you can define simple helpers as follows:

sub register {
  my ($self, $app, $param) = @_;
  $app->helper(
         think => sub {
                return '.o0(' . pop . ')';
              });
};

This adds a helper, that can be called from your Mojolicious app or from any controller inside your app. In a simple Mojolicious::Lite app, you could write:

use Mojolicious::Lite;

get '/(*foo)' => sub {
  my $self = shift;
  $self->render(text => $self->think( $self->stash('foo')));
};

app->start;

Hooks

Hooks can be used to make your plugin extensible by other plugins or to alter the content flow in a specific way in your app. You can emit a hook in your plugin by using the emit_hook or emit_hook_reverse methods of Mojolicious::Plugins.

sub register {
  my ($self, $app, $param) = @_;
  my $string = 'Hello World!';
  $c->app->plugins->emit_hook(
    'before_rendering_hello_world' => ($c, \$string));
  return $c->render_text($string);
};

In your app or another plugin you can run the hook by using the hook method of your app instance:

app->hook('before_rendering_hello_world' => sub {
  my $c = shift;
  my $string_ref = shift;
  $$string_ref =~ s/e/a/;
  return;
});

All hooks are applied in the order they subscribed to the event. You are only able to differ between this normal order or the reversed order.

Types

$mojo->types->type('xrd' => 'application/xrd+xml');

Pitfalls

register is executed each time the plugin is loaded as described above. This can result in unexpected behaviour, if you register a plugin multiple times. If you are not sure if there is already a functionality provided you need, check for that before you load the plugin.

If the plugin in question provides a helper 'myplugin_get' you need and you are not sure, if your application has already loaded the plugin, check for:

unless (exists $app->renderer->helpers->{'myplugin_get'}) {
  $app->plugin('my_plugin')
};

As you can register a plugin with different parameters, plugins can provide different functionality. So if you are not perfectly sure if a function is already there - check for it.

Clone this wiki locally