Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ternary operator support #236

Closed
Tracked by #1743
Pym opened this issue Jul 28, 2013 · 92 comments
Closed
Tracked by #1743

Ternary operator support #236

Pym opened this issue Jul 28, 2013 · 92 comments

Comments

@Pym
Copy link

Pym commented Jul 28, 2013

Hello!

I think it would be awesome to implement ternary operator support like Twig does:

{{ foo ? 'yes' : 'no' }}

{{ foo ?: 'no' }} == {{ foo ? foo : 'no' }}
{{ foo ? 'yes' }} == {{ foo ? 'yes' : '' }}
@fw42
Copy link
Contributor

fw42 commented Aug 2, 2013

Hm I don't think we will implement this. Not a big demand for this at Shopify. Sorry.

@fw42 fw42 closed this as completed Aug 2, 2013
@atticoos
Copy link

+1, Would be a big help for basic ternary operations

{{ foo ? 'yes' : 'no' }} please

@0xcaff
Copy link

0xcaff commented Apr 9, 2014

+1, I think this is needed.

@mkdizajn
Copy link

+1 must have,, gives the point of simplicity!

@getdave
Copy link

getdave commented May 14, 2014

+1 for this please

@Rican7
Copy link

Rican7 commented May 14, 2014

This would definitely be a helpful feature.
+1 here

@Rican7
Copy link

Rican7 commented May 14, 2014

PS: "Not a big demand for this at Shopify" isn't the best answer for why a feature shouldn't exist in an open source project. :/

@Pym
Copy link
Author

Pym commented May 14, 2014

@Rican7 yeah right? That's why I decided to never use liquid again :D

@nickpearson
Copy link
Contributor

I don't work at Shopify and I don't speak for them, but I thought this was worth commenting on.

Liquid is a Shopify project that they were kind enough to open source. If a request comes in for a feature that won't benefit Shopify and its customers, it makes sense that Shopify wouldn't spend resources implementing it and (from their perspective) adding bloat to the project. However, the beautify of open source is that you can fork the project and implement whatever features you want.

For what it's worth, I agree with you that this would be a nice feature. Unfortunately it goes against Liquid's style of using just values, variables, and filters (and not expressions) for output, so I don't expect it to be implemented.

For some of my projects, I add a custom if filter. It basically works like a ternary expression, but it's written as a filter: {{ foo | if: 'yes', 'no' }}. The yes is outputted if foo is truthy, and no is outputted otherwise. The second (else) argument is optional. There's also an unless that's the opposite of if. Here's a super simple implementation:

module TernaryFilters
  def if(value, true_output, untrue_output = '')
    value ? true_output : untrue_output
  end

  def unless(value, untrue_output, true_output = '')
    value ? true_output : untrue_output
  end
end

Try it in an irb session:

# paste the module code from above

template = Liquid::Template.parse("{{ foo | if: 'yes', 'no' }}")
template.render({ 'foo' => true  }, filters: TernaryFilters) # => "yes"
template.render({ 'foo' => false }, filters: TernaryFilters) # => "no"

You of course may want to handle the value differently, such as treating a zero or an empty string as falsy. Hopefully this helps someone who wants a brief syntax for conditional output, Liquid-style.

@fw42
Copy link
Contributor

fw42 commented May 14, 2014

@Rican7: Maybe we have different understandings of what open source software means. To me, it means that we will publish the code that we use ourselves (!) so that others can benefit from it (for free). We are totally cool with you forking this project and implementing whatever features you need for yourself. We are happy to consider any suggestions that you make, but the final decision of whether we will merge it into our version of Liquid is up to us. You have no right at all to demand features being included and I think "we don't need this feature at Shopify" is a totally legit reason to reject things. If you don't like it, don't use it.

Back to topic: I'm totally open to reconsider this decision. @Shopify/liquid, any more thoughts on the usefulness of this? @Shopify/design-gurus might have opinions too. Would this be helpful?

