您混淆了两个不同的 Rails 功能:部分(使用render) http://guides.rubyonrails.org/layouts_and_rendering.html#using-partials and 布局(使用yield) http://guides.rubyonrails.org/layouts_and_rendering.html#understanding-yield.
您可以将其中一个(或两个)的类似 Rails 的版本添加到仅限 Haml 的程序中。
Partials
在 Rails 视图中,您可以使用render :partial_name
导致文件_partial_name.html.haml
在包含视图中的该点进行渲染(实际上 Rails 允许您使用支持的任何模板语言,并且它会找到要使用的正确文件扩展名,但我将在这里坚持使用 Haml)。铁轨外render
不可用,但可以相当容易地添加。
一个简单的render
方法只会找到适当的 haml 文件,渲染它,并返回 html 字符串以包含在父级中:
def render(partial)
# assuming we want to keep the rails practice of prefixing file names
# of partials with "_"
Haml::Engine.new(File.read("_#{partial}.html.haml")).render
end
第一个参数Haml::Engine.render
是一个作用域对象,我们可以使用它来添加 haml 模板中可用的方法。它默认为Object.new
。然而,在像这样的简单情况下,我们可以定义render
方法位于顶层,并且它将在 Haml 模板的范围内可用。我们简单地把我们的render
调用之前脚本中的方法Haml::Engine.new(...).render
,并在我们的模板中这样称呼它:
!!!
%html
%head
%title Hello
%body
=render :the_partial
现在文件_the_partial.html.haml
将在输出的适当位置呈现渲染。
局部变量
我们可以更进一步。 Rails 允许你传递一个哈希值局部变量 http://guides.rubyonrails.org/layouts_and_rendering.html#passing-local-variables到部分。 Haml 还将接受作为局部变量传递的变量哈希,作为 Haml 的第二个参数render
方法。因此,如果我们将渲染方法扩展为:
def render(partial, locals = {})
Haml::Engine.new(File.read("_#{partial}.html.haml")).render(Object.new, locals)
end
我们可以使用如下所示的部分:
%p You passed in #{foo}
并从我们的模板中调用它:
%body
=render :partial, :foo => "bar"
这将呈现
<body>
<p>You passed in bar</p>
</body>
Layouts
在 Rails 中,您可以为视图指定布局,以便所有页面可以共享相同的布局
标题、菜单区域等。这是通过指定布局文件来完成的,您可以在其中调用yield
渲染相关的实际视图。添加到 haml 的布局稍微复杂一些,但仍然可以完成。
Hamls render
方法还接受一个块,因此一个简单的解决方案是渲染布局文件,并传递一个渲染视图文件的块:
Haml::Engine.new(File.read("layout.html.haml")).render do
Haml::Engine.new(File.read("view.html.haml")).render
end
这将给出的内容layout.html.haml
呈现的内容view.html.haml
在布局文件包含的位置呈现=yield
.
内容_for
不过 Rails 比这更灵活一些。它可以让你打电话yield
在布局文件中多次,在每种情况下命名特定区域,并使用content_for
方法在你的观点之内。所以在你的布局文件中:
!!!
%html
%head
= yield :title
%body
=yield
在你看来:
-content_for :title do
%title Hello
%p
Here's a paragraph.
Rails 实际工作的方式是首先渲染视图部分,存储所有不同的部分,然后渲染布局,传递一个提供适当块的块yield
在布局中被调用。我们可以使用一个小帮助器类来复制它来提供content_for
方法并跟踪每个区域的渲染块:
class Regions
def initialize
@regions_hash={}
end
def content_for(region, &blk)
@regions_hash[region] = capture_haml(&blk)
end
def [](region)
@regions_hash[region]
end
end
这里我们使用的是capture_haml method http://haml.info/docs/yardoc/Haml/Helpers.html#capture_haml-instance_method获取渲染的 haml,而不直接输出。请注意,这不会捕获视图的未命名部分。
我们现在可以使用辅助类来渲染最终输出。
regions = Regions.new
unnamed = Haml::Engine.new(File.read("view_named.html.haml")).render(regions)
output = Haml::Engine.new(File.read("layout_named.html.haml")).render do |region|
region ? regions[region] : unnamed
end
现在变量output
包含最终渲染的输出。
请注意,此处的代码并未提供 Rails 所包含的所有灵活性,但希望它足以向您展示从哪里开始自定义 Haml 以满足您的需求。