more logic please!

by Christina - Miss Manners - 10:40AM, Jan 30, 2007

I’m finding myself pushing at the limits of the liquid/admin system these past two weeks, & would like to request some additions to the logic which would make it possible to do away with a lot of manual labour, diverse hacks, multiple nested conditionals and sheer frustration. This sums up a few of the requests/comments I’ve made recently. In order of priority:

1) editable handles : Tobi, you mentioned that you’ve been intending to make product handles etc. editable. This would be fantastic for a consistent system of product reference & would help greatly in setting up bilingual stores, editing product names without 404 penalties and so on.

2) more string manipulation :

  • ”contains” in liquid (or wildcards). usage example: for all products that contain the word “thisword” (or “this ‘asterisk’”), list the product.
  • real truncation – as mentioned here – though if the first two are done, this one won’t be as necessary anymore, but might still be very useful for other purposes.

3) choice of “and” or “or” as conditionals in smart collection setup as requested here in May, here in August, and here in December.

4) more booleans in liquid – in particular “or” – as requested here last April and here again in October

5) Other things that have been mentioned before are:
- letting a product belong to more than one product type
- making it possible to assign a product to a collection (/collections) from the admin product page.

6) And the biggie: custom fields...one day? maybe? then I wouldn’t have to use my “blog as product description” hack anymore.

Sorry for posting such a tall order before breakfast, but I’ve really reached the end of what I can do with the system as it stands, and I would love to do more! It’s such a lovely thing you guys created, I’d really like to be able to use all of its potential.

And with that, ummm…have a beautiful day!

edited to add this, which I’m battling with:

7 – enlarged variable scope

for example: allow for this:

{% for link in linklists.{{my_variable}}.links %}

and this:

{% for product in collection.{{my_variable}}.products %}

That could solve A LOT of problems – fix all the related products problems quite elegantly for example! I’ll share the code as soon as I hatch it, as soon as I can use variables in more contexts – promise!

---

operation absurdist feature requests: terminated

(http://en.wikipedia.org/wiki/Absurdism)

Last edited 01:47PM, Jan 30, 2007

tobi

Shopify

09:44PM, Jan 30, 2007

Thanks for the list christina. I agree with the need for all of these things. You are really pushing the boundaries of liquid and our theming system so its great to hear from you what the most pressing issues are in this area.

1) Ok soon

2) truncate works like this. I’ll add if a contains b to liquid.

3) Thats unlikely to happen soon. Very very complicated implementation and UI.

4) Tricky, i get this request a lot from the mephisto crowd. I’ll see what it takes.

5) I’d rather get rid of product types entirly, they are really superseded by collections. They are only around now becuase of the convenience. I don’t quite understand the second point, you can add a product to a collection on the product page, can you not?

6) Custom fields are something i really want eventually but it will probably take a while till we can tackle this one.

7) Would be nice… i spend a transatlantic flight working on this before but didn’t come up with a satisfactory result. There is hoping that i get to revisit this.

---

Tobias Lütke
Shopify – Founder, CEO

Christina

Miss Manners

10:54PM, Jan 30, 2007

& thank you very much for the quick answer & positive response, Tobi!

1) am delighted!
2) truncate is fine, now that i know about that extra parameter. a contains b – great!
3) this isn’t really absolutely necessary if there’s the possibility to code it differently. it’s the absence of “or” in both the smart collections and in liquid which makes it difficult to do certain things. if there’s 4) we don’t really need 3)
4) see above – would be very helpful.
5) agree with getting rid of product types. i always thought that was just another name for collections anyway :). apologies for the second point, came from an area of deep confusion in my brain – something about switching back and forth between product and collection admin, but it wasn’t that. never mind.
6) ya, i understand that’s a big one. no rush.
7) this one i would really like. i spent not quite the equivalent of a transatlantic flight, ( but almost :)) trying to do related products in this way:

{% for link in linklists.product_families.links %}
{% assign: related = link.title %}
{% endfor %}>

no problem, variable assigned.

but I couldn’t understand why this works:

<ul>
{% for tag in product.tags %}
    {% if tag =={{related}} %}
        <li><a href="/collections/{{related}}">{{ tag | highlight_active_tag }}</a></li>
    {% endif %}
{% endfor %}
</ul>

and links to a collection page with related products (which is not quite what I want but it’s a start.)

- but this just throws up a liquid error:

{% for tag in product.tags %}
    {% if tag == {{related}} %}
        <ul>
        {% for link in linklists.{{related}}.links %}
            <li><a href="{{link.url}}" title="{{link.title}}"><span>{{link.title}}</span></a></li>
        {% endfor %}
        </ul>
    {% endif %}
{% endfor %}

where the problem is obviously this:

{% for link in linklists.{{related}}.links %}