@atticoos
Copy link

@nickpearson makes a good point that Liquid folllows an approach of using just values, variables, and filters, rather than expressions, for output, however that can be a little constricting for many edge cases developers may encounter. Sure we can still achieve the desired output with a different set of variable assignments and conditions, but that, to us, is just a work around for not having an easy expression to call.

So without asking to review Liquid's approach to have a higher focus on expressions, it would be useful to introduce some basic/fundamental expressions that have low complexity and introduce an easier process of spitting out information, ternary support being one.

@fw42 Thanks for considering this as a possibility per discussion.

@Rican7
Copy link

Rican7 commented May 14, 2014

I want to make it clear that I wasn't trying to insult anyone here. If I did, I apologize.

I was simply trying to say that its a very closed off approach to just deny a feature and close the issue without further conversation from the community. The decision absolutely comes down to the owner of the project, and pandering to every community request isn't an option either, but its discouraging to see such a terse response on a feature request that may prove valuable to the community.

Yes, the beauty of open source is that you're giving your code away for free, something that I believe anyone could appreciate. Its also under a very lenient license (MIT), so it could be modified and redistributed. However liquid has quite a large user base and usage pattern that isn't easily controlled by the user due to one fact: GitHub uses Jekyll, which uses Liquid templating, for both generating repo and user pages, so simply forking the project doesn't allow for the same workflow here.

Either way, I'm happy to see the reconsideration here. Thanks for listening! 👍

@fw42 fw42 reopened this May 14, 2014
@fredryk
Copy link

fredryk commented May 14, 2014

In what we deal with day to day, I don't see a huge use for this… unless just to save a couple lines of code. I'd love to see a real world use case though.

@atticoos
Copy link

@fredryk Basic example..

{% if product.available %}
  <link itemprop="availability" href="http://schema.org/InStock" />
{% else %}
  <link itemprop="availability" href="http://schema.org/OutOfStock" />
{% endif %}

versus

<link itemprop="availability" 
   href="http://schema.org/{{ product.available ? 'InStock' : 'OutofStock' }}" />

Just one off the top of my head. It's pretty much a code saver, but it'd be a great-to-have 😄

Or conditional classes, it's much more conventional to have

<div class="{{ product.available ? 'available' : 'outofstock' }}"> .. </div>

versus

{% if product.available %}
<div class="available">
{% else %}
<div class="unavaialble">
{% endif %}
   .. content ..
</div>

@fredryk
Copy link

fredryk commented May 14, 2014

@ajwhite, we could simplify things a bit more already:

{% if product.available %}
<div class="available">
{% else %}
<div class="unavaialble">
{% endif %}
   .. content ..
</div>

Can be shortened down:

<div class="{% if product.available %}available{% else %}unavaialble{% endif %}">
   .. content ..
</div>

I like the use case though. Thanks for posting it! :)

@atticoos
Copy link

@fredryk Ah yes, can I embarrassingly remove that comment now? 😉

Good point though, that isn't too ugly, but also slightly less friendly as a ternary. Works though

@fw42 fw42 closed this as completed Aug 4, 2014
@fulldecent
Copy link

Here is the use case:

<h1>REPLACE ME</h1>

Filling in by finding the first available:

  • page.heading
  • page.title
  • site.title

@TWiStErRob
Copy link

Here's another one:

{% assign postCount = site.categories[other_category.slug].size %}
{% unless postCount %}{% assign postCount = 0 %}{% endunless %}
Versus
{% assign postCount = site.categories[other_category.slug].size ?: 0 %}

@carolineschnapp
Copy link

I find Ternary operator construct unnecessarily hard to read in Liquid. To me anyway, Liquid is not a programming language, it is meant to be super simple. I am all for making Liquid do things that were not possible before, when these things are most needed, but since Liquid can do in a more verbose ( in my opinion easier to read ) way what a Ternary operator would allow, then this would make me give a 👎 .

