1

I have a Middleman data file 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

It can have either default "short" text or an alternative text. For some testimonials, I want to use alternative text for some pages, while using "short" text for others.

In my test.haml I am trying to write HAML statement that checks whether alternative text exists. If it does, it should be inserted; if it doesn't, the standard text should be used instead.

Following example shows that data.testimonials[person].alt properly refers to information from data, because it can be inserted manually. However, when I use the same variable in if defined? statement, it never returns 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

The result is this:

What am I doing wrong? Is there any way to use a conditional statement that checks whether data exists?

Rafal
  • 864
  • 10
  • 21

1 Answers1

1

defined? does not really do what you want. You can just just leave it away, the if will just evaluate to false because the value will be nil for alt.

So just put

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

Or you could actually write it much shorter:

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

I don't really know for sure, why defined? does not work, but generally you don't need the method to check for it, because undefined values will just give you a nil in middleman.

Roland Studer
  • 4,315
  • 3
  • 27
  • 43
  • This works great and I love shorter version! Now I can introduce even more variations as this solution works with any number of OR statements. – Rafal Aug 07 '17 at 06:38
  • @Rafal You are welcome I just wish I understood, why exactly `defined?` is not working. – Roland Studer Aug 07 '17 at 07:00
  • It is kind of good it doesn't work, as then I wouldn't know about this shorter version :) I thought I was missing something about how Ruby conditionals works, but apparently this is just a bug in Middleman. – Rafal Aug 07 '17 at 13:45