在没有Rails的Ruby中进行部分HAML模板化

时间:2022-03-08 00:11:55

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.

对于我的小项目,我真的不需要Rails的开销,所以我只想使用普通的Ruby和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.

我想在我的HAML模板中包含另一个HAML文件。但我还没有找到一种好的或实用的方法。

For example, I have these two HAML files:

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

documents.haml

documents.haml

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

menu.haml

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.

包括显然不是去这里的方式。但它描述了我在这个例子中想要实现的目标。

5 个解决方案

#1


18  

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:

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

%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:

你很可能想要构建一些方法来使这更容易 - 一些辅助方法。也许你写一个名为render_file的文件,它将文件名作为参数。该方法可能类似于:

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.

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

#2


23  

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.

我完全推荐这些东西的Tilt宝石。它提供了一个标准界面,用于使用相同的API呈现许多不同的模板语言,允许您设置自定义范围和本地,允许您使用yield,并且稳健且快速。 Sinatra正在将它用于模板。

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.

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

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.

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

#3


3  

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

我只是使用David Richards以连接方式发布的指令取得了巨大成功,没有变量,如下所示:

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

= 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.

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

#4


0  

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

#5


-1  

(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.

在您的设置代码中包含类似的内容,以便对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

Then in your Haml file

然后在你的Haml文件中

.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.

显然这是一个Rails-ish示例(因为我想在我的资产管道中使用HAML而不是视图)...你会想要用一种方法来替换Rails.root.join(...)项目的模板或部分目录。

#1


18  

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:

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

%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:

你很可能想要构建一些方法来使这更容易 - 一些辅助方法。也许你写一个名为render_file的文件,它将文件名作为参数。该方法可能类似于:

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.

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

#2


23  

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.

我完全推荐这些东西的Tilt宝石。它提供了一个标准界面,用于使用相同的API呈现许多不同的模板语言,允许您设置自定义范围和本地,允许您使用yield,并且稳健且快速。 Sinatra正在将它用于模板。

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.

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

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.

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

#3


3  

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

我只是使用David Richards以连接方式发布的指令取得了巨大成功,没有变量,如下所示:

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

= 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.

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

#4


0  

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

#5


-1  

(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.

在您的设置代码中包含类似的内容,以便对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

Then in your Haml file

然后在你的Haml文件中

.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.

显然这是一个Rails-ish示例(因为我想在我的资产管道中使用HAML而不是视图)...你会想要用一种方法来替换Rails.root.join(...)项目的模板或部分目录。