Multiline Pipe at the Beginning of a Line

21 views
Skip to first unread message

svoop

unread,
Nov 24, 2009, 1:15:37 PM11/24/09
to Haml
Hi

How about allowing an alternative multiline syntax:

http://pastie.org/713107

Maybe this is a no go for the parser, though.

Cheers, -sven

Nathan Weizenbaum

unread,
Nov 24, 2009, 8:44:44 PM11/24/09
to ha...@googlegroups.com
The Haml multiline syntax is intentionally awkward. It's meant to encourage people away from putting large blocks of Ruby in their views, and towards moving their code into helpers. This almost always results in nicer code and easier-to-read views.


--

You received this message because you are subscribed to the Google Groups "Haml" group.
To post to this group, send email to ha...@googlegroups.com.
To unsubscribe from this group, send email to haml+uns...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/haml?hl=en.



Nathan Weizenbaum

unread,
Nov 24, 2009, 8:45:33 PM11/24/09
to ha...@googlegroups.com

Jacques Crocker

unread,
Nov 24, 2009, 10:31:25 PM11/24/09
to ha...@googlegroups.com
If thats the case, can we at least make it easier to call helpers with lots of arguments?

= some_long_helper_name arg1,
arg2,
arg3


Comma + newlines are allowed when specifying attribute syntax. We should allow it when calling helpers too.

In a large haml project, I often have helpers just to provide arguments to other helpers. Ends up being pretty terrible sometimes

Nathan Weizenbaum

unread,
Nov 24, 2009, 10:37:17 PM11/24/09
to ha...@googlegroups.com
Even in this case, it ends up working better if you factor those out into individual named helpers. "= get_new_posts_link" is a lot easier to understand than a long helper with a lot of arguments, even if that's the only place you use that helper.

Alexander Wallace

unread,
Nov 24, 2009, 10:43:10 PM11/24/09
to ha...@googlegroups.com
This sounds more of an architectural problem than a markup problem. Argument names for your helpers should (probably) be coming from your controllers - e.g. = some_helper_function(@page, @section, @user) ... I'm not sure what the necessity is to split arguments up into separate lines unless they are strangely long (in which case they could just be shortened) or are actually the return statements from other helpers (in which case it would be cleaner to set those values in the controller)...

Alex

Jacques Crocker

unread,
Nov 24, 2009, 10:48:57 PM11/24/09
to ha...@googlegroups.com
It's not always so cut and dry. Should I be creating a new helper for every complicated link_to statement in rails?

Here's one I picked out of a random project

= link_to "Favorites <em class='count_favorites'>#{count_favorites}</em>", "#"+resource(:users, :favorites), :class => "dropmenu_trigger", :rel => "#dropmenu_favorites"

Why should I force this to be on one line? And why should I create a helper just for a single link_to statement used once on the site?

Nathan Weizenbaum

unread,
Nov 24, 2009, 10:53:04 PM11/24/09
to ha...@googlegroups.com
No, you shouldn't force it to be on one line, but yes, you should create a helper for just that link_to. That's precisely what we're encouraging you to do. "= favorites_link" is a hell of a lot easier to read in a view.

I recognize that, like anything, this isn't a black-and-white issue. That's why Haml has multline syntax in the first place: for those rare cases where it is better design to have a large amount of Ruby code in your views. But that use case is a lot less common than most people think, so nudging them in the right direction is worth it being nastier when you actually need to use multiline.

Jacques Crocker

unread,
Nov 24, 2009, 10:54:52 PM11/24/09
to ha...@googlegroups.com
This would make more sense if helpers were more sensible in merb and rails. Using a lot of partials, reused across different controller actions, you end up having to include all the helpers in to just about every view. So you end up working off a global namespace for helper method names. Creating a new helper wrapper around every long rails helper is a recipe for frustration. Maybe they are highly readable, but they're incomprehensible since you have to swap files back and forth just to see what every single thing does.

If it isnt a black and white issue, haml should really try to support both instead of making the one case painful, even when its the appropriate course of action.

Alexander Wallace

unread,
Nov 24, 2009, 10:56:35 PM11/24/09
to ha...@googlegroups.com
Not all situations are cut and dry, and I can't claim that I keep every line under 80 chars. But I'd try to reduce some of the cruft by abstracting each larger argument chunk into a helper, e.g.

=link_to favorite_title, favorites_path, :class => "dropmenu_trigger", :rel => "#dropmenu_favorites"

The <em> and interpolation is a good place to start cleaning... it can't make every link_to statement a one-liner, but the line above is only ~100 chars (less than some of my uglier link_to statements, which tend to encourage lots of arguments)

Best,
Alex

Jacques Crocker