@atticoos
Copy link

To me anyway, Liquid is not a programming language, it is meant to be super simple.

Correct, but when you can make assignments, it would be nice to have decent support in that. Nothing crazy, but something like a ternary makes an assignment based on a condition a lot easier to write.

I find Ternary operator construct unnecessarily hard to read in Liquid.

I disagree, using @TWiStErRob's example, i think

{% assign postCount = site.categories[other_category.slug].size ?: 0 %}

reads pretty easily. It feels a lot easier to read than

{% assign postCount = site.categories[other_category.slug].size %}
{% unless postCount %}{% assign postCount = 0 %}{% endunless %}

but since Liquid can do in a more verbose ( in my opinion easier to read ) way what a Ternary operator would allow

I guess that comes down to personal preference. I, personally, don't think multi-lined assignments due to verbosity is easier to read. Being used to ternaries, it feels like extra work to understand the assignment by having to read multiple lines of conditional reassignments.

@TWiStErRob
Copy link

TWiStErRob commented Jun 12, 2015

I guess that comes down to personal preference.

I think this is key here, liquid is a framework/library. How one uses a library is their problem. But if a library lacks a feature that's everyone's problem (at least those who want to use it).

I could also argue for size to return 0 when the object is null, but that's a different issue.

@TWiStErRob
Copy link

Hmm, lookey here, it's not ternary, but at least Elvis is alive! (added in #267)
{% assign postCount = site.categories[other_category.slug].size | default: 0 %}
I just wish GitHub pages/Jekyll would bump to 3.x...

@atticoos
Copy link

Nice, even an "Elvis operator" is a nice step up. Would still be nice to have a true ternary, but this is a good find

@ThePJMP
Copy link

ThePJMP commented Nov 30, 2015

@fredryk you can simplify it even more:

<div class="{% unless product.available %}un{% endunless %}available">
   .. content ..
</div>

@bbuie
Copy link

bbuie commented Mar 11, 2016

This is a good reason why Shopify hasn't become the clear leader in ecommerce. They think supporting developers is not in their best interest. Unfortunately, they don't realize the power of a strong recommendation from a developer to a potential customer.

@nickpearson
Copy link
Contributor

Yes, because they do not implement every single requested feature in an excellent library they make freely available to everyone, Shopify hates developers.

Sure, ternary operator support would be great, but your claim is unreasonable and way out of proportion. And if I remember correctly, they do accept pull requests.

@bbuie
Copy link

bbuie commented Mar 11, 2016

I just re-read my comment and it did sound a bit harsh. :(

That said, the only reason I know Liquid is because they require it to build their themes. I'm a customer myself, and I've developed themes for many of their customers, so don't think I'm using a free library and then complaining.

In addition, this is just one of the many examples where it is clear that shopify ignores requests even with a need. This isn't helping them become a clear leader.

I've been developing ecommerce sites for almost a decade and continue to have a high hope that someone will emerge as the leader. I really thought Shopify would, and it has a lot going for it, but I can see they're missing the opportunity to cater to developers and thus grow their market share.

@synsa
Copy link

synsa commented Mar 14, 2022

Please reconsider reopening this issue as such a feature would be beneficial to some and [optional] to many as it wouldn't (re: shouldn't) break existing themes.

@notrealdev
Copy link

Can anyone create a new issue for this?

@paulshryock
Copy link

It appears there is another open issue about this feature request: #1264

@pablogiralt
Copy link

+1

2 similar comments
@Jellyfishboy
Copy link

+1

@mhraihan
Copy link

+1

@rvibit
Copy link

rvibit commented Dec 31, 2022

+ထ

@pinguluk
Copy link

pinguluk commented Mar 15, 2023

