HAML Если определено? оператор, оценивающий, существует ли запись в файле данных Middleman

У меня есть файл данных посредника data/testimonials.yaml:

tom:
  short: Tom short
  alt: Tom alt (this should be shown)
  name: Thomas

jeff:
  short: Jeff short
  alt: Jeff alt (this should be shown)
  name: Jeffrey

joel:
  short: Joel short (he doesn't have alt)
  name: Joel

Он может иметь либо «короткий» текст по умолчанию, либо альтернативный текст. Для некоторых отзывов я хочу использовать альтернативный текст для одних страниц и «короткий» текст для других.

В моем test.haml я пытаюсь написать оператор HAML, который проверяет, существует ли альтернативный текст. Если это так, его следует вставить; если это не так, вместо этого следует использовать стандартный текст.

Следующий пример показывает, что data.testimonials[person].alt правильно относится к информации из данных, поскольку ее можно вставить вручную. Однако, когда я использую ту же переменную в операторе if defined?, она никогда не возвращает true.

Not-working 'if' way, because 'if defined?' never evaluates to true:
- ['tom','jeff','joel'].each do |person|
    %blockquote
        - if defined? data.testimonials[person].alt
            = data.testimonials[person].alt
        - else
            = data.testimonials[person].short

Manual way (code above should return exactly this):
- ['tom','jeff'].each do |person|
    %blockquote
        = data.testimonials[person].alt

- ['joel'].each do |person|
    %blockquote
        = data.testimonials[person].short

Результат таков:

Что я делаю не так? Есть ли способ использовать условный оператор, который проверяет, существуют ли данные?


person Rafal    schedule 04.08.2017    source источник


Ответы (1)


defined? на самом деле не делает то, что вы хотите. Вы можете просто оставить его, if просто будет оцениваться как false, потому что значение будет nil для alt.

Так что просто поставь

- ['tom','jeff','joel'].each do |person|
    %blockquote
        - if data.testimonials[person].alt
            = data.testimonials[person].alt
        - else
            = data.testimonials[person].short

Или вы могли бы написать намного короче:

- ['tom','jeff','joel'].each do |person|
    %blockquote
        = data.testimonials[person].alt || data.testimonials[person].short

Я точно не знаю, почему defined? не работает, но обычно вам не нужен метод для его проверки, потому что неопределенные значения просто дадут вам nil в посреднике.

person Roland Studer    schedule 04.08.2017
comment
Это прекрасно работает, и мне нравится более короткая версия! Теперь я могу ввести еще больше вариантов, так как это решение работает с любым количеством операторов ИЛИ. - person Rafal; 07.08.2017
comment
@Rafal Пожалуйста, я просто хотел бы понять, почему именно defined? не работает. - person Roland Studer; 07.08.2017
comment
Это вроде как хорошо, что это не работает, так как тогда я бы не знал об этой более короткой версии :) Я думал, что упустил что-то в том, как работают условные операторы Ruby, но, видимо, это просто ошибка в Middleman. - person Rafal; 07.08.2017