Skip to content

Commit

Permalink
added helpers method to Mojolicious::Controller
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Aug 14, 2014
1 parent 9b7c1e2 commit 6c14c2a
Show file tree
Hide file tree
Showing 6 changed files with 33 additions and 13 deletions.
10 changes: 5 additions & 5 deletions lib/Mojolicious.pm
Expand Up @@ -158,11 +158,11 @@ sub new {
my $r = $self->routes->namespaces(["@{[ref $self]}::Controller", ref $self]);

# Hide controller attributes/methods and "handler"
$r->hide(qw(app continue cookie finish flash handler match on param));
$r->hide(qw(redirect_to render render_exception render_later render_maybe));
$r->hide(qw(render_not_found render_static render_to_string rendered req));
$r->hide(qw(res respond_to send session signed_cookie stash tx url_for));
$r->hide(qw(validation write write_chunk));
$r->hide(qw(app continue cookie finish flash handler helpers match on));
$r->hide(qw(param redirect_to render render_exception render_later));
$r->hide(qw(render_maybe render_not_found render_static render_to_string));
$r->hide(qw(rendered req res respond_to send session signed_cookie stash));
$r->hide(qw(tx url_for validation write write_chunk));

# Check if we have a log directory
my $mode = $self->mode;
Expand Down
10 changes: 10 additions & 0 deletions lib/Mojolicious/Controller.pm
Expand Up @@ -93,6 +93,8 @@ sub flash {
return $self;
}

sub helpers { $_[0]->app->renderer->get_helper('')->($_[0]) }

sub on {
my ($self, $name, $cb) = @_;
my $tx = $self->tx;
Expand Down Expand Up @@ -554,6 +556,14 @@ L</"session">.
$c->flash(message => 'User created successfully!');
$c->redirect_to('show_user', id => 23);
=head2 helpers
my $helpers = $c->helpers;
Return proxy object on which all helpers can be called.
$c->helpers->layout('green');
=head2 on
my $cb = $c->on(finish => sub {...});
Expand Down
12 changes: 8 additions & 4 deletions lib/Mojolicious/Guides/Rendering.pod
Expand Up @@ -474,12 +474,16 @@ be very useful for debugging. We differentiate between default helpers which
are more general purpose like C<dumper> and tag helpers, which are template
specific and mostly used to generate HTML tags.

%= javascript '/script.js'

%= javascript begin
var a = 'b';
%= link_to 'http://mojolicio.us' => begin
Mojolicious
% end

In controllers you can also use the method
L<Mojolicious::Controller/"helpers"> to ensure that helper calls don't
conflict with existing methods you may already have.

my $serialized = $c->helpers->dumper([1, 2, 3]);

A list of all built-in helpers can be found in
L<Mojolicious::Plugin::DefaultHelpers> and L<Mojolicious::Plugin::TagHelpers>.

Expand Down
3 changes: 2 additions & 1 deletion lib/Mojolicious/Renderer.pm
Expand Up @@ -76,8 +76,9 @@ sub get_helper {

my $found;
my $class = 'Mojolicious::Renderer::Helpers::' . md5_sum "$name:$self";
my $re = $name eq '' ? qr/^(([^.]+))/ : qr/^(\Q$name\E\.([^.]+))/;
for my $key (keys %{$self->helpers}) {
$key =~ /^(\Q$name\E\.([^.]+))/ ? ($found, my $method) = (1, $2) : next;
$key =~ $re ? ($found, my $method) = (1, $2) : next;
my $sub = $self->get_helper($1);
monkey_patch $class, $method => sub { ${shift()}->$sub(@_) };
}
Expand Down
1 change: 1 addition & 0 deletions t/mojolicious/app.t
Expand Up @@ -104,6 +104,7 @@ ok $t->app->routes->is_hidden('finish'), 'is hidden';
ok $t->app->routes->is_hidden('flash'), 'is hidden';
ok $t->app->routes->is_hidden('handler'), 'is hidden';
ok $t->app->routes->is_hidden('has'), 'is hidden';
ok $t->app->routes->is_hidden('helpers'), 'is hidden';
ok $t->app->routes->is_hidden('match'), 'is hidden';
ok $t->app->routes->is_hidden('new'), 'is hidden';
ok $t->app->routes->is_hidden('on'), 'is hidden';
Expand Down
10 changes: 7 additions & 3 deletions t/mojolicious/renderer.t
Expand Up @@ -64,19 +64,21 @@ $c->app->log->unsubscribe(message => $cb);

# Nested helpers
my $first = Mojolicious::Controller->new;
$first->app->log->level('fatal');
$first->helpers->app->log->level('fatal');
$first->app->helper('myapp.multi_level.test' => sub {'works!'});
ok $first->app->renderer->get_helper('myapp'), 'found helper';
ok $first->app->renderer->get_helper('myapp.multi_level'), 'found helper';
ok $first->app->renderer->get_helper('myapp.multi_level.test'), 'found helper';
is $first->myapp->multi_level->test, 'works!', 'right result';
is $first->helpers->myapp->multi_level->test, 'works!', 'right result';
$first->app->helper('myapp.defaults' => sub { shift->app->defaults(@_) });
ok $first->app->renderer->get_helper('myapp.defaults'), 'found helper';
is $first->app->renderer->get_helper('myap.'), undef, 'no helper';
is $first->app->renderer->get_helper('yapp'), undef, 'no helper';
$first->myapp->defaults(foo => 'bar');
is $first->myapp->defaults('foo'), 'bar', 'right result';
is $first->app->myapp->defaults('foo'), 'bar', 'right result';
is $first->helpers->myapp->defaults('foo'), 'bar', 'right result';
is $first->app->myapp->defaults('foo'), 'bar', 'right result';
my $second = Mojolicious::Controller->new;
$second->app->log->level('fatal');
is $second->app->renderer->get_helper('myapp'), undef, 'no helper';
Expand All @@ -85,7 +87,9 @@ $second->app->helper('myapp.defaults' => sub {'nothing'});
my $myapp = $first->myapp;
is $first->myapp->defaults('foo'), 'bar', 'right result';
is $second->myapp->defaults('foo'), 'nothing', 'right result';
is $first->myapp->defaults('foo'), 'bar', 'right result';
is $second->helpers->myapp->defaults('foo'), 'nothing', 'right result';
is $first->myapp->defaults('foo'), 'bar', 'right result';
is $first->helpers->myapp->defaults('foo'), 'bar', 'right result';

# Missing method (AUTOLOAD)
my $class = ref $first->myapp;
Expand Down

0 comments on commit 6c14c2a

Please sign in to comment.