How to postpone <head> rendering?

不想你离开。 提交于 2019-12-12 12:32:23

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!