Компактный if-then-else в шаблонах Hamlet

Я пытаюсь понять интерполяцию переменных в «Гамлете» Йесода, в частности, реализуя логику «если-то-иначе». Допустим, я хочу добавить стили CSS в зависимости от того, какое значение имеет целое число x. 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>

person Norrius    schedule 30.08.2018    source источник


Ответы (1)


Большая часть синтаксиса Haskell не поддерживается внутри этих шаблонных выражений. Я думаю, что это задумано, поскольку вы не хотите, чтобы ваш шаблон содержал сложную бизнес-логику.

Я бы написал код как функцию на конце Haskell и вызвал бы его из шаблона. Что-то вроде:

-- .hs file
altclass, signclass :: Int -> String
altclass x = if even x then "even" else "odd"
signclass x = if x > 0 then "positive" else "non-positive"

-- .hamlet file
<span class="#{altclass x} #{signclass x}">#{x}</span>

Такой способ правильно отделяет бизнес-логику от шаблона, но все же позволяет вам использовать переменные в шаблоне.

person DarthFennec    schedule 30.08.2018
comment
Верно. Написание логики программы на вашем языке шаблонов — это прямой путь к катастрофе. Что ж, катастрофа — это немного сильно, но это не очень хорошая идея. Имейте в виду, Haskell в любом случае на самом деле не нуждается в языках шаблонов — blaze также можно отлично использовать в качестве eDSL без какого-либо Template Haskell. Тем не менее, шекспировские шаблоны хороши, когда вам нужен большой кусок CSS или JavaScript без какой-либо серверной логики. - person leftaroundabout; 31.08.2018