unread,
Nov 24, 2009, 11:01:31 PM11/24/09
to ha...@googlegroups.com
I don't think there's fundamentally anything unreadable about a long helper call, with lots of arguments. Even simple html creation helpers encourage this since often you'll add lots of attributes to support complex unobtrusive behaviors.

Breaking it up onto separate lines with commas would still be extremely readable and understandable. Also, there's a solid precedent already for this in HAML (attributes can already do this) so it doesn't break the syntax at all.

Show me a rails project with thousands of helpers for every single long haml line and I'll show you one giant unmaintainable mess.

Justin Dossey

unread,
Nov 24, 2009, 11:22:18 PM11/24/09
to ha...@googlegroups.com
It's not about what is unreadable vs. what is readable, it's about
what is _more_ readable. The syntactic vinegar associated with the
multiline syntax is a great motivator to ask yourself, "Should this
really be in a helper?" If the answer is no, leave it how it is. If
the answer is yes, your code just got better.

I support a large rails project (>50 controllers, >100 models) and the
unpleasant multiline syntax has helped a lot. It's so unpleasant, in
fact, that we don't use it. If I don't want to create a helper
method for one line of code, I break it up. The example below would
start as
= link_to "Favorites <em
class='count_favorites'>#{count_favorites}</em>", "#"+resource(:users,
:favorites), :class => "dropmenu_trigger", :rel =>
"#dropmenu_favorites"

and become 3 lines if not a helper:

- favorites = "Favorites <em class='count_favorites'>#{count_favorites}</em>"
- fave_link_attrs = { :class => 'dropmenu_trigger', :rel =>
'#dropmenu_favorites' }
= link_to favorites, "##{resource(:users, :favorites)}", fave_link_attrs

Find your own style with this, but don't push for a syntax change
immediately, just because this isn't what you're used to.

Justin Dossey

Jacques Crocker

unread,
Nov 24, 2009, 11:29:30 PM11/24/09
to ha...@googlegroups.com
It's not just syntactic vinegar, it makes things extremely hard to change. Editing every line of the helper with the pipe syntax makes you have to rebalance the pipes. Also, not a huge syntax change. HAML used to be of the same opinion on attributes, yet this changed to allow multiline via commas. My argument could just as easily be about consistency.

Should also mention I've also been using HAML as my primary templating language for almost 2 years.

Nathan Weizenbaum

unread,
Nov 25, 2009, 12:00:13 AM11/25/09
to ha...@googlegroups.com
The reason the change was made for attributes was that there wasn't a reasonable alternative by way of writing helpers, and that attributes are distinctly part of the HTML document. Helpers, in general, are not: they're application logic, and as such their presence in views should be kept to a minimum.

svoop

unread,
Nov 26, 2009, 4:36:33 AM11/26/09
to Haml
There are those who see helpers as supersemanitc placeholders, others
who see helpers as extensions to the HTML markup. Personally, I'm not
dogmatic enough to always prefer one of the two. In the latter case
what attributes are for HTML are options for the helper.

Not sure whether the parser could handle this, but why not using the
comma as line continuation marker?

= link_to 'Akzeptieren', accept_registration_path(user),
:class => 'accept button',
:'data-remote' => true,
:'data-method' => :put

If you're that concerned about abuse, just raise an exception if the
first non-whitespace on the followup line is not a colon.

Jacques Crocker

unread,
Nov 30, 2009, 6:44:28 PM11/30/09
to ha...@googlegroups.com
Totally agree with svoop. Specifying attributes for HTML tag helpers should be just as seamless as specifying attributes for haml elements. I don't see the point in having the haml markup decide that one is better than the other, and making things miserable for the people who use the tag helper approach.

Based on the response so far, I really think there's a fundamental disagreement here that is worth exploring. Why is it "cleaner" and more readable to create a helper just so I can define a long list of attributes to an html helper function.

Here's an example from a project of mine (github.com/merbjedi/alertme_tv)

= form_for @user, :action => "/users/mini_register", :method => :put, :class => "ajax_form", :rel => "#dropmenu_account", :builder => FieldBuilder do
  .....

If this is used only one place in the project, what possible benefit is there in turning this into a helper? The cost: I'd have to name the helper, add tests for it, then have to worry about wrapping the yield statement. The end result: obfuscating a perfectly readable (though verbose) line of code. And say I later want to change the target of the ajax form. I have to first track it to the template, then track the helper that I created to build the form. All hidden costs that make the code less maintainable for something that is logically nothing more than a wrapper for a <form> tag.

The alternative:

= form_for @user, 
            :action => "/users/mini_register", 
            :method => :put, :class => "ajax_form", 
            :rel => "#dropmenu_account", 
            :builder => FieldBuilder do
  .....


I think this is slightly better than having it all on one line. And in my opinion, superior to moving it into a helper. But I can assure you this tweak wont all of a sudden force you to stop using helpers within your haml templates.