and that’s just so weird!

---

operation absurdist feature requests: terminated

(http://en.wikipedia.org/wiki/Absurdism)

Christina

Miss Manners

11:42PM, Jan 30, 2007

so with my new truncating skills, I’m now trying this:

{% for variant in product.variants %}
  {% assign: base_sku ={{variant.sku | truncate:6,''}}%}
  {{base_sku}}
{% endfor %}

but var base_sku returns the untruncated variant.sku, so I’m supposing it doesn’t read the filter. is this syntax not accepted?

---

operation absurdist feature requests: terminated

(http://en.wikipedia.org/wiki/Absurdism)

danW

Shopify Advisor

12:37AM, Jan 31, 2007

Try this

{% for variant in product.variants %}
  {% assign: base_sku = variant.sku %}
  {{ base_sku | truncate: 6, '' }}
{% endfor %}

Couldn’t you just go for this?

{% for variant in product.variants %}
  {{ variant.sku | truncate: 6, '' }}
{% endfor %}

Or is there a reason to assign variant.sku to base_sku?

tobi

Shopify

03:40AM, Jan 31, 2007

Currently it should never work to use {{ }} within a {% %} tag. If it seems to work then thats just because liquid is very liberal at ignoring syntax errors and tries to make the most out of it.

Similarly you cannot use filters in {% %} tag. Its just one of those limitations of the language. Liquid was designed to emit strings, not be a Turing complete programming language.

Can’t your problem be better solved by a links list though?

---

Tobias Lütke
Shopify – Founder, CEO

Christina

Miss Manners

09:47AM, Jan 31, 2007

Ok, i’ll explain the use:

When I set up my shop, and looked at what one could do with variants vs. products, I decided not to use variants for identical products of a different colour, but to list them as independent products because 1)I wanted to be able to display “Item X – blue” in the same way as Item X – red”, and 2) I wanted to be able to tag them independently.

So now, I have products that are almost identical, with the only difference being the colour. They’re scattered all over the collection, with no way of getting from “Item X – red” to “Item X – blue”. And that bothers me. What I’m trying to do is say on product page “Item X- red”, display small pictures of “Item X – blue” and “Item X – green” with links, to say, “if you prefer this same thing in blue or green, go here”.

The SKU structure is as follows:

  • “Item X – red” – ABC001001
  • “Item X – blue” – ABC001002

where the first three letters are the code for the manufacturer, the next group of three figures the code for the item model, and the last group of three figures the color code.

So what I want to do is chop the last three digits off the SKU, and have that as a variable called “base_sku” which will indicate the product model without the colour.

So variant.sku (9 digits) is not the same thing as base_sku (6 digits).

This is what I’m trying to do with:

{% assign: base_sku ={{variant.sku | truncate:6,''}}%}

In a second step, I’d like to do a forloop for products in products that contain “base_sku”, and list them on the product page. (once we have “a contains b” in liquid). And that should take care of the display of identical products of a different colour on any given product page.

But if this kind of logic is impossible, then I’ll have to try something else. I was trying to avoid setting up collections for each of the identical product groups, with linklists and the whole kit & caboodle.

I do miss some more powerful variable use though.

Or – another way around this would be to be able to attach independent tags to the variants, i.e. for item X – a group of shared tags, and for variant “item X – red” independent tag “red” and for variant “item X – blue” independent tag “blue”. But that seems like a much more intrusive change to the existing system. Hence my coding attempts.

Voilà!

---

operation absurdist feature requests: terminated

