gpt4 book ai didi

ruby - 独立于 Rails 在 HAML 文件中使用布局

转载 作者:数据小太阳 更新时间:2023-10-29 06:23:48 25 4
gpt4 key购买 nike

我的最终目标是创建几个静态 HTML 文件以传递给其他人。

但对于我的工作流程,我希望将 HAML 作为基本源文件。这样做时,我希望至少在我这边结束这个过程。

现在我有很多页面最终将共享一个通用布局,我想知道如何合并这些布局。

这是我当前的代码:

./编译.rb

#!/usr/bin/env ruby

require 'rubygems'
require 'rake'
require 'haml'

FileList.new('./src/*.html.haml').each do |filename|
if filename =~ /([^\/]+)\.haml$/
File.open($1, 'w') do |f|
f.write Haml::Engine.new(File.read(filename)).render
end
end
end

./src/layout.html.haml

!!!
%html
%head
%title Yay
%body
= yield

./src/home.html.haml

= render :layout => 'header' do
%p This is awesome

现在这显然行不通,因为渲染方法在 Rails 的上下文之外是未定义的,但我希望它能理解我正在尝试做的事情。

有什么建议吗?

最佳答案

您混淆了两个不同的 Rails 特性:partials (using render)layouts (using yield) .

您可以将其中一个(或两者)的类似 rails 的版本添加到仅 Haml 程序中。

局部

在 Rails View 中,您可以使用 render :partial_name 使文件 _partial_name.html.haml 在包含 View (实际上是 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 模板的范围内可用。我们只需将我们的 render 方法放在调用 Haml::Engine.new(...).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 中,您可以为您的 View 指定布局,以便您的所有页面都可以共享相同的布局 header 、菜单区域等。这是通过指定布局文件来完成的,您可以在其中调用 yield 来呈现相关的实际 View 。添加到 haml 中的布局稍微有点棘手,但仍然可以完成。

Hamls render 方法也接受一个 block ,所以一个简单的解决方案是渲染布局文件,并传递一个渲染 View 文件的 block :

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 实际工作的方式是首先呈现 View 部分,存储所有不同的部分,然后呈现布局,每当在布局中调用 yield 时传递一个提供适当 block 的 block .我们可以使用一个小助手类来复制它,以提供 content_for 方法并跟踪每个区域的渲染 block :

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 而无需直接输出。请注意,这不会捕获 View 的未命名部分。

我们现在可以使用我们的帮助类来呈现最终输出。

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 中包含的所有灵 active ,但希望它足以向您展示从何处开始自定义 Haml 以满足您的需求。

关于ruby - 独立于 Rails 在 HAML 文件中使用布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6125265/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com