Skip to content

Instantly share code, notes, and snippets.

@KES777
Last active March 26, 2018 18:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KES777/1d3e4a5fa342c906f2ea5fde3bb165b9 to your computer and use it in GitHub Desktop.
Save KES777/1d3e4a5fa342c906f2ea5fde3bb165b9 to your computer and use it in GitHub Desktop.
proposition
Initial problem:
use Mojolicious::Lite;
use Test::Mojo;
use Test::More;
get '/test' => { format => 'xxx' };
my $t = Test::Mojo->new;
$t->get_ok('/test')->content_is( "xxx\n" );
$t->get_ok('/test.json')->content_is( "json\n" );
$t->get_ok('/test?format=json')->content_is( "json\n" );
done_testing();
__DATA__
@@ test.xxx.ep
xxx
@@ test.json.ep
json
$ perl basic.t
ok 1 - GET /test
ok 2 - exact match for content
ok 3 - GET /test.json
ok 4 - exact match for content
ok 5 - GET /test?format=json
not ok 6 - exact match for content
# Failed test 'exact match for content'
# at basic.t line 11.
# got: 'xxx
# '
# expected: 'json
# '
1..6
# Looks like you failed 1 test of 6.
As you can see default stash value for {format} take precedence over format
query parameter.
Whithout splitting out {format} default stash value
from {format} requested by client
we can not do proper content negotiation:
https://github.com/kraih/mojo/blob/v7.50/lib/Mojolicious/Renderer.pm#L31
Notice: this is v7.50
I propose that splitting in next patch:
https://github.com/KES777/mojo/pull/36/files#diff-2650135fc08c671d8b875d9b8480f498
This will allow better fallbacks for content negotiation when html is not
the default. I'm proposing an array ref valued stash parameter
which could take that into account. Example:
https://github.com/KES777/mojo/pull/36/files#diff-08d2a3a980946f364c7bf445ea6d4a2cR114
# Restrict all controllers to given format:
# /hello -> "html"
# /hello (Accept: text/html) -> "html"
# /hello (Accept: text/xml) -> "xml"
# /hello (Accept: text/plain) -> undef
# /hello.html -> "html"
# /hello.xml -> "xml"
# /hello.txt -> undef
# /hello?format=html -> "html"
# /hello?format=xml -> "xml"
# /hello?format=txt -> undef
$app->plugin('Format');
$app>defaults( format => [qw( html xml )] );
# Or only current route:
# /custom -> "json"
# /custom.html -> undef
# /custom.xml -> "xml"
# /custom.txt -> undef
$r->get( '/custom', { format => [qw( json, xml )] );
# Same but in controller's action (fallback is disabled):
# /action -> undef
# /action.html -> "html"
# /action.xml -> "xml"
# /action.txt -> undef
my $format = $c->format(undef, 'html', 'xml');
@KES777
Copy link
Author

KES777 commented Mar 26, 2018

Personally I prefer: $c->format('', 'html', 'xml'); (as accepts do) but in this case the ''empty string will be returned. To be consistent we need to return '' empty string instead of undef for other cases too

I can not decide which variant is better, so it is up to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment