Shopify / liquid

Liquid markup language. Safe, customer facing template language for flexible web apps.
https://shopify.github.io/liquid/
MIT License
11.11k stars 1.39k forks source link

if condition on empty string #223

Closed etienneroudeix closed 11 years ago

etienneroudeix commented 11 years ago

Hello, I was just wanting to test if my_variable was an empty string.

I'm using Liquid through Jekyll if it can help.

I tried :

{% if my_variable == '' %} I'm not empty {% endif %}

but no way.

In fact I have to do like this

{% if my_variable == %} I'm not empty {% endif %}

It sound ugly to me so I let you know.

By the way it's the same behaviour using case condition.

Thank you for your job on this rocking project.

nickpearson commented 11 years ago

You can use the blank keyword: {% if my_variable == blank %}, which internally checks my_variable.blank?. See the 'blank' entry in the LITERALS hash if you're curious about how it works.

etienneroudeix commented 11 years ago

Hi, thank you for your response ! Kind regards.

etienneroudeix commented 11 years ago

Well, I just tested :

{% if my_variable == blank %} I'm not empty {% endif %}

and

{% if my_variable.blank? %} I'm not empty {% endif %}

And none of them behave as it should :(

nickpearson commented 11 years ago

What is the exact output of this?

my_variable is {% if my_variable == blank %}blank{% else %}"{{ my_variable }}"{% endif %}

This will result in one of the following:

my_variable is blank
my_variable is "something"

Also, to make your logic match up, you'll either want to change == to != or remove "not" from "I'm not empty".

Sorry if I wasn't clear -- the .blank? is what Liquid uses internally (in its Ruby code) -- you can't actually call my_variable.blank? in your Liquid code (unless you've added a custom blank? Liquid method to whatever class my_variable is).

fw42 commented 11 years ago

Shit, that might be a bug. "blank?" is not a Ruby thing but Rails. If you use Jekyll, that might not work. Not sure though.

nickpearson commented 11 years ago

True. empty is also in there (aliases to :empty?). @etienneroudeix, this is standard Ruby (doesn't depend on Rails), but it behaves different from blank?, so be careful when using it on strings:

# same
"".blank? #=> true
"".empty? #=> true

# different
"  ".blank? #=> true
"  ".empty? #=> false
fw42 commented 11 years ago

I can't reproduce the bug. This:

{% assign my_variable = '' %}
{% if my_variable == '' %} works {% endif %}

works for me.

fw42 commented 11 years ago

Do you want to test on the variable being the empty string or do you want to test on it being defined? Try testing for nil instead maybe?

etienneroudeix commented 11 years ago

WOW lot of passionate talking thank you.

my_variable is {% if my_variable == blank %}blank{% else %}"{{ my_variable }}"{% endif %} gave me :

my_variable is ""

and my_variable is {% if my_variable == empty %}empty{% else %}"{{ my_variable }}"{% endif %} gave me the same exactly.

I want to test an empty (not even a space) or unset string

my_variable is {% if my_variable == nil %}nil{% else %}"{{ my_variable }}"{% endif %} works fine when the variable is not define.

But I still only can test empty string like that : my_variable is {% if my_variable == %}blank or not set{% else %}"{{ my_variable }}"{% endif %}

Thanks

etienneroudeix commented 11 years ago

Well my bad !

my_variable is {% if my_variable == %}blank or not set{% else %}"{{ my_variable }}"{% endif %}

does not work with empty string. It just behave exactly like nil testing.

fw42 commented 11 years ago

How about {% if my_variable == "" or my_variable == nil %}?

etienneroudeix commented 11 years ago

Excellent ! It works !

Thank you very much !

To let you know : if my_variable == blank or my_variable == nil does not works.

My problem is solved thank you !

chrishough commented 10 years ago

In case anyone comes across this thread, I had to add 1 more piece to the conditional to make it work:

{% if post.image_thumbnail_500x500 And post.image_thumbnail_500x500 != "" And post.image_thumbnail_500x500 != nil %}
  <img src="{{ post.image_thumbnail_500x500 | asset_path }}">
{% endif %}
tonybrasunas commented 9 years ago

The != nil test works for me.

etienneroudeix commented 9 years ago

It's a 17 monthes old issue. Maybe it's fixed now.

apla commented 9 years ago

none of this really works in jekyll 2.5.4

{{ if page.xxx and page.xxx != "" and page.xxx != nil }}
<h1>crap!</h1>
{{ endif }}
parkr commented 9 years ago

@apla Have you tried the Jekyll 3 beta? Jekyll 2 is still using Liquid 2.

rickydazla commented 9 years ago

Is there a / what is the difference between nil, blank, and empty? Are they interchangeable? In Shopify Liquid is one preferable or are there situations where different ones should be used?

onsitediary-blog-de commented 9 years ago

Github pages still use Jekyll 2.4.0. Would be great, if this issue would be fixed.

onsitediary-blog-de commented 9 years ago

In meantime I use following workaround: {% capture site_info %}X{{ site.form-info-website }}{% endcapture %} {% if site_info == "X" %} <h1>form-info-website is not set</h1> {% endif %}

yoshyosh commented 9 years ago

What is the way to do this in Jekyll 2?

Edit: I just check if the variable exists {% if site_info %} // Do things {% endif %}

7blink commented 9 years ago

I have been using {% if page.testVariable.size != 0 %}

OilSlick commented 8 years ago

I'm running Jekyll 3.0.1 and had to implement the "capture" workaround proposed by onsitediary-blog-de on April 12. I tried other solutions mentioned in this thread with no luck.

edwinwright commented 8 years ago

I found that if the variable has not been set, then I get no value back on the size calculation. To get around this I turned it into a truthy test which seems to be working fine. I'm running Jekyll 3.1.1

{% if component.status.size %}

tatarjr commented 7 years ago

In case anyone is still having this issue, try comparing against undefined. I've run into this with page.previous / page.next variables, and was able to solve it by comparing if it's undefined.

{% if my.variable == undefined %} ... {% endif %}

dylanahsmith commented 7 years ago

{% if my_variable == '' %} is fine if you just want to check if the variable equals the empty string.

However, it sounds like the variable was actually nil and that is why that condition didn't work. In that case use {% unless my_variable %} to check if the variable is nil.

RNCTX commented 7 years ago

@edwinwright 's comment works for me on jekyll as well (3.1.6). Thanks!

In my case I was trying to find all files but exclude those without a front matter tag defined, in other words, filter out posts with an empty string like tags:

Nil, 0, undefined, and blank did not work.

thing.subthing.size != 0 does work.

rickydazla commented 7 years ago

Null, nil, empty, blank, undefined; possibilities are many, answers are æthereal and perhaps esoteric. ' '

bdanin commented 6 years ago

<% if !thing.subthing.empty? %>not-empty: <%= thing.subthing %><% end %> didn't see this exact answer in here, but this is what works for me in ruby middleman templates

syu-id commented 6 years ago

{% if var and var != blank %} works for me.

tomjoht commented 6 years ago

I have a collection and am trying to use tags as a property in the frontmatter of pages (not posts) in this collection. I found that empty works to check whether the tags have any content. For example:

{% if page.tags == empty %}
there are no tags
{% else %}
there are page tags
{% endif %}

Again, I'm working with pages in a collection, not posts.

sbliven commented 6 years ago

To summarize, here's a table of the boolean value of various values (jekyll 3.7.3, liquid 4.0.0):

Operator nil "" " "
var false true true
var == blank false false false
var == empty false true false
var == "" false true false
var == nil true false false

Generated with statements like {%if Operator %}true{% else %}false{% endif %}

vinyanalista commented 6 years ago

I'm moving my blog from Jekyll 2.5.3 (Liquid 2.6.1) to Jekyll 3.8.0 (Liquid 3.0).

In my template, there was an if checking that variable1 and variable2 were undefined and defined, respectively. It was just as simple as:

{% if !variable1 and variable2 %}
    ...
{% endif %}

Now, Liquid complains about that:

Liquid Warning: Liquid syntax error (line 23): Unexpected character ! in "!variable1 and variable2" in search/index.html

See the new code (references are this issue and Checking if a variable is set in Jekyll):

{% if variable1 == nil or variable1 == empty %}
    {% if variable2 and variable2 != "" and variable2 != nil %}
        ...
    {% endif %}
{% endif %}

To make things even more verbose, parentheses are not permitted by Liquid, so necessarily I need two ifs to accomplish that task.

Does one believe that change was for good? If so, why?

dylanahsmith commented 6 years ago

@vinyanalista that ! in {% if !variable1 and variable2 %} was never supported syntax, so was just being ignored by the lax parser. E.g.

require 'liquid'

source = <<-LIQUID
!true = {% if !true_var %}true{% else %}false{% endif %}
!false = {% if !false_var %}true{% else %}false{% endif %}
LIQUID
output = Liquid::Template.parse(source).render('true_var' => true, 'false_var' => false)
puts output

outputs

!true = true
!false = false

It works the same way on 2.6.1, so doesn't appear to be changed in liquid. I think the only difference is that jekyll is using the strict parser now which is catching your syntax error.

obendev commented 5 years ago

{% if include.banner.video == undefined %} worked for me jekyll version 3.8.5

{% if include.banner.video %} works as well, if the variable isn't set, it will be false.

gojimmypi commented 3 years ago

I came here thinking I had a problem detecting blank or empty strings. When, in fact - I actually had a blank record in my authors.yml file, with an extra - that had not been commented out:

-
  id: gojimmypi
  name: gojimmypi
-
# warning: having only one author generates this message:
#  Liquid Exception: undefined method `[]' for nil:NilClass in author/gojimmypi/index.html
#             Error: undefined method `[]' for nil:NilClass
#             Error: Run jekyll build --trace for more information.
  # id: person2
  # name: gojimmypi

I tried doing something like this to detect the "blank" ID:

{% for siteauthor in site.data.authors %}
  {% if  siteauthor.size == "" or siteauthor.size == empty or siteauthor.size == blank  or siteauthor.size == nil or siteauthor.size < 1  %}
    WARNING: blank record found in authors.yml (stray ' character? single quotes are row delimiters!)
    {% assign the_author_id = "" %}
    {% assign the_author = "missing" %}
  {% else %}
    {% assign the_author_id = siteauthor.id  %}
    {% assign the_author = site.data.authors | where: 'id', siteauthor.id %}
  {% endif %}
{% endfor %}

But the siteauthor.id still causes this error:

gems/jekyll-3.9.0/lib/jekyll/filters.rb:323:in `block in item_property': undefined method `[]' for nil:NilClass (NoMethodError)

Lesson learned: never have a blank record with a stray - in the yml data file.

vachana815 commented 3 years ago

{ % if settings.custom_message % } Thank you. { { settings.custom_message } } { % endif % } what would be the output of this one then ??

oDinZu commented 2 years ago

Awesome, thanks for sharing guys and gals.

This worked for me when I am looping through paginator.posts. I had a display bug when the author data was empty.

{% if post == blank %}
{% comment %}
  Fix display bug when author data is empty.
{% endcomment %}
  {% else %}
    <div class="meta">
      <time class="published">{{ post.date | date_to_string }} {{ page.date | date_to_string }}</time>
      <h5 class="author"><img src="{{ author.avatar }}" alt="{{ author.first_name }} {{ author.last_name }}" /><span class="name">{{ author.first_name }}</span></h5>
    </div>
{% endif %}
swshamiq commented 1 year ago

not even a space

variable == nil worked the best

MrHinsh commented 1 year ago

my_variable is {% if my_variable == blank %}blank{% else %}"{{ my_variable }}"{% endif %}

include.category is {% if include.category == blank %}blank{% else %}"{{ include.category }}"{% endif %} results in:

include.category is ""

include.category is {% if include.category == nil %}blank{% else %}"{{ include.category }}"{% endif %} results in:

include.category is "blank"


I ended up with:

{% if include.category == or item.category contains include.category %}

Which works as expected but totally looks broken, but works.