Liquid variable scope between Layout and Template - shopify

Is is possible to define liquid variables in a layout file that are visible in the template files?
Variables defined in a layout (e.g. theme.liquid) are visible to any snippets included via <% include %> (and vice versa).
Variables defined in a template (e.g. index.liquid) are visible in any snippets included via <% include %> (e.g. product-grid-item.liquid) and are also visible in the layout file.
And yet variables defined in a layout don't seem to be visible to the template. Presumably the template is evaluated prior to the evaluation of the layout. Is there any way to override this behavior?

Currently in Shopify, Liquid variables cannot be passed from the layout into the template.
One way to get around this would be to do the same logic twice, perhaps in a snippet. Then place the same snippet in both the Layout and the template.
Also worth noting on the subject of Shopify Liquid scope as it isn't documented anywhere is that variables defined inside of sections are scoped inside of that section and cannot be access outside.
EDIT:
Also on the subject of Shopify Liquid variable scope.
There is now also the {% render %} tag which forces a snippet to be called with the required variables explicitly passed in.
For example you could do this with include
{% assign name = 'cart' %}
{% include 'icon' %}
Alternatively, you can use the render tag which has some performance benefits. Just ensure you explicitly pass the name variable.
{% render 'icon' name: 'cart' %}
<!-- OR -->
{% assign name = 'cart' %}
{% render 'icon' name: name %}
The benefit of using render is that the variables are always scoped to the snippet which can prevent some confusing bugs. Additional there is a big speed performance on Shopify's server which will improve the Time to First Byte.

Related

Customizing Accordion Based On Product Selected

So I am wondering how I can change the image under an accordion section for just one product page and not the others. I see in the code of the product page template where the image is located but I am not experienced enough to know how to change it for just the one product. Is there a way to do this without needing to create a whole new template?
Website: https://auntethels.com (I'm trying to change the image under "heating instructions" for just the Lentil Chili Pot Pie product page)
Not sure if it helps but here is the code snippet I found: 1
(I need the 'directions.png' to be different for just the one page.)
I've been able to make other changes she needed but this one has stumped me :( I tried to reach the developer who made the custom site but he has stopped replying so I'm on my own for this one.
you can conditionally render the accordion with product handle
{% if product.handle == 'cumin-lentil-pot-pie-vegetarian'%}
<div class="accordion">
<h4>Heating Instructions</h4>
<button class="x">✕</button>
<p class="answer"><img src="//cdn.shopify.com/s/files/1/0332/6997/3128/t/15/assets/directions.png?v=63874448465039500411650314323" alt="Directions"></p>
</div>
{% endif %}

Reviews section seems to be duplicating on some products

I am completly miffed. I'm new to using liquid but not new to programming, it's my day job. Below we have a snippet of the product-template.liquid file. Hopefully, it looks familiar to folk rather than me pasting the whole file. That being said, here's a link to a paste of it.
{% else %}
<div class="product-description rte" itemprop="description">
{{ product.description }}
</div>
{% endunless %}
<div id="shopify-product-reviews" data-id="{{product.id}}">{{ product.metafields.spr.reviews }}</div>
I wanted to add a footer onto descriptions as there's some copy pasted text at the bottom of every product description.
So I changed the above to the the following:
{% else %}
<div class="product-description rte" itemprop="description">
{{ product.description }}
</div>
{% endunless %}
<p>Here's my footer text.</p>
<div id="shopify-product-reviews" data-id="{{product.id}}">{{ product.metafields.spr.reviews }}</div>
This seemed to do the job until I noticed the duplication of the review sections. The content of the <p> tag was in between the two review sections prior to this screenshot:
I removed the <p> tag so that it was back to its original state. However, the review duplication is still there.
Inspecting the page shows one review section nested in the product description div and another one outside of it.
To make matters worse, this issue doesn't seem to be repeatable as far as I can see. I've looked at a product where there is the duplication and another product where there isn't duplication, yet no difference as far as I can see.
Either I'm completely blind in what I returned the code too or maybe Shopify takes time to propagate these changes to templates to each product?
It's worth mentioning, maybe, that I did these code changes using their site code editor.
Update 1
I've worked out the repeatable part. I'm making these changes whilst my partner is creating her products for the site. By my estimations the code changes I made and the products she's added after that point have the review duplication. It seems to be that products prior do not exhibit the duplication issue.
Update 2
Update 1 might not be the case. I duplicated a product where there was not a duplicate review section. The duplicate also showed that there was just one review section. Time of creation doesn't seem to have an impact.

Shortcodes in Shopify no longer working when using render instead of include

I'm currently using shortcodes in Shopify via this customization. Shopify updated liquid to deprecate include and replaced it with render. This seems to break all of my embeds. I have them on pages and product descriptions, enabling using:
{% render 'shortcode' load: page.content %}
It used to be:
{% include 'shortcode' load: page.content %}
Now that I use render, I just get an error on page "include usage is not allowed in this context"
Does the render call change to work properly?
There are a few differences with the render tag in comparison to the include:
You can't use include inside render tag (like in your case)
You must pass all variables to the render tag as arguments, it can't read them if you defined them outside of it and don't pass them.
Variables defined in the render tag are not accessible outside of it.
These are the main differences, so you will need to update your snippet to use only render tags and pass the appropriate variables to it.

How to handle Django templates in Transifex?

Transifex is widely used to manage translation for Django projects, as well as internally. It does very well on gettext (PO) files. Django templates, however, are not one of its known formats. You can tell Transifex that they are HTML, in which case it takes something like this:
{% extends "base.html" %}
{% block "banner" %}
<h1>Hi there</h1>
<p>Banner text</p>
{% endblock "banner" %}
and turns it into:
<div>
<p>
{% extends "base.html" %}
{% block "banner" %}</p>
<h1>Hi there</h1>
<p>Banner text</p>
{% endblock "banner" %}</div>
An additional problem is that Transifex then treats the template markup as strings to be translated, forcing you to go through the file and tag each one as "locked" - and even then, I think that the markup counts against your word count.
Adding HTML comments around the Django template tags doesn't work either, because they become part of the template and get inserted into the final document. Commenting out template tags and then post-processing the file to remove them might work, but there's not necessarily any guarantee that Transifex would leave the comments alone, and, even if they did, this seems clunky and error-prone.
I'm hoping that someone has a better strategy that lets you hand a template to Transifex without it getting munched.
You should rather use localization support in Django and then you will get Gettext PO files for translation, which can be handled by any localization tool.

DjangoCMS aldryn-bootstrap3 link/button add a custom field (data-toggle)

i am using DjangoCMS with aldryn-bootstrap3 and i need extra attributes on the button/link element. Is it possible to add extra attributes to an element? I need data-* attributes
thank you!
btw: screenshot is fake :)
You can install the package called djangocms-attributes-field to edit attributes (including data-*) via the front-end editor.
Here is my quick and dirty workaround:
i edit the template:
./templates/aldryn_bootstrap3/plugins/button.html
aldryn_bootstrap3 button template
{% if 'modal' in instance.classes %}
data-toggle="modal"
{% endif %}
So if i edit the class "modal" data-toggle="modal" appears.