Multiple multi-line HAML blocks

[亡魂溺海] 提交于 2019-11-30 17:18:51

This is a feature, not a bug. Haml multiline blocks are intentionally unwieldy - including hard to follow one after another - because almost all the time it's better to put that Ruby code into a helper. Even if the helper is only called once, it will make your template much easier to read. For instance:

def blatz_link
  call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3',
    :foo4 => 'bar4', :foo5 => 'bar5'
end

def blootz_link
  call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3',
    :foo4 => 'bar4', :foo5 => 'bar5'
end

Then in your Haml, just do

= blatz_link
= blootz_link

which will be much more readable and easier to understand.


If you absolutely must follow one multiline block with another, just add a comment in between:

= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |
-#
= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |

I've encountered the same problems and workarounds as have been mentioned here, and the weird (and yes, it IS weird) behavior of HAML with regard to multi-line blocks has bitten me quite a few times. I know that it's intentional and that it was probably intended to force the user to make his code easier to read. However, it's a well known fact that every developer has his own preferences when it comes to structuring code. HAML is the only language I know of (c, c++, ruby, python, HTML, etc.) that tries to impose such restrictions.

Calling the weird multi-line handling a feature rather than a bug, just indicates a flawed language design. In the end it will always be a bug in the eyes of the user. Multi-line support is a basic feature of any main stream language and the lack of this feature is just plain annoing - just like the M$ paperclip, which I believe was also an attempt to guide the user.

That being said, HAML is a fantastically compact and useful language for writing HTML. Those of us who (in some cases) prefer multi-line blocks would just love to at least be offered some kind of configuration option to enable/disable decent multi line block support - regardless of the language designer's personal definition of "easy to read code".

Until we get there, I guess we'll have to work around the language using the "-#" hack...

You could use a block on your helper, yielding whatever makes sense.

module SomeHelper
  def call_to_helper
    foo = Foo.new
    yield foo
    # build your html here, using the foo object's attributes
  end

  class Foo
    attr_accessor :foo1, :foo2, :foo3, :foo4, :foo5
  end

end

Now on your haml:

= call_to_helper do |foo|
  -foo.foo1 = 'bar1'
  -foo.foo2 = 'bar2'
  -foo.foo3 = 'bar3'
  -foo.foo4 = 'bar4'
  -foo.foo5 = 'bar5'

= call_to_helper do |foo|
  -foo.foo1 = 'bar1'
  -foo.foo2 = 'bar2'
  -foo.foo3 = 'bar3'
  -foo.foo4 = 'bar4'
  -foo.foo5 = 'bar5'

It's a hack (sort-of), but you could always use a "+" instead of a "=" on your 2nd, 3rd, etc. lines in the chain.

= call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |
+ call_to_helper :foo1 => 'bar1', :foo2 => 'bar2', :foo3 => 'bar3', |
  :foo4 => 'bar4', :foo5 => 'bar5' |
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!