(http://en.wikipedia.org/wiki/Absurdism)

Christina

Miss Manners

04:05PM, Feb 10, 2007

bumpety-bumpety-bump…

I’ll add if a contains b to liquid.

would be extremely vastly incredibly useful right now! please soon?

---

operation absurdist feature requests: terminated

(http://en.wikipedia.org/wiki/Absurdism)

Jeff

Member

01:30AM, Feb 12, 2007

Ok, where do we find ALL the liquid options available. I see above there is an assign option. Haven’t found it documented anywhere yet. I see on the leetsoft site, an ifchanged option. The assign option looks like it allows you to assign a value to a variable, but I’ve tried to use it to just assign text, but that does not work.. eg:

 {% assign: test = "abc" %}
 {{test}}
prints nothing. Does that mean it can only assign other liquid values???

Christina

Miss Manners

01:44AM, Feb 12, 2007

yes – to the last question.

it’s documented here: http://help.shopify.com/design/show/The+Shopify+Theme+Guide

& other info availabe in the wiki, specifically in “pages and tags”

---

operation absurdist feature requests: terminated

(http://en.wikipedia.org/wiki/Absurdism)

Jeff

Member

05:27AM, Feb 12, 2007

So I’m guessing I’ve run into another limitation of Liquid??

    {% for variant in product.variants limit:2 offset: {% cycle '0','2' %} %}
does not work, and yes, I’m trying to reduce the amount of basically duplicate code I have to write, since variables are unavailable…

Christina

Miss Manners

09:48AM, Feb 12, 2007

i’m puzzled as to what you’re trying to achieve by this – as i parse it this would give you:

product 1 variant 1
product 1 variant 3

product 2 variant 1
product 2 variant 3

and so on -

so this would capture your odd variants, and i suppose you’d have another loop to capture your even ones. that makes 2 forloops for the same variants – i.e. double the server calls.

if you want to just style variants differently, you could do:

<ul>
{% for variant in product.variants %}
<li class="{% cycle 'odd', 'even' %}">
{{variant.title}} //- or whatever </li>
{% endfor %}
</ul>

and then style your items with css:

li.odd{whatever}
li.even{something else}
---

operation absurdist feature requests: terminated

(http://en.wikipedia.org/wiki/Absurdism)

Jeff

Member

02:23PM, Feb 12, 2007

I’m trying to get around coding a bazillion lines of code to deal with my various tables I want to implement to deal with size/colour… I have the tables solution working.. However due to the lack of variable substitution, I have to code each product and each line, as opposed to have a single set of code and passing variables to it. It has been a tad frustrating… For example, I may have a product that has 14 variants. I can put them on two lines in my table, but it requires double the code since I need a line with limit:7 offset:0 and a second line with limit:7 and offset:7. If I could get the offset to be a variable, then, I would only require one set of code. Extrapolate that further, I could build tables using a single set of code, if I could set variables.. Then limit could be variablized, and all would be goodness. Use a case statement for the specific products that require the table module, set the variables, and call one piece of code.

tobi

Shopify

02:51PM, Feb 12, 2007

you can use offset: continue which starts where the last limit left off.

---

Tobias Lütke
Shopify – Founder, CEO

Jeff

Member

04:51PM, Feb 12, 2007

Ok, well that’s a handy little item… I’ve tested it and now can use a table for variations, with at least a reasonable amount of code. If anyone wants to see a table working for size/type take a look at my test store, http://gams.myshopify.com/products/test-variation. I can post the code here if anyone is interested.

Christina

Miss Manners

10:03PM, Feb 12, 2007

pretty cool! yes i’d be interested in seeing the code.

---

operation absurdist feature requests: terminated

(http://en.wikipedia.org/wiki/Absurdism)

Jeff

Member

10:15PM, Feb 12, 2007

Ok, here it is….

{% else %}
    <form id="product-form" action="/cart/add" method="post">
      <table width="100%" border="1" class="variantstable">
    <thead>
       <tr>
          <th></th>
          <th>0</th>
          <th>1</th>
          <th>2</th>
          <th>3</th>
          <th>4</th>
          <th>5</th>
          <th>6</th>
          <th>Price</th>
        </tr>
    </thead>
    <tbody>

   {% for i in (1..4) %}
    <tr style="background: {% cycle '#fff', '#eee',%};" >
        <td>{% cycle 'Womens 3/4','Womens Full','Mens 3/4','Mens Full' %}</td> 
<!--    <td>{% cycle {{testcycle}} %}</td> -->
    {% for variant in product.variants limit:7 offset: continue %}

        {% if variant.available == true %}
           <td align="center" ><input type="radio" name="id" value="{{variant.id}}" id="radio_{{variant.id}}" onclick="testMe(this.value)" {%if forloop.first%} checked="checked" {%endif%} /> {{ variant.title | truncatewords: 1,''}}</td>
        {% else %}
           <td align="center">X</td>
        {% endif %}
{% assign: test = variant.price %}
    {% endfor %}
    <td>{{ test | money_with_currency }}</td>
    </tr>
   {% endfor %}
    </tbody>
     </table>
{% endif %}

     {% unless product.available == false %}            
     <div><input type="submit" value="Add to Cart" name="Add" id="add" /></div>
     {% endunless %}

    </form>
  </div>       

There is some test stuff in there, and some things I’d still like to change. Working on having the price updated based on the item you select, instead of having it at the end of the row. Also you have to make sure you have the same number of variations so I have some variations, I have called blank, and set to 0 available and deny, to get the X options. Any ideas suggestions on improvements, just let me know.

tobi

Shopify

10:24PM, Feb 12, 2007


bumpety-bumpety-bump… I’ll add if a contains b to liquid.

would be extremely vastly incredibly useful right now! please soon?

Well why don’t you use it then ? ... ;)

---

Tobias Lütke
Shopify – Founder, CEO

Christina

Miss Manners

10:40PM, Feb 12, 2007

lol! – you’re a darling, tobi!

---

operation absurdist feature requests: terminated

(http://en.wikipedia.org/wiki/Absurdism)

Christina

Miss Manners

10:48PM, Feb 12, 2007

@ jeff: thanks, very nice!

I hereby nominate you for official shopify cycling champion.

p.s. i didn’t know we were allowed to do this:

{% for i in (1..4) %}

nice find!

---

operation absurdist feature requests: terminated

(http://en.wikipedia.org/wiki/Absurdism)

Jeff

Member

10:54PM, Feb 12, 2007

Yeah, finding the tricks within liquid has been shall we say challenging… :) Anyone know how to do if else if endif syntax?? How I thought it should work it doesn’t….

Jared Burns

Shopify Advisor

10:57PM, Feb 12, 2007

{% if %}
    ....
{% elsif %}
    ....
{% endif %}

tobi

Shopify

11:11PM, Feb 12, 2007

Please do consider to update the wiki with all those amazing hacks you guys uncover ;)

---

Tobias Lütke
Shopify – Founder, CEO

Jeff

Member

04:53PM, Feb 13, 2007

Is there a way within case to apply two when clauses to the same code?? or is there a way within if to have and/or logic?? eg:

{% case product.title %}
{% when "product A" or "product B"}
woo hoo, it works... :)
{% endcase%}
or
{% if product.title  "product A" or product.title  “product B” %}
woo hoo, it works… :)
{% endif %}
And yes, the == signs are getting stripped out for some reason. Basically I do not want to duplicate the code where I have the woo hoo....

tobi

Shopify

09:44PM, Feb 13, 2007

Liquid can’t do that yet. Its one of the most requested features though. I hope someone one day sends me a patch :)

---

Tobias Lütke
Shopify – Founder, CEO

Dan Diemer

Member

12:08AM, Feb 14, 2007

can you also add a way to edit the variables of my pasta salad. I’d realllly like to strip out the olives in an easy fashion. =)

