Copy link to clipboard
Copied
So normally we might set a loop argument up like this:
{% for item in webapp1.items %}
But I want to set the argument (not sure if that's the right terminology) as a variable, so something like:
{% assign arg = 'items' %}
{% for item in webapp1.arg %}
...
or
{% assign arg = 'webapp1.items' %}
{% for item in arg %}
...
but this doesn't work (I'm assuming because the variable is treated as a string and not a true argument).
Is there any way to achieve the same idea?
Or some way to "convert" the variable into the right data type...?
I'm going to assume you want to do this within the large_product.html template - one way of doing this might be to approach it the following way:
...
{% for attr in this.attributes -%}
{% assign key = attr[0] -%}
{% assign values = attr[1] -%}
{% for value in values -%}
{{ value.id | prepend: "ID: " }}
{{ value.name | prepend: "Name: "}}
{{ value.displayType | prepend: "Display Type: " }}
{{ value.image | prepend: "Image: "}}
{{ value.price | prepend: "Price: "}}
Copy link to clipboard
Copied
The following should work - if you use quotation marks, or apostrophes it will assume it is a string - not an array like it is.
{% assign arg = webapp1.items -%}
{% for item in arg -%}
Also - I am just curious why do you want to put the items within their own variable? It seems like an unneccesary step in most situations to duplicate the work (especially if its a large amount of items).
Copy link to clipboard
Copied
Thanks Justin.
Ok, so that works (and I see why), however I reduced my example to simplify the question and my use case goes a little deeper.
Consider that my 'end result' variable is that I'm using is constructed by other variables, so:
{% assign part1 = 'webapp1' %}
{% assign part2 = '.items' %}
{% assign arg = part1 | append: 'part2' %}
{% for item in arg %}
...
Resulting in the argument being a string because of how it is constructed:
{% for item in "webapp1.items" %}
...
How do I force it to be seen as an argument and not a string?
I've tried converting it to a number and boolean just to see, but that doesn't work either.
The reason for doing this is because the for loops are looping collections/items that are variable and the names of those collections are sourced from a dynamic array.
So I'm using the above for loop within another for loop which has the array of variable I want to use (don't worry, the loops are only small - 4 or 5 items generally).
Something like:
{% for a in array %}
{% assign part1 = a.name %}
{% assign part2 = '.items' %}
{% assign arg = part1 | append: 'part2' %}
{% for item in arg %}
...
I need a way to join the arguments, like as in javascript it might be:
{% for a in array %}
{% for item in a + '.items' %}
...
but liquid doesn't work this way as far as I know.
Copy link to clipboard
Copied
Adam's after computed property keys. I did something similar recently:
{% assign thisProduct = webapp.items[0] -%}
{% for blockN in (1..9) -%}
{% assign keyPrefix = "Block " | append: blockN -%}
{% assign headingKey = keyPrefix | append: ": Heading" -%}
{% assign contentKey = keyPrefix | append: ": Content" -%}
<h1>{{ thisItem[headingKey] }}</h1>
<div>{{ thisItem[contentKey] }}</div>
{% endfor -%}
This goes through the custom fields of a webapp which are predictably named, like Block 1: Heading, Block 1: Content, Block 2: Heading etc etc.
Copy link to clipboard
Copied
Thanks Robert,
This looks very interesting... I'll try and wrap my head around this ![]()
I have another reply here to Justin's post giving more info on my issue, but it's being 'moderated' by the forum so it may be a while before it shows up... grrrr
Copy link to clipboard
Copied
Oh. looks like it's been approved now ![]()
Copy link to clipboard
Copied
Hey Adam,
Thanks for the Elaboration - I don't think given Adobe's build of liquid that we currently have the ability to do that with any filters - Shopify's Liquid has a Filter called Handleize that would do exactly what you are saying - but unfortunately it doesn't work on BC (Some of Shopify's Liquid filters do work on BC that havent been documented yet).So I think you may be out of luck at least with this avenue - could you maybe elaborate on your ultimate goal (Why you are constructing these out of two strings?)
Hopefully we can see if we can find a solution together here.
Copy link to clipboard
Copied
Thanks Justin,
My goal is to rebuild the attributes listing of a ecommerce product entirely with liquid. But I'm struggling here because of how the JSON data is output from BC (each attribute is an object inside the 'attributes' object named by their custom attribute name, they are not arrays within the object, so this is stumping me).
Looking ahead into my goal, I also see an issue with knowing the attribute type (checkbox, dropdown, radio...) as we only get that info from within each option rather then at the object level.
Then..... I can see that each options HTML 'name' attribute (ie: name="", not the text name) is not available in liquid, so this might be an issue also (need to do more tests here).
So there will be some challenges ahead but I thought I'd start here with the first one ![]()
Why am I recreating the attributes? Just for the fun of it
...and also to ultimately get full control over how we can present product attributes.
Maybe I'm looking at it all from the wrong angle. Happy to be shown a different way if so. This is pushing my coding comfort level.
In saying that, the initial problem by itself I'd like to solve regardless of my end goal if possible, as I've come across wanting similar before (variables/strings as arguments).
Copy link to clipboard
Copied
I'm going to assume you want to do this within the large_product.html template - one way of doing this might be to approach it the following way:
{% for attr in this.attributes -%}
{% assign key = attr[0] -%}
{% assign values = attr[1] -%}
{% for value in values -%}
{{ value.id | prepend: "ID: " }}
{{ value.name | prepend: "Name: "}}
{{ value.displayType | prepend: "Display Type: " }}
{{ value.image | prepend: "Image: "}}
{{ value.price | prepend: "Price: "}}
{% endfor -%}
{% endfor -%}
Essentially you could build the container (lets say you had a dropdown (you arent going to know until you get into the values of attribute - but Im going to assume you can only have one type of a value - So a Dropdown, Select or Radio List. on the last item of the array you can set the type based upon the DisplayType Variable... have a switch .. or even just check the first value of an attribute and set it before you loop through them... I would then have a switch that builds the appropriate "holder" such as <select> before and after the 2nd For loop - and within the 2nd for loop build the "options" using an item like <option> , also adding a Default "Please select an option" item...
You could really do this for a listing of products as well, this set of loops just needs to reside within a loop going through the products - hopefully this is helpful.
Copy link to clipboard
Copied
Awesome, that looks promising. Thank you!
It was the first key/value part that I wasn't up with, so I think that's making sense to me now...
And yes, your suggestion with looping first to check type and then looping to build the containers is where I was going to head too.
I have to check if not having the name attribute will be an issue though (I'm thinking it will be - with BC there's always one little simple bit that stuffs the whole thing!!!)
Thanks so much Justin and Robert for sticking with me and assisting. I'll post my findings here if I get it all working.
Copy link to clipboard
Copied
Just reading up on this for the first time.
1. Assign and things like module parameter passing do not support object data, If you find it does in some cases this is a lucky outcome but very likely also buggy. I have requested for these to support that as an idea on the developer forum.
2. The related product attribute output by default in liquid is a bit broken, this is something I also raised and BC have got back to. You will find important data for the scripting to work missing etc. You can not fully build the attributes output in liquid to be feature parity at this time so do not try. I have, BC been told, waiting for updates ![]()
3. You can do a bit more with module_data on product large layout, but again this actually has some missing data you need for the BC scripting to work. your other option is to have a full understanding of the script to server BC calls and completely rebuild the BC scripting BUT again, you got some missing data you need to complete it fully. (Again I tried that too)
Hope that helps.
Copy link to clipboard
Copied
Thanks Liam, all good to know.
1. Ok, understood.
2. I've so far only found one piece of critical info missing in the liquid data and that is the mandatory state - but I've found a fairly smooth workaround for this.
As for the BC scripts not being loaded for the attributes module, what I did here was still include the module on the page but just comment it out or hide it (HTML comments not liquid comments). That way BC still loads the scripts it normally would.
To combat duplicate IDs on the form fields I just made sure the module was below my custom form in the code and it seems the first encountered ID is honoured while following duplicates ignored (I'm assuming at this point all browsers behave the same in this regard... haven't tested cross browser yet)
So at the moment (early days though) I have a working model that I haven't been able to break yet.
I haven't touched inventory/product variation yet but I'm thinking that probably has nothing to do with the front-end so should hopefully still work fine if those options are turned on.
I'd be interested in sharing the code with you once I'm finished to run your eye over it to either validate it works or fine any holes if you're keen?
3. Understood. I haven't look down the module_data avenue yet but thinking perhaps it could be used in conjunction with my current solution to properly plug the gaps with the mandatory state and any inventory/variation issues encountered???
Copy link to clipboard
Copied
With 2 Adam you need to look at it more closely..
- How does BC know to associate attributes, how BC knows to attach to the product, how the pricing and SKU stuff works with attributes and associated product and so on. Your missing quite a bit (about 4/5 things) to make those work properly. Face value you may get an output for example, add to cart though - you wont see attributes come through etc. Look at it carefully - more them eats the eye and you will see what I mean.
This is experience, I know ![]()
Your doing something I did a year ago and the data is still not there.
Get ready! An upgraded Adobe Community experience is coming in January.
Learn more