33

I use HAML in my rails project for my html templates. I would like to figure out if its possible to divide a very long line and make it a couple of rows:

%a.open-service{href: '#', data: {
  service_name: service.description,
  balance_type: "coinsurance",
  total: service.a_total_billed - service.a_rejected - service.a_not_covered, 
  discount: service} }

As you can see, I just want to have an anchor with href and some data-attributes, and making it one-line won't be a pretty code. But when I do it like above I get an error: "Unbalanced brackets."

any help?

Paul Fioravanti
  • 16,423
  • 7
  • 71
  • 122
benams
  • 4,308
  • 9
  • 32
  • 74

5 Answers5

40

New lines can be placed after commas, according to the Haml documentation. So, perhaps something like the following would work:

%a.open-service{href: '#', 
                data: { service_name: service.description,
                        balance_type: "coinsurance",
                        total: service.a_total_billed - service.a_rejected - service.a_not_covered, 
                        discount: service} }
Paul Fioravanti
  • 16,423
  • 7
  • 71
  • 122
9

I believe you can achieve this with the help of |. You can read about it in the haml documentation here.

Mikhail Nikalyukin
  • 11,867
  • 1
  • 46
  • 70
  • Its intentional akward but the only way to break up attributes that are all long. Ie. the first line contains the first attribute before the comma that is already too long for a linter etc. – wintersolutions Sep 13 '17 at 21:15
  • 1
    Unfortunately, the haml.info documentation site has been broken/down for a while :( so thanks for that tip about pipe; since it's harder to find otherwise. – Aaron Wallentine Jul 02 '22 at 00:39
4

You can always break your line after commas. So if you had this:

%div.panel
  .panel-body
    = column_chart @consumptions.filter_by_meter(params[:meter]).filter_by_appliance(params[:appliance]).where('start > ?', Time.now - 1.month).group_by_day(:start, format: '%d').sum(:power), colors: ["#7FC564"], title: 'Últimos 30 dias', library: { chartArea: { left: 60, top: 20, width: '95%', height: '85%' }, hAxis: { textPosition: 'bottom', textStyle: { fontSize: 12 }, minTextSpacing: 2 }, vAxis: { textPosition: 'left', format: '# kWh' } }

You could, firstly, break lines on every comma to get into this:

%div.panel
  .panel-body
    = column_chart @consumptions.filter_by_meter(params[:meter]).filter_by_appliance(params[:appliance]).where('start > ?', Time.now - 1.month).group_by_day(:start, format: '%d').sum(:power),
      colors: ["#7FC564"],
      title: 'Últimos 30 dias',
      library: { chartArea: { left: 60, top: 20, width: '95%', height: '85%' },
      hAxis: { textPosition: 'bottom', textStyle: { fontSize: 12 }, minTextSpacing: 2 },
      vAxis: { textPosition: 'left', format: '# kWh' } |

Still, the first line is too big! No problem. The pipe character can designate a multiline string.

It’s placed at the end of a line (after some whitespace) and means that all following lines that end with | will be evaluated as though they were on the same line. So you'd finally get:

%div.panel
  .panel-body
    = column_chart @consumptions.filter_by_meter(params[:meter]) |
      .filter_by_appliance(params[:appliance]) |
      .where('start > ?', Time.now - 1.month) |
      .group_by_day(:start, format: '%d') |
      .sum(:power), |
      colors: ["#7FC456"],
      title: 'Últimos 30 dias',
      library: { chartArea: { left: 60, top: 20, width: '95%', height: '85%' },
      hAxis: { textPosition: 'bottom', textStyle: { fontSize: 12 }, minTextSpacing: 2 },
      vAxis: { textPosition: 'left', format: '# kWh' } |

Note that even the last line in the multiline block should end with |.

Hope it helps!

Slava Nikulin
  • 505
  • 5
  • 16
Flavio Wuensche
  • 9,460
  • 1
  • 57
  • 54
3

I just came accross this question, I was having the same issue but the selected answer didn't help me. So I'm just building upon Mikhail's answer. If you have very long attributes that are not separated by commas (say you're using something like angularjs), you can split it on several lines by adding + | at the end of each line (including the last line in this multiline block, which is the tricky part).

Just like this :

%select{ ng: { model: "my_model_name",
             options: "myitem as myitem.formattedName for myitem in container.item_list() | " + |
                      "without: another_list.item_list()" }}                                    |

You can read about this in HAML documentation.

Pierre-Adrien
  • 2,836
  • 29
  • 30
2

Sometimes Multiline in HAML can have little to nothing to do with adding rails code, since some elements need to have lots of attributes, such as the Bootstrap Progress Bar, and simply look hideous on one line.

This was giving me a headache:

.progress
  .progress-bar.progress-bar-striped.progress-bar-success{ |
                  role: "progressbar",                     |
                  aria: {                                  |
                    valuenow: "#{@percent}",               |
                    valuemin: "0",                         |
                    valuemax: "100",                       |
                  },                                       |
                  style: "width: #{@percent}%;" }          |
    = "#{@percent}%"

And here was the solution to my struggle:

.progress
  .progress-bar { class: "progress-bar-striped progress-bar-success",
                  role: "progressbar",
                  aria: { valuenow: "#{@percent}",
                          valuemin: "0",
                          valuemax: "100", 
                  },
                  style: "width: #{@percent}%;" }
    = "#{@percent}%"

Please note that even without the pipebar lines, so long as the preceding line ended in a comma, and no line ended with an open bracket,

Okomikeruko
  • 1,123
  • 10
  • 22