Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
added some nested helpers as examples
  • Loading branch information
kraih committed Sep 11, 2014
1 parent 2fb41c6 commit 8ec15ea
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 63 deletions.
2 changes: 2 additions & 0 deletions Changes
@@ -1,5 +1,7 @@

5.40 2014-09-11
- Added reply->exception and reply->not_found helpers to
Mojolicious::Plugin::DefaultHelpers.
- Deprecated Mojo::EventEmitter::emit_safe.
- Improved all events to work the same.

Expand Down
59 changes: 4 additions & 55 deletions lib/Mojolicious/Controller.pm
Expand Up @@ -4,7 +4,6 @@ use Mojo::Base -base;
# No imports, for security reasons!
use Carp ();
use Mojo::ByteStream;
use Mojo::Exception;
use Mojo::Transaction::HTTP;
use Mojo::URL;
use Mojo::Util;
Expand Down Expand Up @@ -172,13 +171,13 @@ sub render {
return !!$self->rendered($self->stash->{status});
}

sub render_exception { _development('exception', @_) }
sub render_exception { shift->helpers->reply->exception(@_) }

sub render_later { shift->stash('mojo.rendered' => 1) }

sub render_maybe { shift->render(@_, 'mojo.maybe' => 1) }

sub render_not_found { _development('not_found', @_) }
sub render_not_found { shift->helpers->reply->not_found }

