Liquid Warning: Unexpected character - syntax-error

To assign class depending on page category I have following in my code:
{% assign category_class = 'category-' | append: {{ page.category }} %}
As expected I get <div class="category-sometext". But when building I also get warning about an unexpected character in this line.
What's wrong and how I can fix it?

You need to remove the {{ }} around page.category as you are already inside {% %}. So:
{% assign category_class = 'category-' | append: page.category %}

Related

Replace Filter - How to pass a variable for the string to be replaced?

I am currently working on a symfony 6 project and try to pass a variable into a replace filter from Twig. However that does not work for me.
I tried it like this:
{% if form.vars.data.fileName|default %}
{% set system_type_short = get_env("SYSTEM_TYPE_SHORT") %}
{% set replaces = '/var/www/' ~ system_type_short ~ '.domain.de/public/uploads/images/' %}
{% set url = 'uploads/images/' ~ form.vars.data.fileName|replace({(replaces): ('')}) %}
<img src="{{ asset(url) }}" height="100"><br><br>
{% endif %}
The error I get:
A hash key must be followed by a colon (:). Unexpected token "punctuation" of value "{" ("punctuation" expected with value ":").
Can anyone tell me what I am doing wrong or how to pass a variable into the filter function "replace"?
You cannot use the variable syntax ({{ }}) when already in a twig expression.
So you just have to fix {{system_type_short}} and use string concatenation ~ instead.
You would get:
{% if form.vars.data.fileName|default %}
{% set system_type_short = get_env("SYSTEM_TYPE_SHORT") %}
{% set url = 'uploads/images/' ~ form.vars.data.fileName|replace({('/var/www/' ~ system_type_short ~ '.domain.de/public/uploads/images/'): ''}) %}
<img src="{{ asset(url) }}" height="100"><br><br>
{% endif %}

working with 'strings' as 'arrays' in shopify liquid

