├── Add item to cart with the JavaScript Fetch API
└── add-item-to-cart-with-fetch.js
├── Checkout liquid layout
├── README.md
└── checkout.liquid
├── Create a media or press page
├── README.md
└── snippet-press-grid.liquid
├── Create edit in admin button for current view
├── README.md
├── create-edit-button-for-current-view.js
└── create-edit-button-for-current-view.min.js
├── Detect if a collection is published with Liquid
├── README.md
└── is-collection-published.liquid.html
├── Detect search type used in searches
├── README.md
└── show-search-type.liquid
├── Disable sorting by best seller
├── README.md
└── collection.liquid
├── Dynamic pagination without alternate templates
├── README.md
├── dynamic-pagination-select.liquid
├── dynamic-pagination.js
└── dynamic-pagination.liquid
├── Export a list of files from the Admin
├── README.md
└── export-list-of-files-in-shopify.js
├── Get Shopify cart data with JSONP
├── README.md
├── cart-jsonp-jquery.js
└── cart-jsonp-plain.js
├── Get a cart json response with compare at price
├── README.md
└── cart.compare.liquid
├── Get articles in Liquid by their handle
├── README.md
└── related-articles.liquid
├── Get cart token with Liquid
├── README.md
└── get-cart-token.liquid
├── Get current domain name with Liquid
├── README.md
└── request_host.liquid
├── Get querystring in Shopify Liquid
├── README.md
└── querystrings.liquid
├── Get shipping estimate on Shopify product page
├── README.md
└── get-estimate.js
├── Get total stock value
├── README.md
├── get-total-stock-value.js
└── get-total-stock-value.min.js
├── LICENSE
├── Multiple 404 caches
├── 404.liquid
└── README.md
├── Multiple shopify reviews on one page
├── README.md
└── get-reviews.liquid
├── README.md
├── Remove map from order status page
└── README.md
├── Search by SKU
├── README.md
└── search.sku.liquid
├── Shopify Mailchimp RSS feed
├── README.md
└── blog.feed.liquid
├── Shopify Scripts
├── Line Items
│ ├── email-domain-discount.rb
│ ├── limit-line-item-quantity.rb
│ └── reject-discount-codes.rb
├── Payments
│ └── remove-gateway-on-billing-country.rb
└── README.md
├── Shopify persitent cart without apps
├── README.md
└── persistent-cart.js.liquid
├── Sort Shopify collection by inventory count
├── README.md
└── sort-shopify-collection-products-by-inventory.liquid
├── Sort Shopify collection by metafield
├── README.md
├── sort-shopify-collection-products-by-metafield-value-commentless.liquid
└── sort-shopify-collection-products-by-metafield-value.liquid
├── Starts with string check in Shopify Liquid
└── starts-with-example.liquid
├── Translate date strings into other languages
├── README.md
└── date-translate.liquid
├── Use articles to shedule theme updates
├── README.md
└── show-collection-based-on-last-article.liquid
└── Use variant image on Gift Card template
├── README.md
├── capture-image.liquid
└── gift_card.liquid
/Add item to cart with the JavaScript Fetch API/add-item-to-cart-with-fetch.js:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Example code showing how to add an item to
4 | the cart in Shopify using the Fetch API.
5 |
6 | The important line is where we add the
7 | X-Requested-With header. Without that the
8 | fetch call will fail with a bad request error.
9 |
10 | */
11 |
12 |
13 | (function(){
14 |
15 | var addData = {
16 | 'id':21373873027, /* for testing, change this to a variant ID on your store */
17 | 'quantity':1
18 | };
19 |
20 | fetch('/cart/add.js', {
21 | body: JSON.stringify(addData),
22 | credentials: 'same-origin',
23 | headers: {
24 | 'Content-Type': 'application/json',
25 | 'X-Requested-With':'xmlhttprequest' /* XMLHttpRequest is ok too, it's case insensitive */
26 | },
27 | method: 'POST'
28 | }).then(function(response) {
29 | return response.json();
30 | }).then(function(json) {
31 | /* we have JSON */
32 | console.log(json)
33 | }).catch(function(err) {
34 | /* uh oh, we have error. */
35 | console.error(err)
36 | });
37 |
38 | })();
39 |
--------------------------------------------------------------------------------
/Checkout liquid layout/README.md:
--------------------------------------------------------------------------------
1 | # Shopify Checkout Liquid Layout
2 |
3 | The checkout.liquid layout is a file used by Shopify Plus merchants for added checkout customisations. If you're a developer that is curious about the contents of the file, here it is. You'll note that it's a small file as a lot of the content is generated server side.
4 |
5 | ### Notes
6 | - Adding this file to a non-plus store won't enable it.
7 | - Plus merchants need to have the feature enabled by their Merchant Success Manager or Launch Engineer before the file will be used.
8 |
--------------------------------------------------------------------------------
/Checkout liquid layout/checkout.liquid:
--------------------------------------------------------------------------------
1 |
2 |
3 |
51 |
52 | {{ tracking_code }}
53 |
54 |
55 |
--------------------------------------------------------------------------------
/Create a media or press page/README.md:
--------------------------------------------------------------------------------
1 | # Shopify press page
2 | A great way to showcase your press appearances is with a social proof page showing those publications you're featured in. Dedicated blogs make it easy to feature collections of publications, so let's explore how.
3 | Relates to the [How to create a press page](http://freakdesign.com.au/blogs/news/how-to-create-a-press-page-in-shopify) post on the freakdesign blog.
--------------------------------------------------------------------------------
/Create a media or press page/snippet-press-grid.liquid:
--------------------------------------------------------------------------------
1 | {% comment %}
2 | /*
3 | * Simple press grid snippet
4 | *
5 | * Copyright (c) 2016 Jason Bowman (jason@freakdesign.com.au)
6 | * Licensed under the MIT license:
7 | * http://www.opensource.org/licenses/mit-license.php
8 | *
9 | *
10 | */
11 | {% endcomment %}
12 | {% for i in (1..1) %}
13 |
14 | {% comment %}
15 | Define the blog that contains all our press posts
16 | {% endcomment %}
17 | {% assign pressHandle = 'press' %}
18 |
19 | {% comment %}
20 | Check to make sure the blog has posts before going any further. If there are none found, show a simple message.
21 | {% endcomment %}
22 | {% if blogs[pressHandle].articles.size < 1 %}
23 |
No publications found. Check back soon
24 | {% break %}
25 | {% endif %}
26 |
27 | {% comment %}
28 | The Variables below should be added to Theme Settings if you are building this into a theme for a client.
29 | {% endcomment %}
30 | {% assign showPressTitle = true %}
31 |
32 | {% comment %}
33 | Show the plublished date for the article? Be sure to change the date to be the actual data of the press publication - not when you decided to publish the post on Shopify.
34 | {% endcomment %}
35 | {% assign showPressDate = true %}
36 |
37 | {% comment %}
38 | Show the article excerpt (if it exists)?
39 | {% endcomment %}
40 | {% assign showPressExcerpt = false %}
41 |
42 | {% comment %}
43 | Add a link to the article?
44 | {% endcomment %}
45 | {% assign showPressLink = false %}
46 |
47 | {% comment %}
48 | Define the image size. Change this to whatever size makes sense for your images.
49 | https://help.shopify.com/themes/liquid/filters/url-filters#img_url
50 | {% endcomment %}
51 | {% assign pressImageSize = '370x480' %}
52 |
53 | {% comment %}
54 | Basic styles for the example. You'll want to add your styles to the main stylesheet.
55 | {% endcomment %}
56 |
65 |
66 | {% comment %}
67 | The grid structure used below is based off the one in the Venture theme.
68 | You may need to adapt the code to match your grid.
69 | {% endcomment %}
70 |
71 | {% for article in blogs[pressHandle].articles limit:50 %}
72 | {% assign gridSize = 'medium-up--one-third' %}
73 |
74 | {% if showPressLink %}{% endif %}
75 |
76 |
77 |
78 | {% if showPressTitle %}
79 |
90 | {% endif %}
91 | {% if showPressLink %}{% endif %}
92 |
93 | {% endfor %}
94 |
95 |
96 | {% endfor %}
--------------------------------------------------------------------------------
/Create edit in admin button for current view/README.md:
--------------------------------------------------------------------------------
1 | # Create view in Admin button for current view
2 | Adds a quick button to the page to jump to the currently viewed resource.
3 |
4 |
5 | This version opts to avoid any Liquid edits so can be handled in JavaScript alone. The drawback to this is that Articles can be harder to capture so we fallback to the common tracking scripts in place. If the theme removes `content_for_header` or the tracking object changes, this script will no longer be able to jump to articles. Adding the ID to the page as a global within the theme (along with the edits to this script) could overcome that.
6 |
7 | This is related to [this blog post](http://freakdesign.com.au/blogs/news/15572921-add-an-edit-button-on-shopify-storefronts).
--------------------------------------------------------------------------------
/Create edit in admin button for current view/create-edit-button-for-current-view.js:
--------------------------------------------------------------------------------
1 | (function(){
2 |
3 | /* check for the admin bar. Remove the check if you want to show things regardless */
4 | if(document.getElementById('admin_bar_iframe')){ return }
5 |
6 | /* basic translation */
7 | var lang = {
8 | 'no':'Sorry, that can not be run here...',
9 | 'not_json':'That does not look like json...'
10 | };
11 |
12 | /* json test */
13 | var isJson = function(a) {
14 | try { JSON.parse(a) } catch (e) { return false }
15 | return true;
16 | };
17 |
18 | /* shortcut fn for adding warning messages to the console */
19 | var nope = function(a){
20 | if(typeof a === 'undefined'){ var a = lang.no }
21 | console.warn(a)
22 | return false
23 | }
24 |
25 | /* build the json path */
26 | var getJsonPath = function(){
27 | return [location.protocol, '//', location.host,location.pathname,'.json'].join('')
28 | };
29 |
30 | /* get the json */
31 | var getJson = function(u,c){
32 | var req = new XMLHttpRequest();
33 | req.open('GET', u, false);
34 | req.onreadystatechange = function() {
35 | if (req.readyState == 4 && req.status == 200) {
36 | if(typeof c === 'function'){
37 | if(!isJson(req.responseText)){ return nope(lang.not_json) }
38 | var json = JSON.parse(req.responseText);
39 | c(json,Object.keys(json)[0]);
40 | }
41 | }
42 | };
43 | req.send();
44 | };
45 |
46 | /* create the button and add the event listeners */
47 | var button = document.createElement('button');
48 | button.id = 'admin_bar_iframe';
49 | button.style = 'position: fixed;top: 70px;right: 1em;background-color: rgb(16, 206, 223);padding: .75em 1em;color: #FFF;cursor: pointer;border:none;z-index:99999';
50 | button.innerHTML = 'Edit This';
51 | button.addEventListener('click',function(e){
52 | e.target.blur();
53 | if(location.pathname === '/'){ return nope() }
54 | if(location.pathname.split('/')[1] === 'blogs'){
55 | /* fallback to the tracking script data, should it exist */
56 | if(typeof __st !== 'undefined' && __st.s){
57 | location.href = [location.protocol, '//', location.host,'/admin/articles/',__st.s.split('-')[1]].join('');
58 | return false;
59 | }
60 | return nope()
61 | }
62 | getJson(getJsonPath(),function(a,b){
63 | location.href = [location.protocol, '//', location.host,'/admin/',b+'s/',a[b].id].join('');
64 | })
65 | return false;
66 | });
67 | /* add the button to the DOM */
68 | document.getElementsByTagName('body')[0].appendChild(button);
69 |
70 | })()
--------------------------------------------------------------------------------
/Create edit in admin button for current view/create-edit-button-for-current-view.min.js:
--------------------------------------------------------------------------------
1 | (function(){if(!document.getElementById("admin_bar_iframe")){var d=function(a){"undefined"===typeof a&&(a="Sorry, that can not be run here...");console.warn(a);return!1},e=function(a,c){var b=new XMLHttpRequest;b.open("GET",a,!1);b.onreadystatechange=function(){if(4==b.readyState&&200==b.status&&"function"===typeof c){var a;a:{try{JSON.parse(b.responseText)}catch(e){a=!1;break a}a=!0}if(!a)return d("That does not look like json...");a=JSON.parse(b.responseText);c(a,Object.keys(a)[0])}};b.send()},
2 | c=document.createElement("button");c.id="admin_bar_iframe";c.style="position: fixed;top: 70px;right: 1em;background-color: rgb(16, 206, 223);padding: .75em 1em;color: #FFF;cursor: pointer;border:none;z-index:99999";c.innerHTML="Edit This";c.addEventListener("click",function(a){a.target.blur();if("/"===location.pathname)return d();if("blogs"===location.pathname.split("/")[1])return"undefined"!==typeof __st&&__st.s?(location.href=[location.protocol,"//",location.host,"/admin/articles/",__st.s.split("-")[1]].join(""),
3 | !1):d();e([location.protocol,"//",location.host,location.pathname,".json"].join(""),function(a,b){location.href=[location.protocol,"//",location.host,"/admin/",b+"s/",a[b].id].join("")});return!1});document.getElementsByTagName("body")[0].appendChild(c)}})();
--------------------------------------------------------------------------------
/Detect if a collection is published with Liquid/README.md:
--------------------------------------------------------------------------------
1 | # Detect if a collection is published
2 | Quick snippet to test a collections publish status. Really only useful when you're using collections in a menu (linklist)
3 |
4 | This is related to [this blog post](http://freakdesign.com.au/blogs/news/detect-if-a-collection-is-published-with-liquid).
--------------------------------------------------------------------------------
/Detect if a collection is published with Liquid/is-collection-published.liquid.html:
--------------------------------------------------------------------------------
1 | {%- for link in linklists.test-this.links -%}
2 | {%- assign collection = link.object -%}
3 | {%- if collection.published_at == blank -%}
4 |
{{ collection.title }} is not published
5 | {%- else -%}
6 |
{{ collection.title }} is published
7 | {%- endif %}
8 | {%- endfor -%}
--------------------------------------------------------------------------------
/Detect search type used in searches/README.md:
--------------------------------------------------------------------------------
1 | # Detect the search type in searches with Liquid
2 | Simple code to parse content from the `canonical_url` to grab the search type used.
3 |
4 | Relates to [Detect Search Type](http://freakdesign.com.au/blogs/news/detect-the-search-type-used-in-a-shopify-search-with-liquid) post on the freakdesign blog.
5 |
6 |
7 | ### Basic setup
8 | - Add the code as is or via a snippet to the search template (search.liquid)
9 | - Modify as per your needs
10 | - done...
--------------------------------------------------------------------------------
/Detect search type used in searches/show-search-type.liquid:
--------------------------------------------------------------------------------
1 | {%- comment -%}
2 |
3 | Liquid by Jason @ freakdesign.
4 | Questions? Ping me on twitter: @freakdesign
5 |
6 | Relates to blog post:
7 | http://freakdesign.com.au/blogs/news/detect-the-search-type-used-in-a-shopify-search-with-liquid
8 |
9 | {%- endcomment -%}
10 | {%- capture url %}{{ canonical_url }}{% endcapture -%}
11 | {%- if url contains 'type=' -%}
12 | {%- assign allowedTypes = 'product,page,article' | split:',' -%}
13 | {%- assign searchType = url | split:'type=' | last | split:'&' | first | strip -%}
14 | {%- if allowedTypes contains searchType -%}
15 | This search type was for {{ searchType }}s
16 | {%- endif -%}
17 | {%- endif -%}
--------------------------------------------------------------------------------
/Disable sorting by best seller/README.md:
--------------------------------------------------------------------------------
1 | # Disable collection sorting by best seller
2 |
3 | Refers to the [freakdesign blog post](https://freakdesign.com.au/blogs/news/disable-sort-by-best-selling-on-shopify).
4 |
5 | Shopify allows you to dynamically adjust the order of a collection using the sort_by querystring in the url. Let's explore some simple code that makes it harder for a customer to use that sorting querystring to see your best sellers.
6 |
--------------------------------------------------------------------------------
/Disable sorting by best seller/collection.liquid:
--------------------------------------------------------------------------------
1 | {% if collection.sort_by == 'best-selling' %}
2 | Nope.
3 | {% else %}
4 |
5 | {% endif %}
--------------------------------------------------------------------------------
/Dynamic pagination without alternate templates/README.md:
--------------------------------------------------------------------------------
1 | # Dynamic Shopify pagination without alternate or multiple templates
2 | When wanting to view Shopify collections with varied amounts of products per page (aka, pagination) the usual method involves creating a series of alternate templates. Let's explore an idea that ditches the multiples, and just uses one.
3 |
4 | [Blog Post](http://freakdesign.com.au/blogs/news/167340935-paginate-a-shopify-collection-by-dynamic-amounts-without-multiple-templates)
5 |
6 | [Demo](https://jasons-experiments.myshopify.com/collections/all)
7 |
8 |
9 | ##### dynamic-pagination-select.liquid:
10 | Example HTML / Liquid for the `