How to change the background color for individual rows in a collapsible content menu in liquid? - shopify

I'm just getting used to liquid and can't for the life of me figure out how to input the code to assign a color for each row in an accordion style collapsible menu.
I've managed to make the schema for the theme editor but can't get it to control the liquid.
I'm thinking it belongs where I've written [HERE] below but have no idea. If anyone could help I would super appreciate it!
Code below:
{% endif %}
<div class="grid__item">
{%- for block in section.blocks -%}
[ HERE?? ]
<div class="accordion{% if section.settings.layout == 'row' %} content-container color-{{ section.settings.row.color }} gradient{% endif %}" {{ block.shopify_attributes }}>
<details id="Details-{{ block.id }}-{{ section.id }}"{% if section.settings.open_first_collapsible_row and forloop.first %} open{% endif %}>
<summary id="Summary-{{ block.id }}-{{ section.id }}">
{% render 'icon-accordion', icon: block.settings.icon %}
<h3 class="accordion__title h4">
{{ block.settings.heading | default: block.settings.page.title }}
</h3>
{% render 'icon-caret' %}
</summary>
<div class="accordion__content rte" id="CollapsibleAccordion-{{ block.id }}-{{ section.id }}" role="region" aria-labelledby="Summary-{{ block.id }}-{{ section.id }}">
{{ block.settings.row_content }}
{{ block.settings.page.content }}
</div>
</details>
</div>
{%- endfor -%}
</div>
Schema I created:
{
"type": "color",
"id": "row_color",
"default": "#FFFFFF",
"label": "Row Color",
"info": "Changes color for this individual row"
},

You can access the section block schema data like this:
{{ block.settings.id }}
id is the ID you defined for the specific setting, in this case it would be row_color.
In conclusion:
{{ block.settings.row_color }} // Returns either your default value `#ffffff` or the one selected in the customizer

Related

Can't add image via Liquid in Shopify section

I already read the tutorial, documentary and looked for similar questions. I'm following instructions as I understood them, but I'm missing something here. I'm trying to add the possibility to add an image into a section. I can add an image in the backend, but it won't show.
The position the image with the id badges1 should be loaded:
{%- when 'badges' -%}
<div class="footer-block__details-content footer-block-badges {{ block.settings.alignment }}">
{%- if block.settings.badges1 != blank -%}
{{ block.settings.badges1 | img_url: '160x160', scale: 2 | img_tag: block.settings.badges1.alt }}
{%- else -%}
{{ 'logo' | placeholder_svg_tag: 'placeholder-svg' }}
{%- endif -%}
</div>
{%- endcase -%}
The Setting:
{
"type": "badges",
"name": "Badges",
"settings": [
{
"type": "image_picker",
"id": "badges1",
"label": "Image"
},
{
"type": "image_picker",
"id": "badges2",
"label": "Image"
}
]
}
You are trying to call block in your template code and block is missing in your schema setting.
Use this code in your template code:-
{%- when 'badges' -%}
<div class="footer-block__details-content footer-block-badges {{ block.settings.alignment }}">
{%- if block.settings.badges1 != blank -%}
<img class="if1img" src="{{block.settings.badges1 | img_url: '160x160' }}" alt="{{block.settings.heading1}}" />
{%- else -%}
{{ 'logo' | placeholder_svg_tag: 'placeholder-svg' }}
{%- endif -%}
{%- if block.settings.badges2 != blank -%}
<img class="if1img" src="{{block.settings.badges2 | img_url: '160x160' }}" alt="{{block.settings.heading2}}" />
{%- else -%}
{{ 'logo' | placeholder_svg_tag: 'placeholder-svg' }}
{%- endif -%}
</div>

Referencing a product in Shopify

I'm developing a Shopify website for a client who wasn't happy with the native related products section.
I started developing a custom section where my client can choose the products to display.
The only problem is I'm having a hard time find documentation relative to the product object. Or at least not understanding it well.
In my schema I added a product setting which allows to choose the product I want:
{
"type": "product",
"label": "Produit 1",
"id": "produit_premier"
}
This works fine, but the only output I'm getting is the name of my product.
How can I achieve displaying the product image?
Thanks for your help!
When you use the input type product in Shopify it returns to your handle of the product.
You need to use the all_products object to get more information regarding the product.
Update: you can use it like
This is the settings json code:
[UPDATED - FINAL]
Finished working on this, here's the final code:
<!-- GETS PRODUCT HANDLE AND ASSIGNS TO VARIABLE -->
<div class="hidden">
{% assign product = section.settings.produit_quatrieme %}
</div>
<!-- GETS PRODUCT FIRST IMAGE + LINK -->
{% for image in all_products[product].images %}
{% if forloop.first == true %}
<a href=" {{ all_products[product].url }} ">
<img src="{{image.src | img_url:"grande"}}" />
</a>
{% endif %}
{% endfor %}
<!-- GETS PRODUCT TITLE + LINK -->
{% for title in all_products[product].title %}
{% if forloop.first == true %}
<a href=" {{ all_products[product].url }} ">
<h2 class="ProductItem__Title Heading margin-none"> {{ all_products[product].title }} </h2>
</a>
{% endif %}
{% endfor %}
Add schema code to the section blocks instead of section settings. Then you can select as many products as you want.
{% for block in section.blocks %}
{% assign product = all_products[block.settings.produit_quatrieme] %}
<a href=" {{ product.url }} ">
<img src="{{product.featured_image| img_url:"grande"}}" />
</a>
<a href=" {{ product.url }} ">
<h2 class="ProductItem__Title Heading margin-none"> {{ product.title }} </h2>
</a>
{% endfor %}
If you want to display a single product then just add section instead of block, then no need to use for loop.

