In the below code, how do I get “/” to render a template ?
my $auth = $r->under('/' => sub ($c) {
# Authenticated
return 1 if $c->req->headers->header('X-Bender');
# Not authenticated
$c->render(text => "You're not Bender.", status => 401);
return undef;
});
$auth->get('/blackjack')->to('hideout#blackjack');
(Source: https://docs.mojolicious.org/Mojolicious/Guides/Routing#Under).
For example, if I browse to “http://localhost:3000/blackjack” it renders “You’re not Bender.”
I want “http://localhost:3000/” to render “Hello, world !” (while still using Mojolicious::Routes::Route::under
).
Use Case:
It appears that under()
wastes an endpoint in order to prefix nested routes.
I want to make use of an intermediate prefix/parent route without losing the ability to share code between nested/child routes.
For example, in the below tree:
/company
/company/products
/company/services
“/company” should display a home page, and “/company/products” and “/company/services” should run shared code in “/company”.
1
Option 1
Stop using the $auth
routes for /
. Instead use the existing Mojolicious::Routes
you have in $r
.
my $auth = $r->under(
'/' => sub {
my $c = shift;
# Authenticated
return 1 if $c->req->headers->header('X-Bender');
# Not authenticated
$c->render( text => "You're not Bender.", status => 401 );
return undef;
}
);
$auth->get('/blackjack')->to('hideout#blackjack');
$r->get('/' => sub { shift->render(template => 'my_template') });
Option 2 (what I would recommend)
What you probably want is a “condition”. You can translate your under
to a condition like so:
$r->add_condition(
authenticated => sub {
my ($r, $c, $captures, $required) = @_;
return 1 unless $required;
return 1 if $c->req->headers->header('X-Bender');
# Not authenticated
$c->render( text => "You're not Bender.", status => 401 );
return undef;
}
);
Then all you have to do is add it to the routes you want like so:
$r->get('/blackjack')->requires(authenticated => 1)->to('hideout#blackjack');