Using interpolation with nunjucks and vue.js - 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.

Related

why do js liquid don't render product variable?

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

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.

How to iterate over the namespaces in the metafields using shopify liquid

In the "product.liquid" template, I want to expose all the metafields to my javascript code. Right now I have a namespace called "mystuff", so I did this...
// Copy all the METAFIELDS into the meta object
let meta = {
global: {{ product.metafields.global | json }},
mystuff: {{ product.metafields.mystuff | json }}
};
and this works. However, it requires me to know in advance all the namespaces and list them one per line. Can I get the list of namespaces programmatically, like this?
let meta = {
{% for ns in product.metafields.namespaces %}
{{ ns.name }} : {{ ns | json }},
{% endfor %}
};
I tried, but this does not work. Is there a way to do it?
Step back one level and iterate just Metafields, and you might be able to see the ones you are allowed to see. I believe as App developers we can finally hide our own Metafield namespaces from prying eyes, so YMMV here.
Note that your code trying to turn this result into JSON is not recommended either. Instead, get the namespace Metafields, iterate them, and each will have a type, key and value. You get JSON values too in some fields.

Jinja / Django for loop range not working

I'm building a django template to duplicate images based on an argument passed from the view; the template then uses Jinja2 in a for loop to duplicate the image.
BUT, I can only get this to work by passing a list I make in the view. If I try to use the jinja range, I get an error ("Could not parse the remainder: ...").
Reading this link, I swear I'm using the right syntax.
template
{% for i in range(variable) %}
<img src=...>
{% endfor %}
I checked the variable I was passing in; it's type int. Heck, I even tried to get rid of the variable (for testing) and tried using a hard-coded number:
{% for i in range(5) %}
<img src=...>
{% endfor %}
I get the following error:
Could not parse the remainder: '(5)' from 'range(5)'
If I pass to the template a list in the arguments dictionary (and use the list in place of the range statement), it works; the image is repeated however many times I want.
What am I missing? The docs on Jinja (for loop and range) and the previous link all tell me that this should work with range and a variable.
Soooo.... based on Franndy's comment that this isn't automatically supported by Django, and following their link, which leads to this link, I found how to write your own filter.
Inside views.py:
from django.template.defaulttags import register
#register.filter
def get_range(value):
return range(value)
Then, inside template:
{% for i in variable|get_range %}
<img src=...>
{% endfor %}

comparing custom template tag within if tag

i have a custom template tag that takes some argument and calculates the result.
I want to compare that value obtained from that custom tag with another variable.
Custom template tag(having three arguments)
{% price_for_pax service pax '' %}
variable :
{{service.price}}
What i want is
{% if service.price == price_for_pax service pax '' %}
do something
{% endif %}
When i look for the result it does not show anything
Can i compare like this ? If not what can be the solution ?
Thanks in advance
There were a couple of questions similar to this before:
Django - use template tag and 'with'?
django templatetags template , combine {{ }} method call with template tag context variable
Making a template filter rather than a template tag could do the trick.