tobi

Shopify

12:45AM, Feb 14, 2007

{{pasta | stip_ingredients: 'italian' }} comign right up

---

Tobias Lütke
Shopify – Founder, CEO

Jeff

Member

09:39PM, Feb 15, 2007

Tobi, like to point me to info on creating patches for Liquid. I might take a shot at or/and in if, once I know what’s required…

george

Member

12:06PM, Mar 05, 2007

@Jeff – I assume you’d go here:
http://home.leetsoft.com/liquid

tobi

Shopify

03:43PM, Mar 05, 2007

that would be amazing jeff!

---

Tobias Lütke
Shopify – Founder, CEO

eric

Member

06:48AM, Apr 30, 2007

Here’s a patch that uses Jeff’s format for collapsing “when” statements:
http://home.leetsoft.com/liquid/ticket/382

---

Find a unique handmade greeting card.
http://www.cardsbyirene.com/

eric

Member

10:05PM, Apr 30, 2007

It looks like tobi has the “when” statement change I submitted up on Shopify now.

http://groups.google.com/group/liquid-templates/browse_thread/thread/e3d4f79803a6b041/48b0dd188ee52ec4#48b0dd188ee52ec4

Depending on interest, I may look at making the change for “if” statements as well.

---

Find a unique handmade greeting card.
http://www.cardsbyirene.com/

danW

Shopify Advisor

12:04AM, May 01, 2007

Nice work Eric. I have a few uses for this. Thanks.

tobi

Shopify

12:59AM, May 01, 2007

eric: thanks a lot for the great submission! Please have a look at if statements. Proper conditions support would be absolutely amazing.

I applied the patch as soon as i saw it but i also added comma as a seperator so you can use {% when 1,2,3 %} as well as {% when 1 or 2 or 3 %}

---

Tobias Lütke
Shopify – Founder, CEO

rawsterne

Member

02:23PM, Jul 05, 2007

Does anyone know if it’s possible to use the mod operator in an if statement, something like this…

{% if forloop.index mod 3 == 0 %}
{% else %}
{% endif %}

It compiles but throws up a liquid error.

A bit of background info…I’m looping thru a collection and want to do something to every 3rd product. The only other way I can think of is to have a huge case statement like this…

{% case forloop.index0 %} 
{% when 3,6,9,12,15,18,21,24,27,30,33,36...etc %>
do something...
{% else %} 
do something else...
{% endcase %} 

It’s a workaround, but it’s not ideal :(

Any ideas anyone?

tobi

Shopify

03:05PM, Jul 05, 2007

You can use the cycle tag for this.

{% cycle '', '', '</tr><tr>' %} for example

---

Tobias Lütke
Shopify – Founder, CEO

rawsterne

Member

03:31PM, Jul 05, 2007

doh! now why didn’t I think of that ;)

Thanks Tobi, works a treat

You must login to post a comment!

Don't have an account yet? Sign up for one.