您混淆了两个不同的 Rails 功能:partials (using render) 和 layouts (using yield)。
您可以将其中任何一个(或两个)的类似 rails 的版本添加到仅 Haml 的程序中。
部分
在 Rails 视图中,您可以使用 render :partial_name 使文件 _partial_name.html.haml 在包含视图中的该点呈现(实际上 Rails 允许您使用任何支持的模板语言,它会找到正确的文件扩展名使用,但我会在这里坚持使用 Haml)。 Rails 之外的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 模板的范围内使用。我们只是在调用Haml::Engine.new(...).render之前将我们的render方法放在脚本中,然后在我们的模板中这样调用它:
!!!
%html
%head
%title Hello
%body
=render :the_partial
现在文件_the_partial.html.haml 将呈现在输出的适当位置。
局部变量
我们可以更进一步。 Rails 允许您将 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>
布局
在 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。
content_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 来获取渲染后的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 以满足您的需求。