Haml:控制文本周围的空白

100
在我的Rails模板中,我想使用HAML实现最终HTML的效果:
I will first <a href="http://example.com">link somewhere</a>, then render this half of the sentence if a condition is met

最接近的模板:

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

然而,您可能会注意到这会在链接和逗号之间产生一个空格。有没有什么实际的方法可以避免这个空白?我知道有一种语法可以删除标签周围的空格,但是这种语法是否也可以应用于纯文本?我真的不喜欢使用额外的标记来完成这个任务。

13个回答

215

通过Haml的辅助函数,引入了一种更好的方法:

surround

= surround '(', ')' do
  %a{:href => "food"} chicken
产生:
(<a href='food'>chicken</a>)

成功执行:

click
= succeed '.' do
  %a{:href=>"thing"} here
产生:
click
<a href='thing'>here</a>.

precede:

= precede '*' do
  %span.small Not really
产生:
*<span class='small'>Not really</span>

回答原问题:

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
产生:
I will first
<a href="http://example.com">link somewhere</a>,
then render this half of the sentence if a condition is met

1
好巧,我刚刚通过阅读 Haml 的源代码发现了这些。显然它们已经存在一段时间了。奇怪的是它们没有在主参考页面中记录... - Groxx
1
你能否扩展一下你的回答,并演示如何使用这些助手(可能是succeed)来表达OP的示例?对我来说,它仍然看起来不太明显且有点丑陋:https://gist.github.com/1665374 - John
16
我感觉自己缺少了一些东西(查看点赞数时),但是“成功”的变体并不等同于原始的版本,因为即使 @condition == false,尾随逗号也会被呈现出来,这比在逗号前加上空格更丑陋。 - Nash Bridges
2
我通过使用precede而不是succeed成功地获得了正确的结果。干杯! - Cam

40

你也可以使用Haml的“去除空白”修饰符来实现这一点。在Haml声明后插入>将防止在其周围添加空格:

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

输出结果:

I will first<a href='http://example.com'>link somewhere</a>, then render this half of the sentence if a condition is met
然而,正如您所见,>修饰符也会剥离链接前面的空格,从而删除单词和链接之间所需的空格。我还没有找到一个比较好的方法来解决这个问题,除了在"I will first"的末尾添加&nbsp;,就像这样:
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

这样做最终会产生所需的输出结果,而无需大量难以阅读的插值:

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

1
忘记提到我是从 Haml 速查表中获得的,这对我很有帮助:http://cheat.errtheblog.com/s/haml/ - Ryenski
3
它适用于标签但不适用于表达式;在你的例子中,你已经将他的表达式改成了一个标签。我也有同样的问题,不幸的是这并不是一个解决方案。 - Teflon Ted
1
我想指出 &nbsp; 具有特殊含义,它不是普通的空格 - 它是不间断的空格,这意味着在换行时,浏览器会尽一切努力将与 &nbsp; 相关的单词保持在一起,而这并不总是你想要的。 - Andrew
1
除了安德鲁的评论之外,对于普通空格,请使用&#032;而不是&nbsp; - Daniel A. R. Werner

12

好的,这是我最终选择的解决方案:

辅助函数

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

视图

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

这样,默认情况下排除了空格,但我仍然可以使用"\n"行来明确地包含它。(需要双斜杠,否则HAML会将其解释为实际换行符。)如果有更好的选择,请告诉我!


注:最终我变聪明了,把它们移到帮助程序中。 :P - Matchu
另一个注释给世界:这些天,我使用Groxx的解决方案 :) - Matchu
这对于生成文本文件的HAML非常有帮助!在我的情况下,我有一行代码,其中部分内容是由“if”决定的,但我无法使用mysmallidea的解决方案来修复它,因为它不能去除换行符,它只是将逗号移到换行符之前。(尽管我同意对于原始问题的答案,mysmallidea的解决方案是最好的。) - cesoid

6
你可以使用HAML的“鳄鱼语法”。

空格移除: > 和 <

< 可以让你更好地控制标签附近的空格。> 会删除标签周围的所有空格,而<将删除标签内部的所有空格。你可以把它们想象成吃掉空格的鳄鱼:>面向标签外部并吃掉外部的空格,而<面向标签内部并吃掉内部的空格。它们放置在标签定义的末尾,在类、ID和属性声明之后但在/或=之前。

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


5

我在这类事情上采用的一种方法是使用字符串插值:

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

我不喜欢插值中的字面字符串,但我之前已经将其与先前声明的字符串或动态生成的字符串一起使用过。


嗯,这是我对此类事情的一般处理方法,但我从未想过在其中使用条件语句。很遗憾,我正在使用的模板比只是一个句子的后半部分要复杂一些...但这绝对值得记住 - 谢谢! - Matchu

5
您可以通过以下方式保留前导空格:
%a{:href => 'http://example.com'}>= ' link somewhere'

引号中间是空格。


3
尽管没有很好的文档记录,但可以通过使用HAML空格保留(>)与ASCII空格(& #32;)相结合来实现,而不是使用helpers:
%a{:href=>'/home'}> Home link
,&#32; 
%a{:href=>'/page'} Next link

这将产生您想要的结果:
<a href='/home'>Anchor text</a>,&#32;
<a href='/page'>More text</a>

但我同意,HAML需要想出更好的方法来做这件事,因为它会在页面中添加不必要的ASCII字符(但仍然比使用helpers更高效)。


1

我遇到了类似的问题,并找到了这个解决方案,所以我想发布另一个不需要辅助方法的解决方案。使用Ruby插值#{}来包装链接和if语句:

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}

这在3.0.18中有效,它也可能适用于早期版本。


当然,Haml并不是为内容而设计的。虽然我们谈论的不是内容,而是模板。那篇博客文章的作者指的是使用Haml编写完整静态网页之类的东西,这不是我正在做的事情。我提供的代码片段几乎就是完整的.haml文件——它包括一个链接和一个逗号并不能表明任何事情。 - Matchu
1
啊,我懂了。我已经编辑了我的答案,让解决方案独立存在。 - biscuits
虽然这样可能可以工作,但我认为它会使标记难以阅读。相反,只需像其他人提到的那样使用HAML空格修饰符<和>,这将使您的HAML代码清晰易读。 - ToddH

1

我过去使用过的另一个选项:

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

1

有角括号的“空格消耗”语法,否则编写一个辅助方法。


一个辅助工具应该怎么工作呢?嗯,我会看看我能想出什么... - Matchu
关于空格消耗,如果它不在某种标签定义上,我无法弄清楚如何使该语法工作。我是做错了吗?还是这个语法没有标签就无法工作? - Matchu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接