Can I use liquid inside JS file? - javascript

I'm using Shopify and I need to show some message if specific product tag is exist. I need to check for product tags from JS file and need to know how can I do that.
I tried to use {{product.tags}} in the js file but I got an error, I also tried that in .js.liquid file and it still throw an error.
{% assign clearance = false %}
{% for tag in product.tags %}
{% if tag contains 'Clearance' %}
{% assign clearance = true %}
{% endif %}
{% endfor %}
There is a way that I could use that in js? If not, how can I grab all product tags in js way? I know I can do that from liquid file but I have to do that only in the js file.

You are probably looking for an extension to Javascript called jsx.
Aside from that, natively, you have template literals, but you can only use expressions in that, no looping or other logic (aside from ternary expressions).
If what you are looking for is not related to creating HTML, but only to modifying a variable (or executing other code on data), you can use standard Javascript:
let clearance = false;
for (const tag in product.tags) { // this assumes product.tags is an object
for (const tag of product.tags) { // this assumes product.tags is an array
if (tag.includes('Clearance') {
clearance = true;
}
}

The .js.liquid file will only accept translation string as var in Liquid (example: {{ "my_text" | t }}.
If you want to use other kind of Liquid strings in Javascript code, you may use a section and include your javascript inside {% javascript %} tags.
This will also work in a snippet or a template.

Related

Twig - Showing/Hiding Element Based Upon Date

I am looking to customize a Twig template by making the display of an element (i.e. a url link) sensitive to the current date. As I'm fairly new to Twig, would Twig have any in-house ways to facilitate this, or would I most likely utilize some Javascript to achieve this?
Thanks for any leads.
You could use the date-filter and the special keyword NOW to achieve this
{% if "NOW"|date('U') > '2018-06-10'|date('U') %}
Show this
{% endif %}
{% if "NOW"|date('U') > '2029-06-10'|date('U') %}
Don't show this
{% endif %}
do note that you could just pass the date as a DateTime to your template to avoid the static code in the template`

Shopify - using if statements within js.liquid and scss.liquid files

I am trying to merge JS files together in 1 file, however I need to set conditions using the if statements within the js file.
I have created file.js.liquid but it does not seem to working; I added a test for example:
{% if template contains 'index' %}
console.log('homepage loaded');
{% endif %}
Example of what i am trying to do, of course have plenty i need to do.
{% if settings.the_simpsons_enabled and settings.simpsons_video_enable %}
// video popup
$(".video-popup").videoPopup();
{% endif %}
The conditional statements are also not working within scss.liquid files either:
{% if template contains 'index' or template contains 'collection' or template contains 'product' %}
#import url("{{ 'owl.carousel.scss' | asset_url }}");
{% endif %}
Any ideas why if would not be working or if its even possible? I assume it is being a liquid file.
The Liquid extension on such files like CSS or JS allows use of Liquid variables but not statements.
So {{ write_my_liquid_var_here }} will work. {% if liquid_statement %}do something{% endif %} won't.
Regarding Shopify and SASS
The following won't work as you can't use #import in Shopify's SASS files.
#import url("{{ 'owl.carousel.scss' | asset_url }}"); //This will not work
Regarding using conditional liquid statements in .js.liquid files
I don't know everything about this subject, but I do know the following two things.
1) Check out this thread and you'll see that this type of statement won't work because js files are parsed independent of normal liquid templates, so it would have no idea which template you're viewing.
{% if template contains 'index' %} //This will not work
A better place to put the above logic would be at the bottom of your theme.liquid file above the </body> tag. However this won't help you with what seems to be your goal of reducing HTTP requests by using one JavaScript fie.
2) However, you can access values in your settings_data.json file
{% if settings.the_simpsons_enabled and settings.simpsons_video_enable %} //This will work
I hope this helps

How to include properly Javascript using a Javascript Twig Template

I know how to access my assets, but i wanted to create a template working with Javascript and Twig, which would allow me to use Twig variables in my script.
For example, I have a template called 'details.html.twig', which extends a 'layout.html.twig':
{% extends '#AcmeBundle/Front/layout.html.twig %}
{# SOME CODE AND CONTENT #}
{% block page_script %}
{{ parent() }}
<script>
{# Part of my script #}
</script>
{% endblock page_script %}
All of this worked perfectly, but to be able to reuse some js code (using twig variables), I cut some part of my script and put I in an external template, called 'viewer.html.twig'. To be able to use it in my 'details.html.twig', I used:
{% include '#AcmeBundle/Front/Model/viewer.html.twig' %}
I put this line right after the {{ parent() }} one and before the <script> tag.
However, my script which used to work when directly written in 'details' template seems to be quite ignored right now.
If any of you could have a clue of what makes my template being included but skipped, or a way to include the template easier or properly, I'm open to all kind of observations.
G'day,
Jérémy
If you code a file containing only javascript you should name your file:
{% include '#AcmeBundle/Front/Model/viewer.js.twig' %}
Then Twig (as of 1.17) automatically defines its escaping strategy based on the extension.
See the twig docs and an example of js twig file in symfony.

How to render a component with dynamic content in a page using an npm-based static site generator?

The goal is to render a component with dynamic content in a page using an npm-based static site generator:
I can't seem to find a solution to this in in Harp, Brunch or Metalsmith. I have been playing with each of these and it feels like I am going about this the wrong way.
The structure will be something like:
/pages
|_ home.??
|_ about.??
/partial
|_ header.??
|_ body.??
|_ portfolio-item.??
/data
/home
partial-1.??
partial-2.??
partial-3.??
partial-4.??
Now I need home to include each partial with the data passed to the partial.
//home.??
include header with partial-1
include body with partial-2
include portfolio-item with partial-3
include portfolio-item with partial-4
And each partial needs markup:
//portfolio-item.??
<p>
{{project-description}}
</p>
And each data item needs to have the relating id for data:
//sort of like json
{
project-description: whatever i need
}
Why do this? I want to:
Separate markup from data
Have files act like a CMS
Speed up development as I am not copying partials around if I am reusing them. (For example, harp supports unique values for files but not reusing files with unique values)
Any tips will be great! I think jade or Ejs might be solutions, but the data might have to be manipulated by some custom code. This, however, feels like someone has done this before.
After #MikeC pointed me in the direction of Jekyll I went ahead and explored it.
By using the documentation I came up with the following solution to the problem:
The standard Jekyll structure is was used.
We must make the builder partial that will add components from data files
{% assign page_data = site.data.[page.context] %}
{% assign counter = 0 %}
{% for partial_name in page_data.partials %}
{% assign counter = counter | plus:1 %}
{% include {{ partial_name }}.html %}
{% endfor %}
In about.md add the following
---
layout: page
title: About
context: about
permalink: /about/
---
{% include builder.html %}
Then add a partial that you would like to test on like _includes/hello-text.html.
{% capture data_file %}{{ page.context }}-{{ counter }}{% endcapture %}
{% assign context = site.data.[data_file] %}
<p>
{{ context.content }}
</p>
Finally add your data files _data/about.json
{
"partials": ["foobar", "foobar", "foobar"],
}
and _data/about-1.json
{
"content": "helloworld"
}
You can add about-2.json for the second partial and so on. I would still appreciate any improvements on this issue if anyone has any suggestions you can check out the repo on github to bash it out.

Django, html tags not interpreted

I am loading a text from the DB of a django project to display it in the template.
In the text stored within the data base, I added some HTML tags but it seems like the browser cannot interprete this html tags.
Here is my template:
<div>
<!-- body_text = "<strong>Hello</strong> word" -->
{{ entry.body_text }}
</div>
And I got the raw text: <strong>Hello</strong> word instead of
<strong>Hello</strong> word
What I am doing wrong?
If you don't want your HTML to be escaped, use safe filter:
{{ entry.body_text|safe }}
django doc about safe filter.
You can also try this:
{% autoescape off %}
{{ your_html_content }}
{% endautoescape %}
From django docs for autoescape:
Controls the current auto-escaping behavior. This tag takes either
on or off as an argument and that determines whether auto-escaping is in effect inside the block. The block is closed with
an endautoescape ending tag.
When auto-escaping is in effect, all variable content has HTML
escaping applied to it before placing the result into the output (but
after any filters have been applied). This is equivalent to manually
applying the escape filter to each variable.
As pointed out in the other answer, you can also use safe filter which:
Marks a string as not requiring further HTML escaping prior to output.
When autoescaping is off, this filter has no effect.
See here: safe filter.
Read more about django template tags and filters: Django Built-in template tags and filters

Categories

Resources