From 2c65608e72368b1907484ad16c8ba9edea4b4c9d Mon Sep 17 00:00:00 2001 From: Mathias Kende Date: Mon, 10 May 2021 01:03:04 +0200 Subject: [PATCH] Add an inline_layout stash keyword, based on the mojo.js inlineLayout one. --- lib/Mojolicious/Guides/Rendering.pod | 4 ++++ lib/Mojolicious/Renderer.pm | 19 +++++++++++++++---- t/mojolicious/layouted_lite_app.t | 10 ++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/lib/Mojolicious/Guides/Rendering.pod b/lib/Mojolicious/Guides/Rendering.pod index b173277028..7f4cb4adb0 100644 --- a/lib/Mojolicious/Guides/Rendering.pod +++ b/lib/Mojolicious/Guides/Rendering.pod @@ -530,6 +530,10 @@ as a render argument (not a stash value). my $html = $c->render_to_string('reminder', layout => 'mail'); +Layouts can also be passed inline, using the C value. + + my $text = $c->render(inline => 'text', inline_layout => '<%== content %>'); + =head2 Partial templates You can break up bigger templates into smaller, more manageable chunks. These partial templates can also be shared with diff --git a/lib/Mojolicious/Renderer.pm b/lib/Mojolicious/Renderer.pm index 1e7dd70d1f..cc550aed98 100644 --- a/lib/Mojolicious/Renderer.pm +++ b/lib/Mojolicious/Renderer.pm @@ -108,11 +108,13 @@ sub render { # Inheritance my $content = $stash->{'mojo.content'} //= {}; local $content->{content} = $output =~ /\S/ ? $output : undef if $stash->{extends} || $stash->{layout}; + if ($stash->{inline_layout}) { + $options->{inline} = delete $stash->{inline_layout}; + local $stash->{handler} = $options->{handler}; + $self->_render_content($c, undef, $options, \$output); + } while ((my $next = _next($stash)) && !defined $inline) { - @$options{qw(handler template)} = ($stash->{handler}, $next); - $options->{format} = $stash->{format} || $self->default_format; - if ($self->_render_template($c, \my $tmp, $options)) { $output = $tmp } - $content->{content} //= $output if $output =~ /\S/; + $self->_render_content($c, $next, $options, \$output); } return $output if $stash->{'mojo.string'}; @@ -214,6 +216,15 @@ sub _next { return join '/', 'layouts', $layout; } +sub _render_content { + my ($self, $c, $next, $options, $output) = @_; + my $stash = $c->stash; + @$options{qw(handler template)} = ($stash->{handler}, $next); + $options->{format} = $stash->{format} || $self->default_format; + if ($self->_render_template($c, \my $tmp, $options)) { $$output = $tmp } + $stash->{'mojo.content'}->{content} //= $$output if $$output =~ /\S/; +} + sub _render_template { my ($self, $c, $output, $options) = @_; diff --git a/t/mojolicious/layouted_lite_app.t b/t/mojolicious/layouted_lite_app.t index 8756f96587..886dea48f2 100644 --- a/t/mojolicious/layouted_lite_app.t +++ b/t/mojolicious/layouted_lite_app.t @@ -97,6 +97,11 @@ get '/content_with'; get '/inline' => {inline => '<%= "inline!" %>'}; +get '/inline/inline_layout' => sub { + my $c = shift; + $c->render(inline => '<%= "inline!" %>', inline_layout => 'layouted_inline <%== content %>'); +}; + get '/inline/again' => {inline => 0}; get '/data' => {data => 0}; @@ -254,6 +259,11 @@ subtest 'Inline template' => sub { $t->get_ok('/inline')->status_is(200)->header_is(Server => 'Mojolicious (Perl)')->content_is("inline!\n"); }; +subtest 'Inline with layout' => sub { + $t->get_ok('/inline/inline_layout')->status_is(200)->header_is(Server => 'Mojolicious (Perl)') + ->content_is("layouted_inline inline!\n\n"); +}; + subtest '"0" inline template' => sub { $t->get_ok('/inline/again')->status_is(200)->header_is(Server => 'Mojolicious (Perl)')->content_is("0\n"); };