Current Shopify page URL for Blog page tagged view - shopify

I have replaced the Shopify signup form by a GetResponse form and I want the page to stay in the same place after the form is submitted. For that I am trying to dynamically generate the current URL so that I can pass it as the return URL. Here’s what my code snippet looks like:
{% assign current_url = '' %}
{% case template %}
{% when 'page' %}
{% assign current_url = page.url %}
{% when 'blog' %}
{% assign current_url = blog.url %}
{% when 'article' %}
{% assign current_url = article.url %}
{% when 'collection' %}
{% assign current_url = collection.url %}
{% when 'product' %}
{% assign current_url = product.url %}
{% endcase %}
<form action="https://app.getresponse.com/add_subscriber.html" accept-charset="utf-8" method="post">
<!-- Show the name field (required) -->
<input type="hidden" name="name"/>
<!-- Email field (required) -->
<input type="text" name="email"/>
<!-- Campaign token -->
<!-- Get the token at: https://app.getresponse.com/campaign_list.html -->
<input type="hidden" name="campaign_token" value="xxxxx"/>
<!-- Subscriber button -->
<input type="submit" value="Sign Me Up" onclick="javascript:window.alert('Thanks for entering your email address!');"/>
<!-- Add any optional code here (explained below) -->
<input type="hidden" name="thankyou_url" value="https://example.com{{ current_url }}"/>
As you can see in the case statements I have taken care of all the page types separately. When the user is in the main blog page (https://example.com/blogs/news), blog.url correctly returns /blogs/news. However when I click on any of the tags, I go to the URL line https://example.com/blogs/news/tagged/diy or https://example.com/blogs/news/tagged/bizarre. So I am trying to get my code to handle this case as well so that current_url gets the value /blogs/news/tagged/diy or /blogs/news/tagged/bizarre etc.
If there’s no single variable that returns it that’s OK too. I just need a way to return the tag value (like diy or bizarre). Then I can concatenate blog.url + /tagged/ +
Is this possible?

You can do this using current_tags. Refer https://help.shopify.com/themes/liquid/objects/current-tags#inside-collection-liquid
A simple change in your code will be like this
{% capture current_url %}
{% case template %}
{% when 'page' %}{{page.url}}
{% when 'blog' %}{% if current_tags %}/{{ current_tags.first | handleize }}{% endif %}
{% when 'article' %}{{article.url}}
{% when 'collection' %}{{collection.url}}{% if current_tags %}/{{ current_tags.first | handleize }}{% endif %}
{% when 'product' %}{{product.url}}
{% endcase %}
{% endcapture %}
<input type="hidden" name="thankyou_url" value="https://example.com{{ current_url | strip_newlines }}" />

Related

Shopify: Product grid - how overwrite a Product STOCK-OUT msg, with "Coming Soon" if it's in a ComingSoon collection

Our existing theme displays a 'Stock Out' banner over the product image if there is no stock.
We want to change this banner to "Coming Soon" if the Product is in a ComingSoon Collection.
The theme's 'product-grid-item.liquid file contains:
<a href="{{ product.url | within: current_collection }}" class="product-grid-item">
<div class="product-grid-image">
<div class="product-grid-image--centered">
{% if sold_out %}
<div class="badge badge--sold-out"><span class="badge-label">{{ 'products.product.sold_out' | t }}</span></div>
{% endif %}
...
Which I changed to:
<!-- added ###For Test ### -->
{% assign found_collection = false %}
{% for collection in product.collections %}
{% if collection.handle contains 'Coming Soon' %}
{% assign found_collection = true %}
{% break %}
{% endif %}
{% endfor %}
{% if found_collection %}
<div class="badge badge--sold-out"><span class="badge-label">Coming Soon</span></div>
{% else %}
<div class="badge badge--sold-out"><span class="badge-label">{{ 'products.product.sold_out' | t }}</span></div> <!-- this is the original line of code -->
{% endif %}
<!-- end of added code -->
But is doesn't work, all 'no-stock' products display with the banner "Stock out"
Nb The actual Title of the ComingSoon collection is "Coming Soon ..." - so the contains statement should work?
We could change the code to look for a Tag, but admin maintaining a tag would be more work.
Most likely this is because 'Coming Soon' is not the correct handle. A handle is part of your URL that can be found under Collection SEO inside the admin panel
e.g. store.myshopify.com/collections/my-collection -> my-collection is the handle

How to avoid calling content when two tags are partially the same in Shopify

I am currently trying to display content based on product tags that are assigned to products in Shopify.
This is working ok, but my problem is that I have two tags that contain partially the same tag name, so I am getting both sets of content appearing on the front end.
One tag shows a field that is required "r-[tag-name]" and the other shows the same field but it is not required "[tag-name]".
Obviously I know this is due to the fact that I am using 'contains' so the logic is true for both when either tag is applied, but I have tried using '==' (equals) but it when I do, nothing appears at all :/
What I would like to know is, what do I need to change so that the statement is only true if a tag exists that is exactly the same as the if statement.
I am new to Liquid so any help would be greatly appreciated!
<!--Convert the tags into a string by joining them with COMMA-->
{% assign productTags = product.tags | join: ', ' %}
<!--Now Check for the desired tag name-->
{% if productTags contains 'r-custom-name-one' %}
<p class="line-item-property__field">
<label for="name-one">Name One:</label>
<input class="required" id="name-one" type="text" name="properties[Name One]">
</p>
{% endif %}
{% if productTags contains 'custom-name-one' %}
<p class="line-item-property__field">
<label for="name-one">Name One:</label>
<input id="name-one" type="text" name="properties[Name One]">
</p>
{% endif %}
I need to change so that the statement is only true if a tag exists that is exactly the same as the if statement
This should do it:
{% for tag in product.tags %}
{% if tag == 'r-custom-name-one' %}
<p class="line-item-property__field">
<label for="name-one">Name One:</label>
<input class="required" id="name-one" type="text" name="properties[Name One]">
</p>
{% break %}
{% endif %}
{% if tag == 'custom-name-one' %}
<p class="line-item-property__field">
<label for="name-one">Name One:</label>
<input id="name-one" type="text" name="properties[Name One]">
</p>
{% break %}
{% endif %}
{% endfor %}
I added {% break %} which will
Causes the loop to stop iterating when it encounters the break tag.
I assumed that once the tag is found, you don't need need to continue looping through the rest of the tags!

TemplateSyntaxError at /admin/ Invalid block tag on line 23: 'translate', expected 'endblock'. Did you forget to register or load this tag?

**
TemplateSyntaxError at /admin/
Invalid block tag on line 23: 'translate', expected 'endblock'. Did you forget to register or load this tag?
Request Method: GET
Request URL: http://127.0.0.1:8000/admin/
Django Version: 2.1
Exception Type: TemplateSyntaxError
Exception Value:
Invalid block tag on line 23: 'translate', expected 'endblock'. Did you forget to register or load this tag?
Exception Location: C:\Users\subramanyam.s.g\PycharmProject\pyyshop\LEARN\lib\site-packages\django\template\base.py, line 522, in invalid_block_tag
Python Executable: C:\Users\subramanyam.s.g\PycharmProject\pyyshop\LEARN\Scripts\python.exe
Python Version: 3.8.3**
I also happened to come across this error while using Django Version: 2.1.
I was customizing the admin look and feel as per the django documentation 3.1 https://docs.djangoproject.com/en/3.1/intro/tutorial07/.
Django Version: 2.1 can be hosted in a shared hosting domain with reference to https://pythonfusion.com/deploy-django-on-shared-hosting/.
Here is part of the screenshot to just show you i got the same error and see where the problem https://i.stack.imgur.com/RV52y.png
If you have difficulty finding where the Django source files(the ones you want to customise eg admin) are located on your system, use the following procedure:
In your computer locate where your django project is located in the file explorer e.g
C:\Users\yourname\Desktop\yourproject.
In your file explorer window, there is a path above your folder showing your current
location in the file explorer e.g This PC > Desktop > yourproject. Click inside this
path and rewrite cmd and then hit enter key on your keyboard. A command prompt will be
opened.
Now if you installed django in a global environment, that is, in local disk without
creating a virtual environment enter this code python -c "import django; print(django.__path__)" in the opened command prompt.
If you installed Django into the virtual environment then activate first the virtual environment using still the opened Command prompt, i normally use workon myvirtualenvironmentname to activate my virtual environment. Then paste this code python -c "import django; print(django.__path__)" in the opened command prompt.
Hit enter key on your keyboard and you will see something like this ['C:\\Users\\yourname\\Envs\\yourvirtualenvironmentname\\lib\\site-packages\\django']. This is the location we should arrive to access the Django resources.
Go to your file explorer by pressing CTRL + E on your keyboard.
Navigate to your local disk C, open the Users folder, next open the folder with your name next locate and open the Envs folder and locate your yourvirtualenvironmentname your project is using.
Open your yourvirtualenvironmentname> Lib > site-packages > django > contrib > admin > templates >admin.
You should be here C:\Users\yourname\Envs\yourvirtualenvironmentname\Lib\site-packages\django\contrib\admin\templates\admin in your machine.
Now take key note on the Django version you are using. Where we are currently there are some files that are in Django Version: 2.1 and not in Django Version: 3.1 e.g app_list.html is in Django Version 2.1 and not in 3.1 with respect to this directory where we are.
Note 2. The file names maybe the same but the content inside the file may differ slightly and this is what causes the error
The code below is some of the content in base.html (i have just copied a few of the code where i want to emphasize ) from Django V 3.1.
base.html from Django Version 3.1
`
{% if not is_popup %}
<!-- Header -->
<div id="header">
<div id="branding">
{% block branding %}{% endblock %}
</div>
{% block usertools %}
{% if has_permission %}
<div id="user-tools">
{% block welcome-msg %}
{% translate 'Welcome,' %}
<strong>{% firstof user.get_short_name user.get_username %}</strong>.
{% endblock %}
{% block userlinks %}
{% if site_url %}
{% translate 'View site' %} /
{% endif %}
{% if user.is_active and user.is_staff %}
{% url 'django-admindocs-docroot' as docsroot %}
{% if docsroot %}
{% translate 'Documentation' %} /
{% endif %}
{% endif %}
{% if user.has_usable_password %}
{% translate 'Change password' %} /
{% endif %}
{% translate 'Log out' %}
{% endblock %}
</div>
{% endif %}
{% endblock %}
{% block nav-global %}{% endblock %}
</div>
<!-- END Header -->
{% block breadcrumbs %}
<div class="breadcrumbs">
{% translate 'Home' %}
{% if title %} › {{ title }}{% endif %}
</div>
{% endblock %}
{% endif %}
<div class="main shifted" id="main">
{% if not is_popup and is_nav_sidebar_enabled %}
{% block nav-sidebar %}
{% include "admin/nav_sidebar.html" %}
{% endblock %}
{% endif %}
<div class="content">
{% block messages %}
{% if messages %}
<ul class="messagelist">{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message|capfirst }}</li>
{% endfor %}</ul>
{% endif %}
{% endblock messages %}
<!-- Content -->
<div id="content" class="{% block coltype %}colM{% endblock %}">
{% block pretitle %}{% endblock %}
{% block content_title %}{% if title %}<h1>{{ title }}</h1>{% endif %}{% endblock %}
{% block content %}
{% block object-tools %}{% endblock %}
{{ content }}
{% endblock %}
{% block sidebar %}{% endblock %}
<br class="clear">
</div>
<!-- END Content -->
{% block footer %}<div id="footer"></div>{% endblock %}
</div>
</div>
`
I wanted to highlight these lines of code but i was unable. So check of the following in your base.html {% translate 'Welcome,' %}, {% translate 'View site' %}, {% translate 'Documentation' %}, {% translate 'Change password' %}, {% translate 'Log out' %} and {% translate 'Home' %}.
Lets compare the above base.html file with that of Django Version 2.1. Take a close look to discover the difference.
base.html file in Django Version 3.1
`
{% if not is_popup %}
<!-- Header -->
<div id="header">
<div id="branding">
{% block branding %}{% endblock %}
</div>
{% block usertools %}
{% if has_permission %}
<div id="user-tools">
{% block welcome-msg %}
{% trans 'Welcome,' %}
<strong>{% firstof user.get_short_name user.get_username %}</strong>.
{% endblock %}
{% block userlinks %}
{% if site_url %}
{% trans 'View site' %} /
{% endif %}
{% if user.is_active and user.is_staff %}
{% url 'django-admindocs-docroot' as docsroot %}
{% if docsroot %}
{% trans 'Documentation' %} /
{% endif %}
{% endif %}
{% if user.has_usable_password %}
{% trans 'Change password' %} /
{% endif %}
{% trans 'Log out' %}
{% endblock %}
</div>
{% endif %}
{% endblock %}
{% block nav-global %}{% endblock %}
</div>
<!-- END Header -->
{% block breadcrumbs %}
<div class="breadcrumbs">
{% trans 'Home' %}
{% if title %} › {{ title }}{% endif %}
</div>
{% endblock %}
{% endif %}
{% block messages %}
{% if messages %}
<ul class="messagelist">{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message|capfirst }}</li>
{% endfor %}</ul>
{% endif %}
{% endblock messages %}
<!-- Content -->
<div id="content" class="{% block coltype %}colM{% endblock %}">
{% block pretitle %}{% endblock %}
{% block content_title %}{% if title %}<h1>{{ title }}</h1>{% endif %}{% endblock %}
{% block content %}
{% block object-tools %}{% endblock %}
{{ content }}
{% endblock %}
{% block sidebar %}{% endblock %}
<br class="clear">
</div>
<!-- END Content -->
{% block footer %}<div id="footer"></div>{% endblock %}
`
You will see the following in your base.html {% trans 'Welcome,' %}, {% trans 'View site' %}, {% trans 'Documentation' %}, {% trans 'Change password' %}, {% trans 'Log out' %} and {% trans 'Home' %}.
To solve your *TemplateSyntaxError at /admin/ Invalid block tag on line 23: 'translate', expected 'endblock'. Did you forget to register or load this tag?
*
Just rename the translate to trans and save your file. In conclusion whenever you will add app_list.html or any other file in your admin folder and get and error. Just open the file and rename anything that has translate to trans. This solved my problem.
Incase i miss quoted something for example the django versions remember to let me know. Lets learn together. Thank you
Only way I can come up with for this could happen is if you've created a custom tag module named 'i18n' which would override the builtin i18n module. I can reproduce it by creating a file 'i18n.py' in my app's templatetags/ folder - is that what you have done?
In my case it was a template I've copied and modified. The template was from newer version of django. After upgrading django it all normalised.

Assigning a collection to a custom created collection page in Shopify?

I am using a free Venture theme on Shopify and i am trying to make a custom collection page.
I found a solution in stackoverflow but it was able to help someplace.
How to add collection.liquid to an existing page?
The summery of the solution is:
Copy everything that's in collection.liquid and paste it into a new snippet (let's say you call it collection-copy.liquid).
Then, in the page you want to add the collections page to, just add {% include 'collection-copy' %}
This solution worked well but there is one more issue for me. In the custom created page it says "Sorry, there are no products in this collection" In the customization of the same page there is a "collection" section. But in the "collection" section there is no option to choose a collection. There is only "Enable tag filtering" and "Enable sorting" check boxes.
Webpage: https://mottomfreedom.com/pages/less-is-more
Do you have any idea of assigning a collection with this custom created snippet?
{% paginate collections[settings.frontpage_collection].products by 20 %}
<div class="page-width">
<header class="grid medium-up--grid--table section-header small--text-center">
<div class="grid__item medium-up--one-half section-header__item">
<h1 class="section-header__title">
{{ collection.title }}
{% if current_tags %}
– {% assign title_tags = current_tags | join: ', ' %}
{{ title_tags }}
{% endif %}
</h1>
{% if collection.description != blank %}
<div class="section-header__subtext rte">
{{ collection.description }}
</div>
{% endif %}
</div>
<div class="grid__item medium-up--one-half medium-up--text-right section-header__item">
{% section 'collection-filters' %}
</div>
</header>
<div class="grid grid--no-gutters grid--uniform">
{% for product in collection.products %}
<div class="grid__item small--one- medium-up--one-third">
{% include 'product-card', product: product %}
</div>
{% else %}
{% comment %}
Add default products to help with onboarding for collections/all only.
The onboarding styles and products are only loaded if the
store has no products.
{% endcomment %}
{% if shop.products_count == 0 %}
<div class="grid__item">
<div class="grid grid--no-gutters grid--uniform">
{% assign collection_index = 1 %}
{% for i in (1..10) %}
{% case i %}
{% when 7 %}
{% assign collection_index = 1 %}
{% when 8 %}
{% assign collection_index = 2 %}
{% when 9 %}
{% assign collection_index = 3 %}
{% when 10 %}
{% assign collection_index = 4 %}
{% endcase %}
<div class="grid__item small--one-half medium-up--one-fifth">
<a href="/admin/products" class="product-card">
<div class="product-card__image-container">
<div class="product-card__image-wrapper">
<div class="product-card__image">
{% capture current %}{% cycle 1, 2, 3, 4, 5, 6 %}{% endcapture %}
{{ 'product-' | append: current | placeholder_svg_tag: 'placeholder-svg' }}
</div>
</div>
</div>
<div class="product-card__info">
<div class="product-card__name">{{ 'homepage.onboarding.product_title' | t }}</div>
<div class="product-card__price">
$19.99
</div>
</div>
<div class="product-card__overlay">
{% assign view_string_length = 'products.product.view' | t | size %}
<span class="btn product-card__overlay-btn {% if view_string_length > 8 %} btn--narrow{% endif %}">{{ 'products.product.view' | t }}</span>
</div>
</a>
</div>
{% assign collection_index = collection_index | plus: 1 %}
{% endfor %}
</div>
</div>
{% else %}
{% comment %}
If collection exists but is empty, display message
{% endcomment %}
<div class="grid__item small--text-center">
<p>{{ 'collections.general.no_matches' | t }}</p>
</div>
{% endif %}
{% endfor %}
</div>
{% if paginate.pages > 1 %}
<div class="pagination">
{{ paginate | default_pagination | replace: '« Previous', '←' | replace: 'Next »', '→' }}
</div>
{% endif %}
</div>
{% endpaginate %}
You are right about giving some time before accepting an answer :)) The solution worked but forced me to create 1 page and 4 liquid files per collection. And at the end, i figured out that some sections like "collection.list" doesn't directs to the page which i have created. I think you were talking about this at the beginning of the answer :)
After that, i found a much better solution. Just creating a new section.liquid file and placing it in "collection.liquid" with an "if" statement solved my problem.
{% if collection.handle == 'less-is-more' %}
{% section 'custom-featured-products-LESSisMORE' %}
{% endif %}
But in any way, i'm grateful for your interest. Thank you very much Dave.
It looks like there's nothing defining the collection variable anywhere.
I would suggest changing the beginning of your code snippet from:
{% paginate collections[settings.frontpage_collection].products by 20 %}
To:
{% assign collection = collections[settings.frontpage_collection] %}
{% paginate collection.products by 20 %}
There is an implicit collections variable whenever you're on a page that includes /collections/[something] in the URL, but when you're on a URL that's /page/[something], you have an implicit page variable in Liquid instead.
Note: if the collection set in your theme's value for settings.frontpage_collection isn't the one you want, you can possibly:
a. Change the value using the 'Customize' link beside your theme (most easily found on the /admin/themes page), useful if you're not going to use that setting for anything else;
b. Hard-code a collection handle, eg: collections['i-am-sure-this-will-never-change'], but hard-coded strings are ugly and should generally be avoided;
c. Create your own theme setting by adding an entry to config/settings_schema.json - see https://help.shopify.com/en/themes/development/theme-editor/settings-schema if you're still getting up to speed with custom theme settings; or
d. If all your content is in a section, you can use section settings (similar to theme settings) to make a variable that's tied specifically to just that block of code.
If you need to make these special pages for multiple collections, and each of these pages is largely reusing the same code, you can make your life easier by moving the common code to a snippet and passing variables to it from your page template. To do so:
Create a file in the 'snippets' folder of your theme. (For this example, let's say the file is called collection-in-page.liquid. We will be passing a collection into this snippet, so you can remove the assign statement.
In your page-specific template, figure out what the collection handle is going to be
a. This might be hard-coded, or it might be something you could look up by using metafields or tags on the page. Examples:
{% assign collection_handle = 'hardcoded-handle' %}, {% assign collection_handle = page.metafields.related_items.collection %}
In your page template, include the snippet you created. I find it helps to explicitly pass any variables I want to use, like so:
{% include 'collection-in-page', collection: collections[collection_handle] %}
Hope this helps!

Django template inheritance the other way round

Django template system lets you easily specify a template and fill it with different data using extends and blocks.
What I need to do is to have several templates, filled with the same data (blocks) while avoiding code repetition. It sounds like a usecase for templatetags but consider this example:
<div class="container">
{% get_tags page as tags %}
{% if tags %}
<div class="ribbon">
<span class="ribbon-inner">{{ tags|join:' | ' }}</span>
</div>
{% endif %}
</div>
If I wanted to display the tags in another template using a different html elements/classes I would have to create at least two templatetags (has_tags and get_tags) or include html in templatetags code.
I'd like to have something like this:
#common.html
{% block tags %}
{% get_tags page as tags %}
{% if tags %}
<div class="ribbon">
<span class="ribbon-inner">{{ tags|join:' | ' }}</span>
</div>
{% endif %}
{% endblock %}
#template_A.html
{% include common.html %}
<div class="container-1">
{% block tags %}
{{ block.super }}
{% endblock %}
</div>
#template_B.html
{% include common.html %}
{% block tags %}
{% get_tags page as tags %}
{{ tags|join:', ' }}
{% endblock %}
The problem is that include renders the template first, therefore it doesn't work this way. There are a lot of similar points in the file I'm editing, so creating and including template for each of them is not a great solution either.
Any thoughts?
Well, this is my solution:
#templateA.html
{% include "_common.html" with parent_file="_templateA.html" %}
#templateB.html
{% include "_common.html" with parent_file="_templateB.html" %}
#_templateA.html
<i>{% block tags %}{% endblock %}</i>
#_templateB.html
<b>{% block tags %}{{ tags|join:' & ' }}{% endblock %}</b>
#_common.html
{% extends parent_file %}
{% block tags %}
{% if not block.super %} # this does the trick
{{ tags|join:' I ' }}
{% else %}
{{ block.super }}
{% endif %}
{% endblock %}
This allows having HTML templates in _templateA.html and _templateB.html. If the block is left empty, it is filled with default from _common.html, while it can be overriden in _template.
It would be nice to override the block tag to avoid code repetition in _common.html but the following implementation fails on block.super() because of missing context.
#register.tag('overridable_block')
def overridable_block(parser, token):
from django.template.loader_tags import do_block
block = do_block(parser, token)
if block.super():
return block.parent
return block
Haven't found a way past this yet.