Rails: 是否可以使用HAML语法编写视图辅助工具?

19

重构代码时,将HAML模板的一部分复制并粘贴到帮助器代码中会非常方便。但目前这样做有两个问题:1)我必须从零开始重新编写视图的那部分内容;2)我必须使用冗长的语法如content_tag或haml_tag。

我知道可以使用HAML语法定义partials作为helper。但是,对我来说,创建一个单独的文件来处理每个小函数是不方便的,而且partial的调用语法也相当冗长。

理想情况下,我希望我的*_helper类看起来像这样:

- def some_helper(*its_args)
  .some_class
    = some_ruby_expression
  %some_tag#some_id
    - another_expression do
      etc

或者至少像这样:

define_haml_helper :some_helper, [:arg1, :arg2], %{
  .some_class
    = some_ruby_expression
  %some_tag#some_id
    - another_expression do
      etc
}

有没有插件可以解决我的问题?

或者,您可以描述一下如何将HAML片段重构为可重复使用的元素(helpers/functions/partials/builders等)?

4个回答

13

来自参考文献

def render_haml(code)
    engine = Haml::Engine.new(code)
    engine.render
end

这将初始化一个新的Haml引擎并进行渲染。


能够拥有一个带有漂亮语法的功能来封装引擎缓存将是非常好的。我只是想知道是否存在这方面的宝石库。 - Alexey
@Alexy 我现在很无聊,所以我会写那个 gem。很快就会完成。我现在想不到已经存在的这样一个 gem,但实现起来并不难。 - user142019
值得缓存吗?所以 @haml_engine ||= 等等...? - Simon
1
@PeterEhrlich 我有一个名为hamlize的帮助方法,它只包含Haml::Engine.new(yield).render if block_given?。这似乎就是你想要的:hamlize{“%div.some-class”+some_method_that_returns_valid_haml(arg1,arg2)}。不过我也很感兴趣 @Simon 的评论答案——不确定我是否应该缓存引擎?还在努力将其他辅助方法放入引擎上下文中…… - Jazz
@Simon 如果你想渲染不同的模板,那么这个会出问题。 - user142019

4

3
现在Haml有一个capture_haml方法,您可以使用它来完成这个任务。
  def some_helper
    capture_haml do
      .some_class
        = yield
      #some-code-after
    end
  end

some_helper do
  %h1 Hello World
end
=> <div class="some_class">
     <h1>Hello World</h1>
   </div>
   <div id="some-code-after"></div>

以下链接提供了更多有关capture_haml的信息: http://haml.info/docs/yardoc/Haml/Helpers.html#capture_haml-instance_method


4
你误解了这个函数的含义。你提供的代码片段无法运行 - 你不能把 HAML 直接写在 Ruby 的中间。 - Alexey

0

我使用heredoc来实现这样的目的:

  def view_helper
    Haml::Engine.new(<<~HAML).render
      .example
        #id ID
        .desc Description
    HAML
  end

这种方法在变量作用域方面存在许多问题,因此,如上所述,更正确的方法是使用partials。

UPD1:下面是解决作用域问题的解决方案:

  def view_helper
    Haml::Engine.new(<<~HAML).render(self)
      .form
        = form_tag root_path do
          = submit_tag :submit
    HAML
  end

更新2:更好的解决方案(在互联网上发现):

def render_haml(haml, locals = {})
  Haml::Engine.new(haml.strip_heredoc, format: :html5).render(self, locals)
end

def greeting
  render_haml <<-HAML
    .greeting
      Welcome to
      %span.greeting--location
        = Rails.env
  HAML
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接