问题
I have the layout like this:
@@ layouts/v2.html.ep
<html lang="en">
<head>
%= content_for 'stylesheets'
</head>
<body>
%= include 'layouts/v2/header'
<main class="main">
%= include 'layouts/v2/menu'
<div class="content">
%= content
</div>
</main>
</body>
</html>
@@ layouts/v2/menu
% content_for stylesheets => begin
%= stylesheet 'v2/css/menu.css'
% end
<aside class="menu">
...
</aside>
@@ layouts/v2/header
% content_for stylesheets => begin
%= stylesheet 'v2/css/header.css'
% end
<header class="header">
...
</header>
Here when templates are included I include their style sheets. Notice this in template:
% content_for stylesheets => begin
%= stylesheet 'v2/css/menu.css'
% end
But this is too late to do that, because the <head>
is already rendered.
As workaround this problem I can move %= content_for 'stylesheets'
from <head>
to the bottom of page. But I want style sheets are loaded first.
Is there any way to postpone rendering for the content of 'stylesheets' block until whole page is rendered?
UPD
Thank to @amon about that Mojolicous layouts are rendered inside out
. I understand the problem and there for templates included from first layout
I include stylesheets manually:
@@ layouts/v2.html.ep
<html lang="en">
<head>
%= stylesheet 'v2/css/header.css'
%= stylesheet 'v2/css/menu.css'
%= content_for 'stylesheets'
</head>
<body>
%= include 'layouts/v2/header'
<main class="main">
%= include 'layouts/v2/menu'
<div class="content">
%= content
</div>
</main>
</body>
</html>
So in any rendered/included template (except layout) next works fine:
@@ some/template
% content_for stylesheets => begin
%= stylesheet 'some/template.css'
% end
template content
回答1:
Mojolicous layouts are rendered inside-out, and you can nest arbitrarily many layouts.
Create a template that includes just the outermost document content and other HTML boilerplate, with a placeholder for the content of <body>
<html lang="en">
<head>
%= content_for 'stylesheets'
</head>
<body>
%= content
</body>
</html>
Then you can use that template as the layout for the body of your HTML page. I.e., use the layout
helper like this:
% layout 'outermost_layout';
%= include 'layouts/v2/header'
<main class="main">
%= include 'layouts/v2/menu'
<div class="content">
%= content
</div>
</main>
After rendering the template, Mojolicious will check whether you specified a layout
and then render it, using the output from this template as the outer layout's content
. So because the innermost layout is rendered first, data can flow from your templates through the stash to wrapping layouts.
来源:https://stackoverflow.com/questions/47798400/how-to-postpone-head-rendering