不带 Rails 的 Ruby 中的部分 HAML 模板

发布于 2024-10-27 08:20:43 字数 387 浏览 2 评论 0原文

对于我的非常小的项目,我确实不需要 Rails 的开销,因此我尝试仅使用普通的 Ruby 和 HAML 来实现这一目标。

我想在我的 HAML 模板中包含另一个 HAML 文件。但我还没有找到一个好的——或者说真正有用的——方法来做到这一点。

例如,我有这两个 HAML 文件:

documents.haml

%html
 %body
  = include(menu.haml) body
  %article …

menu.haml

%ul
 %li
  %a whatever …

Include 显然不是这里的方法。但它很好地描述了我在这个例子中想要实现的目标。

I really don’t need the overhead of Rails for my very small project, so I’m trying to achieve this just using just plain Ruby and HAML.

I want to include another HAML file inside my HAML template. But I haven’t found a good—or really usable—way of doing this.

For example, I have these two HAML files:

documents.haml

%html
 %body
  = include(menu.haml) body
  %article …

menu.haml

%ul
 %li
  %a whatever …

Include is obviously not the way to go here. But it does a nice job describing what I’m trying to achieve in this example.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

心欲静而疯不止 2024-11-03 08:20:43

我完全推荐 Tilt gem 来完成这些事情。它提供了一个标准接口,用于使用相同的 API 渲染许多不同的模板语言,允许您设置自定义范围和局部变量,允许您使用收益,并且健壮且快速。 Sinatra 将其用作模板。

示例:

require 'haml'
require 'tilt'

template = Tilt.new('path/to/file.haml')
# => #<Tilt::HAMLTemplate @file="path/to/file.haml" ...>
layout   = Tilt.new('path/to/layout.haml')

output = layout.render { template.render }

这可以让您在布局内 yield 来获取渲染的模板,就像 Rails 一样。至于部分,大卫已经描述了一个简单而好的方法。

但实际上,如果您正在编写的内容将通过 HTTP 提供,我建议您看一下 Sinatra,它已经提供了模板,并且具有您可以想象到的最简单的请求路由。

I totally recommend the Tilt gem for these things. It provides a standard interface for rendering many different template langages with the same API, lets you set custom scope and locals, lets you use yield, and is robust and fast. Sinatra is using it for templates.

Example:

require 'haml'
require 'tilt'

template = Tilt.new('path/to/file.haml')
# => #<Tilt::HAMLTemplate @file="path/to/file.haml" ...>
layout   = Tilt.new('path/to/layout.haml')

output = layout.render { template.render }

This lets you yield inside the layout to get the rendered template, just like Rails. As for partials, David already described a simple and nice way to go.

But actually, if what you're writing is going to be served over HTTP, i suggest you take a look at Sinatra, which already provides templating, and has the simplest request routing you could imagine.

美煞众生 2024-11-03 08:20:43

我以前曾这样做过,只是为了一个快速而肮脏的模板制作者。最简单的方法是在父对象中渲染 HAML:

%p some haml that's interesting
= Haml::Engine.new('%p this is a test').render
%p some more template

您很可能希望构建一些方法来简化此操作 - 几个辅助方法。也许您编写了一个名为 render_file 的文件,它将文件名作为参数。该方法可能看起来像:

def render_file(filename)
  contents = File.read(filename)
  Haml::Engine.new(contents).render
end

然后,您的模板看起来更像:

%p some template
= render_file('some_filename.haml')
%p more template

注意,您可能需要将 self 传递给原始 Haml::Engine 渲染,以便它知道如何找到您的 render_file 方法。

I've done this before, just for a quick-and-dirty template producer. The easiest way is to just render the HAML inside the parent object:

%p some haml that's interesting
= Haml::Engine.new('%p this is a test').render
%p some more template

You'll more than likely want to build some methods to make this easier--a couple of helper methods. Maybe you write one called render_file that takes a filename as an argument. That method might look something like:

def render_file(filename)
  contents = File.read(filename)
  Haml::Engine.new(contents).render
end

Then, your template would look more like:

%p some template
= render_file('some_filename.haml')
%p more template

Note, you will probably need to pass self to the original Haml::Engine render so that it knows how to find your render_file method.

天暗了我发光 2024-11-03 08:20:43

我仅以串联方式使用 David Richards 发布的说明就取得了巨大成功,没有变量,如下所示:

= Haml::Engine.new(File.read('/Volumes/Project/file_to_include.haml')).render

显然有一种更优雅的方式。但对于只想包含一两个文件的人来说,这应该很有效。一个缺点是,在对后者进行一些更改后,所有使用这些包含的基本文件都必须重新编译。如果环境允许的话,只使用 php include 可能是值得的。

I've had great success just using the instructions posted by David Richards in a concatenated way, without variables, like this:

= Haml::Engine.new(File.read('/Volumes/Project/file_to_include.haml')).render

There's obviously a more elegant way. But for someone who just wants to include one or two files, this should work nicely. It's a drawback that all base files using these includes have to be recompiled after some changes to the latter. It might be worthwile to just use php include if the environment allows that.

溇涏 2024-11-03 08:20:43
def render_file(filename)
  contents = File.read('views/'+filename)
  Haml::Engine.new(contents).render
end
def render_file(filename)
  contents = File.read('views/'+filename)
  Haml::Engine.new(contents).render
end
同尘 2024-11-03 08:20:43

(添加这个半冗余的答案是为了展示如何合并其他答案中的技术。)

在您的设置代码中包含类似的内容来对 Haml 库进行猴子修补。

module Haml::Helpers
  def render_haml(filename)
    contents = File.read(Rails.root.join("app", "assets", "templates", filename))
    Haml::Engine.new(contents).render
  end
end

然后在你的 Haml 文件中

.foo
= render_haml('partial.haml')
.bar

显然这是一个 Rails-ish 示例(因为我想在我的资产管道中使用 HAML 而不是视图)...你将需要替换 Rails.root.join(...) 可以在项目的模板或部分目录中查找filename

(Adding this semi-redundant answer to show how one might incorporate the techniques from other answers.)

Include something like this in your setup code to monkey-patch the Haml library.

module Haml::Helpers
  def render_haml(filename)
    contents = File.read(Rails.root.join("app", "assets", "templates", filename))
    Haml::Engine.new(contents).render
  end
end

Then in your Haml file

.foo
= render_haml('partial.haml')
.bar

Obviously this is a Rails-ish example (because I wanted to use HAML in my asset pipeline instead of as views)... You will want to replace Rails.root.join(...) with a way to find filename in your project's templates or partials directory.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文