Display Items in Collection that Do Not Exist In Shopping Cart Shopify

I'm trying to iterate over items in the shopping cart and generate an upsell div with products NOT in the cart. Below is the code I have so far, but I run into issues when adding two items to cart running the loop twice generating the html twice. Any ideas on how to resolve it? I'm stumped.
{% for item in cart.items %} // iterates over items in cart
{% if item.product.id == 4456879040188 %} // checks if product id matches in item in cart
<div class="upsell-pop" style="text-align:center; width: 100%;">
<h4>Frequently bought together</h4>
{% for prod in collections.upsell.products %} // iterates products in collection upsell
{% unless prod.handle contains "product-name" %} // shows only prods that do not contain url handle
<div>
<span class="upsell-title">{{ prod.title }}</span>
<span class="upsell-price">{{ prod.metafields["meta"]["promo"] }} {{ prod.price | money }}</span>
<img src="{{ prod.featured_image | img_url: '200x' }}" />
<a class="btn-product" href="{{prod.url}}">View Product</a>
</div>
{% endunless %}
{% endfor %}
</div>
{% endif %}
{% endfor %}
Another thought is to somehow check to see if product is NOT in cart items inside to replace the existing "unless" statement, but not sure how to code it.
{% unless cart.items exist then %} // I know this is not correct syntax
<div>
<span class="upsell-title">{{ prod.title }}</span>
<span class="upsell-price">{{ prod.metafields["meta"]["promo"] }} {{ prod.price | money }}</span>
<img src="{{ prod.featured_image | img_url: '200x' }}" />
<a class="btn-product" href="{{prod.url}}">View Product</a>
</div>
{% endunless %}
On my mind, there are two steps here.
First, capture your cart content to get string to compare to when you loop through your upsell collection. This could be something like that:
{%- capture cart_items -%}
{% for item in cart.items %}
{{ item.product.handle }}{% unless forloop.last %} , {% endunless %}
{% endfor %}
{%- endcapture -%}
Then loop through your collection while checking your string does not contain the handle of the current product at each iteration:
{% for product in collections['upsell'].products %}
{% unless cart_items contains product.handle %}
{{ product.title }}
{% endunless %}
{% endfor %}
Remarks:
Snippet 1 => In line_item (here called item because it's shorter to write) object you may access product object attributes: item.product.product_attr_needed
Snippet 2 => To access directly a collection object using its handle you must use collections + square brackets containing collection handle + attribute. Here 'upsell' is the handle of your upsell collection.
Not tested but this should work.
HTH

Display name of colour variant selected on Shopify

On this page I have some swatches that when selected they don't display the variant name.
Basically, I need to add a paragraph text under the variant swatches that indicate the name of the variant selected...
I'm not good on javascript and online I didn't found any complete guide about that
Thanks a lot for your help!
That looks like a theme I've seen before. If I recall correctly, that theme uses a file called swatch.liquid to make those colour circles. I'm writing this answer using a version of a swatch file that I happen to have on hand, so the specific code may not be exactly what your theme has, but hopefully I'll be able to help you find what you need.
Here is the code from my swatch.liquid file that prints out the swatches. (This is roughly the bottom half of the swatch.liquid file, found in the snippets folder)
<div class="product-options">
<div class="swatch clearfix" data-option-index="{{ option_index }}">
<div class="header">
{% assign values = '' %}
{% for variant in product.variants %}
{% assign value = variant.options[option_index] %}
{% unless values contains value %}
{% assign values = values | join: ',' %}
{% assign values = values | append: ',' | append: value %}
{% assign values = values | split: ',' %}
<div data-value="{{ value | escape }}" class="swatch-element {% if is_color %}color {% else %}size {% endif %}{{ value | handle }} {% if variant.available %}available{% else %}soldout{% endif %}">
<input id="swatch-{{ option_index }}-{{ value | handle }}" type="radio" name="option-{{ option_index }}" value="{{ value | escape }}"{% if forloop.first %} checked{% endif %} {% unless variant.available %}disabled{% endunless %} />
{% if is_color %}
<label for="swatch-{{ option_index }}-{{ value | handle }}" style="background-color: {{ value | split: ' ' | last | handle }};">
<img class="crossed-out" src="{{ 'soldout.png' | asset_url }}" />
</label>
{% else %}
<label for="swatch-{{ option_index }}-{{ value | handle }}">
{{ value }}
<img class="crossed-out" src="{{ 'soldout.png' | asset_url }}" />
</label>
{% endif %}
</div>
{% endunless %}
{% if variant.available %}
<script>
jQuery('.swatch[data-option-index="{{ option_index }}"] .{{ value | handle }}').removeClass('soldout').addClass('available').find(':radio').removeAttr('disabled');
</script>
{% endif %}
{% endfor %}
</div>
</div>
</div>
That looks a bit messy, I know - so let's try and find the part that you'll want to modify.
Here's the part from the above example that prints the swatch element when the swatch is a colour:
{% if is_color %}
<label for="swatch-{{ option_index }}-{{ value | handle }}" style="background-color: {{ value | split: ' ' | last | handle }};">
<img class="crossed-out" src="{{ 'soldout.png' | asset_url }}" />
</label>
{% else %}
In between those <label> tags you should be able to add any text that you need - such as a <span class="swatch-color-name">{{ value }}</span>
Adding extra HTML in here may throw off the current styles of your page, so you may need to add some extra CSS rules to apply to any elements you add to get things to line up nicely again.
Hope this helps!
NB: If you're using Chrome, there's a useful extension called "Search All" that lets you search your entire Shopify theme if you're having trouble finding the file that needs to be edited. Searching for keywords like 'color' or 'variant.options' should help point you in the right direction.

Trying to target only frontpage collection to apply a style(Shopify)

OK, so I had asked a few weeks ago on the Shopify forum(slow responses) how to target just one product on a collection page so that there is no hover affect, but now I only want to target the frontpage collection and not my many other collection pages on the site.
Theme is Masonry and here is a snipet of the code I'm working with:
{% if settings.prod_block_display contains 'hover' %}
{% unless forloop.index == 1%}
<div class="hoverinfo{% if forloop.index == 1 %}no-overlay {% endif %}">
<a href="{{ product_url }}">
<div class="info-box">
<div class="title">{{ product-block.title }}</div>
<div class="price">
{% if product-block.compare_at_price_max > product-block.price %}
<span class="previously">{{ product-block.compare_at_price_max | money }}</span>
{% endif %}
{% if product-block.price_varies %}<span class="from">{{ 'products.listing.from' | t }}</span>{% endif %}
<span class="actual">{{ product-block.price | money }}</span>
</div>
</div>
</a>
</div>
{% endunless %}
{% endif %}
{% if settings.prod_block_qv and no_quick_buy == false %}
{% unless forloop.index == 1 %}
<div class="quick-buy-row{% if forloop.index == 1%}no-overlay {% endif %}">
{{ 'products.listing.quick_view' | t }}
</div>
{% endunless %}
{% endif %}
The "{% unless forloop.index == 1%}
" codes are the effects I only want to apply to the frontpage. Any help would be great!
You can add {{ collection.handle }} to classes of product divs where you want to apply the effect. Then in styles.css.liquid add a style for the collection handle (collection.handle) class as required.
What #HymnZ was trying to point to was that you can do things like in styles.liquid.css:
.frontpage .hoverinfo{
display:none;
}
and then in your template:
<div class="{{collection.handle}}">
<div class="hoverinfo">
...
</div>
</div>
This is the easiest way to use this strategy. What I was trying to add on was that you can potentially also use prefixes and suffixes on classes that concatenate with handles to offer more functionality. In styles:
.hide{
display:none;
}
.frontpage-show{
display:block;
}
and then in your template:
<div class="hide {{collection.handle}}-show">
Since most browsers support stacked selectors you probably don't need the -hide, -show variants but they can be helpful depending on how your mind works these things out. The sample above can be used to show/hide things for a variety of circumstances. e.g. you could target elements for a variety of collections:
.frontpage-show,
.collection1-show,
.frontpage.hide, /* these second two are the stacked equivalents to the -show variants */
.collection1.hide{
display:block;
}
Of course you can also do much of this in liquid itself:
{% assign showFor = "frontpage,collection1" |split ','%}
{% if showFor contains collection.handle %}
<div>Something limited</div>
{% endif %}
or
{% assign showFor = "frontpage,collection1" |split ','%}
<div class="{% if showFor contains collection.handle %}conditional{% endif %}">
Something limited
</div>