So all I'm after is an answer to this question: if I go ahead and implement this minor syntax within haml, will it be supported and allowed to be merged into a future release of haml?

Thanks to everyone on the thread so far for the discussion & feedback.

Jacques Crocker

unread,
Nov 30, 2009, 7:10:44 PM11/30/09
to Haml
Nathan... please read Justin Dossey's post carefully. I believe this
is the negative end result of trying to force this issue via haml
syntax. You end up with workarounds that end up doing the exact
opposite of what was intended in the first place (to reduce ruby code
in the haml template).

On one of my client's project (with half dozen developers), I also see
code very similar to this in much of the haml code (evaluation lines
in the template to build an attribute hash to pass to a helper). This
is much worse than allowing helpers with multiple lines, and just
serves to introduce more ruby code into the template layer.

Yaohan Chen

unread,
Dec 3, 2009, 7:55:06 PM12/3/09
to Haml
I also think there should be a non-awkward way for multi-line code in
haml. Having consecutive lines of ruby doesn't necessarily indicate
bad readability or maintainability. Especially because in ruby, the
same amount of code can be more readable when written on multiple
lines, such as the helper calls in other peoples' posts.

I think it would be more consistent with the existing HAML syntax, if
- and = could just contain "children" with indentation. For example,

=
link_to(arg1,
arg2,
...)

This is similar to how a regular html element can have indented child
in HAML. The child begins if the next line is indented deeper and ends
when indentation is back to the level of = or -. The whole child would
be evaluated as ruby, lines inside it can have "free" indentation to
line up arguments or not, as long as they are deeper than = or -.

Hampton

unread,
Dec 4, 2009, 4:52:28 AM12/4/09
to ha...@googlegroups.com
Doing this much Android programming over the week
has melted my brain into liking multi-line arguement strings.

I've always fought against endless "multilines". But, I think there are lots of
cases that this won't support... and one that it will... which is having lots
of arguments.

I DO think in the examples, that you should do something about those link_to's.
There is always an abstraction in behaviour. At least, I've rarely found a time
when there isn't one.

However, even a good helper might need several arguments. So.... (drum roll please)...
Hampton Catlin doesn't hate the idea of multilines that *only* apply to method calls
with commas between the arguements.

*NO* String concatenation on multiple lines
*NO* Static single-line HTML information going multiline (make sense?)
*NO* Whatever people will think of when they go "weeeeee!"

A good language should be readable online. However, a well indented arguement list
as we saw in the example is very clearly a single element visually... and is therefore
OK semantically/syntactically/usably.

-hampton.

Jacques Crocker

unread,
Dec 4, 2009, 11:07:26 AM12/4/09
to ha...@googlegroups.com
Thanks for the feedback Hampton! Gave me some good motivation to work on the patch. Hopefully should have it ready soon.

I totally agree that this patch address be a very limited syntax change. Specifically for multiline argument lists (separated by commas). No special cases that I can think of at the moment.

Here's the unit test I'm targeting first (in helpers_test.rb)

Hampton

unread,
Dec 4, 2009, 12:25:01 PM12/4/09
to ha...@googlegroups.com
Oh, people will think of exceptions....

svoop

unread,
Dec 9, 2009, 4:03:11 AM12/9/09
to Haml
Thanks for considering the change, Hempton, and Jacques for the patch.
Looking forward to breaking down these 90 character lines to slim, vi-
ready ones.

And while you're at it, how about ... :-D

Nathan Weizenbaum

unread,
Apr 24, 2010, 4:12:55 AM4/24/10
to ha...@googlegroups.com
This has been implemented in the latest master.

Si

unread,
Apr 24, 2010, 9:47:43 AM4/24/10
to Haml
This will certainly help tidy up the rare helpers that need it. Cheers
Nathan.

On Apr 24, 10:12 am, Nathan Weizenbaum <nex...@gmail.com> wrote:
> This has been implemented in the latest master.
>
>
>
> On Wed, Dec 9, 2009 at 2:03 AM, svoop <sv...@delirium.ch> wrote:
> > Thanks for considering the change, Hempton, and Jacques for the patch.
> > Looking forward to breaking down these 90 character lines to slim, vi-
> > ready ones.
>
> > And while you're at it, how about ... :-D
>
> > --
>
> > You received this message because you are subscribed to the Google Groups "Haml" group.
> > To post to this group, send email to ha...@googlegroups.com.
> > To unsubscribe from this group, send email to haml+uns...@googlegroups.com.
> > For more options, visit this group athttp://groups.google.com/group/haml?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups "Haml" group.
> To post to this group, send email to ha...@googlegroups.com.
> To unsubscribe from this group, send email to haml+uns...@googlegroups.com.
> For more options, visit this group athttp://groups.google.com/group/haml?hl=en.
Reply all
Reply to author
Forward
0 new messages