在Hamlet模板中压缩if-then-else

时间:2018-08-30 22:29:17

标签: haskell yesod hamlet shakespeare-text

我试图理解Yesod的Hamlet中的变量插值,特别是实现类似if-then-else的逻辑。假设我想基于整数x的值添加CSS样式。 x来自模板中的for循环,即我无法通过Haskell代码访问它。

所需结果:

<span class="even positive">2</span>
<span class="odd positive">13</span>
<span class="odd non-positive">-1</span>
<span class="even non-positive">0</span>

在内联if上进行尝试:

<span class="#{if even x then "even" else "odd"} ...">#{x}</span>

尝试使用$with

$with cls <- (if even x then "even" else "odd")
    <span class="#{cls}">#{x}</span>

均无效;都导致

• Illegal variable name: ‘if’
  When splicing a TH expression

很显然,#{...}解析器中未实现Haskell语法的一部分。有没有一种干净的方法可以做到这一点?我目前只能看到一个出路,而且很难看:

$if ((even x) && (x > 0))
    <span class="even positive">#{x}</span>
$elseif (even x)
    <span class="even non-positive">#{x}</span>
$elseif (x > 0)
    <span class="odd positive">#{x}</span>
$else
    <span class="odd non-positive">#{x}</span>

1 个答案:

答案 0 :(得分:5)

这些模板表达式中不支持

大多数Haskell语法。我认为这是设计使然,因为您不希望模板包含复杂的业务逻辑。

我会在Haskell端将代码作为函数编写,然后从模板调用它。像这样:

="text"

以这种方式正确地将业务逻辑从模板中分离出来,但仍然允许您使用模板中的变量。