Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access JSON lumps in metafields with Shopify Liquid templates

I was wondering if anyone knew if I can access JSON in Liquid such as the example below.

I have created a metafield for the suppliers page with the namespace suppliers_details, with the key suppliers and the value:

{
  name: "Supplier Name One",
  address: "Supplier Address One"
},
{
  name: "Supplier Name Two",
  address: "Supplier Address Two"
}

In the template I have:

{% assign suppliers = page.metafields.suppliers.suppliers %}
{% for supplier in suppliers %}
  <p>{{ supplier.name }}</p>
  <p>{{ supplier.address }}</p>
{% endfor %}

This doesn't work as I can't change the data into a format the the template can use to iterate through, is there a way to do this?

Cheers

like image 838
Tom Hamilton Stubber Avatar asked Nov 14 '16 22:11

Tom Hamilton Stubber


4 Answers

Shopify has since deprecated the "json_string" metafield and supplied a "json" metafield option.

To access the data using dot notation, you need to use .value after the key.

For example, if I have this JSON:

{
  name: "Supplier Name One",
  address: "Supplier Address One"
},
{
  name: "Supplier Name Two",
  address: "Supplier Address Two"
}

I would access it like this:

{% assign suppliers = page.metafields.suppliers.suppliers.value %}
{% for supplier in suppliers %}
  <p>{{ supplier.name }}</p>
  <p>{{ supplier.address }}</p>
{% endfor %}
like image 114
Kohlmann Kearley Avatar answered Nov 18 '22 03:11

Kohlmann Kearley


There is no way to parse a JSON using Liquid or at least not a default way.

You can write some code to split it into parts, but you won't be able to chain the objects:

{% capture string %}{name:"Supplier Name One",address:"Supplier Address One"},{name:"Supplier Name Two",address:"Supplier Address Two"}{% endcapture %}

{% assign jsplit = string | replace: '},{', '@@' %}
{% assign jsplit = jsplit | replace: '{' %}
{% assign jsplit = jsplit | replace: '}' %}
{% assign jsplit = jsplit | split: '@@' %}

{% for json in jsplit %}
  {% assign splitByComma = json | split: ',' %}
  {% for comma in splitByComma %}
    {% assign splitByDots = comma | split: ':' %}
    <p>{{ splitByDots[1] }}</p>
  {% endfor %}
{% endfor %}

You will get the wanted result, but not the same way you imagined it.

The best approach will be to pass the string to Javascript, parse it there and populate the DOM via JS.

like image 20
drip Avatar answered Nov 18 '22 04:11

drip


This is now supported and is a game changer! Shopify released a new metafield format type called "json_string" that lets you directly access the value of each node via normal liquid dot notation. I know this will make EVERYONE'S life easier. Taken from the documentation (https://help.shopify.com/en/themes/liquid/objects/metafield):

https://help.shopify.com/en/themes/liquid/objects/metafield

Here was one of the initial posts from a Shopify developer on the Shopify forums that may help: https://ecommerce.shopify.com/c/api-announcements/t/new-json_string-value-type-for-metafield-object-540896

like image 28
dave4jr Avatar answered Nov 18 '22 05:11

dave4jr


I think it is working now, below is my json , it is product metafield & valueType is json string

[ 
   { 
      "question":"hello this is question",
      "answer":"Hello This is answer"
   },
   { 
      "question":"hello this is question2 ",
      "answer":"Hello This is answer 2"
   }
]

Blow is liquid code

{% assign qas = product.metafields.manifester.product_qa %} // product.metafields.{namespace}.{key}

{% for qa in qas %}
  <div style="border-bottom: 1px solid #222222;">
    <p> {{ qa.question }} </p>
    <p style="font-weight:bold"> {{ qa.answer }} </p>
  </div>
{% endfor %}
like image 2
Bhargav Kaklotara Avatar answered Nov 18 '22 04:11

Bhargav Kaklotara