How to display product ingredients using metaobjects?


Here is a short video that describes my issue:

https://www.loom.com/share/30d72a3fd4d14a678c06f26aae83fd6c

Here is a visual of what I’m trying to achieve

I have created a metaobject called Product Overview (product_overview)

It contains various fields like product_ingredients

I have created metaobject entries where all the ingredients have been entered for a particular product.

I have created a custom product metafield (product.metafields.custom.product_overview) which contains the metaobject as its ‘type’ and references the metaobject entry that is specific to that product.

I have created a new Liquid Section (overview.liquid) in the default product page that contains HTML to display the values from the metaobject entry for the product in question.

I have the section schema correct - the product page customizer has loaded my overview.liquid section but it is not outputting the metaobject’s values so there is no HTML displaying.

I think my problem is that I don’t know how to reference the metaobject properly in the section’s liquid code.

Here is the first line of my overview.liquid section:

{% for product_overview in product.metafields.custom.product_overview.values %}

It is then followed by HTML like

{{ product_overview.product_ingredients }}

What am I doing wrong - how can I get the metaobject entry values for that product (and only that product) to display in the new section in the product page?

Thanks in advance.

1 Like

Quick glance you may need to also loop over the metaobject itself and it’s name+keys.

Re-review the docs:

https://help.shopify.com/en/manual/custom-data/metaobjects/

https://shopify.dev/docs/apps/custom-data/metaobjects

https://help.shopify.com/en/manual/custom-data/metaobjects/using-metaobjects#product-highlights-tutorial (when you add a dynamic source to some setting types, like rich-text, you can click the little text-button representing the DS and press ctrl+c to copy the underlying liquid syntax as text for use elsewhere)

Thanks Paul - taking a look at what you sent.

If I can’t figure this out can I pay you to just tell me the answer? I’m guessing it’s just one extra line of code.

Dan

Yes I do services like that it could be 1 or a few lines but figuring out the path can take stepping through the whole the setup and then checking the code, etc etc.

It can be more useful to first use a custom-liquid section in the visual theme editor to have a quicker REPL feedback on code-logic your trying to figure out instead of working in a code editor and flipping back and forth.

Good Hunting.

Thanks Paul,

I have tried that.

See this short video I just made:

https://www.loom.com/share/8f6e4318722b48edbde818578aff09d5

Click the inserted dynamic source UI element text-button and press ctrl+c that should give you the exact text it’s using, see screenshot.

When doing the shop.metaobjects approach try to see if there’s an {% if %} condition that would only output the info for current product, such as matching a keyword in the description or some .

That way if it works there’s something working while the proper syntax is figured out.

The custom-liquid is helpful to step through such things much more quickly and in smaller steps such as trying to just raw output the metafields data.

you can try this

{% for product_overview in product.metafields.custom.product_overview.value %}
{{ product_overview | json }}

{% endfor %}

1 Like

Thanks Paul,

I clicked on that inserted dynamic source from your screenshot. It doesn’t tell you what code was used to insert the content - it just takes you back to my product and says “here is the metafield I got the content from”

eg. https://www.loom.com/share/714751e462bc48f1ad11dd990538626e

I have tried the {% if %} method you described, tell it to only display results if the product handle matches a product handle entered into the metaobject. That works but it’s now not fully ‘dynamic’. I have multiple products that would use that metaboject entry because those products all contain the same ingredients. In order for me to make sure they all display and any future products I add with those ingredients, I would have to keep updating the metaobject definition to include more and more product handles.

Not the menu actions, copy the UI element’s underlying liquid-text with ctrl+c.

Under the hood it should :thinking: just be inserting liquid syntax the same as it does for metafield definitions. If so it’s also findable within either that JSON template’s file or the themes settings_data.json file depending on if a setting is for a section or global.

There’s also that more {% for %} loops may be needed they didn’t make these things easily chainable through dot notation.

https://shopify.dev/docs/api/liquid/objects/metaobject

Metaobjects still new and confusing so troubleshooting is subpar , abhi05’s got the similar idea break it down and output step by step though metaobjects don’t behave with some filters like most other objects.

If you can make a pared down simplified version of everything and share the steps along with code for other possible contributors. If I have time tomorrow I’ll try going through it in a dev store.

Thanks Abhi - I tried that, it didn’t work. See this short video:

https://www.loom.com/share/f78f7646d1bf45b8931950b7ade4de8a

Thanks Paul

I tried Abi’s suggestion. It didn’t work. I tried inspecting the code behind that UI element and all I could see was a whole pile of javascript which I don’t understand.

I will try and prepare a simplified version as you suggested so you can test it out in your dev store.

Why are you using metaobject in the first place?

From what I see, you just need to define the meta fields you need at the product level. It it way simpler and easy to work with.

Hi Ivan, thanks for responding.

:heart: Niki :heart: from ecommercepot.com was able to solve it.

We still use metaobjects as this actually makes things simpler. Instead of creating many metafields, I just create one metaobject and use it wherever I want.

Niki suggested I do not need the for loops and replaced it with this:

{% assign overview = product.metafields.custom.product_overview.value %}

So this creates a shorthand, wherever I include ‘overview’, liquid reads it as the full metafield reference ‘product.metafields.custom.product_overview.value’

So then where I have the following:

{{ **overview.ingredients_content** }}

Liquid understands that as:

go to the the metafield for this product that contains the ‘overview’ metaobject. Look inside that metaobject and output the content for ‘ingredients_content’

It worked perfectly.

Thanks
Dan

2 Likes

AFAIK you are going to create a meta-object for each product, as you are storing ingredients inside. And unless your products are exactly the same, ingredients will be different from one product to another.

From an architectural point of view, you should consider that Metaobject has its own lifecycle, different than a product. So you will run into a situation when you have orphaned metaobjects. And when a wrong metaobject is attached to a product.

To avoid this situation you must design the data store that lives and die with a product. In Shopify’s case, it would be meta fields. As they belong to a product and share the same lifecycle.

Just a point to consider, you know better what will or will not work for you.

1 Like

Thanks Ivan,

Yes, I understand what you mean.

With the metaobject I have incuded other attributes in addition to the ingredients.

I created one metaobject ‘definition’ and then for each product I created an ‘entry’ so there is one metaobject with many entries. Then the entry is attached to the product inside a product metafield.

So if the product dies, the link to the entry dies and there is no way that a dead entry can be displayed in the shop.

I also plan on including photographs of each ingredient so my metaobject will grow. Some products share some of the same ingredients so it will save time if the products take their ingredients all from the one place - one metaobject instead of having to create duplicates of certain ingredients over and over for each product. eg. every product contains “water”. With metaobject I create one ‘water’ entry and all products can share it.

If I used metafields only, I would have to create 47 copies of ‘water’.

Does that make sense?