I am trying to display color boxes next to items based on item varients. However, it has been giving me weird results in my array. Yes I know there are no real arrays in liquid. I have two options below. The first one doesnt work. It gives me things like "background-color: [''''''' ". Along with all the correct ones too.
So the second option i just hard coded all the colors and checked against that. This works as long as the colors are in order... but if the colors are not in order than it will display duplicates.
New to liquid but this seems super ugly and probably means i am doing it wrong.
<div class="color-box-wrapper">
{% assign values = '' %}
{% for variant in product.variants %}
{% assign value = variant.option2%}
{% unless values contains value %}
{% assign values = values | append: ',' | append: value %}
{% assign values = values | split: ',' %}
{% for color in values %}
{% if color.size > 0%}
<div class="product-color-box" style="background-color:{{color}}"></div>
{% endif %}
{% endfor %}
{% endunless %}
{% endfor %}
</div>
THIS WAY KINDA WORKS BUT SEEMS HACKY.
<div class="color-box-wrapper">
{% assign realColors = 'yellow, blue, white, burgandy, black, red, green, purple, beige, light_brown' | split: ", "%}
{% assign values = '' %}
{% for variant in product.variants %}
{% assign value = variant.option2 | downcase%}
{% unless values contains value %}
{% assign values = values | append: ',' | append: value %}
{% assign values = values | split: ',' %}
{% for color in values %}
{% if realColors contains color %}
<div class="product-color-box" style="background-color:{{color}}"></div>
{% endif %}
{% endfor %}
{% endunless %}
{% endfor %}
</div>
It might work better to use the product.options_with_values field, something like this:
{% assign color_option = product.options_with_values | where: 'name', 'color' | first %}
<h1>Color option is in position {{ color_option.position }}!</h1>
<h2>Array of all values is: {{ color_option.values | json }}</h2>
{% for value in color_option %}
<h3>Gimmie a {{ value }}!! {% if value == color_option.selected_value %}(Selected){% endif %}</h3>
{% endfor %}
It's a bit trickier if your colours are not CSS-recognized colour names, but there are certainly a number of things you can do for that. I typically prefer adding a CSS layer that can translate colour values into the appropriate display values (either background images or colour hex-codes). Some ideas are:
Add a data attribute or a class to your element (usually using the | handle filter to standardize the output) and use a CSS sheet to assign background images or colours appropriately
Create a section with blocks that allows you to map colour values to hex codes. If you are creating this for someone other than yourself, it would allow the merchant to set up the colours themselves and fine-tune all the shades.
Use metafields on your product that can generate the correct colour code using the options as the lookup. (Eg: If you create a metafield namespace on your products of product.metafields.colors and use the colour names as the keys and hex codes as the values, you can output {{ product.metafields.colors[value] }} to get the right computer colour. (This generally requires installing an app to manage - though metafields themselves are native Shopify functionality, Shopify doesn't have any native way to set them in the admin)
Hope this helps!
References:
Shopify Liquid Reference - Product objects: https://help.shopify.com/en/themes/liquid/objects/product#product-options_with_values
Shopify Liquid Reference - Product Option objects (from options_with_values): https://help.shopify.com/en/themes/liquid/objects/product_option

Shopify Line item variants in separate lines

Currently in my shopify code I can use a line item input like so:
line_item.variant.title
This will output the following:
Snapback / One Size Fits All / Camo
What I'm trying to do is to break up each one into it's own line. So I can get this back:
Snapback
One Size Fits All
Camo
The challenge is that there are several products with different variants. Some contain the string "7/9" so I wouldn't be able to use "/" as a delimiter. Any suggestions?
The variant title is generated based on the variant options.
So if you like to show the different options you just call the options instead of the title.
Example:
{{ variant.option1 }}<br/>
{{ variant.option2 }}<br/>
{{ variant.option3 }}
Refer to the docs here: https://help.shopify.com/en/themes/liquid/objects/variant#variant-option1
I found this one is a better solution to set this dynamically:
{% if line.variant.title != 'Default Title' %}
<span class="order-list__item-variant variant-title">
{% assign variantOptions = line.variant.title | split: ' / ' %}
{% assign count = 0 %}
{% for option in line.product.options_with_values %}
<span><b>{{ option.name }} :</b> {{variantOptions[count]}}</span>
<br />
{% assign count = count | plus: 1 %}
{% endfor %}
<br />
</span>
{% endif %}
As by default, we are getting / in the value of line.variant.title. So we need to split this first So that we can get individual option values. and because there is no feasible object to get option label so we need to use the
line.product.options_with_values in a loop and iterate and set label with value as in the above code.
So, just use this code in your order confirmation email and you will get the format in the email as follow. Here Embroidery as yes and no. and Border as Zigzag and Simple are the options for product variants.

Variable alias in a for cycle with Jinja2

I have this code inside my html:
{% for macchine in range(20) %}
{% set macchina_usata = 'M'+ macchine|string %}
{{ data['macchina_usata'] }}
{% if data['macchina_usata'] is defined %}
do something..
{% endif %}
{% endfor %}
before it was without the for cycle, I just had to check if a variable is defined and I got the result, but now I want to put it in a Cycle for because I have to check 20 or more variables.
The variables that I got from the previous html are like M1, M2, M3, ... M20 then I thought that was a good idea to create a varible macchina_usata composed by M+ the int macchine converted in a string, but when I try to print it nothing happen, so, i guess that I'm using the Alias in a wrong way
You're using the literal string 'macchina_usata' as an index for data. You should instead use variable macchina_usata, without the quotes:
{{ data[macchina_usata] }}
{% if data[macchina_usata] is defined %}

Using a string to create a Liquid variable

In my shopify store, I am using SuperFields in order to customize my site, though my question isn't about the app. On one of my pages, I need the value for the following:
variant.metafields.sf_{{ collection.title | downcase }}[meta_tag_key]
The value should be 0 or 1. If I evaluate the statement directly, such as:
{if variant.metafields.sf_{{ collection.title | downcase }}[meta_tag_key] =1%}
It throws an error when I render the page: Unexpected character '{'
I've also tried the following:
{% capture defaultImage %}variant.metafields.sf_{{ collection.title | downcase }}[meta_tag_key]{% endcapture %}
{% assign test = defaultImage %}
But 'test' is considered nil and doesn't return any value. I have tried to search for answers here and on the shopify forum, but, as my clumsy post title suggests, I'm having a hard time concisely searching for a solution to this problem. Any help is greatly appreciated.
You can try :
{% assign metafield-key = collection.title | downcase | prepend: "sf_" %}
{% assign key = variant.metafields[metafield-key][meta_tag_key] %}
{% if key == 1 %}
Do the twist !
{% endif %}
You are missing a % sign in your code. Hence the error message. Your if statement started with {% and not just {
If you working in liquid then you have to use {% %} for defining any variable & also for condition in shopify. You can't use { this.