The most problematic thing I can see about introducing ternary operators is that a lot of designers make Shopify themes in Liquid and don't know a lot of code. For loops are scary enough. If developers start putting in a lot of weird operations, it may scare away the designers from using the language, which is most advantageous to Shopify's growth.

Bruh, the ternary operators are literally some of the simplest things out there. And by making and developing Shopify themes, you'll have to eventually learn some Liquid template coding.

You still have to learn for if/else statement for example:

{% if product.available %}
<div class="available">
{% else %}
<div class="unavaialble">
{% endif %}
   .. content ..
</div>

and with the ternary operator you will end up only with:

<div class="{{ product.available ? 'available' : 'outofstock' }}"> .. </div>

which is much simpler and easier to read.

By the way, it's 2023, still not added?

@leandrovitto
Copy link

leandrovitto commented Mar 30, 2023

I found this temp solution

  <div class="inline-flex gap-4">
      {% assign default_colour = "bg-indigo-600" %}
      {% assign success_colur = "bg-green-600" %}

      {% capture btn_classes %}
        block rounded-md px-3 py-2 text-center text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600
      {% endcapture %}

       <button type="button" class='{{ btn_classes }} {% if piletV.pilet.enabled %}{{default_colour}}{% else %}{{success_colur}}{% endif %}'>Enabled</button>
       <button type="button" class='{{ btn_classes }} {{ default_colour }}'>View Versions</button>
  </div>

and with the ternary operator you will end up only with:

<div class="{{ varToTest ? ' bg-indigo-600' : 'bg-green-600' }} px-3 py-2 text-center text-sm "> .. </div>
which is much simpler and easier to read.

By the way, it's 2023, still not added?

@Jellyfishboy
Copy link

10 years down the line and still not implemented. Why does Shopify provide such bad tools and support for developers?

@simonbarker
Copy link

Another vote for this one

@LiaqatSaeed
Copy link

+1

@dexter845
Copy link

+1 Please

@BaggioGiacomo
Copy link

+1

2 similar comments
@Furxx2000
Copy link

+1

@lantchou
Copy link

lantchou commented Jul 6, 2023

+1

@galmis
Copy link

galmis commented Jul 19, 2023

+1

2 similar comments
@illia108
Copy link

+1

@yveveke
Copy link

yveveke commented Jul 26, 2023

+1

@bdogaru
Copy link

bdogaru commented Sep 7, 2023

10 years down the line and still not implemented. Why does Shopify provide such bad tools and support for developers?

Oh come on.. I got on this thread because I'd love a ternary operator and yes, 10 years after this has been open is a long time but...Shopify has really been great towards devs, especially in the past couple of years. I'd rather send them some love, maybe that's the way to get this topic sorted 😆

@robwatkins1988
Copy link

I must admit i am surprised this still hasnt been added.

@Czx00000 Czx00000 mentioned this issue Sep 12, 2023
@danvc
Copy link

danvc commented Nov 8, 2023

One century later..

@mryurii
Copy link

mryurii commented Nov 20, 2023

maxresdefault

@danvc
Copy link

danvc commented Nov 20, 2023

Or... "one eternary later" 🤪. The most impressive comment is "Hm I don't think we will implement this. Not a big demand for this at Shopify. Sorry." (@fw42 )

@fw42
Copy link
Contributor

fw42 commented Nov 20, 2023

That comment is over 10 years old. At the time it didn't seem like there was demand. Obviously I was wrong. Unfortunately I haven't worked for Shopify in over 4 years.

@adictonator
Copy link

@fw42 With your experience and approach, could you talk to the higher-ups, considering you're still in touch with them, and get them to notice this issue?

@MariannaAtPlay
Copy link

Pleeeese add this feature!

@muke5hy
Copy link

muke5hy commented Mar 18, 2024

I am tired of writing
{% if setting.foo == 'bar' %} 'hello' {% else %} 'world' {% endif %}

I just want to do

{% setting.foo == 'bar' ? 'hello' : 'world' %}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests