Haml: Control whitespace around text

Ruby on-RailsHaml

Ruby on-Rails Problem Overview


In my Rails template, I'd like to accomplish final HTML to this effect using HAML:

I will first <a href="http://example.com">link somewhere</a>, then render this half of the sentence if a condition is met

The template that comes close:

I will first
= link_to 'link somewhere', 'http://example.com'
- if @condition
  , then render this half of the sentence if a condition is met

You may, however, note that this produces a space between the link and the comma. Is there any practical way to avoid this whitespace? I know there's syntax to remove whitespace around tags, but can this same syntax be applied to just text? I really don't like the solution of extra markup to accomplish this.

Ruby on-Rails Solutions


Solution 1 - Ruby on-Rails

A better way to do this has been introduced via Haml's helpers:

surround
= surround '(', ')' do
  %a{:href => "food"} chicken
Produces:
(<a href='food'>chicken</a>)
succeed:
click
= succeed '.' do
  %a{:href=>"thing"} here
Produces:
click
<a href='thing'>here</a>.
precede:
= precede '*' do
  %span.small Not really
Produces:
*<span class='small'>Not really</span>
To answer the original question:
I will first
= succeed ',' do
  = link_to 'link somewhere', 'http://example.com'
- if @condition
  then render this half of the sentence if a condition is met
Produces:
I will first
<a href="http://example.com">link somewhere</a>,
then render this half of the sentence if a condition is met

Solution 2 - Ruby on-Rails

You can also do this using Haml's "trim whitespace" modifier. Inserting > after a Haml declaration will prevent whitespace from being added around it:

I will first
%a{:href => 'http://example.com'}> link somewhere
- if @condition
  , then render this half of the sentence if a condition is met

produces:

I will first<a href='http://example.com'>link somewhere</a>, then render this half of the sentence if a condition is met

However, as you can see, the > modifier also strips the whitespace in front of the link, removing the desired space between the words and the link. I haven't figured a pretty way around this yet, except to add &nbsp; to the end of "I will first", like so:

I will first&nbsp;
%a{:href => 'http://example.com'}> link somewhere
- if @condition
  , then render this half of the sentence if a condition is met

Which finally produces the desired output without lots of hard-to-read interpolation:

I will first&nbsp;<span><a href="http://example.com">link somewhere</a></span>, then render this half of the sentence if a condition is met

Solution 3 - Ruby on-Rails

Alright, here's the solution I'm settling on:

Helper

def one_line(&block)
  haml_concat capture_haml(&block).gsub("\n", '').gsub('\\n', "\n")
end

View

I will first
- one_line do
  = link_to 'link somewhere', 'http://example.com'
  - if @condition
    , then render this half of the sentence
    \\n
    if a condition is met

That way, whitespace is excluded by default, but I can still explicitly include it with a "\n" line. (It needs the double-backslash because otherwise HAML interprets it as an actual newline.) Let me know if there's a better option out there!

Solution 4 - Ruby on-Rails

You can use the 'aligator syntax' of HAML

> Whitespace Removal: > and <

> and < give you more control over the whitespace near a tag. > will remove all whitespace surrounding a tag, while < will remove all whitespace immediately within a tag. You can think of them as alligators eating the whitespace: > faces out of the tag and eats the whitespace on the outside, and < faces into the tag and eats the whitespace on the inside. They’re placed at the end of a tag definition, after class, id, and attribute declarations but before / or =.

http://haml.info/docs/yardoc/file.REFERENCE.html#whitespace_removal__and_

Solution 5 - Ruby on-Rails

Once approach I've taken to this sort of thing is to use string interpolation:

I will first #{link_to 'Link somewhere'}#{', then render this half of the sentence if a condition is met' if condition}

I don't like the look of the literal string in the interpolation, but I've used it with previously declared strings or dynamically generated strings before.

Solution 6 - Ruby on-Rails

You can do this to keep the leading space:

%a{:href => 'http://example.com'}>= ' link somewhere'

The space is in the quotes.

Solution 7 - Ruby on-Rails

Although not well documented, this is cleanly achieved using HAML whitespace preservation (>) combined with an ASCII space (& #32;), and not with helpers:

%a{:href=>'/home'}> Home link
,&#32; 
%a{:href=>'/page'} Next link

This will produce what you want:

<a href='/home'>Anchor text</a>,&#32;
<a href='/page'>More text</a>

But I agree, HAML needs to come up with a better way of doing this, as it does add unnecessary ASCII characters to the page (but it's still more efficient than using helpers).

Solution 8 - Ruby on-Rails

There's the angle bracket "whitespace munching" syntax, otherwise write a helper method for it.

Solution 9 - Ruby on-Rails

I came across a similar problem and found this so I thought I would post another solution which doesn't require a helper method. Use Ruby interpolation #{} to wrap the link and if statements:

I will first 
#{link_to 'link somewhere', 'http://example.com'}#{if true : ", then render this half of the sentence if a condition is met" end}

This works in 3.0.18, it may also work in earlier releases.

Solution 10 - Ruby on-Rails

Yet another option that I've used in the past:

- if @condition
  %span> , then some more text after the link.

Solution 11 - Ruby on-Rails

You could also always do:

= link_to url_path do 
  = ["part_1", "part_2"].join(", ")

Solution 12 - Ruby on-Rails

The solution that I got working is:

I will first
= link_to 'link somewhere', 'http://example.com'
- if @condition
  = ", then render this half of the sentence if a condition is met"

You can use =, though = is used to output the result of Rails code, but here it will server the purpose.

Solution 13 - Ruby on-Rails

The preserve function worked for me

.white-space-pre= preserve "TEXT"

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMatchuView Question on Stackoverflow
Solution 1 - Ruby on-RailsRyenskiView Answer on Stackoverflow
Solution 2 - Ruby on-RailsRyenskiView Answer on Stackoverflow
Solution 3 - Ruby on-RailsMatchuView Answer on Stackoverflow
Solution 4 - Ruby on-RailsYo LudkeView Answer on Stackoverflow
Solution 5 - Ruby on-RailsChuckView Answer on Stackoverflow
Solution 6 - Ruby on-RailsthethinmanView Answer on Stackoverflow
Solution 7 - Ruby on-RailsojakView Answer on Stackoverflow
Solution 8 - Ruby on-RailsAndrew VitView Answer on Stackoverflow
Solution 9 - Ruby on-RailsbiscuitsView Answer on Stackoverflow
Solution 10 - Ruby on-RailscolllinView Answer on Stackoverflow
Solution 11 - Ruby on-RailsbcackermanView Answer on Stackoverflow
Solution 12 - Ruby on-RailsArslan AliView Answer on Stackoverflow
Solution 13 - Ruby on-RailsgtournieView Answer on Stackoverflow