【问题标题】:How to postpone <head> rendering?如何推迟 <head> 渲染?
【发布时间】:2017-12-13 16:52:57
【问题描述】:

我有这样的布局:

@@ 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>

在这里,当包含模板时,我会包含它们的样式表。 请注意模板中的这一点:

% content_for stylesheets => begin
  %= stylesheet 'v2/css/menu.css'
% end

但这已经太晚了,因为&lt;head&gt; 已经被渲染了。

作为解决此问题的方法,我可以将 %= content_for 'stylesheets'&lt;head&gt; 移动到页面底部。但我希望先加载样式表。

有什么办法可以推迟渲染“样式表”块的内容,直到整个页面渲染完?

UPD

感谢@amon 关于Mojolicous layouts are rendered inside out。我理解这个问题,对于第一个 layout 中包含的模板,我手动包含样式表:

@@ 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>

因此,在任何渲染/包含的模板(布局除外)中,下一个都可以正常工作:

@@ some/template
% content_for stylesheets => begin
  %= stylesheet 'some/template.css'
% end
template content

【问题讨论】:

  • 与 TT 一起使用的方法:some_page.tt:[% stylesheet = ... %][% WRAPPER wrapper.tt %]...[% END %]wrapper.tt:&lt;head&gt;[% stylesheet %]&lt;/head&gt;[% content %]。 Mojolicious 有某种包装指令吗?
  • @ikegami:好像是layout辅助命令

标签: perl mojolicious


【解决方案1】:

Mojolicous 布局由内向外渲染,您可以嵌套任意多个布局。

创建一个仅包含最外层文档内容和其他 HTML 样板的模板,并为 &lt;body&gt; 的内容使用占位符

<html lang="en">
  <head>
    %= content_for 'stylesheets'
  </head>
  <body>
    %= content
  </body>
</html>

然后,您可以使用该模板作为 HTML 页面正文的布局。即,像这样使用 layout 助手:

% layout 'outermost_layout';
%= include 'layouts/v2/header'
<main class="main">
  %= include 'layouts/v2/menu'
  <div class="content">
  %= content
  </div>
</main>

渲染模板后,Mojolicious 将检查您是否指定了layout,然后使用此模板的输出作为外部布局的content 进行渲染。因此,因为最里面的布局首先呈现,所以数据可以从您的模板通过 stash 流向包装布局。

【讨论】:

  • 在您的帮助下,我了解了我遇到的问题
  • @amon: “这允许数据从内部模板流向外部布局” 我不确定这是真的还是相关的
  • @Borodin 感谢您对风格的改进(我稍后会回来编辑相关的技术术语)。我认为提到数据流非常相关,因为这是问题的核心:数据无法及时流回已经渲染块的位置,但可以流向外部布局。
  • @amon:不客气,但我不认为 数据流Mojolicious 模板的相关性比与 Perl 的相关性更高子程序,你永远不会想强调这个概念。
猜你喜欢
  • 2018-07-12
  • 2019-10-11
  • 1970-01-01
  • 1970-01-01
  • 2019-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多