sub render_static {
my ($self, $file) = @_;
Expand Down Expand Up @@ -386,50 +385,6 @@ sub write_chunk {
return $self->rendered;
}

sub _development {
my ($page, $self, $e) = @_;

my $app = $self->app;
$app->log->error($e = Mojo::Exception->new($e)) if $page eq 'exception';

# Filtered stash snapshot
my $stash = $self->stash;
my %snapshot = map { $_ => $stash->{$_} }
grep { !/^mojo\./ and defined $stash->{$_} } keys %$stash;

# Render with fallbacks
my $mode = $app->mode;
my $renderer = $app->renderer;
my $options = {
exception => $page eq 'exception' ? $e : undef,
format => $stash->{format} || $renderer->default_format,
handler => undef,
snapshot => \%snapshot,
status => $page eq 'exception' ? 500 : 404,
template => "$page.$mode"
};
my $inline = $renderer->_bundled($mode eq 'development' ? $mode : $page);
return $self if _fallbacks($self, $options, $page, $inline);
_fallbacks($self, {%$options, format => 'html'}, $page, $inline);
return $self;
}

sub _fallbacks {
my ($self, $options, $template, $inline) = @_;

# Mode specific template
return 1 if $self->render_maybe(%$options);

# Normal template
return 1 if $self->render_maybe(%$options, template => $template);

# Inline template
my $stash = $self->stash;
return undef unless $stash->{format} eq 'html';
delete @$stash{qw(extends layout)};
return $self->render_maybe(%$options, inline => $inline, handler => 'ep');
}

1;

=encoding utf8
Expand Down Expand Up @@ -700,10 +655,7 @@ additional pairs get merged into the L</"stash">.
$c = $c->render_exception('Oops!');
$c = $c->render_exception(Mojo::Exception->new('Oops!'));
Render the exception template C<exception.$mode.$format.*> or
C<exception.$format.*> and set the response status code to C<500>. Also sets
the stash values C<exception> to a L<Mojo::Exception> object and C<snapshot>
to a copy of the L</"stash"> for use in the templates.
Alias for L<Mojolicious::Plugin::DefaultHelpers/"reply-E<gt>exception">.
=head2 render_later
Expand Down Expand Up @@ -734,10 +686,7 @@ could be generated, takes the same arguments as L</"render">.
$c = $c->render_not_found;
Render the not found template C<not_found.$mode.$format.*> or
C<not_found.$format.*> and set the response status code to C<404>. Also sets
the stash value C<snapshot> to a copy of the L</"stash"> for use in the
templates.
Alias for L<Mojolicious::Plugin::DefaultHelpers/"reply-E<gt>not_found">.
=head2 render_static
Expand Down
9 changes: 5 additions & 4 deletions lib/Mojolicious/Guides/Rendering.pod
Expand Up @@ -445,8 +445,9 @@ By now you've probably already encountered the built-in 404 (Not Found) and
500 (Server Error) pages, that get rendered automatically when you make a
mistake. Those are fallbacks for when your own exception handling fails, but
especially during development they can also be a great help, you can render
them manually with the methods L<Mojolicious::Controller/"render_exception">
and L<Mojolicious::Controller/"render_not_found">.
them manually with the helpers
L<Mojolicious::Plugin::DefaultHelpers/"reply-E<gt>exception"> and
L<Mojolicious::Plugin::DefaultHelpers/"reply-E<gt>not_found">.

use Mojolicious::Lite;
use Scalar::Util 'looks_like_number';
Expand All @@ -456,11 +457,11 @@ and L<Mojolicious::Controller/"render_not_found">.
my ($dividend, $divisor) = $c->param(['dividend', 'divisor']);

# 404
return $c->render_not_found
return $c->reply->not_found
unless looks_like_number $dividend && looks_like_number $divisor;

# 500
return $c->render_exception('Division by zero!') if $divisor == 0;
return $c->reply->exception('Division by zero!') if $divisor == 0;

# 200
$c->render(text => $dividend / $divisor);
Expand Down
74 changes: 70 additions & 4 deletions lib/Mojolicious/Plugin/DefaultHelpers.pm
Expand Up @@ -3,6 +3,7 @@ use Mojo::Base 'Mojolicious::Plugin';

use Mojo::ByteStream;
use Mojo::Collection;
use Mojo::Exception;
use Mojo::IOLoop;
use Mojo::Util qw(dumper sha1_sum steady_time);

Expand Down Expand Up @@ -32,10 +33,12 @@ sub register {
qw(inactivity_timeout is_fresh url_with);
$app->helper(b => sub { shift; Mojo::ByteStream->new(@_) });
$app->helper(c => sub { shift; Mojo::Collection->new(@_) });
$app->helper(config => sub { shift->app->config(@_) });
$app->helper(dumper => sub { shift; dumper(@_) });
$app->helper(include => sub { shift->render_to_string(@_) });
$app->helper(ua => sub { shift->app->ua });
$app->helper(config => sub { shift->app->config(@_) });
$app->helper(dumper => sub { shift; dumper(@_) });
$app->helper(include => sub { shift->render_to_string(@_) });
$app->helper('reply.exception' => sub { _development('exception', @_) });
$app->helper('reply.not_found' => sub { _development('not_found', @_) });
$app->helper(ua => sub { shift->app->ua });
}

sub _accepts {
Expand Down Expand Up @@ -82,6 +85,50 @@ sub _delay {
$delay->catch(sub { $c->render_exception(pop) and undef $tx })->wait;
}

sub _development {
my ($page, $self, $e) = @_;

my $app = $self->app;
$app->log->error($e = Mojo::Exception->new($e)) if $page eq 'exception';

# Filtered stash snapshot
my $stash = $self->stash;
my %snapshot = map { $_ => $stash->{$_} }
grep { !/^mojo\./ and defined $stash->{$_} } keys %$stash;

# Render with fallbacks
my $mode = $app->mode;
my $renderer = $app->renderer;
my $options = {
exception => $page eq 'exception' ? $e : undef,
format => $stash->{format} || $renderer->default_format,
handler => undef,
snapshot => \%snapshot,
status => $page eq 'exception' ? 500 : 404,
template => "$page.$mode"
};
my $inline = $renderer->_bundled($mode eq 'development' ? $mode : $page);
return $self if _fallbacks($self, $options, $page, $inline);
_fallbacks($self, {%$options, format => 'html'}, $page, $inline);
return $self;
}

sub _fallbacks {
my ($self, $options, $template, $inline) = @_;

# Mode specific template
return 1 if $self->render_maybe(%$options);

# Normal template
return 1 if $self->render_maybe(%$options, template => $template);

# Inline template
my $stash = $self->stash;
return undef unless $stash->{format} eq 'html';
delete @$stash{qw(extends layout)};
return $self->render_maybe(%$options, inline => $inline, handler => 'ep');
}

sub _inactivity_timeout {
return unless my $stream = Mojo::IOLoop->stream(shift->tx->connection // '');
$stream->timeout(shift);
Expand Down Expand Up @@ -319,6 +366,25 @@ L</"stash">.
Alias for L<Mojolicious::Controller/"param">.
=head2 reply->exception
$c = $c->reply->exception('Oops!');
$c = $c->reply->exception(Mojo::Exception->new('Oops!'));
Render the exception template C<exception.$mode.$format.*> or
C<exception.$format.*> and set the response status code to C<500>. Also sets
the stash values C<exception> to a L<Mojo::Exception> object and C<snapshot>
to a copy of the L</"stash"> for use in the templates.
=head2 reply->not_found
$c = $c->reply->not_found;
Render the not found template C<not_found.$mode.$format.*> or
C<not_found.$format.*> and set the response status code to C<404>. Also sets
the stash value C<snapshot> to a copy of the L</"stash"> for use in the
templates.
=head2 session
%= session 'foo'
Expand Down

0 comments on commit 8ec15ea

Please sign in to comment.