你混淆了两个截然不同的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
的第一个参数是scope对象,我们可以使用它添加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中,可以为视图指定布局,这样所有页面都可以共享相同的视图
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
的内容,其中布局文件包含=yield
,呈现view.html.haml
的内容.
内容
不过,这比Rails更灵活.它允许您在布局文件中多次调用yield
,在每种情况下命名一个特定区域,并在视图中使用内容
方法指定要在每个区域添加的内容.所以在布局文件中:
!!!
%html
%head
= yield :title
%body
=yield
在你看来:
-内容 :title do
%title Hello
%p
Here's a paragraph.
Rails的实际工作方式是首先渲染视图部分,存储所有不同的部分,然后渲染布局,在布局中调用yield
时传递一个提供适当块的块.我们可以使用一个小助手类来复制它,以提供内容
方法,并跟踪每个区域的渲染块:
class Regions
def initialize
@regions_hash={}
end
def 内容(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以满足您的需求.