Haml: Control whitespace around text
-
19-09-2019 - |
Question
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.
Solution
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
OTHER TIPS
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
to the end of "I will first", like so:
I will first
%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 <span><a href="http://example.com">link somewhere</a></span>, then render this half of the sentence if a condition is met
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!
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_
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.
You can do this to keep the leading space:
%a{:href => 'http://example.com'}>= ' link somewhere'
The space is in the quotes.
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
, 
%a{:href=>'/page'} Next link
This will produce what you want:
<a href='/home'>Anchor text</a>, 
<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).
There's the angle bracket "whitespace munching" syntax, otherwise write a helper method for it.
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.
Yet another option that I've used in the past:
- if @condition
%span> , then some more text after the link.
You could also always do:
= link_to url_path do
= ["part_1", "part_2"].join(", ")
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.
The preserve function worked for me
.white-space-pre= preserve "TEXT"