Liquid, JavaScript, themes, sales channels
Hello there, everyone!
I'm trying to create a loop to generate 'rows' for a table using metafields for each of the data points. I know there's a tablerow loop in Liquid, however it won't work well with the current codebase since we're not able to use HTML tables due to very specific technical limitations.
That being the case, I'm trying to generate rows as divs dynamically using the forloop index as a variable on the metafields themselves, because the only thing that changes on the metafield handle for each datapoint is the number as you can see in the code below. That way the logic can be written once instead of having to do it in a super repetitive way (and also not dynamic).
The issue is that when the page is rendered, instead of rendering the value of the metafields themselves, it's rendering the metafield path as a string directly to the front end:
Here's my current code:
{% assign rowLimit = product.metafields.global.row-count %}
{% for i in (1..rowLimit) %}
{% capture tableLength %}
product.metafields.global.table-length-{{ i }}
{% endcapture %}
{% capture tableWidth %}
product.metafields.global.table-width-{{ i }}
{% endcapture %}
{% capture tableThickness %}
product.metafields.global.table-thickness-{{ i }}
{% endcapture %}
{% capture tableVolume %}
product.metafields.global.table-volume-{{ i }}
{% endcapture %}
{% if tableLength %}
<div id="w-node-0ee9c7b704a0-ffe50a8f" class="table-row">
<div class="table-text">{{ tableLength }}</div>
<div class="table-text">{{ tableWidth }}</div>
<div class="table-text">{{ tableThickness }}</div>
<div class="table-text">{{ tableVolume }}</div>
</div>
{% endif %}
{% endfor %}
I believe the liquid variable is being processed and returning the variable's value as a string which is then the output to the browser. How can I process the value of the variable and then use it inside {{ }} for example to process the actual metafield path instead of a string?
I would really appreciate it if you would help me figure this out!
Thanks in advance and have a great day!
Solved! Go to the solution
This is an accepted solution.
Not tested but it should work:
{% assign key = 'table-thickness-' | append: i %}
{{ product.metafields.global[key] }}
This is an accepted solution.
Not tested but it should work:
{% assign key = 'table-thickness-' | append: i %}
{{ product.metafields.global[key] }}
{% assign rowLimit = product.metafields.global.row-count %}
{% for i in (1..rowLimit) %}
{% assign tableLength = 'table-length-' | append:i %}
{% assign tableWidth = 'table-width-' | append:i %}
{% assign tableThickness = 'table-thickness-' | append:i %}
{% assign tableVolume = 'table-volume-' | append:i %}
<div id="w-node-0ee9c7b704a0-ffe50a8f" class="table-row">
<div class="table-text">{{ product.metafields.global.[tableLength] }}</div>
<div class="table-text">{{ product.metafields.global.[tableWidth] }}</div>
<div class="table-text">{{ product.metafields.global.[tableThickness] }}</div>
<div class="table-text">{{ product.metafields.global.[tableVolume] }}</div>
</div>
{% endfor %}
Thanks a million once again, @Mircea_Piturca !
Have a great one : )
Yes, Liquid is cool like that!
You can access object's properties by using the dot notation or the bracket notation. Same as in JS.
Happy to help out
Hi Fernando and Mircea,
I'm having a similar problem but this approach isn't solving it for me. It's either returning nothing or weird obj like {"11053187399853"=>"rx requested 2x"}. Would greatly appreciate any advice.
My problem: I want to store specialized line item fulfillment statuses that a user will see when viewing an order. (Client has a complicated flow for insurance and prescription verifications with like a dozen Salesforce statuses.) The LineItem object does not have metafields, so I want to store them in Orders using the line item ID as the metafield key.
The idea is that I can then programmatically update statuses via API and display them via Liquid. However, I'm having a devil of a time getting the liquid side to work.
An example metafield as seen in GraphiQL:
"metafields": [
{
"id": "gid://shopify/Metafield/20905653272749",
"namespace": "sfc",
"key": "11053187399853",
"value": "RX Requested 2x",
"createdAt": "2022-02-23T07:12:39Z",
"updatedAt": "2022-02-23T07:12:39Z"
}
In a loop of
{%- for line_item in order.line_items -%}
I tried your method, but it would not return a value. When I tried a few different workarounds, the best I've come up with gives me a strangely formatted string instead: {"11053187399853"=>"rx requested 2x"}
I have the following example tests:
{% capture line_txt %}
{{ line_item.id }}.value
{% endcapture %}
{% capture line_ind %}
['{{ line_item.id }}']
{% endcapture %}
{% assign lid = {{line_item.id}} %}
{% assign no_frills = order.metafields.sfc.{{ line_item.id }}.value %}
{% assign no_frills_ind = order.metafields.sfc['{{ line_item.id }}'] %}
{% assign test_case = order.metafields.sfc.{{ line_txt }} %}
{% assign test_ind = order.metafields.sfc{{ line_ind }}} %}
<script>
window.cases = {{ order.metafields.salesforce.cases }}
</script>
<p>counter: 35</p>
<p>no frills: {{ no_frills }}</p>
<p>no frills ind: {{ no_frills_ind }}</p>
<p>test case: {{ test_case | capitalize}}</p>
<p>test index: {{ test_ind }}</p>
<p>indirect dot: {{ order.metafields.sfc.[line_txt] }}</p>
<p>lid dot: {{ order.metafields.sfc.[lid].value }}</p>
<p>indirect ind: {{ order.metafields.sfc[line_ind] }}</p>
<p>direct: {{ order.metafields.sfc.11053187399853.value }} </p>
<p>direct ind: {{order.metafields.sfc['11053187399853'] }}</p>
<p>test is still json: {{ test_case['11053187399853'] }}</p>
Which give me these results:
counter: 35 no frills: {"11053187399853"=>"RX Requested 2x"} no frills ind: test case: {"11053187399853"=>"rx requested 2x"} test index: {"11053187399853"=>"RX Requested 2x"} indirect dot: lid dot: indirect ind: direct: RX Requested 2x direct ind: RX Requested 2x test is still json: RX Requested 2x |
If you're able to give any guidance at all, I'd greatly appreciate it! I've been banging my head on the desk over this one.
For anyone else who has similar problem. The arrow function looking thing I'm pretty sure was Ruby hash rocket getting passed b/c of bad key.
Source of my problem was type. The key was an integer instead of string, and my attempts to convert to string were failing quietly. But not entirely, so I was getting hash rocket instead of the value.
Anyway, this worked:
{% capture line_txt %}
{{ line_item.id }}
{% endcapture %}
{% assign str_id = line_txt | strip %}
<p>str id: {{ order.metafields.sfc.[str_id].value }}</p>
Are you ready to take your business to the next level? Look no further than the latest ...
By SarahF_Shopify Apr 15, 2024We’re keeping the ball rolling to make sure you’re always ahead of the game. So buckle ...
By JasonH Apr 8, 2024Portrait of Stephen positioned next to an image of planet Earth, with the Stephen's World ...
By JasonH Mar 18, 2024