why do js liquid don't render product variable? - shopify

I have, in product-template.liquid
<script src="{{ 'variant.js' | asset_url }}" defer="defer"></script>
And variant.js.liquid is this
alert('{{product.title}}');
But the render of variant.js is
alert('')
Do I need anymore for rendering?

You cannot include a script like that and expect that to be interpreted server side.
Or you do as suggested by Jahanzaib Muneer or you can do like this
<script>
{% render 'variant.js.liquid' %}
</script>

Unfortunately, js files are not supposed to run liquid and "js.liquid" files do not work.
It give us error:
MIME type ('application/x-liquid') is not executable
If you really want to get the liquid variable value in JS then you can use the Shopify Global JS variable.
As per your example:
Add this to your product template:
<script>
Shopify.product_title = '{{ product.title }}';
</script>
In your JS file use this:
console.log(Shopify.product_title);
Hope this will solve your problem.
Thanks

Related

Loading Shopify Product Metafields in snippets

I am trying to edit the default "Dawn" theme in my shopify store. My aim is to output product meta fields through a snippet. To do that, I have created a snippet called "color-swatches.liquid" which has the following code:
<div class="sw-external-links modification">
{%- if product.metafields.my_fields.current_product_color -%}
</div>
When calling this snippet from product-card.liquid, I use the following liquid code:
{% render 'color-swatches', product: product_card_product %}
But I am not able to output the value of current_product_color metafield inside product.
If I paste the snipped code directly in product-card.liquid like this, it works:
{{ product_card_product.metafields.my_fields.current_product_color }}
Can you please tell me what am I doing wrong? I just want the snippet code to output the current_product_color metafield when I pass the product_card_product variable to it.
Although there is not enough information in your question, I will try to help you the best I can.
In the snippet file (color-swatches.liquid), check if you're using the correct variable when accessing the product's metafield.
If you render your snippet (in 'product-card.liquid') like this:
{% render 'color-swatches', MY_PRODUCT: product_card_product %},
Then you should access the metafield (in 'color-swatches.liquid') like this:
{{ MY_PRODUCT.metafields.my_fields.current_product_color }}
Check that if statement.
In liquid, prefer the != blank syntax:
{%- if product.metafields.my_fields.current_product_color != blank -%}
Check if the if statement even works.
For that try to render the snippet outside the if.
If nothing is working double check yourself everywhere.
Do this using <script>console.log({{ YOUR_LIQUID_CODE | json }})</script> and check the browser's console to see the logs.
In both files, check the metafield, and the product.

Using interpolation with nunjucks and vue.js

I'm using nunjucks which compile mustache syntax like this : {{ value }}, and I'm using in the same time vue.js, which also use the same syntax for interpolation.
When I use interpolation to bind some value, nunjucks compile it first, which I want to be compiled by vue.js later and not nunjucks, so I was looking for something that I can do to skip interpolation for nunjucks, but with no luck.
A solution I can do here, is to use something else to print the value in vue.js without the use of interpolation, but it seems like it's the only why to print variables in the vue.
Any suggestions on how to solve this ?
There's two ways to do this. I prefer the first way.
1. Tell Nunjucks to ignore {{ }} for a specific portion of code
From the docs: If you want to output any of the special Nunjucks tags like {{, you can use a {% raw %} block and anything inside of it will be output as plain text.
{% raw %}
...put all your Vue template code in here...
{% endraw %}
2. Tell Vue to use different delimeters
new Vue({
el: '#app',
data: data,
delimiters: ["<%","%>"]
});
Then in your Vue templates, use <% someValue %> instead of {{ someValue }}.
Vue 3 has a slightly different syntax, but the concept is the same.

Handlebars VueJS escape img src

To use VueJS data variables in my hbs view engine I need to add this \ before the variable so it looks like this for example \{{name}} - this would show the name from vue data variable name.
Now I cannot find a way to do this with img src.
<div v-for="item in itemsImgArr">
<img src="{{item.img}}">
\{{item.img}} - returns me a normal img link
</div>
I have tried this option: <img src="\" + "{{ item.img }}"> but it doesn't work. I've tried to experiment but I cannot get the link. Maybe someone could help ?
So if anybody uses Handlebars with VueJS you can show images like this:
<img :src="item.img"> and it works perfectly!

How to show product object?

In Shopify if we print title of product then we can use like :
{{ product.title }}
If we want to show whole object that includes whole data of product how we can do this? Thanks in advance.
You can use the JSON filter .
If you like to output it directly on the frontend you use it like so: {{ product | json }}
But its much better to log it as a javascript object like so:
<script type="text/javascript">
console.log({{ product | json }});
</script>

Using Ember & Handlebars with Django 1.4.2

I'm trying to get Ember & Handlebars to work with Django 1.4.2 without much success. I'm using Django-ember (latest version from here): https://github.com/noirbizarre/django-ember, Handlebars.js (1.0.rc.1) & Ember.js (1.0.0-pre.2).
Following the Django-ember instructions, I've added 'ember' to the installed apps in settings, placed {% load ember %} at the top of my template, and then placed this in a block:
{% handlebars "application" %}
{{App.name}}
{% endhandlebars %}
where I've declared App with name variable in a js file.
The output is just blank however, no script tag is inserted as viewed in the browser console window (Chrome).
If I completely remove the javascript includes, the script tag is rendered - just with "{{App.name}}" left entact as expected. So it looks like, Ember/Handlebars isn't rendering the template correctly. Any ideas why?
A probably related quirk is that if I try
{% tplhandlebars "tpl-infos" %}
{{total}} {% trans "result(s)." %}
<p>{% trans "Min" %}: {{min}}</p>
<p>{% trans "Max" %}: {{max}}</p>
{% endtplhandlebars %}
it throws a template error about {% trans being an invalid tag. This can be fixed by including {% load i18n %} but seeing as this isn't in the Django-Ember instructions, I'm inclined to think this is a sign of a bigger problem; perhaps it's not designed to work with Django 1.4.2.
Update
Seems it was actually rendering after all but that it's wrapping it in a div and putting it right at the bottom of the page where I hadn't noticed it. So, now the next question is how do I get this back at it's orignal point in the html?