├── .gitignore ├── LICENSE ├── README.md ├── config-sample.yml ├── jsconfig.json ├── package.json ├── src ├── App.vue ├── components │ ├── Footer.vue │ ├── Header.vue │ └── ProductGridTile.vue ├── config │ └── settings_data.js ├── core │ ├── app-data.js │ ├── models │ │ ├── product.js │ │ └── variant.js │ ├── modern │ │ ├── layout │ │ │ └── theme.liquid │ │ ├── snippets │ │ │ ├── collections-data-json.liquid │ │ │ ├── collections-data-script.liquid │ │ │ ├── data-script-tags.liquid │ │ │ ├── error-404-json.liquid │ │ │ ├── errors-data-script.liquid │ │ │ ├── products-data-json.liquid │ │ │ └── products-data-script.liquid │ │ └── templates │ │ │ ├── collection.endpoint.liquid │ │ │ └── product.endpoint.liquid │ ├── shopify │ │ ├── assets │ │ │ ├── giftcard.js │ │ │ ├── ico-select.svg.liquid │ │ │ ├── theme.js │ │ │ ├── theme.scss.liquid │ │ │ └── vendor.js │ │ ├── config │ │ │ ├── settings_data.json │ │ │ └── settings_schema.json │ │ ├── layout │ │ │ ├── gift_card.liquid │ │ │ └── password.liquid │ │ ├── locales │ │ │ ├── de.json │ │ │ ├── en.default.json │ │ │ ├── es.json │ │ │ ├── fr.json │ │ │ ├── pt-BR.json │ │ │ └── pt-PT.json │ │ ├── sections │ │ │ ├── collection-list.liquid │ │ │ ├── featured-collection.liquid │ │ │ ├── featured-product.liquid │ │ │ ├── footer.liquid │ │ │ ├── header.liquid │ │ │ └── product.liquid │ │ ├── snippets │ │ │ ├── icon-amazon_payments.liquid │ │ │ ├── icon-american_express.liquid │ │ │ ├── icon-apple_pay.liquid │ │ │ ├── icon-arrow-down.liquid │ │ │ ├── icon-bitcoin.liquid │ │ │ ├── icon-cart.liquid │ │ │ ├── icon-cirrus.liquid │ │ │ ├── icon-close.liquid │ │ │ ├── icon-dankort.liquid │ │ │ ├── icon-diners_club.liquid │ │ │ ├── icon-discover.liquid │ │ │ ├── icon-dogecoin.liquid │ │ │ ├── icon-dwolla.liquid │ │ │ ├── icon-facebook.liquid │ │ │ ├── icon-forbrugsforeningen.liquid │ │ │ ├── icon-hamburger.liquid │ │ │ ├── icon-instagram.liquid │ │ │ ├── icon-interac.liquid │ │ │ ├── icon-jcb.liquid │ │ │ ├── icon-litecoin.liquid │ │ │ ├── icon-lock.liquid │ │ │ ├── icon-maestro.liquid │ │ │ ├── icon-master.liquid │ │ │ ├── icon-minus.liquid │ │ │ ├── icon-paypal.liquid │ │ │ ├── icon-pinterest.liquid │ │ │ ├── icon-plus.liquid │ │ │ ├── icon-rss.liquid │ │ │ ├── icon-search.liquid │ │ │ ├── icon-shopify-logo.liquid │ │ │ ├── icon-snapchat.liquid │ │ │ ├── icon-tumblr.liquid │ │ │ ├── icon-twitter.liquid │ │ │ ├── icon-vimeo.liquid │ │ │ ├── icon-visa.liquid │ │ │ ├── icon-youtube.liquid │ │ │ ├── no-blocks.liquid │ │ │ ├── pagination.liquid │ │ │ ├── social-meta-tags.liquid │ │ │ └── social-sharing.liquid │ │ └── templates │ │ │ ├── 404.liquid │ │ │ ├── article.liquid │ │ │ ├── blog.liquid │ │ │ ├── cart.liquid │ │ │ ├── collection.liquid │ │ │ ├── customers │ │ │ ├── account.liquid │ │ │ ├── activate_account.liquid │ │ │ ├── addresses.liquid │ │ │ ├── login.liquid │ │ │ ├── order.liquid │ │ │ ├── register.liquid │ │ │ └── reset_password.liquid │ │ │ ├── gift_card.liquid │ │ │ ├── index.liquid │ │ │ ├── list-collections.liquid │ │ │ ├── page.contact.liquid │ │ │ ├── page.liquid │ │ │ ├── page.styles.liquid │ │ │ ├── password.liquid │ │ │ ├── product.liquid │ │ │ └── search.liquid │ └── stores │ │ ├── collections-store.js │ │ ├── errors-store.js │ │ └── products-store.js ├── index.js ├── locales │ └── en-default.js ├── routes.js ├── services │ └── i18n.js └── views │ ├── BlogPostView.vue │ ├── BlogView.vue │ ├── CollectionView.vue │ ├── Error404View.vue │ ├── HomeView.vue │ ├── PageView.vue │ └── ProductDetailView.vue └── webpack.config.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | config.yml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 David McCuskey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # shopify-modern 2 | 3 | This proof-of-concept shows a method of creating an ecommerce experience for Shopify by using modern front-end development tools and techniques, while still leveraging some of the beneficial features of the Shopify system & infrastructure. 4 | 5 | 6 | ## Overview 7 | 8 | Shopify's Wordpress-like structure is as much fun to work with as Wordpress – "let's develop like it's 1999!" :-) These days we know that it can be done better. 9 | 10 | This project shows a working, hybrid Shopify-template which still runs on the Shopify infrastructure. However, because of a very clear separation between Shopify and the front-end, we can develop the web experience using modern tools. 11 | 12 | While this project template is NOT full-SPA, it helps by giving a roadmap for those wanting to transform an existing Shopify template into one which is both modern and full-SPA. The project already has features to help with that goal in mind. 13 | 14 | 15 | 16 | ## Benefits 17 | 18 | Here are some of the benefits of this framework / concept: 19 | 20 | **Framework** 21 | 22 | * Modern development with Vuejs 23 | * Internationalization (i18n) 24 | * Special tags & filters (like in Shopify Liquid) 25 | * Clear separation between Shopify Liquid & Vuejs code & markup 26 | * Rendered page components determined using Vuejs routes paired with Shopify URLs. 27 | * Avoid any potential issues with [Shopify 64k page-limit](https://help.shopify.com/manual/using-themes/troubleshooting/fix-64-kilobyte-limit-errors) 28 | * Search-bot friendly (soon) 29 | 30 | **Shopify** 31 | 32 | * Hosting / Scalability handled by Shopify 33 | * SEO friendly 34 | * Server-Side-Augmentation (ie, lightweight Server Side Rendering) 35 | * Settings / Config files still useful 36 | 37 | **Future** 38 | 39 | * Clear path to full-SPA 40 | * Ability to do *local* development ! 41 | 42 | 43 | ## How it works 44 | 45 | One of the main benefits is that the framework can serialize many of the [Shopify data-objects](https://help.shopify.com/themes/liquid/objects). This serialized data can either be embedded in the primary HTML page or loaded later using HTTP requests. The corresponding front-end Vuejs objects can initialize themselves with either method. 46 | 47 | Though this doesn't qualify as full server-side rendering, having embedded data speeds up the initial page draw since the information will not need to be loaded by subsequent AJAX requests. 48 | 49 | In the future, there will be more control over which data is embedded and which is lazy-loaded after the first page render. 50 | 51 | ### Steps to Template-Freedom 52 | 53 | If you want to start integrating the ideas into an existing project, your main goal is to move almost all of the site information out of the Liquid templates. Two important steps for that would be: 54 | 55 | 1. insert app anchors into HTML 56 | 57 | Depending on how far along you are with the transition, you can use one or many anchors which will be under control of your framework (eg, Vuejs). 58 | 59 | ``` 60 | 61 |
62 | ``` 63 | 64 | ``` 65 | 66 |
67 |
68 | ``` 69 | 70 | 1. integrate a normal build process 71 | 72 | use Webpack or Gulp to generate a typical build file, eg `dist/build.js`. 73 | 74 | *Do NOT include any of your front-end code in the Fluid templates*. All of it should be inside of `build.js`, and that file being sourced from `theme.liquid`. 75 | 76 | 77 | ## Setup 78 | 79 | (rough notes!) 80 | 81 | 1. Install [Shopify Themekit](https://shopify.github.io/themekit/) 82 | 1. Rename `config-sample.yml` to `config.yml`. Add your password, theme id, store name. 83 | 1. Run `webpack` to re-pack code upon changes 84 | 1. Run `themekit` to upload webpack output to Shopify 85 | 86 | 87 | ## Libraries 88 | 89 | This project uses these libraries: 90 | 91 | * https://shopify.github.io/themekit/ 92 | 93 | We use **themekit** to upload files, as opposed to [Slate](https://github.com/Shopify/slate), since **Slate** is geared towards traditional Shopify theme development. ([Quickshot](https://quickshot.readme.io) seems like a good choice, too.) 94 | 95 | 96 | ## Inspiration 97 | 98 | Inspiration for this project came from the following: 99 | 100 | * https://www.shopify.com/partners/blog/28500611-using-javascript-to-super-power-your-clients-shopify-site 101 | * https://github.com/tshamz/shopify-frankenstein 102 | 103 | 104 | ## References 105 | 106 | * https://stackoverflow.com/questions/43505094/using-vue-js-in-shopify-liquid-templates 107 | 108 | As a side benefit of using this structure, any issues with delimiter conflicts are avoided. 109 | -------------------------------------------------------------------------------- /config-sample.yml: -------------------------------------------------------------------------------- 1 | # This file contains the information needed for Shopify to authenticate 2 | # requests and edit/update your remote theme files. 3 | # 4 | # 1. Set up a private app (https://help.shopify.com/api/guides/api-credentials#generate-private-app-credentials) 5 | # with "Read and write" permissions for "Theme templates and theme assets". 6 | # 2. Replace the required variables for each environment below. 7 | # 8 | # password, theme_id, and store variables are required. 9 | # 10 | # For more information on this config file: 11 | # Configuration variables | http://shopify.github.io/themekit/configuration/ 12 | # Ignore patterns | http://shopify.github.io/themekit/ignores/ 13 | 14 | --- 15 | 16 | development: 17 | password: 18 | theme_id: 19 | directory: "dist" 20 | store: your-shop.myshopify.com 21 | ignore_files: 22 | 23 | production: 24 | password: 25 | theme_id: "live" 26 | store: your-shop.myshopify.com 27 | ignore_files: -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "es2015" 7 | ], 8 | "module": "commonjs", 9 | "isolatedModules": false, 10 | "experimentalDecorators": true, 11 | "noImplicitAny": false, 12 | "noImplicitThis": true, 13 | "strictNullChecks": true, 14 | "removeComments": true, 15 | "suppressImplicitAnyIndexErrors": true, 16 | "allowSyntheticDefaultImports": true, 17 | "sourceMap": true 18 | }, 19 | "exclude": [ 20 | "node_modules", 21 | "dist" 22 | ], 23 | "include": [ 24 | "src/**/*.js", 25 | "src/**/*.vue" 26 | ], 27 | "compileOnSave": false 28 | } 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-theme", 3 | "version": "0.0.1", 4 | "devDependencies": { 5 | "babel-loader": "^7.0.0", 6 | "babel-plugin-transform-runtime": "^6.23.0", 7 | "babel-preset-es2015": "^6.24.1", 8 | "babelify": "^7.3.0", 9 | "browserify": "^14.4.0", 10 | "copy-webpack-plugin": "^4.0.1", 11 | "css-loader": "^0.28.4", 12 | "file-loader": "^0.11.2", 13 | "style-loader": "^0.18.2", 14 | "vue": "^2.3.4", 15 | "vue-loader": "^12.2.1", 16 | "vueify": "^9.4.1", 17 | "webpack": "^2.6.1", 18 | "webpack-merge": "^4.1.0", 19 | "webpack-notifier": "^1.5.0" 20 | }, 21 | "dependencies": { 22 | "jquery": "^3.2.1", 23 | "vue-router": "^2.5.3" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | /* 2 | main application Vue component 3 | */ 4 | 5 | 15 | 16 | 17 | 40 | 41 | 42 | 47 | -------------------------------------------------------------------------------- /src/components/Footer.vue: -------------------------------------------------------------------------------- 1 | /* 2 | Footer component 3 | */ 4 | 5 | 11 | 12 | 16 | 17 | 19 | -------------------------------------------------------------------------------- /src/components/Header.vue: -------------------------------------------------------------------------------- 1 | /* 2 | Header component 3 | */ 4 | 5 | 6 | 32 | 33 | 34 | 61 | 62 | 63 | 65 | -------------------------------------------------------------------------------- /src/components/ProductGridTile.vue: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | */ 4 | 5 | 28 | 29 | 30 | 45 | 46 | 47 | 55 | -------------------------------------------------------------------------------- /src/config/settings_data.js: -------------------------------------------------------------------------------- 1 | export default { 2 | "header": { 3 | "settings": { 4 | "logo": "", 5 | "logo_home": "", 6 | "logo_mobile": "", 7 | "logo_width": "250", 8 | "main_linklist": "main-menu", 9 | "dropdown_column_links": "5", 10 | "logo_top_padding": "10", 11 | "menu_top_padding": "5", 12 | "content_top_padding": "66", 13 | "button_label": "Preorder", 14 | "link": "shopify:\/\/products\/hello", 15 | "social_icons_enabled": false, 16 | "search_enabled": false, 17 | "fixed_header": true, 18 | "behind_menu": false, 19 | "announcement_message": "", 20 | "announcement_link": "" 21 | } 22 | }, 23 | "footer": { 24 | "type": "footer", 25 | "settings": { 26 | "copyright_text": "", 27 | "display_designed_by": true, 28 | "display_payment_methods": false 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/core/app-data.js: -------------------------------------------------------------------------------- 1 | /* 2 | App Data service 3 | 4 | this module processes all of the json data from Shopify 5 | */ 6 | 7 | // Components 8 | import { CollectionsStore } from './stores/collections-store' 9 | import { ErrorsStore } from './stores/errors-store' 10 | import { ProductsStore } from './stores/products-store' 11 | 12 | 13 | 14 | // Support functions 15 | 16 | const WARN_MISSING_DATA_NODE = "No HTML data-node found" 17 | const WARN_NO_NODE_DATA = "Node data is empty" 18 | 19 | function getHtmlData( key ) { 20 | const node = document.getElementById( key ) 21 | if ( !node ) return Promise.reject( WARN_MISSING_DATA_NODE ) 22 | return Promise.resolve( node.innerHTML ) 23 | } 24 | 25 | function processHtmlData( data ) { 26 | if ( data=="" ) 27 | return Promise.reject( WARN_NO_NODE_DATA ) 28 | else { 29 | try { 30 | return Promise.resolve( JSON.parse( data ) ) 31 | } catch( e ) { 32 | return Promise.reject( e ) 33 | } 34 | } 35 | } 36 | 37 | function setJsonDataOnInstance( instance ) { 38 | return function( json ) { 39 | instance.setData( json ) 40 | } 41 | } 42 | 43 | 44 | // initialize Data Stores 45 | 46 | 47 | const COLLECTIONS_DATA_ID = 'collections-data' 48 | const Collections = new CollectionsStore(); // need the semi here 49 | 50 | (function( key, instance ) { 51 | 52 | const setJsonData = setJsonDataOnInstance( instance ) 53 | 54 | getHtmlData( key ) 55 | .then( processHtmlData ) 56 | .then( setJsonData ) 57 | .catch( err => console.warn( `WARNING while loading '${key}':`, err ) ) 58 | 59 | })( COLLECTIONS_DATA_ID, Collections ) 60 | 61 | 62 | const ERRORS_DATA_ID = 'errors-data' 63 | const Errors = new ErrorsStore(); // need the semi here 64 | 65 | (function( key, instance ) { 66 | 67 | const setJsonData = setJsonDataOnInstance( instance ) 68 | 69 | getHtmlData( key ) 70 | .then( processHtmlData ) 71 | .then( setJsonData ) 72 | .catch( err => console.warn( `WARNING while loading '${key}':`, err ) ) 73 | 74 | })( ERRORS_DATA_ID, Errors ) 75 | 76 | 77 | const PRODUCTS_DATA_ID = 'products-data' 78 | const Products = new ProductsStore(); // need the semi here 79 | 80 | (function( key, instance ) { 81 | 82 | const setJsonData = setJsonDataOnInstance( instance ) 83 | 84 | getHtmlData( key ) 85 | .then( processHtmlData ) 86 | .then( setJsonData ) 87 | .catch( err => console.warn( `WARNING while loading '${key}':`, err ) ) 88 | 89 | })( PRODUCTS_DATA_ID, Products ) 90 | 91 | 92 | 93 | export { Collections, Errors, Products } 94 | -------------------------------------------------------------------------------- /src/core/models/product.js: -------------------------------------------------------------------------------- 1 | /* 2 | Product model 3 | 4 | object to help retrieve Product information from Collections data 5 | */ 6 | 7 | // Libs 8 | import Vue from 'vue' 9 | 10 | // Components 11 | import { Variant } from '../models/variant' 12 | 13 | 14 | export const Product = Vue.extend( { 15 | 16 | data: function() { 17 | return { 18 | available: false, 19 | compare_at_price: null, 20 | compare_at_price_max: 0, 21 | compare_at_price_min: 0, 22 | compare_at_price_varies: false, 23 | content: "", 24 | created_at: "", // ISO date string 25 | description: "", 26 | featured_image: "", 27 | handle: "", // 'i-love-unicorn' 28 | id: 0, 29 | images: [], 30 | options: [], 31 | price: 0, 32 | price_max: 0, 33 | price_min: 0, 34 | price_varies: false, 35 | published_at: "", // ISO date string 36 | tags: [], 37 | title: "", 38 | type: "", 39 | _variants: {}, 40 | vendor: "", 41 | } 42 | }, 43 | 44 | 45 | computed: { 46 | 47 | variants: { 48 | get: function() { 49 | console.log("product variants", this.$data._variants ) 50 | return this.$data._variants 51 | }, 52 | set: function( list ) { 53 | for (let idx=0, len=list.length; idx < len; idx++) { 54 | let d = list[ idx ] 55 | let id = d.id 56 | let o = this.$data._variants[ id ] 57 | if ( o==undefined ) { 58 | o = new Variant() 59 | this.$data._variants[ id ] = o 60 | } 61 | o.setData( d ) 62 | } 63 | } 64 | }, 65 | 66 | url() { 67 | return `/products/${this.handle}` 68 | } 69 | 70 | }, 71 | 72 | 73 | methods: { 74 | 75 | setData( data ) { 76 | if (!data) return 77 | for ( let prop in data ) { 78 | this[ prop ] = data[ prop ] 79 | } 80 | }, 81 | 82 | } 83 | 84 | }) 85 | -------------------------------------------------------------------------------- /src/core/models/variant.js: -------------------------------------------------------------------------------- 1 | /* 2 | Variant model 3 | 4 | object to help retrieve Variant information from Product data 5 | */ 6 | 7 | // Libs 8 | import Vue from 'vue' 9 | 10 | 11 | export const Variant = Vue.extend( { 12 | 13 | data: function() { 14 | return { 15 | available: false, 16 | barcode: "", 17 | compare_at_price_max: 0, 18 | featured_image: "", 19 | id: 0, 20 | inventory_management: null, 21 | inventory_policy: "deny", 22 | inventory_quantity: 1, 23 | name: "", 24 | option1: "", 25 | option2: "", 26 | option3: "", 27 | options: [], // 28 | price: 0, 29 | public_title: "", 30 | requires_shipping: true, 31 | sku: "", 32 | taxable: true, 33 | title: "", 34 | weight: 0, 35 | } 36 | }, 37 | 38 | 39 | methods: { 40 | 41 | setData( data ) { 42 | if (!data) return 43 | for ( let prop in data ) { 44 | this[ prop ] = data[ prop ] 45 | } 46 | }, 47 | 48 | } 49 | 50 | }) 51 | -------------------------------------------------------------------------------- /src/core/modern/layout/theme.liquid: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {% if settings.favicon != blank %} 12 | 13 | {% endif %} 14 | 15 | {% capture seo_title %} 16 | {{ page_title }} 17 | {% if current_tags %} 18 | {%- assign meta_tags = current_tags | join: ', ' %} – {{ 'general.meta.tags' | t: tags: meta_tags -}} 19 | {% endif %} 20 | {% if current_page != 1 %} 21 | – {{ 'general.meta.page' | t: page: current_page }} 22 | {% endif %} 23 | {% unless page_title contains shop.name %} 24 | – {{ shop.name }} 25 | {% endunless %} 26 | {% endcapture %} 27 | {{ seo_title }} 28 | 29 | {% if page_description %} 30 | 31 | {% endif %} 32 | 33 | {% include 'social-meta-tags' %} 34 | 35 | {{ 'theme.scss.css' | asset_url | stylesheet_tag }} 36 | 37 | 49 | 50 | {% if template.directory == 'customers' %} 51 | 52 | 53 | {% endif %} 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | {{ content_for_header }} 62 | 63 | {% include 'data-script-tags' %} 64 | 65 | 66 | 67 | 68 | 69 |
Loading...
70 | 71 | 72 | 73 | {% section 'header' %} 74 | 75 | 76 |
77 | {{ content_for_layout }} 78 |
79 | 80 | {% section 'footer' %} 81 | 82 | {{ 'build.js' | asset_url | script_tag }} 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /src/core/modern/snippets/collections-data-json.liquid: -------------------------------------------------------------------------------- 1 | {%- if collection.products -%} 2 | { "title": {{ collection.title | json }}, "products": {{ collection.products | json }} } 3 | {%- endif -%} 4 | -------------------------------------------------------------------------------- /src/core/modern/snippets/collections-data-script.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/modern/snippets/data-script-tags.liquid: -------------------------------------------------------------------------------- 1 | {% include 'errors-data-script' %} 2 | {% include 'collections-data-script' %} 3 | {% include 'products-data-script' %} 4 | -------------------------------------------------------------------------------- /src/core/modern/snippets/error-404-json.liquid: -------------------------------------------------------------------------------- 1 | { "is_error": true, "type":"404" } -------------------------------------------------------------------------------- /src/core/modern/snippets/errors-data-script.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/modern/snippets/products-data-json.liquid: -------------------------------------------------------------------------------- 1 | {%- if product -%}{{ product | json }}{%- endif -%} 2 | -------------------------------------------------------------------------------- /src/core/modern/snippets/products-data-script.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/modern/templates/collection.endpoint.liquid: -------------------------------------------------------------------------------- 1 | {% layout none %}{%- include 'collections-data-json' -%} -------------------------------------------------------------------------------- /src/core/modern/templates/product.endpoint.liquid: -------------------------------------------------------------------------------- 1 | {% layout none %}{%- include 'products-data-json' -%} -------------------------------------------------------------------------------- /src/core/shopify/assets/giftcard.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Gift Card Template Script 3 | * ------------------------------------------------------------------------------ 4 | * A file that contains scripts highly couple code to the Gift Card template. 5 | */ 6 | 7 | (function() { 8 | var config = { 9 | qrCode: '#QrCode', 10 | printButton: '#PrintGiftCard', 11 | giftCardCode: '.giftcard__code' 12 | }; 13 | 14 | var $qrCode = $(config.qrCode); 15 | 16 | new QRCode($qrCode[0], { 17 | text: $qrCode.attr('data-identifier'), 18 | width: 120, 19 | height: 120 20 | }); 21 | 22 | $(config.printButton).on('click', function() { 23 | window.print(); 24 | }); 25 | 26 | // Auto-select gift card code on click, based on ID passed to the function 27 | $(config.giftCardCode).on('click', {element: 'GiftCardDigits'}, selectText); 28 | 29 | function selectText(evt) { 30 | var text = document.getElementById(evt.data.element); 31 | var range = ''; 32 | 33 | if (document.body.createTextRange) { 34 | range = document.body.createTextRange(); 35 | range.moveToElementText(text); 36 | range.select(); 37 | } else if (window.getSelection) { 38 | var selection = window.getSelection(); 39 | range = document.createRange(); 40 | range.selectNodeContents(text); 41 | selection.removeAllRanges(); 42 | selection.addRange(range); 43 | } 44 | } 45 | })(); 46 | -------------------------------------------------------------------------------- /src/core/shopify/assets/ico-select.svg.liquid: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/core/shopify/config/settings_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "current": "Default", 3 | "presets": { 4 | "Default": { 5 | "sections": { 6 | "collection-list": { 7 | "type": "collection-list", 8 | "blocks": { 9 | "collection-list-0": { 10 | "type": "collection" 11 | }, 12 | "collection-list-1": { 13 | "type": "collection" 14 | }, 15 | "collection-list-2": { 16 | "type": "collection" 17 | } 18 | }, 19 | "block_order": [ 20 | "collection-list-0", 21 | "collection-list-1", 22 | "collection-list-2" 23 | ] 24 | }, 25 | "featured-collection": { 26 | "type": "featured-collection", 27 | "settings": { 28 | "collection": "frontpage" 29 | } 30 | }, 31 | "featured-product": { 32 | "type": "featured-product" 33 | } 34 | }, 35 | "content_for_index": [ 36 | "collection-list", 37 | "featured-collection", 38 | "featured-product" 39 | ] 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/core/shopify/config/settings_schema.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "theme_info", 4 | "theme_name": "Slate", 5 | "theme_version": "1.0.0", 6 | "theme_author": "Shopify", 7 | "theme_documentation_url": "https://github.com/Shopify/slate", 8 | "theme_support_email": "theme-support@shopify.com" 9 | }, 10 | { 11 | "name": "Typography", 12 | "settings": [ 13 | { 14 | "type": "select", 15 | "id": "type_base_size", 16 | "label": "Base size", 17 | "default": "16px", 18 | "options": [ 19 | { 20 | "value": "14px", 21 | "label": "14px" 22 | }, 23 | { 24 | "value": "15px", 25 | "label": "15px" 26 | }, 27 | { 28 | "value": "16px", 29 | "label": "16px" 30 | }, 31 | { 32 | "value": "17px", 33 | "label": "17px" 34 | } 35 | ] 36 | } 37 | ] 38 | }, 39 | { 40 | "name": "Colors", 41 | "settings": [ 42 | { 43 | "type": "header", 44 | "content": "General colors" 45 | }, 46 | { 47 | "type": "color", 48 | "id": "color_primary", 49 | "label": "Primary color", 50 | "default": "#000", 51 | "info": "Used for text links, and primary buttons" 52 | }, 53 | { 54 | "type": "color", 55 | "id": "color_body_text", 56 | "label": "Text color", 57 | "default": "#000", 58 | "info": "Color used for content and paragraph text" 59 | } 60 | ] 61 | }, 62 | { 63 | "name": "Social media", 64 | "settings": [ 65 | { 66 | "type": "header", 67 | "content": "Social sharing options" 68 | }, 69 | { 70 | "type": "checkbox", 71 | "id": "social_sharing_blog", 72 | "label": "Enable sharing for blog articles", 73 | "default": true 74 | }, 75 | { 76 | "type": "checkbox", 77 | "id": "share_facebook", 78 | "label": "Share on Facebook", 79 | "default": true 80 | }, 81 | { 82 | "type": "checkbox", 83 | "id": "share_twitter", 84 | "label": "Tweet on Twitter", 85 | "default": true 86 | }, 87 | { 88 | "type": "checkbox", 89 | "id": "share_pinterest", 90 | "label": "Pin on Pinterest", 91 | "default": true 92 | }, 93 | { 94 | "type": "header", 95 | "content": "Sharing links" 96 | }, 97 | { 98 | "type": "text", 99 | "id": "social_twitter_link", 100 | "label": "Twitter link" 101 | }, 102 | { 103 | "type": "text", 104 | "id": "social_facebook_link", 105 | "label": "Facebook link" 106 | }, 107 | { 108 | "type": "text", 109 | "id": "social_pinterest_link", 110 | "label": "Pinterest link" 111 | }, 112 | { 113 | "type": "text", 114 | "id": "social_instagram_link", 115 | "label": "Instagram link" 116 | }, 117 | { 118 | "type": "text", 119 | "id": "social_snapchat_link", 120 | "label": "Snapchat link" 121 | }, 122 | { 123 | "type": "text", 124 | "id": "social_tumblr_link", 125 | "label": "Tumblr link" 126 | }, 127 | { 128 | "type": "text", 129 | "id": "social_youtube_link", 130 | "label": "Youtube link" 131 | }, 132 | { 133 | "type": "text", 134 | "id": "social_vimeo_link", 135 | "label": "Vimeo link" 136 | } 137 | ] 138 | }, 139 | { 140 | "name": "Cart", 141 | "settings": [ 142 | { 143 | "type": "checkbox", 144 | "id": "cart_notes_enable", 145 | "label": "Enable cart notes", 146 | "default": true 147 | } 148 | ] 149 | }, 150 | { 151 | "name": "Favicon", 152 | "settings": [ 153 | { 154 | "type": "image_picker", 155 | "id": "favicon", 156 | "label": "Favicon image", 157 | "info": "Will be scaled down to 32 x 32px" 158 | } 159 | ] 160 | } 161 | ] 162 | -------------------------------------------------------------------------------- /src/core/shopify/layout/gift_card.liquid: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {% if settings.favicon != blank %} 12 | 13 | {% endif %} 14 | 15 | {%- assign formatted_initial_value = gift_card.initial_value | money_without_trailing_zeros: gift_card.currency -%} 16 | {%- assign formatted_initial_value_stripped = formatted_initial_value | strip_html -%} 17 | {{ 'gift_cards.issued.title' | t: value: formatted_initial_value_stripped, shop: shop.name }} 18 | 19 | 20 | 21 | {{ 'theme.scss.css' | asset_url | stylesheet_tag }} 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | {{ content_for_header }} 33 | 34 | 35 | 36 |
37 | {{ content_for_layout }} 38 |
39 | 40 | 41 | -------------------------------------------------------------------------------- /src/core/shopify/layout/password.liquid: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {% if settings.favicon != blank %} 12 | 13 | {% endif %} 14 | 15 | {{ shop.name }} 16 | 17 | {% if page_description %} 18 | 19 | {% endif %} 20 | 21 | {% include 'social-meta-tags' %} 22 | 23 | {{ 'theme.scss.css' | asset_url | stylesheet_tag }} 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {{ content_for_header }} 32 | 33 | 34 | 35 |
36 |

37 | 40 |

41 |
42 | 43 |
44 | {{ content_for_layout }} 45 |
46 | 47 | 56 | 57 |
58 |

{{ 'general.password_page.login_form_heading' | t }}

59 | {% form 'storefront_password' %} 60 | {{ form.errors | default_errors }} 61 | 62 | 66 | 69 | {% endform %} 70 |

{{ 'general.password_page.admin_link_html' | t }}

71 |
72 | 73 | 74 | -------------------------------------------------------------------------------- /src/core/shopify/locales/en.default.json: -------------------------------------------------------------------------------- 1 | { 2 | "general": { 3 | "accessibility": { 4 | "skip_to_content": "Skip to content" 5 | }, 6 | "meta": { 7 | "tags": "Tagged \"{{ tags }}\"", 8 | "page": "Page {{ page }}" 9 | }, 10 | "404": { 11 | "title": "404 Page Not Found", 12 | "subtext_html": "The page you requested does not exist. Click here to continue shopping." 13 | }, 14 | "password_page": { 15 | "opening_soon": "Opening Soon", 16 | "spread_the_word": "Spread the word", 17 | "login_form_heading": "Enter store using password", 18 | "login_form_password_label": "Password", 19 | "login_form_password_placeholder": "Your password", 20 | "login_form_submit": "Enter", 21 | "signup_form_heading": "Find out when we open", 22 | "signup_form_email_label": "Email", 23 | "signup_form_email_placeholder": "Your email", 24 | "signup_form_submit": "Submit", 25 | "signup_form_success": "We will send you an email right before we open!", 26 | "admin_link_html": "Are you the store owner? Log in here", 27 | "password_link": "Enter using password", 28 | "powered_by_shopify_html": "This shop will be powered by {{ shopify }}" 29 | }, 30 | "social": { 31 | "share_on_facebook": "Share", 32 | "share_on_twitter": "Tweet", 33 | "share_on_pinterest": "Pin it", 34 | "alt_text": { 35 | "share_on_facebook": "Share on Facebook", 36 | "share_on_twitter": "Tweet on Twitter", 37 | "share_on_pinterest": "Pin on Pinterest" 38 | } 39 | }, 40 | "search": { 41 | "no_results_html": "Your search for \"{{ terms }}\" did not yield any results.", 42 | "results_for_html": "Your search for \"{{ terms }}\" revealed the following:", 43 | "title": "Search for products on our site", 44 | "placeholder": "Search our store", 45 | "submit": "Search" 46 | } 47 | }, 48 | "blogs": { 49 | "article": { 50 | "author_on_date_html": "Posted by {{ author }} on {{ date }}", 51 | "comment_meta_html": "{{ author }} on {{ date }}", 52 | "read_more": "Read more" 53 | }, 54 | "comments": { 55 | "title": "Leave a comment", 56 | "name": "Name", 57 | "email": "Email", 58 | "message": "Message", 59 | "post": "Post comment", 60 | "moderated": "Please note, comments must be approved before they are published", 61 | "success_moderated": "Your comment was posted successfully. We will publish it in a little while, as our blog is moderated.", 62 | "success": "Your comment was posted successfully! Thank you!", 63 | "with_count": { 64 | "one": "{{ count }} comment", 65 | "other": "{{ count }} comments" 66 | } 67 | }, 68 | "general": { 69 | "categories": "Categories" 70 | } 71 | }, 72 | "cart": { 73 | "general": { 74 | "title": "Shopping Cart", 75 | "remove": "Remove", 76 | "note": "Special instructions for seller", 77 | "subtotal": "Subtotal", 78 | "shipping_at_checkout": "Shipping & taxes calculated at checkout", 79 | "update": "Update Cart", 80 | "checkout": "Check Out", 81 | "empty": "Your cart is currently empty.", 82 | "cookies_required": "Enable cookies to use the shopping cart", 83 | "continue_browsing_html": "Continue browsing here.", 84 | "item_quantity": "Item quantity", 85 | "savings": "You're saving" 86 | }, 87 | "label": { 88 | "product": "Product", 89 | "price": "Price", 90 | "quantity": "Quantity", 91 | "total": "Total", 92 | "discounted_price": "Discounted price", 93 | "original_price": "Original price" 94 | } 95 | }, 96 | "collections": { 97 | "general": { 98 | "no_matches": "Sorry, there are no products in this collection", 99 | "link_title": "Browse our {{ title }} collection" 100 | } 101 | }, 102 | "contact": { 103 | "form": { 104 | "name": "Name", 105 | "email": "Email", 106 | "phone": "Phone Number", 107 | "message": "Message", 108 | "send": "Send", 109 | "post_success": "Thanks for contacting us. We'll get back to you as soon as possible." 110 | } 111 | }, 112 | "customer": { 113 | "account": { 114 | "title": "My Account", 115 | "details": "Account Details", 116 | "view_addresses": "View Addresses", 117 | "return": "Return to Account Details" 118 | }, 119 | "activate_account": { 120 | "title": "Activate Account", 121 | "subtext": "Create your password to activate your account.", 122 | "password": "Password", 123 | "password_confirm": "Confirm Password", 124 | "submit": "Activate Account", 125 | "cancel": "Decline Invitation" 126 | }, 127 | "addresses": { 128 | "title": "Your Addresses", 129 | "default": "Default", 130 | "add_new": "Add a New Address", 131 | "edit_address": "Edit address", 132 | "first_name": "First Name", 133 | "last_name": "Last Name", 134 | "company": "Company", 135 | "address1": "Address1", 136 | "address2": "Address2", 137 | "city": "City", 138 | "country": "Country", 139 | "province": "Province", 140 | "zip": "Postal/Zip Code", 141 | "phone": "Phone", 142 | "set_default": "Set as default address", 143 | "add": "Add Address", 144 | "update": "Update Address", 145 | "cancel": "Cancel", 146 | "edit": "Edit", 147 | "delete": "Delete", 148 | "delete_confirm": "Are you sure you wish to delete this address?" 149 | }, 150 | "login": { 151 | "title": "Login", 152 | "email": "Email", 153 | "password": "Password", 154 | "forgot_password": "Forgot your password?", 155 | "sign_in": "Sign In", 156 | "cancel": "Return to Store", 157 | "guest_title": "Continue as a guest", 158 | "guest_continue": "Continue" 159 | }, 160 | "orders": { 161 | "title": "Order History", 162 | "order_number": "Order", 163 | "date": "Date", 164 | "payment_status": "Payment Status", 165 | "fulfillment_status": "Fulfillment Status", 166 | "total": "Total", 167 | "none": "You haven't placed any orders yet." 168 | }, 169 | "order": { 170 | "title": "Order {{ name }}", 171 | "date": "Placed on {{ date }}", 172 | "cancelled": "Order Cancelled on {{ date }}", 173 | "cancelled_reason": "Reason: {{ reason }}", 174 | "billing_address": "Billing Address", 175 | "payment_status": "Payment Status", 176 | "shipping_address": "Shipping Address", 177 | "fulfillment_status": "Fulfillment Status", 178 | "discount": "Discount", 179 | "shipping": "Shipping", 180 | "tax": "Tax", 181 | "product": "Product", 182 | "sku": "SKU", 183 | "price": "Price", 184 | "quantity": "Quantity", 185 | "total": "Total", 186 | "fulfilled_at": "Fulfilled {{ date }}", 187 | "subtotal": "Subtotal" 188 | }, 189 | "recover_password": { 190 | "title": "Reset your password", 191 | "email": "Email", 192 | "submit": "Submit", 193 | "cancel": "Cancel", 194 | "subtext": "We will send you an email to reset your password.", 195 | "success": "We've sent you an email with a link to update your password." 196 | }, 197 | "reset_password": { 198 | "title": "Reset account password", 199 | "subtext": "Enter a new password for {{ email }}", 200 | "password": "Password", 201 | "password_confirm": "Confirm Password", 202 | "submit": "Reset Password" 203 | }, 204 | "register": { 205 | "title": "Create Account", 206 | "first_name": "First Name", 207 | "last_name": "Last Name", 208 | "email": "Email", 209 | "password": "Password", 210 | "submit": "Create", 211 | "cancel": "Return to Store" 212 | } 213 | }, 214 | "homepage": { 215 | "onboarding": { 216 | "product_title": "Example Product Title", 217 | "collection_title": "Example Collection Title", 218 | "no_content": "This section doesn’t currently include any content. Add content to this section using the sidebar." 219 | } 220 | }, 221 | "layout": { 222 | "cart": { 223 | "title": "Cart", 224 | "items_count": { 225 | "one": "item", 226 | "other": "items" 227 | } 228 | }, 229 | "customer": { 230 | "account": "Account", 231 | "logged_in_as_html": "Logged in as {{ first_name }}", 232 | "log_out": "Log out", 233 | "log_in": "Log in", 234 | "create_account": "Create account" 235 | }, 236 | "footer": { 237 | "social_platform": "{{ name }} on {{ platform }}", 238 | "copyright": "Copyright" 239 | } 240 | }, 241 | "products": { 242 | "product": { 243 | "regular_price": "Regular price", 244 | "sold_out": "Sold Out", 245 | "unavailable": "Unavailable", 246 | "on_sale": "On Sale", 247 | "on_sale_from_html": "On Sale from {{ price }}", 248 | "from_text_html": "From {{ price }}", 249 | "quantity": "Quantity", 250 | "add_to_cart": "Add to Cart" 251 | } 252 | }, 253 | "gift_cards": { 254 | "issued": { 255 | "title": "Here's your {{ value }} gift card for {{ shop }}!", 256 | "subtext": "Here's your gift card!", 257 | "disabled": "Disabled", 258 | "expired": "Expired on {{ expiry }}", 259 | "active": "Expires on {{ expiry }}", 260 | "redeem": "Use this code at checkout to redeem your gift card", 261 | "shop_link": "Start shopping", 262 | "print": "Print", 263 | "remaining_html": "{{ balance }} left", 264 | "add_to_apple_wallet": "Add to Apple Wallet" 265 | } 266 | }, 267 | "date_formats":{ 268 | "month_day_year": "%B %d, %Y" 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /src/core/shopify/locales/pt-BR.json: -------------------------------------------------------------------------------- 1 | { 2 | "general": { 3 | "accessibility": { 4 | "skip_to_content": "Pular para o Conteúdo" 5 | }, 6 | "meta": { 7 | "tags": "Marcado \"{{ tags }}\"", 8 | "page": "Página {{ page }}" 9 | }, 10 | "404": { 11 | "title": "404 Página não encontrada", 12 | "subtext_html": "A página que você solicitou não existe. Clique aqui para voltar às compras." 13 | }, 14 | "password_page": { 15 | "opening_soon": "Abertura em Breve", 16 | "spread_the_word": "Espalhe a novidade", 17 | "login_form_heading": "Entre na loja usando a senha", 18 | "login_form_password_label": "Senha", 19 | "login_form_password_placeholder": "Sua senha", 20 | "login_form_submit": "Entrar", 21 | "signup_form_heading": "Descubra quando abrimos", 22 | "signup_form_email_label": "E-mail", 23 | "signup_form_email_placeholder": "Seu e-mail", 24 | "signup_form_submit": "Enviar", 25 | "signup_form_success": "Nós lhe enviaremos um e-mail logo antes de abrirmos!", 26 | "admin_link_html": "Você é o dono da loja? Faça login aqui", 27 | "password_link": "Entre usando a senha", 28 | "powered_by_shopify_html": "Esta loja será patrocinada por {{ shopify }}" 29 | }, 30 | "social": { 31 | "share_on_facebook": "Compartilhar", 32 | "share_on_twitter": "Tweetar", 33 | "share_on_pinterest": "Pin it", 34 | "alt_text": { 35 | "share_on_facebook": "Compartilhe no Facebook", 36 | "share_on_twitter": "Tuite no Twitter", 37 | "share_on_pinterest": "Adicione no Pinterest" 38 | } 39 | }, 40 | "search": { 41 | "no_results_html": "Sua busca por \"{{ terms }}\" não gerou resultados.", 42 | "results_for_html": "Sua busca por \"{{ terms }}\" encontrou os itens a seguir:", 43 | "title": "Buscar produtos em nosso site", 44 | "placeholder": "Busque em nossa loja", 45 | "submit": "Buscar" 46 | } 47 | }, 48 | "blogs": { 49 | "article": { 50 | "author_on_date_html": "Postado por{{ author }} em {{ date }}", 51 | "comment_meta_html": "{{ author }} em {{ date }}", 52 | "read_more": "Ler mais" 53 | }, 54 | "comments": { 55 | "title": "Deixe um comentário", 56 | "name": "Nome", 57 | "email": "E-mail", 58 | "message": "Mensagem", 59 | "post": "Postar comentário", 60 | "moderated": "Observe que os comentários precisam ser aprovados antes de serem publicados", 61 | "success_moderated": "Seu comentário foi postado. Nós o publicaremos em alguns instantes, já que o nosso blog é moderado.", 62 | "success": "Seu comentário foi postado! Obrigado!", 63 | "with_count": { 64 | "one": "{{ count }} comentário", 65 | "other": "{{ count }} comentários" 66 | } 67 | }, 68 | "general": { 69 | "categories": "Categorias" 70 | } 71 | }, 72 | "cart": { 73 | "general": { 74 | "title": "Carrinho de compras", 75 | "remove": "Remover", 76 | "note": "Instruções especiais para o vendedor", 77 | "subtotal": "Subtotal", 78 | "shipping_at_checkout": "Envios e descontos calculados no checkout", 79 | "update": "Atualizar Carrinho", 80 | "checkout": "Fechar pedido", 81 | "empty": "Seu carrinho está vazio no momento.", 82 | "cookies_required": "Habilite os cookies para usar o carrinho de compras", 83 | "continue_browsing_html": "Continue navegando aqui.", 84 | "item_quantity": "Quantidade de itens", 85 | "savings": "Você está economizando" 86 | }, 87 | "label": { 88 | "product": "Produto", 89 | "price": "Preço", 90 | "quantity": "Quantidade", 91 | "total": "Total", 92 | "discounted_price": "Preço com desconto", 93 | "original_price": "Preço original" 94 | } 95 | }, 96 | "collections": { 97 | "general": { 98 | "no_matches": "Desculpe, mas não há produtos correspondentes à sua busca.", 99 | "link_title": "Explore a nossa coleção {{ title }}" 100 | } 101 | }, 102 | "contact": { 103 | "form": { 104 | "name": "Nome", 105 | "email": "E-mail", 106 | "phone": "Telefone", 107 | "message": "Mensagem", 108 | "send": "Enviar", 109 | "post_success": "Obrigado por entrar em contato. Nós lhe retornaremos assim que possível." 110 | } 111 | }, 112 | "customer": { 113 | "account": { 114 | "title": "Minha conta", 115 | "details": "Detalhes da conta", 116 | "view_addresses": "Ver endereços", 117 | "return": "Retornar aos detalhes da conta" 118 | }, 119 | "activate_account": { 120 | "title": "Ativar conta", 121 | "subtext": "Crie uma senha para ativar a sua conta.", 122 | "password": "Senha", 123 | "password_confirm": "Confirmar senha", 124 | "submit": "Ativar conta", 125 | "cancel": "Recusar convite" 126 | }, 127 | "addresses": { 128 | "title": "Seus endereços", 129 | "default": "Padrão", 130 | "add_new": "Adicionar um novo endereço", 131 | "edit_address": "Editar endereço", 132 | "first_name": "Nome", 133 | "last_name": "Sobrenome", 134 | "company": "Empresa", 135 | "address1": "Endereço1", 136 | "address2": "Endereço2", 137 | "city": "Cidade", 138 | "country": "País", 139 | "province": "Estado", 140 | "zip": "CEP", 141 | "phone": "Telefone", 142 | "set_default": "Definir como endereço padrão", 143 | "add": "Adicionar endereço", 144 | "update": "Atualizar endereço", 145 | "cancel": "Cancelar", 146 | "edit": "Editar", 147 | "delete": "Excluir", 148 | "delete_confirm": "Deseja realmente excluir este endereço?" 149 | }, 150 | "login": { 151 | "title": "Entrar", 152 | "email": "E-mail", 153 | "password": "Senha", 154 | "forgot_password": "Esqueceu sua senha?", 155 | "sign_in": "Entrar", 156 | "cancel": "Retornar à loja", 157 | "guest_title": "Prosseguir como convidado(a)", 158 | "guest_continue": "Prosseguir" 159 | }, 160 | "orders": { 161 | "title": "Histórico de pedidos", 162 | "order_number": "Pedido", 163 | "date": "Data", 164 | "payment_status": "Status do pagamento", 165 | "fulfillment_status": "Status do processamento", 166 | "total": "Total", 167 | "none": "Você ainda não efetuou nenhum pedido." 168 | }, 169 | "order": { 170 | "title": "Pedido {{ name }}", 171 | "date": "Efetuado em {{ date }}", 172 | "cancelled": "Pedido cancelado em {{ date }}", 173 | "cancelled_reason": "Motivo: {{ reason }}", 174 | "billing_address": "Endereço de cobrança", 175 | "payment_status": "Status do pagamento", 176 | "shipping_address": "Endereço de entrega", 177 | "fulfillment_status": "Status do processamento", 178 | "discount": "Desconto", 179 | "shipping": "Frete", 180 | "tax": "Impostos", 181 | "product": "Produto", 182 | "sku": "Código SKU", 183 | "price": "Preço", 184 | "quantity": "Quantidade", 185 | "total": "Total", 186 | "fulfilled_at": "Processado em {{ date }}", 187 | "subtotal": "Subtotal" 188 | }, 189 | "recover_password": { 190 | "title": "Redefinir sua senha", 191 | "email": "E-mail", 192 | "submit": "Enviar", 193 | "cancel": "Cancelar", 194 | "subtext": "Enviaremos a você um e-mail para redefinir a sua senha.", 195 | "success": "Nós lhe enviamos um e-mail com o link para atualizar a sua senha." 196 | }, 197 | "reset_password": { 198 | "title": "Redefinir sua senha", 199 | "subtext": "Digite uma nova senha para {{ email }}", 200 | "password": "Senha", 201 | "password_confirm": "Confirmar senha", 202 | "submit": "Redefinir senha" 203 | }, 204 | "register": { 205 | "title": "Criar conta", 206 | "first_name": "Nome", 207 | "last_name": "Sobrenome", 208 | "email": "E-mail", 209 | "password": "Senha", 210 | "submit": "Criar", 211 | "cancel": "Retornar à loja" 212 | } 213 | }, 214 | "homepage": { 215 | "onboarding": { 216 | "product_title": "Exemplo de título de produto", 217 | "collection_title": "Exemplo de título de coleção", 218 | "no_content": "Atualmente, esta seção não inclui nenhum conteúdo. Adicione conteúdo nesta seção usando a barra lateral." 219 | } 220 | }, 221 | "layout": { 222 | "cart": { 223 | "title": "Carrinho", 224 | "items_count": { 225 | "one": "item", 226 | "other": "itens" 227 | } 228 | }, 229 | "customer": { 230 | "account": "Conta", 231 | "logged_in_as_html": "Conectado(a) como {{ first_name }}", 232 | "log_out": "Sair", 233 | "log_in": "Entrar", 234 | "create_account": "Criar conta" 235 | }, 236 | "footer": { 237 | "social_platform": "{{ name }} em {{ platform }}", 238 | "copyright": "Direitos autorais" 239 | } 240 | }, 241 | "products": { 242 | "product": { 243 | "regular_price": "Preço normal", 244 | "sold_out": "Esgotado", 245 | "unavailable": "Indisponível", 246 | "on_sale": "Em promoção", 247 | "on_sale_from_html": "Em promoção, a partir de {{ price }}", 248 | "from_text_html": "A partir de {{ price }}", 249 | "quantity": "Quantidade", 250 | "add_to_cart": "Adicionar ao carrinho" 251 | } 252 | }, 253 | "gift_cards": { 254 | "issued": { 255 | "title": "Aqui está o seu vale-presente de {{ value }} na {{ shop }}!", 256 | "subtext": "Aqui está o seu vale-presente!", 257 | "disabled": "Inválido", 258 | "expired": "Expirado em {{ expiry }}", 259 | "active": "Expira em {{ expiry }}", 260 | "redeem": "Para resgatar o seu vale-presente, utilize este código no fechamento do pedido", 261 | "shop_link": "Comece a comprar", 262 | "print": "Imprimir", 263 | "remaining_html": "{{ balance }} restantes", 264 | "add_to_apple_wallet": "Adicionar ao Apple Wallet" 265 | } 266 | }, 267 | "date_formats":{ 268 | "month_day_year": "%d de %B de %Y" 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /src/core/shopify/locales/pt-PT.json: -------------------------------------------------------------------------------- 1 | { 2 | "general": { 3 | "accessibility": { 4 | "skip_to_content": "Pular para o Conteúdo" 5 | }, 6 | "meta": { 7 | "tags": "Etiquetado como \"{{ tags }}\"", 8 | "page": "Página {{ page }}" 9 | }, 10 | "404": { 11 | "title": "404 Página Não Encontrada", 12 | "subtext_html": "A página que solicitou não existe. Clique aqui para continuar as suas compras." 13 | }, 14 | "password_page": { 15 | "opening_soon": "Abre Brevemente", 16 | "spread_the_word": "Passe a palavra", 17 | "login_form_heading": "Entre na loja usando a palavra-passe", 18 | "login_form_password_label": "Palavra-passe", 19 | "login_form_password_placeholder": "A sua palavra-passe", 20 | "login_form_submit": "Entrar", 21 | "signup_form_heading": "Descubra quando abrimos", 22 | "signup_form_email_label": "Email", 23 | "signup_form_email_placeholder": "O seu email", 24 | "signup_form_submit": "Submeter", 25 | "signup_form_success": "Iremos enviar-lhe um email imediatamente antes de abrirmos!", 26 | "admin_link_html": "É o dono da loja? Inicie sessão aqui", 27 | "password_link": "Entre usando a palavra-passe", 28 | "powered_by_shopify_html": "Esta loja será movida por {{ shopify }}" 29 | }, 30 | "social": { 31 | "share_on_facebook": "Partilhar", 32 | "share_on_twitter": "Tweetar", 33 | "share_on_pinterest": "Pin it", 34 | "alt_text": { 35 | "share_on_facebook": "Partilhe no Facebook", 36 | "share_on_twitter": "Tuíte no Twitter", 37 | "share_on_pinterest": "Adicione no Pinterest" 38 | } 39 | }, 40 | "search": { 41 | "no_results_html": "A sua pesquisa por \"{{ terms }}\" não produziu resultados.", 42 | "results_for_html": "A sua pesquisa por \"{{ terms }}\" revelou o seguinte:", 43 | "title": "Pesquisar produtos no nosso site", 44 | "placeholder": "Pesquisar a nossa loja", 45 | "submit": "Pesquisar" 46 | } 47 | }, 48 | "blogs": { 49 | "article": { 50 | "author_on_date_html": "Publicado por {{ author }} em {{ date }}", 51 | "comment_meta_html": "{{ author }} em {{ date }}", 52 | "read_more": "Ler mais" 53 | }, 54 | "comments": { 55 | "title": "Deixe um comentário", 56 | "name": "Nome", 57 | "email": "Email", 58 | "message": "Mensagem", 59 | "post": "Publicar comentário", 60 | "moderated": "Tenha em atenção que os comentários precisam de ser aprovados antes de serem exibidos", 61 | "success_moderated": "O seu comentário foi publicado com sucesso! Obrigado!", 62 | "success": "Seu comentário foi postado! Obrigado!", 63 | "with_count": { 64 | "one": "{{ count }} comentário", 65 | "other": "{{ count }} comentários" 66 | } 67 | }, 68 | "general": { 69 | "categories": "Categorias" 70 | } 71 | }, 72 | "cart": { 73 | "general": { 74 | "title": "Carrinho de Compras", 75 | "remove": "Eliminar", 76 | "note": "Instruções especiais para o vendedor", 77 | "subtotal": "Subtotal", 78 | "shipping_at_checkout": "Envios e descontos calculados no checkout", 79 | "update": "Atualizar Carrinho de Compras", 80 | "checkout": "Check-Out", 81 | "empty": "O seu carrinho de compras está neste momento vazio.", 82 | "cookies_required": "Ative cookies para poder usar o carrinho de compras", 83 | "continue_browsing_html": "Continue a ver aqui.", 84 | "item_quantity": "Quantidade de itens", 85 | "savings": "Está a poupar" 86 | }, 87 | "label": { 88 | "product": "Produto", 89 | "price": "Preço", 90 | "quantity": "Quantidade", 91 | "total": "Total", 92 | "discounted_price": "Preço com desconto", 93 | "original_price": "Preço original" 94 | } 95 | }, 96 | "collections": { 97 | "general": { 98 | "no_matches": "Lamentamos, mas nenhum produto corresponde à sua pesquisa.", 99 | "link_title": "Explorar a nossa coleção {{ title }}" 100 | } 101 | }, 102 | "contact": { 103 | "form": { 104 | "name": "Nome", 105 | "email": "Email", 106 | "phone": "Número de Telefone", 107 | "message": "Mensagem", 108 | "send": "Enviar", 109 | "post_success": "Obrigado por entrar em contacto connosco. Responder-lhe-emos logo que possível." 110 | } 111 | }, 112 | "customer": { 113 | "account": { 114 | "title": "A Minha Conta", 115 | "details": "Detalhes da Conta", 116 | "view_addresses": "Ver Endereços", 117 | "return": "Regressar aos Detalhes da Conta" 118 | }, 119 | "activate_account": { 120 | "title": "Ativar Conta", 121 | "subtext": "Crie a sua senha para ativar a sua conta.", 122 | "password": "Senha", 123 | "password_confirm": "Confirmar Senha", 124 | "submit": "Ativar Conta", 125 | "cancel": "Recusar Convite" 126 | }, 127 | "addresses": { 128 | "title": "Os Seus Endereços", 129 | "default": "Predefinição", 130 | "add_new": "Adicionar um Novo Endereço", 131 | "edit_address": "Editar Endereço", 132 | "first_name": "Nome Próprio", 133 | "last_name": "Sobrenome", 134 | "company": "Empresa", 135 | "address1": "Endereço1", 136 | "address2": "Endereço2", 137 | "city": "Localidade", 138 | "country": "País", 139 | "province": "Província", 140 | "zip": "Código Postal", 141 | "phone": "Telefone", 142 | "set_default": "Selecionar como endereço predefinido", 143 | "add": "Adicionar Endereço", 144 | "update": "Atualizar Endereço", 145 | "cancel": "Cancelar", 146 | "edit": "Editar", 147 | "delete": "Eliminar", 148 | "delete_confirm": "Tem a certeza de que quer eliminar este endereço?" 149 | }, 150 | "login": { 151 | "title": "Login", 152 | "email": "Email", 153 | "password": "Senha", 154 | "forgot_password": "Esqueceu-se da sua senha?", 155 | "sign_in": "Iniciar Sessão", 156 | "cancel": "Regressar à Loja", 157 | "guest_title": "Continuar como visitante", 158 | "guest_continue": "Continuar" 159 | }, 160 | "orders": { 161 | "title": "Histórico de Pedidos", 162 | "order_number": "Pedido", 163 | "date": "Data", 164 | "payment_status": "Estado de Pagamento", 165 | "fulfillment_status": "Estado de Atendimento", 166 | "total": "Total", 167 | "none": "Ainda não efetuou nenhum pedido." 168 | }, 169 | "order": { 170 | "title": "Pedido {{ name }}", 171 | "date": "Efetuado em{{ date }}", 172 | "cancelled": "Pedido Cancelado em {{ date }}", 173 | "cancelled_reason": "Motivo: {{ reason }}", 174 | "billing_address": "Endereço de Faturação", 175 | "payment_status": "Estado de Pagamento", 176 | "shipping_address": "Endereço de Envio", 177 | "fulfillment_status": "Estado de Atendimento", 178 | "discount": "Desconto", 179 | "shipping": "Envio", 180 | "tax": "Taxa", 181 | "product": "Produto", 182 | "sku": "SKU", 183 | "price": "Preço", 184 | "quantity": "Quantidade", 185 | "total": "Total", 186 | "fulfilled_at": "Concluído em {{ date }}", 187 | "subtotal": "Subtotal" 188 | }, 189 | "recover_password": { 190 | "title": "Repor a sua senha", 191 | "email": "Email", 192 | "submit": "Enviar", 193 | "cancel": "Cancelar", 194 | "subtext": "Vamos enviar-lhe um email para repor a sua senha.", 195 | "success": "Enviámos-lhe um email com um link para atualizar a sua senha." 196 | }, 197 | "reset_password": { 198 | "title": "Repor senha de conta", 199 | "subtext": "Insira uma nova senha para {{ email }}", 200 | "password": "Senha", 201 | "password_confirm": "Confirmar Senha", 202 | "submit": "Repor Senha" 203 | }, 204 | "register": { 205 | "title": "Criar Conta", 206 | "first_name": "Nome Próprio", 207 | "last_name": "Sobrenome", 208 | "email": "Email", 209 | "password": "Senha", 210 | "submit": "Criar", 211 | "cancel": "Regressar à Loja" 212 | } 213 | }, 214 | "homepage": { 215 | "onboarding": { 216 | "product_title": "Título do Produto Exemplo", 217 | "collection_title": "Título da Coleção Exemplo", 218 | "no_content": "Esta sección actualmente no incluye ningún contenido. Añade un contenido a esta sección utilizando la barra lateral." 219 | } 220 | }, 221 | "layout": { 222 | "cart": { 223 | "title": "Carrinho de Compras", 224 | "items_count": { 225 | "one": "item", 226 | "other": "itens" 227 | } 228 | }, 229 | "customer": { 230 | "account": "Conta", 231 | "logged_in_as_html": "Sessão iniciada como {{ first_name }}", 232 | "log_out": "Terminar sessão", 233 | "log_in": "Iniciar sessão", 234 | "create_account": "Criar conta" 235 | }, 236 | "footer": { 237 | "social_platform": "{{ name }} na {{ plataform }}", 238 | "copyright": "Direitos autorais" 239 | } 240 | }, 241 | "products": { 242 | "product": { 243 | "regular_price": "Preço normal", 244 | "sold_out": "Esgotado", 245 | "unavailable": "Indisponível", 246 | "on_sale": "Em Promoção", 247 | "on_sale_from_html": "Em Promoção desde {{ price }}", 248 | "from_text_html": "Desde {{ price }}", 249 | "quantity": "Quantidade", 250 | "add_to_cart": "Adicionar ao Carrinho de Compras" 251 | } 252 | }, 253 | "gift_cards": { 254 | "issued": { 255 | "title": "Aqui está o seu cartão-presente de {{ value }} para {{ shop }}!", 256 | "subtext": "Aqui está o seu cartão-presente!", 257 | "disabled": "Inválido", 258 | "expired": "Expirou em {{ expiry }}", 259 | "active": "Expira em {{ expiry }}", 260 | "redeem": "Use este código ao fazer o check-out para redimir o seu cartão-presente", 261 | "shop_link": "Começar a fazer compras", 262 | "print": "Imprimir", 263 | "remaining_html": "{{ balance }} restante", 264 | "add_to_apple_wallet": "Adicionar ao Apple Wallet" 265 | } 266 | }, 267 | "date_formats":{ 268 | "month_day_year": "%d de %B de %Y" 269 | } 270 | } 271 | -------------------------------------------------------------------------------- /src/core/shopify/sections/collection-list.liquid: -------------------------------------------------------------------------------- 1 | {% if section.settings.title != blank %} 2 |

{{ section.settings.title | escape }}

3 | {% endif %} 4 | aaaaaaaaa 5 | {% for block in section.blocks limit: section.blocks.size %} 6 |
7 | {%- assign collection = collections[block.settings.collection] -%} 8 | 9 | 10 | {% if collection.image != blank %} 11 | {{ collection | img_url: '480x480' | img_tag: collection.title }} 12 | {% elsif collection.products.first != blank %} 13 | {{ collection.products.first | img_url: '480x480' | img_tag: collection.title }} 14 | {% elsif collection == empty %} 15 | {% capture current %}{% cycle 1, 2, 3, 4, 5, 6 %}{% endcapture %} 16 | {{ 'collection-' | append: current | placeholder_svg_tag: 'placeholder-svg placeholder-svg--small' }} 17 | {% endif %} 18 | 19 |

20 | {% if collection == empty %} 21 | {{ 'homepage.onboarding.collection_title' | t }} 22 | {% else %} 23 | {{ collection.title }} 24 | {% endif %} 25 |

26 |
27 |
28 | {% endfor %} 29 | 30 | {% if section.blocks.size == 0 %} 31 | {% include 'no-blocks' %} 32 | {% endif %} 33 | 34 | {% schema %} 35 | { 36 | "name": "Collection list", 37 | "max_blocks": 12, 38 | "settings": [ 39 | { 40 | "type": "text", 41 | "id": "title", 42 | "label": "Heading", 43 | "default": "Collection list" 44 | } 45 | ], 46 | "blocks": [ 47 | { 48 | "type": "collection", 49 | "name": "Collection", 50 | "settings": [ 51 | { 52 | "label": "Collection", 53 | "id": "collection", 54 | "type": "collection" 55 | } 56 | ] 57 | } 58 | ], 59 | "presets": [ 60 | { 61 | "name": "Collection list", 62 | "category": "Collection", 63 | "blocks": [ 64 | { 65 | "type": "collection" 66 | }, 67 | { 68 | "type": "collection" 69 | }, 70 | { 71 | "type": "collection" 72 | } 73 | ] 74 | } 75 | ] 76 | } 77 | {% endschema %} 78 | -------------------------------------------------------------------------------- /src/core/shopify/sections/featured-collection.liquid: -------------------------------------------------------------------------------- 1 | {% if section.settings.title != blank %} 2 |

{{ section.settings.title | escape }}

3 | {% endif %} 4 | 5 | {%- assign collection = collections[section.settings.collection] -%} 6 | 7 | {% for product in collection.products limit: 6 %} 8 | 9 | {{ product.featured_image.src | img_url: '480x480' | img_tag: product.title }} 10 |

{{ product.title }}

11 |
12 | 13 |

14 | {% if product.compare_at_price > product.price %} 15 | 16 | {% if product.price_varies %} 17 | {%- assign sale_price = product.price | money -%} 18 | {{ 'products.product.on_sale_from_html' | t: price: sale_price }} 19 | {% else %} 20 | {{ 'products.product.on_sale' | t }} 21 | {{ product.price | money }} 22 | {% endif %} 23 | 24 | {% else %} 25 | 26 | {% if product.price_varies %} 27 | {%- assign price = product.price | money -%} 28 | {{ 'products.product.from_text_html' | t: price: price }} 29 | {% else %} 30 | {{ product.price | money }} 31 | {% endif %} 32 | 33 | {% endif %} 34 |

35 | {% else %} 36 | 37 | {% for i in (1..6) %} 38 | 39 | {% capture current %}{% cycle 1, 2, 3, 4, 5, 6 %}{% endcapture %} 40 | {{ 'product-' | append: current | placeholder_svg_tag: 'placeholder-svg placeholder-svg--small' }} 41 | 42 |

43 | {{ 'homepage.onboarding.product_title' | t }} 44 |

45 |
46 | 47 |

{{ 1999 | money }}

48 | {% endfor %} 49 | {% endfor %} 50 | 51 | {% schema %} 52 | { 53 | "name": "Featured collection", 54 | "settings": [ 55 | { 56 | "type": "text", 57 | "id": "title", 58 | "label": "Heading", 59 | "default": "Featured collection" 60 | }, 61 | { 62 | "id": "collection", 63 | "type": "collection", 64 | "label": "Collection" 65 | } 66 | ], 67 | "presets": [ 68 | { 69 | "name": "Featured collection", 70 | "category": "Collection" 71 | } 72 | ] 73 | } 74 | 75 | {% endschema %} 76 | -------------------------------------------------------------------------------- /src/core/shopify/sections/featured-product.liquid: -------------------------------------------------------------------------------- 1 | {%- assign product = all_products[section.settings.product] -%} 2 | {%- assign current_variant = product.selected_or_first_available_variant -%} 3 | 4 | {% if product == empty %} 5 | {%- assign section_onboarding = true -%} 6 | {%- assign onboarding_title = 'homepage.onboarding.product_title' | t -%} 7 | {% endif %} 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | {% if product.featured_image.src != blank %} 16 | {{ featured_image.alt | escape }} 17 | {% else %} 18 | {{ 'product-1' | placeholder_svg_tag: 'placeholder-svg placeholder-svg--small' }} 19 | {% endif %} 20 | 21 | {% if product.images.size > 1 %} 22 | 31 | {% endif %} 32 | 33 |

{{ product.title | default: onboarding_title }}

34 | {% if product.vendor != blank %} 35 |

{{ product.vendor }}

36 | {% endif %} 37 | 38 |
39 | 40 | 41 | 42 | 43 |
44 | {% unless product.variants.size == 1 and product.options.size == 1 and product.options.first == 'Title' and product.variants.first.title == 'Default Title' %} 45 | {% for option in product.options_with_values %} 46 |
47 | 52 | 53 | 65 |
66 | {% endfor %} 67 | {% endunless %} 68 | 69 | 79 | 80 | 81 | 82 | 83 |
84 | 85 | {{ current_variant.price | default: '1999' | money }} 86 | 87 | 88 | {% if product.compare_at_price_max > product.price %} 89 | {{ 'products.product.regular_price' | t }} 90 | 91 | {% if current_variant.compare_at_price > current_variant.price %} 92 | {{ current_variant.compare_at_price | money }} 93 | {% endif %} 94 | 95 | {% endif %} 96 |
97 | 98 | 112 |
113 | 114 |
115 | 116 |
117 | {{ product.description }} 118 |
119 | 120 | {% if section.settings.show_share_buttons %} 121 | {% include 'social-sharing', share_title: product.title, share_permalink: product.url, share_image: product %} 122 | {% endif %} 123 | 124 | {% unless product == empty %} 125 | 128 | {% endunless %} 129 |
130 | 131 | {% schema %} 132 | { 133 | "name": "Featured product", 134 | "settings": [ 135 | { 136 | "type": "product", 137 | "id": "product", 138 | "label": "Product" 139 | }, 140 | { 141 | "type": "checkbox", 142 | "id": "show_share_buttons", 143 | "label": "Show social sharing buttons" 144 | } 145 | ], 146 | "presets": [ 147 | { 148 | "name": "Featured product", 149 | "category": "Product" 150 | } 151 | ] 152 | } 153 | {% endschema %} 154 | -------------------------------------------------------------------------------- /src/core/shopify/sections/footer.liquid: -------------------------------------------------------------------------------- 1 | 52 | 53 | {% schema %} 54 | { 55 | "name": "Footer", 56 | "settings": [ 57 | { 58 | "type": "link_list", 59 | "id": "footer_linklist", 60 | "label": "First menu", 61 | "default": "footer" 62 | }, 63 | { 64 | "type": "checkbox", 65 | "id": "show_payment_icons", 66 | "label": "Show payment icons", 67 | "default": false 68 | } 69 | ] 70 | } 71 | 72 | {% endschema %} 73 | -------------------------------------------------------------------------------- /src/core/shopify/sections/header.liquid: -------------------------------------------------------------------------------- 1 | 14 |
15 |
16 | {% if template.name == 'index' %} 17 |

18 | {% else %} 19 |

34 | {% else %} 35 |
36 | {% endif %} 37 | 38 | 39 | {% include 'icon-cart' %} 40 | {{ 'layout.cart.title' | t }} 41 | ({{ cart.item_count }} {{ 'layout.cart.items_count' | t: count: cart.item_count }}) 42 | 43 | 44 | {% if shop.customer_accounts_enabled %} 45 | 67 | {% endif %} 68 | 69 |
70 | 73 | 78 | 82 |
83 | 84 | 85 | 86 | 112 | 113 | 114 | {% schema %} 115 | { 116 | "name": "Header", 117 | "settings": [ 118 | { 119 | "type": "image_picker", 120 | "id": "logo", 121 | "label": "Logo image" 122 | }, 123 | { 124 | "type": "text", 125 | "id": "logo_max_width", 126 | "label": "Custom logo width (in pixels)", 127 | "default": "250" 128 | }, 129 | { 130 | "type": "link_list", 131 | "id": "main_linklist", 132 | "label": "Menu", 133 | "default": "main-menu" 134 | } 135 | ] 136 | } 137 | {% endschema %} 138 | -------------------------------------------------------------------------------- /src/core/shopify/sections/product.liquid: -------------------------------------------------------------------------------- 1 |
2 | 3 | {%- assign current_variant = product.selected_or_first_available_variant -%} 4 | {%- assign featured_image = current_variant.featured_image | default: product.featured_image -%} 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | {{ featured_image.alt | escape }} 13 | {% if product.images.size > 1 %} 14 | 23 | {% endif %} 24 | 25 | 26 |

{{ product.title }}

27 |

{{ product.vendor }}

28 | 29 |
30 | 31 | 32 | 33 | 34 |
35 | {% unless product.variants.size == 1 and product.options.size == 1 and product.options.first == 'Title' and product.variants.first.title == 'Default Title' %} 36 | {% for option in product.options_with_values %} 37 |
38 | 43 | 44 | 56 |
57 | {% endfor %} 58 | {% endunless %} 59 | 60 | 70 | 71 | 72 | 73 | 74 |
75 | 76 | {{ current_variant.price | money }} 77 | 78 | 79 | {% if product.compare_at_price_max > product.price %} 80 | {{ 'products.product.regular_price' | t }} 81 | 82 | {% if current_variant.compare_at_price > current_variant.price %} 83 | {{ current_variant.compare_at_price | money }} 84 | {% endif %} 85 | 86 | {% endif %} 87 |
88 | 89 | 102 |
103 | 104 |
105 | 106 |
107 | {{ product.description }} 108 |
109 | 110 | {% if section.settings.show_share_buttons %} 111 | {% include 'social-sharing', share_title: product.title, share_permalink: product.url, share_image: product %} 112 | {% endif %} 113 | 114 | {% unless product == empty %} 115 | 118 | {% endunless %} 119 |
120 | 121 | {% schema %} 122 | { 123 | "name": "Product pages", 124 | "settings": [ 125 | { 126 | "type": "checkbox", 127 | "id": "show_share_buttons", 128 | "label": "Show social sharing buttons", 129 | "default": true 130 | } 131 | ] 132 | } 133 | {% endschema %} 134 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-amazon_payments.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-american_express.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-apple_pay.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-arrow-down.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-bitcoin.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-cart.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-cirrus.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-close.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-dankort.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-diners_club.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-discover.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-dogecoin.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-dwolla.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-facebook.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-forbrugsforeningen.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-hamburger.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-instagram.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-interac.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-jcb.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-litecoin.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-lock.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-maestro.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-master.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-minus.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-paypal.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-pinterest.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-plus.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-rss.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-search.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-shopify-logo.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-snapchat.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-tumblr.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-twitter.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-vimeo.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-visa.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/icon-youtube.liquid: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/no-blocks.liquid: -------------------------------------------------------------------------------- 1 |
2 | {{ 'homepage.onboarding.no_content' | t }} 3 |
4 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/pagination.liquid: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/social-meta-tags.liquid: -------------------------------------------------------------------------------- 1 | {%- assign og_title = page_title -%} 2 | {%- assign og_url = canonical_url -%} 3 | {%- assign og_type = 'website' -%} 4 | {%- assign og_description = page_description | default: shop.description | default: shop.name -%} 5 | 6 | {% comment %} 7 | Template specific overides 8 | {% endcomment %} 9 | {%- if template.name == 'product' -%} 10 | {%- assign og_title = product.title | strip_html -%} 11 | {%- assign og_type = 'product' -%} 12 | {%- capture og_image_tags -%} 13 | {%- for image in product.images limit: 3 -%} 14 | 15 | {%- endfor -%} 16 | {%- endcapture -%} 17 | {%- capture og_image_secure_url_tags -%} 18 | {%- for image in product.images limit: 3 -%} 19 | 20 | {%- endfor -%} 21 | {%- endcapture -%} 22 | 23 | {%- elsif template.name == 'article' -%} 24 | {%- assign og_title = article.title | strip_html -%} 25 | {%- assign og_type = 'article' -%} 26 | {%- assign og_description = article.excerpt_or_content | strip_html -%} 27 | {%- if article.image -%} 28 | {%- capture og_image_tags -%}{%- endcapture -%} 29 | {%- capture og_image_secure_url_tags -%}{%- endcapture -%} 30 | {%- endif -%} 31 | 32 | {%- elsif template.name == 'password' -%} 33 | {%- assign og_title = shop.name -%} 34 | {%- assign og_url = shop.url -%} 35 | {%- assign og_description = shop.description | default: shop.name -%} 36 | {%- endif -%} 37 | 38 | 39 | 40 | 41 | 42 | 43 | {%- if template.name == 'product' -%} 44 | 45 | 46 | {%- endif -%} 47 | {{ og_image_tags }} 48 | {{ og_image_secure_url_tags }} 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/core/shopify/snippets/social-sharing.liquid: -------------------------------------------------------------------------------- 1 | 2 |
3 | 4 | {% if settings.share_facebook %} 5 | 6 | {% include 'icon-facebook' %} 7 | 8 | {{ 'general.social.alt_text.share_on_facebook' | t }} 9 | 10 | {% endif %} 11 | 12 | {% if settings.share_twitter %} 13 | 14 | {% include 'icon-twitter' %} 15 | 16 | {{ 'general.social.alt_text.share_on_twitter' | t }} 17 | 18 | {% endif %} 19 | 20 | {% if settings.share_pinterest %} 21 | 22 | {% include 'icon-pinterest' %} 23 | 24 | {{ 'general.social.alt_text.share_on_pinterest' | t }} 25 | 26 | {% endif %} 27 | 28 |
29 | -------------------------------------------------------------------------------- /src/core/shopify/templates/404.liquid: -------------------------------------------------------------------------------- 1 |

{{ 'general.404.title' | t }}

2 |

{{ 'general.404.subtext_html' | t }}

3 | -------------------------------------------------------------------------------- /src/core/shopify/templates/article.liquid: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | When a comment is submitted, the browser is redirected to a page that includes 3 | the new comment id in its URL. 4 | #comments is a required ID and is used as an anchor link by Shopify. 5 | {% endcomment %} 6 | 7 | {%- assign number_of_comments = article.comments_count -%} 8 | 9 | {% comment %} 10 | If a comment was just submitted but requires moderation, we have an extra comment to count. 11 | {% endcomment %} 12 | {% if comment and comment.status != 'published' %} 13 | {% assign number_of_comments = article.comments_count | plus: 1 %} 14 | {% endif %} 15 | 16 |
17 | 18 | {% if article.image %} 19 | {{ article | img_url: '1024x1024' | img_tag: article.title }} 20 | {% endif %} 21 | 22 |
23 |

{{ article.title }}

24 | {% capture date %}{{ article.published_at | time_tag: format: 'month_day_year' }}{% endcapture %} 25 |

{{ 'blogs.article.author_on_date_html' | t: author: article.author, date: date }}

26 |
27 | 28 |
29 | {{ article.content }} 30 |
31 | 32 | {% if article.tags.size > 0 %} 33 | 40 | {% endif %} 41 | 42 | {% if settings.social_sharing_blog %} 43 | {% include 'social-sharing', share_title: article.title, share_permalink: article.url, share_image: article.image %} 44 | {% endif %} 45 | 46 | {% if blog.comments_enabled? %} 47 |

{{ 'blogs.comments.with_count' | t: count: number_of_comments }}

48 | 49 | {% paginate article.comments by 5 %} 50 | 51 |
52 | {% if comment and comment.status and paginate.current_page == 1 %} 53 |

54 | {% if blog.moderated? and comment.status != 'published' %} 55 | {{ 'blogs.comments.success_moderated' | t }} 56 | {% else %} 57 | {{ 'blogs.comments.success' | t }} 58 | {% endif %} 59 |

60 | {% endif %} 61 | 62 | {% if number_of_comments > 0 %} 63 | 88 | 89 | {% if paginate.pages > 1 %} 90 | {% include 'pagination' %} 91 | {% endif %} 92 | {% endif %} 93 |
94 | 95 | {% endpaginate %} 96 | 97 | {% form 'new_comment', article %} 98 |

{{ 'blogs.comments.title' | t }}

99 | 100 | {{ form.errors | default_errors }} 101 | 102 | 105 | 112 | 113 | 116 | 125 | 126 | 129 | 136 | 137 | {% if blog.moderated? %} 138 |

{{ 'blogs.comments.moderated' | t }}

139 | {% endif %} 140 | 141 | 142 | {% endform %} 143 | 144 | {% endif %} 145 | 146 |
147 | -------------------------------------------------------------------------------- /src/core/shopify/templates/blog.liquid: -------------------------------------------------------------------------------- 1 | {% paginate blog.articles by 5 %} 2 | 3 | {%- assign blog_title = blog.title -%} 4 | 5 | {% if current_tags %} 6 | {% capture blog_title %}{{ blog.title | link_to: blog.url }} — {{ current_tags.first }}{% endcapture %} 7 | {% endif %} 8 | 9 |

{{ blog_title }}

10 | 11 | {% if blog.all_tags.size > 0 %} 12 |

{{ 'blogs.general.categories' | t }}

13 | 14 | 25 | {% endif %} 26 | 27 | 28 | {% comment %} 29 | 30 | Article Previews 31 | ==================== 32 | {% endcomment %} 33 | 34 | {% for article in blog.articles %} 35 |

36 | {{ article.title }} 37 |

38 | 39 | {% capture date %}{{ article.published_at | time_tag: format: 'month_day_year' }}{% endcapture %} 40 | 41 |

42 | {{ 'blogs.article.author_on_date_html' | t: author: article.author, date: date }} 43 |

44 | 45 | {% if article.image %} 46 | 47 | {{ article | img_url: '1024x1024' | img_tag: article.title }} 48 | 49 | {% endif %} 50 | 51 |
52 | {% if article.excerpt.size > 0 %} 53 | {{ article.excerpt }} 54 | {% else %} 55 |

56 | {{ article.content | strip_html | truncatewords: 100 }} 57 |

58 | {% endif %} 59 |
60 | 61 | {% if blog.comments_enabled? or article.tags.size > 0 %} 62 | 80 | {% endif %} 81 | 82 |

83 | {{ 'blogs.article.read_more' | t }} → 84 |

85 | 86 | {% endfor %} 87 | 88 | {% if paginate.pages > 1 %} 89 | {% include 'pagination' %} 90 | {% endif %} 91 | 92 | {% endpaginate %} 93 | -------------------------------------------------------------------------------- /src/core/shopify/templates/cart.liquid: -------------------------------------------------------------------------------- 1 | {% if cart.item_count > 0 %} 2 |

{{ 'cart.general.title' | t }}

3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | {% for item in cart.items %} 17 | 18 | {% comment %} 19 | 20 | Cart Item Template 21 | ===================== 22 | The data-label attributes on 27 | 32 | 62 | 72 | 80 | 83 | 84 | 85 | {% endfor %} 86 | 87 |
{{ 'cart.label.product' | t }}{{ 'cart.label.price' | t }}{{ 'cart.label.quantity' | t }}{{ 'cart.label.total' | t }}
elements are mobile-friendly 23 | helpers used for responsive-table labels 24 | {% endcomment %} 25 | 26 |
28 | 29 | {{ item.title | escape }} 30 | 31 | 33 | {{ item.product.title }} 34 | 35 | {% unless item.variant.title contains 'Default' %} 36 |

{{ item.variant.title }}

37 | {% endunless %} 38 | 39 |

{{ item.vendor }}

40 | 41 | {%- assign property_size = item.properties | size -%} 42 | 43 | {% if property_size > 0 %} 44 | {% for p in item.properties %} 45 | {% unless p.last == blank %} 46 | {{ p.first }}: 47 | 48 | {% if p.last contains '/uploads/' %} 49 | {{ p.last | split: '/' | last }} 50 | {% else %} 51 | {{ p.last }} 52 | {% endif %} 53 | 54 | {% endunless %} 55 | {% endfor %} 56 | {% endif %} 57 | 58 | 59 | {{ 'cart.general.remove' | t }} 60 | 61 |
63 | {% if item.original_line_price != item.line_price %} 64 | {{ 'cart.label.discounted_price' | t }} 65 | {{ item.price | money }} 66 | {{ 'cart.label.original_price' | t }} 67 | {{ item.original_price | money }} 68 | {% else %} 69 | {{ item.price | money }} 70 | {% endif %} 71 | 73 | 79 | 81 | {{ item.line_price | money }} 82 |
88 | 89 | {% if settings.cart_notes_enable %} 90 | 91 | 92 | {% endif %} 93 | 94 |

{{ 'cart.general.subtotal' | t }}

95 |

{{ cart.total_price | money }}

96 | {% if cart.total_discounts > 0 %} 97 |

{{ 'cart.general.savings' | t }} {{ cart.total_discounts | money }}

98 | {% endif %} 99 |

{{ 'cart.general.shipping_at_checkout' | t }}

100 | 101 | 102 |
103 | {% else %} 104 |

{{ 'cart.general.title' | t }}

105 | 106 | {% comment %} 107 | Cart empty state 108 | {% endcomment %} 109 |
110 |

{{ 'cart.general.empty' | t }}

111 |

{{ 'cart.general.continue_browsing_html' | t }}

112 |
113 | 114 | {% comment %} 115 | Cart no cookies state 116 | --------------------- 117 | Browser cookies are required to use the cart. If cookies aren't enabled in the 118 | browser a message is displayed prompting the user to enable them. 119 | {% endcomment %} 120 |
121 |

{{ 'cart.general.cookies_required' | t }}

122 |
123 | {% endif %} 124 | -------------------------------------------------------------------------------- /src/core/shopify/templates/collection.liquid: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | https://help.shopify.com/themes/development/templates/collection-liquid 3 | {% endcomment %} -------------------------------------------------------------------------------- /src/core/shopify/templates/customers/account.liquid: -------------------------------------------------------------------------------- 1 |

{{ 'customer.account.title' | t }}

2 | 3 |

{{ 'customer.orders.title' | t }}

4 | 5 | {% paginate customer.orders by 20 %} 6 | {% if customer.orders.size != 0 %} 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | {% for order in customer.orders %} 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {% endfor %} 27 | 28 |
{{ 'customer.orders.order_number' | t }}{{ 'customer.orders.date' | t }}{{ 'customer.orders.payment_status' | t }}{{ 'customer.orders.fulfillment_status' | t }}{{ 'customer.orders.total' | t }}
{{ order.name | link_to: order.customer_url }}{{ order.created_at | date: format: 'month_day_year' }}{{ order.financial_status_label }}{{ order.fulfillment_status_label }}{{ order.total_price | money }}
29 | {% else %} 30 |

{{ 'customer.orders.none' | t }}

31 | {% endif %} 32 | 33 | {% if paginate.pages > 1 %} 34 | {% include 'pagination' %} 35 | {% endif %} 36 | 37 | {% endpaginate %} 38 | 39 |

{{ 'customer.account.details' | t }}

40 | 41 | {{ customer.default_address | format_address }} 42 | 43 | {{ 'customer.account.view_addresses' | t }} ({{ customer.addresses_count }}) 44 | -------------------------------------------------------------------------------- /src/core/shopify/templates/customers/activate_account.liquid: -------------------------------------------------------------------------------- 1 |

{{ 'customer.activate_account.title' | t }}

2 |

{{ 'customer.activate_account.subtext' | t }}

3 | 4 | {% form 'activate_customer_password' %} 5 | {{ form.errors | default_errors }} 6 | 7 |

8 | 11 | 15 |

16 | 17 |

18 | 21 | 25 |

26 | 27 | 28 | 29 | {% endform %} 30 | -------------------------------------------------------------------------------- /src/core/shopify/templates/customers/addresses.liquid: -------------------------------------------------------------------------------- 1 | {% paginate customer.addresses by 5 %} 2 | 3 |
4 |

{{ 'customer.account.title' | t }}

5 | 6 |
7 | 8 |

9 | {{ 'customer.account.return' | t }} 10 |

11 | 12 |
13 | {% form 'customer_address', customer.new_address %} 14 |

{{ 'customer.addresses.add_new' | t }}

15 | 16 | 19 | 24 | 25 | 28 | 33 | 34 | 37 | 42 | 43 | 46 | 51 | 52 | 55 | 60 | 61 | 64 | 69 | 70 | 73 | 79 | 80 | 90 | 91 | 94 | 99 | 100 | 103 | 108 | 109 | {{ form.set_as_default_checkbox }} 110 | 113 | 114 | 115 | 118 | 119 | {% endform %} 120 | 121 |
122 | 123 |

{{ 'customer.addresses.title' | t }}

124 | 125 | {% for address in customer.addresses %} 126 | 127 | {% if address == customer.default_address %} 128 |

{{ 'customer.addresses.default' | t }}

129 | {% endif %} 130 | {{ address | format_address }} 131 | 132 | 135 | 138 | 139 |
140 | {% form 'customer_address', address %} 141 | 142 |

{{ 'customer.addresses.edit_address' | t }}

143 | 144 | 147 | 152 | 153 | 156 | 161 | 162 | 165 | 170 | 171 | 174 | 179 | 180 | 183 | 188 | 189 | 192 | 197 | 198 | 201 | 209 | 210 | 220 | 221 | 224 | 229 | 230 | 233 | 238 | 239 | {{ form.set_as_default_checkbox }} 240 | 243 | 244 | 245 | 248 | 249 | {% endform %} 250 | 251 |
252 | {% endfor %} 253 | 254 | {% if paginate.pages > 1 %} 255 | {% include 'pagination' %} 256 | {% endif %} 257 | 258 | {% endpaginate %} 259 | -------------------------------------------------------------------------------- /src/core/shopify/templates/customers/login.liquid: -------------------------------------------------------------------------------- 1 |
2 | {{ 'customer.recover_password.success' | t }} 3 |
4 | 5 |
6 | {% form 'customer_login' %} 7 |

{{ 'customer.login.title' | t }}

8 | 9 | {{ form.errors | default_errors }} 10 | 11 | 14 | 23 | 24 | {% if form.password_needed %} 25 | 28 | 33 | {% endif %} 34 | 35 | 36 | 37 | {{ 'customer.login.cancel' | t }} 38 | 39 | 40 | {{ 'layout.customer.create_account' | t }} 41 | 42 | 43 | {% if form.password_needed %} 44 | {{ 'customer.login.forgot_password' | t }} 45 | {% endif %} 46 | {% endform %} 47 | 48 |
49 | 50 |
51 |

{{ 'customer.recover_password.title' | t }}

52 |

{{ 'customer.recover_password.subtext' | t }}

53 | 54 | {% form 'recover_customer_password' %} 55 | {{ form.errors | default_errors }} 56 | 57 | {% if form.posted_successfully? %} 58 | 59 | {% endif %} 60 | 61 | 64 | 71 | 72 | 73 | 74 | 77 | {% endform %} 78 | 79 |
80 | 81 | {% if shop.checkout.guest_login %} 82 |

{{ 'customer.login.guest_title' | t }}

83 | 84 | {% form 'guest_login' %} 85 | 86 | {% endform %} 87 | {% endif %} 88 | -------------------------------------------------------------------------------- /src/core/shopify/templates/customers/order.liquid: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | The data-label attributes on elements are mobile-friendly 3 | helpers used for responsive-table labels 4 | {% endcomment %} 5 | 6 |

{{ 'customer.account.title' | t }}

7 | 8 |

{{ 'customer.account.return' | t }}

9 | 10 |

{{ 'customer.order.title' | t: name: order.name }}

11 | 12 |

{{ 'customer.order.date' | t: date: order.created_at | date: "%B %d, %Y %I:%M%p" }}

13 | 14 | {% if order.cancelled %} 15 | {%- assign cancelled_at = order.cancelled_at | date: "%B %d, %Y %I:%M%p" -%} 16 |

{{ 'customer.order.cancelled' | t: date: cancelled_at }}

17 |

{{ 'customer.order.cancelled_reason' | t: reason: order.cancel_reason }}

18 | {% endif %} 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | {% for line_item in order.line_items %} 32 | 33 | 45 | 46 | 47 | 48 | 49 | 50 | {% endfor %} 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {% for discount in order.discounts %} 59 | 60 | 61 | 62 | 63 | {% endfor %} 64 | 65 | {% for shipping_method in order.shipping_methods %} 66 | 67 | 68 | 69 | 70 | {% endfor %} 71 | 72 | {% for tax_line in order.tax_lines %} 73 | 74 | 75 | 76 | 77 | {% endfor %} 78 | 79 | 80 | 81 | 82 | 83 | 84 |
{{ 'customer.order.product' | t }}{{ 'customer.order.sku' | t }}{{ 'customer.order.price' | t }}{{ 'customer.order.quantity' | t }}{{ 'customer.order.total' | t }}
34 | {{ line_item.title | link_to: line_item.product.url }} 35 | {% if line_item.fulfillment %} 36 |
37 | {%- assign created_at = line_item.fulfillment.created_at | date: format: 'month_day_year' -%} 38 | {{ 'customer.order.fulfilled_at' | t: date: created_at }} 39 | {% if line_item.fulfillment.tracking_number %} 40 | {{ line_item.fulfillment.tracking_company }} #{{ line_item.fulfillment.tracking_number}} 41 | {% endif %} 42 |
43 | {% endif %} 44 |
{{ line_item.sku }}{{ line_item.price | money }}{{ line_item.quantity }}{{ line_item.quantity | times: line_item.price | money }}
{{ 'customer.order.subtotal' | t }}{{ order.subtotal_price | money }}
{{ discount.code }} {{ 'customer.order.discount' | t }}{{ discount.savings | money }}
{{ 'customer.order.shipping' | t }} ({{ shipping_method.title }}){{ shipping_method.price | money }}
{{ 'customer.order.tax' | t }} ({{ tax_line.title }} {{ tax_line.rate | times: 100 }}%){{ tax_line.price | money }}
{{ 'customer.order.total' | t }}{{ order.total_price | money }} {{ order.currency }}
85 | 86 |

{{ 'customer.order.billing_address' | t }}

87 | 88 |

{{ 'customer.order.payment_status' | t }}: {{ order.financial_status_label }}

89 | 90 | {{ order.billing_address | format_address }} 91 | 92 |

{{ 'customer.order.shipping_address' | t }}

93 | 94 |

{{ 'customer.order.fulfillment_status' | t }}: {{ order.fulfillment_status_label }}

95 | 96 | {{ order.shipping_address | format_address }} 97 | -------------------------------------------------------------------------------- /src/core/shopify/templates/customers/register.liquid: -------------------------------------------------------------------------------- 1 |

{{ 'customer.register.title' | t }}

2 | 3 | {% form 'create_customer' %} 4 | {{ form.errors | default_errors }} 5 | 6 | 9 | 15 | 16 | 19 | 24 | 25 | 28 | 37 | 38 | 41 | 46 | 47 |

48 | 49 |

50 | {{ 'customer.register.cancel' | t }} 51 | {% endform %} 52 | -------------------------------------------------------------------------------- /src/core/shopify/templates/customers/reset_password.liquid: -------------------------------------------------------------------------------- 1 |
2 | {% form 'reset_customer_password' %} 3 | 4 |

{{ 'customer.reset_password.title' | t }}

5 | 6 |

{{ 'customer.reset_password.subtext' | t: email: email }}

7 | 8 | {{ form.errors | default_errors }} 9 | 10 | 13 | 18 | 19 | 22 | 27 | 28 | 29 | {% endform %} 30 |
31 | -------------------------------------------------------------------------------- /src/core/shopify/templates/gift_card.liquid: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | QR code is rendered in `#QrCode` 3 | 4 | `gift_card.pass_url` is true if apple wallet is enabled for the shop 5 | {% endcomment %} 6 | 7 | {% layout 'gift_card' %} 8 | 9 |
10 |
11 | 14 |
15 |
{{ shop.url | escape }}
16 |
17 | 18 |
19 | 20 |

{{ 'gift_cards.issued.subtext' | t }}

21 | {% unless gift_card.enabled %} 22 | {{ 'gift_cards.issued.disabled' | t }} 23 | {% endunless %} 24 | 25 | {%- assign gift_card_expiry_date = gift_card.expires_on | date: "%d/%m/%y" -%} 26 | 27 | {% if gift_card.expired and gift_card.enabled %} 28 | {{ 'gift_cards.issued.expired' | t: expiry: gift_card_expiry_date }} 29 | {% endif %} 30 | 31 | {% if gift_card.expired != true and gift_card.expires_on and gift_card.enabled %} 32 | {{ 'gift_cards.issued.active' | t: expiry: gift_card_expiry_date }} 33 | {% endif %} 34 | 35 | Gift card illustration 36 | 37 | {%- assign initial_value_size = formatted_initial_value | size -%} 38 |

{{ formatted_initial_value }}

39 | 40 | {% if gift_card.balance != gift_card.initial_value %} 41 |

{{ 'gift_cards.issued.remaining_html' | t: balance: gift_card.balance | money }}

42 | {% endif %} 43 | 44 | {%- assign code_size = gift_card.code | format_code | size -%} 45 | {{ gift_card.code | format_code }} 46 | 47 |

{{ 'gift_cards.issued.redeem' | t }}

48 | 49 | {{ 'gift_cards.issued.shop_link' | t }} 50 | 51 |
52 | 53 | {% if gift_card.pass_url %} 54 | 55 | {{ 'gift_cards.issued.add_to_apple_wallet' | t }} 56 | 57 | {% endif %} 58 | 59 | 60 | {{ 'gift_cards.issued.print' | t }} 61 | 62 | 63 |
64 | -------------------------------------------------------------------------------- /src/core/shopify/templates/index.liquid: -------------------------------------------------------------------------------- 1 | {{ content_for_index }} 2 | -------------------------------------------------------------------------------- /src/core/shopify/templates/list-collections.liquid: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | This page represents the /collections and /products pages. 3 | {% endcomment %} 4 | 5 |

{{ page_title }}

6 | fdsfdfsdfdsfsd 7 | {% for collection in collections %} 8 | {% unless collection.handle == 'frontpage' %} 9 | 10 | {% if collection.image != blank %} 11 | {{ collection | img_url: '480x480' | img_tag: collection.title }} 12 | {% elsif collection.products.first != blank %} 13 | {{ collection.products.first | img_url: '480x480' | img_tag: collection.title }} 14 | {% else %} 15 | {% capture current %}{% cycle 1, 2, 3, 4, 5, 6 %}{% endcapture %} 16 | {{ 'collection-' | append: current | placeholder_svg_tag: 'placeholder-svg placeholder-svg--small' }} 17 | {% endif %} 18 | 19 | 20 |

21 | {{ collection.title }} 22 |

23 | {% endunless %} 24 | {% endfor %} 25 | -------------------------------------------------------------------------------- /src/core/shopify/templates/page.contact.liquid: -------------------------------------------------------------------------------- 1 |

{{ page.title }}

2 | 3 |
4 | {{ page.content }} 5 |
6 | 7 | {% form 'contact' %} 8 | 9 | {% if form.posted_successfully? %} 10 |

11 | {{ 'contact.form.post_success' | t }} 12 |

13 | {% endif %} 14 | 15 | {{ form.errors | default_errors }} 16 | 17 | 18 | 23 | 24 | 25 | 33 | 34 | 35 | 41 | 42 | 43 | 51 | 52 | 53 | 54 | {% endform %} 55 | -------------------------------------------------------------------------------- /src/core/shopify/templates/page.liquid: -------------------------------------------------------------------------------- 1 |

{{ page.title }}

2 | 3 |
4 | {{ page.content }} 5 |
6 | -------------------------------------------------------------------------------- /src/core/shopify/templates/password.liquid: -------------------------------------------------------------------------------- 1 | {% comment %} 2 | The share buttons share the home page URL. The share text is grabbed from the store 3 | meta description. 4 | {% endcomment %} 5 | 6 | {% layout 'password' %} 7 | 8 |

{{ 'general.password_page.opening_soon' | t }}

9 | 10 | {% unless shop.password_message == blank %} 11 |

12 | {{ shop.password_message }} 13 |

14 | {% endunless %} 15 | 16 | {% form 'customer' %} 17 | 18 | {{ form.errors | default_errors }} 19 | 20 | {% if form.posted_successfully? %} 21 | 24 | {% else %} 25 |

{{ 'general.password_page.signup_form_heading' | t }}

26 | 27 | 30 | 37 | 40 | {% endif %} 41 | {% endform %} 42 | 43 | {% if settings.share_facebook or settings.share_twitter %} 44 |

{{ 'general.password_page.spread_the_word' | t }}

45 | {% include 'social-sharing' %} 46 | {% endif %} 47 | 48 | 49 | {% include 'icon-lock' %} 50 | {{ 'general.password_page.password_link' | t }} → 51 | 52 | -------------------------------------------------------------------------------- /src/core/shopify/templates/product.liquid: -------------------------------------------------------------------------------- 1 | {% section 'product' %} 2 | -------------------------------------------------------------------------------- /src/core/shopify/templates/search.liquid: -------------------------------------------------------------------------------- 1 | {% paginate search.results by 10 %} 2 | 3 |

4 | {% if search.performed %} 5 | {% if search.results_count == 0 %} 6 | {{ 'general.search.no_results_html' | t: terms: search.terms }} 7 | {% else %} 8 | {{ 'general.search.results_for_html' | t: terms: search.terms }} 9 | {% endif %} 10 | {% else %} 11 | {{ 'general.search.title' | t }} 12 | {% endif %} 13 |

14 | 15 |
16 | 19 | 24 | 28 |
29 | 30 | 31 | {% if search.performed %} 32 | 74 | 75 | {% if paginate.pages > 1 %} 76 | {% include 'pagination' %} 77 | {% endif %} 78 | {% endif %} 79 | 80 | {% endpaginate %} 81 | -------------------------------------------------------------------------------- /src/core/stores/collections-store.js: -------------------------------------------------------------------------------- 1 | /* 2 | Collection store 3 | 4 | main recipient of Collections data from Shopify 5 | */ 6 | 7 | // Libs 8 | import Vue from 'vue' 9 | 10 | // Components 11 | import { Product } from '../models/product' 12 | 13 | 14 | export const CollectionsStore = Vue.extend( { 15 | 16 | data: function() { 17 | return { 18 | title: '', 19 | _products: {} 20 | } 21 | }, 22 | 23 | 24 | computed: { 25 | 26 | products: { 27 | get: function() { 28 | return this.$data._products 29 | }, 30 | set: function( list ) { 31 | const products = this.$data._products 32 | for (let idx=0, len=list.length; idx < len; idx++) { 33 | let d = list[ idx ] 34 | let id = d.id 35 | let o = products[ id ] 36 | if ( o==undefined ) { 37 | o = new Product() 38 | this.$set( products, id, o ) 39 | } 40 | o.setData( d ) 41 | } 42 | } 43 | }, 44 | 45 | }, 46 | 47 | 48 | methods: { 49 | 50 | setData( data ) { 51 | if (!data) return 52 | for ( let prop in data ) { 53 | const value = data[ prop ] 54 | if ( ['products', 'title'].indexOf( prop )!==-1 ) { 55 | this[prop] = data[ prop ] 56 | } 57 | } 58 | }, 59 | 60 | } 61 | 62 | }) 63 | -------------------------------------------------------------------------------- /src/core/stores/errors-store.js: -------------------------------------------------------------------------------- 1 | /* 2 | Errors store 3 | 4 | main recipient of Errors data from Shopify 5 | */ 6 | 7 | // Libs 8 | import Vue from 'vue' 9 | 10 | 11 | export const ErrorsStore = Vue.extend( { 12 | 13 | data: function() { 14 | return { 15 | is_error: false, 16 | type: '' 17 | } 18 | }, 19 | 20 | 21 | methods: { 22 | 23 | setData( data ) { 24 | if (!data) return 25 | for ( let prop in data ) { 26 | this[prop] = data[ prop ] 27 | } 28 | }, 29 | 30 | } 31 | 32 | }) 33 | -------------------------------------------------------------------------------- /src/core/stores/products-store.js: -------------------------------------------------------------------------------- 1 | /* 2 | Products store 3 | 4 | main recipient of Products data from Shopify 5 | */ 6 | 7 | // Libs 8 | import Vue from 'vue' 9 | 10 | // Components 11 | export { Product as ProductsStore } from '../models/product' 12 | 13 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | /* 2 | file to bootstrap Vuejs 3 | */ 4 | 5 | // Libs 6 | import Vue from 'vue' 7 | import VueRouter from 'vue-router' 8 | 9 | // Components 10 | import App from './App.vue' 11 | import { routes } from './routes' 12 | 13 | 14 | // Setup 15 | 16 | Vue.use( VueRouter ) 17 | Vue.filter( 'money', function(value) { 18 | return (value/100).toFixed(2) 19 | }) 20 | 21 | const router = new VueRouter({ 22 | routes, 23 | mode: 'history', 24 | }) 25 | 26 | new Vue({ 27 | el: '#vueapp', 28 | router, 29 | render: function ( createElement ) { 30 | return createElement( App ) 31 | } 32 | }) 33 | -------------------------------------------------------------------------------- /src/locales/en-default.js: -------------------------------------------------------------------------------- 1 | 2 | const info = { 3 | lang: 'en', 4 | locale: 'US', 5 | is_default: true 6 | } 7 | 8 | const data = { 9 | "general": { 10 | "accessibility": { 11 | "skip_to_content": "Skip to content" 12 | }, 13 | "meta": { 14 | "tags": "Tagged \"{{ tags }}\"", 15 | "page": "Page {{ page }}" 16 | }, 17 | "404": { 18 | "title": "404 Page Not Found", 19 | "subtext_html": "The page you requested does not exist. Click here to continue shopping." 20 | }, 21 | "password_page": { 22 | "opening_soon": "Opening Soon", 23 | "spread_the_word": "Spread the word", 24 | "login_form_heading": "Enter store using password", 25 | "login_form_password_label": "Password", 26 | "login_form_password_placeholder": "Your password", 27 | "login_form_submit": "Enter", 28 | "signup_form_heading": "Find out when we open", 29 | "signup_form_email_label": "Email", 30 | "signup_form_email_placeholder": "Your email", 31 | "signup_form_submit": "Submit", 32 | "signup_form_success": "We will send you an email right before we open!", 33 | "admin_link_html": "Are you the store owner? Log in here", 34 | "password_link": "Enter using password", 35 | "powered_by_shopify_html": "This shop will be powered by {{ shopify }}" 36 | }, 37 | "social": { 38 | "share_on_facebook": "Share", 39 | "share_on_twitter": "Tweet", 40 | "share_on_pinterest": "Pin it", 41 | "alt_text": { 42 | "share_on_facebook": "Share on Facebook", 43 | "share_on_twitter": "Tweet on Twitter", 44 | "share_on_pinterest": "Pin on Pinterest" 45 | } 46 | }, 47 | "search": { 48 | "no_results_html": "Your search for \"{{ terms }}\" did not yield any results.", 49 | "results_for_html": "Your search for \"{{ terms }}\" revealed the following:", 50 | "title": "Search for products on our site", 51 | "placeholder": "Search our store", 52 | "submit": "Search" 53 | } 54 | }, 55 | "blogs": { 56 | "article": { 57 | "author_on_date_html": "Posted by {{ author }} on {{ date }}", 58 | "comment_meta_html": "{{ author }} on {{ date }}", 59 | "read_more": "Read more" 60 | }, 61 | "comments": { 62 | "title": "Leave a comment", 63 | "name": "Name", 64 | "email": "Email", 65 | "message": "Message", 66 | "post": "Post comment", 67 | "moderated": "Please note, comments must be approved before they are published", 68 | "success_moderated": "Your comment was posted successfully. We will publish it in a little while, as our blog is moderated.", 69 | "success": "Your comment was posted successfully! Thank you!", 70 | "with_count": { 71 | "one": "{{ count }} comment", 72 | "other": "{{ count }} comments" 73 | } 74 | }, 75 | "general": { 76 | "categories": "Categories" 77 | } 78 | }, 79 | "cart": { 80 | "general": { 81 | "title": "Shopping Cart", 82 | "remove": "Remove", 83 | "note": "Special instructions for seller", 84 | "subtotal": "Subtotal", 85 | "shipping_at_checkout": "Shipping & taxes calculated at checkout", 86 | "update": "Update Cart", 87 | "checkout": "Check Out", 88 | "empty": "Your cart is currently empty.", 89 | "cookies_required": "Enable cookies to use the shopping cart", 90 | "continue_browsing_html": "Continue browsing here.", 91 | "item_quantity": "Item quantity", 92 | "savings": "You're saving" 93 | }, 94 | "label": { 95 | "product": "Product", 96 | "price": "Price", 97 | "quantity": "Quantity", 98 | "total": "Total", 99 | "discounted_price": "Discounted price", 100 | "original_price": "Original price" 101 | } 102 | }, 103 | "collections": { 104 | "general": { 105 | "no_matches": "Sorry, there are no products in this collection", 106 | "link_title": "Browse our {{ title }} collection" 107 | } 108 | }, 109 | "contact": { 110 | "form": { 111 | "name": "Name", 112 | "email": "Email", 113 | "phone": "Phone Number", 114 | "message": "Message", 115 | "send": "Send", 116 | "post_success": "Thanks for contacting us. We'll get back to you as soon as possible." 117 | } 118 | }, 119 | "customer": { 120 | "account": { 121 | "title": "My Account", 122 | "details": "Account Details", 123 | "view_addresses": "View Addresses", 124 | "return": "Return to Account Details" 125 | }, 126 | "activate_account": { 127 | "title": "Activate Account", 128 | "subtext": "Create your password to activate your account.", 129 | "password": "Password", 130 | "password_confirm": "Confirm Password", 131 | "submit": "Activate Account", 132 | "cancel": "Decline Invitation" 133 | }, 134 | "addresses": { 135 | "title": "Your Addresses", 136 | "default": "Default", 137 | "add_new": "Add a New Address", 138 | "edit_address": "Edit address", 139 | "first_name": "First Name", 140 | "last_name": "Last Name", 141 | "company": "Company", 142 | "address1": "Address1", 143 | "address2": "Address2", 144 | "city": "City", 145 | "country": "Country", 146 | "province": "Province", 147 | "zip": "Postal/Zip Code", 148 | "phone": "Phone", 149 | "set_default": "Set as default address", 150 | "add": "Add Address", 151 | "update": "Update Address", 152 | "cancel": "Cancel", 153 | "edit": "Edit", 154 | "delete": "Delete", 155 | "delete_confirm": "Are you sure you wish to delete this address?" 156 | }, 157 | "login": { 158 | "title": "Login", 159 | "email": "Email", 160 | "password": "Password", 161 | "forgot_password": "Forgot your password?", 162 | "sign_in": "Sign In", 163 | "cancel": "Return to Store", 164 | "guest_title": "Continue as a guest", 165 | "guest_continue": "Continue" 166 | }, 167 | "orders": { 168 | "title": "Order History", 169 | "order_number": "Order", 170 | "date": "Date", 171 | "payment_status": "Payment Status", 172 | "fulfillment_status": "Fulfillment Status", 173 | "total": "Total", 174 | "none": "You haven't placed any orders yet." 175 | }, 176 | "order": { 177 | "title": "Order {{ name }}", 178 | "date": "Placed on {{ date }}", 179 | "cancelled": "Order Cancelled on {{ date }}", 180 | "cancelled_reason": "Reason: {{ reason }}", 181 | "billing_address": "Billing Address", 182 | "payment_status": "Payment Status", 183 | "shipping_address": "Shipping Address", 184 | "fulfillment_status": "Fulfillment Status", 185 | "discount": "Discount", 186 | "shipping": "Shipping", 187 | "tax": "Tax", 188 | "product": "Product", 189 | "sku": "SKU", 190 | "price": "Price", 191 | "quantity": "Quantity", 192 | "total": "Total", 193 | "fulfilled_at": "Fulfilled {{ date }}", 194 | "subtotal": "Subtotal" 195 | }, 196 | "recover_password": { 197 | "title": "Reset your password", 198 | "email": "Email", 199 | "submit": "Submit", 200 | "cancel": "Cancel", 201 | "subtext": "We will send you an email to reset your password.", 202 | "success": "We've sent you an email with a link to update your password." 203 | }, 204 | "reset_password": { 205 | "title": "Reset account password", 206 | "subtext": "Enter a new password for {{ email }}", 207 | "password": "Password", 208 | "password_confirm": "Confirm Password", 209 | "submit": "Reset Password" 210 | }, 211 | "register": { 212 | "title": "Create Account", 213 | "first_name": "First Name", 214 | "last_name": "Last Name", 215 | "email": "Email", 216 | "password": "Password", 217 | "submit": "Create", 218 | "cancel": "Return to Store" 219 | } 220 | }, 221 | "homepage": { 222 | "onboarding": { 223 | "product_title": "Example Product Title", 224 | "collection_title": "Example Collection Title", 225 | "no_content": "This section doesn’t currently include any content. Add content to this section using the sidebar." 226 | } 227 | }, 228 | "layout": { 229 | "cart": { 230 | "title": "Cart", 231 | "items_count": { 232 | "one": "item", 233 | "other": "items" 234 | } 235 | }, 236 | "customer": { 237 | "account": "Account", 238 | "logged_in_as_html": "Logged in as {{ first_name }}", 239 | "log_out": "Log out", 240 | "log_in": "Log in", 241 | "create_account": "Create account" 242 | }, 243 | "footer": { 244 | "social_platform": "{{ name }} on {{ platform }}", 245 | "copyright": "Copyright" 246 | } 247 | }, 248 | "products": { 249 | "product": { 250 | "regular_price": "Regular price", 251 | "sold_out": "Sold Out", 252 | "unavailable": "Unavailable", 253 | "on_sale": "On Sale", 254 | "on_sale_from_html": "On Sale from {{ price }}", 255 | "from_text_html": "From {{ price }}", 256 | "quantity": "Quantity", 257 | "add_to_cart": "Add to Cart" 258 | } 259 | }, 260 | "gift_cards": { 261 | "issued": { 262 | "title": "Here's your {{ value }} gift card for {{ shop }}!", 263 | "subtext": "Here's your gift card!", 264 | "disabled": "Disabled", 265 | "expired": "Expired on {{ expiry }}", 266 | "active": "Expires on {{ expiry }}", 267 | "redeem": "Use this code at checkout to redeem your gift card", 268 | "shop_link": "Start shopping", 269 | "print": "Print", 270 | "remaining_html": "{{ balance }} left", 271 | "add_to_apple_wallet": "Add to Apple Wallet" 272 | } 273 | }, 274 | "date_formats":{ 275 | "month_day_year": "%B %d, %Y" 276 | } 277 | } 278 | 279 | export default { info, data } 280 | -------------------------------------------------------------------------------- /src/routes.js: -------------------------------------------------------------------------------- 1 | /* 2 | template routes 3 | 4 | match generic page routes or add custom versions 5 | */ 6 | 7 | // Components 8 | import BlogView from './views/BlogView.vue' 9 | import BlogPostView from './views/BlogPostView.vue' 10 | import HomeView from './views/HomeView.vue' 11 | import CollectionView from './views/CollectionView.vue' 12 | import PageView from './views/PageView.vue' 13 | import ProductDetailView from './views/ProductDetailView.vue' 14 | 15 | 16 | export const routes = [ 17 | { path: '', component: HomeView }, 18 | { path: '/blogs/:name', component: BlogView }, 19 | { path: '/blogs/:name/:slug', component: BlogPostView }, 20 | { path: '/collections/all', component: CollectionView }, 21 | { path: '/collections/frontpage/products/:slug', component: ProductDetailView }, 22 | { path: '/products/:slug', component: ProductDetailView }, 23 | 24 | // include custom page routes here 25 | // { path: '/pages/custom-page', component: CustomPageView }, 26 | { path: '/pages/:slug', component: PageView }, 27 | ] 28 | -------------------------------------------------------------------------------- /src/services/i18n.js: -------------------------------------------------------------------------------- 1 | /* 2 | Internationalization service 3 | */ 4 | 5 | // Libs 6 | import Vue from 'vue' 7 | 8 | // languages 9 | // import additional languages here, register below 10 | import LangEn from '../locales/en-default' 11 | 12 | 13 | /* 14 | look inside of the data structure to determine the top-level properties 15 | */ 16 | function createDataStructure( data ) { 17 | const result = {} 18 | for (let key in data) { 19 | if (data.hasOwnProperty(key)) { 20 | result[ key ] = null 21 | } 22 | } 23 | return result 24 | } 25 | 26 | 27 | const LocaleService = Vue.extend( { 28 | 29 | data: function() { 30 | const { data } = LangEn 31 | const struct = { 32 | _lang:{}, 33 | _current: "" 34 | } 35 | return Object.assign( struct, createDataStructure( data ) ) 36 | }, 37 | 38 | 39 | methods: { 40 | 41 | register( language ) { 42 | const { is_default } = language.info 43 | 44 | const key = this._createKey( language ) 45 | this.$data._lang[ key ] = language 46 | 47 | if ( is_default==true ) this._setCurrentLang( language ) 48 | }, 49 | 50 | _createKey( language ) { 51 | const { lang, locale } = language.info 52 | return [ lang, locale ].join('-') 53 | }, 54 | 55 | _setCurrentLang( language ) { 56 | const { data } = language 57 | 58 | const key = this._createKey( language ) 59 | this.$data._current = key 60 | 61 | for ( let prop in data ) { 62 | this[ prop ] = data[ prop ] 63 | } 64 | } 65 | 66 | } 67 | 68 | }) 69 | 70 | 71 | const service = new LocaleService() 72 | 73 | // register additional language files 74 | service.register( LangEn ) 75 | 76 | 77 | export default service -------------------------------------------------------------------------------- /src/views/BlogPostView.vue: -------------------------------------------------------------------------------- 1 | /* 2 | generic Blog Post component 3 | */ 4 | 5 | 11 | 12 | 13 | 22 | 23 | 24 | 29 | -------------------------------------------------------------------------------- /src/views/BlogView.vue: -------------------------------------------------------------------------------- 1 | /* 2 | generic Blog component 3 | */ 4 | 5 | 11 | 12 | 13 | 22 | 23 | 24 | 29 | -------------------------------------------------------------------------------- /src/views/CollectionView.vue: -------------------------------------------------------------------------------- 1 | /* 2 | Collections component shown for Collections/All 3 | */ 4 | 5 | 13 | 14 | 15 | 33 | 34 | 35 | 40 | -------------------------------------------------------------------------------- /src/views/Error404View.vue: -------------------------------------------------------------------------------- 1 | /* 2 | 404 Error component 3 | 4 | shown when 404 error is received 5 | */ 6 | 7 | 13 | 14 | 23 | 24 | 29 | -------------------------------------------------------------------------------- /src/views/HomeView.vue: -------------------------------------------------------------------------------- 1 | /* 2 | Home component shown at home 3 | */ 4 | 5 | 11 | 12 | 13 | 22 | 23 | 24 | 29 | -------------------------------------------------------------------------------- /src/views/PageView.vue: -------------------------------------------------------------------------------- 1 | /* 2 | generic Page component 3 | */ 4 | 5 | 11 | 12 | 13 | 22 | 23 | 24 | 29 | -------------------------------------------------------------------------------- /src/views/ProductDetailView.vue: -------------------------------------------------------------------------------- 1 | /* 2 | Product component 3 | 4 | shown at route '/products/:slug' 5 | */ 6 | 7 | 16 | 17 | 43 | 44 | 49 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var webpack = require('webpack') 3 | var WebpackNotifierPlugin = require('webpack-notifier') // Mac notifications 4 | var CopyWebpackPlugin = require('copy-webpack-plugin') 5 | 6 | 7 | var base_config = { 8 | devtool: 'source-map', 9 | entry: { 10 | build: [ 11 | './src/index.js', 12 | ], 13 | }, 14 | output: { 15 | path: path.join(__dirname, 'dist'), 16 | filename: 'assets/[name].js', 17 | publicPath: '/dist/', 18 | pathinfo: true, // dev-only 19 | }, 20 | module: { 21 | rules: [ 22 | { 23 | test: /\.css$/, 24 | loader: 'style-loader!css-loader' 25 | }, 26 | { 27 | test: /\.vue$/, 28 | loader: 'vue-loader', 29 | }, 30 | { 31 | test: /\.js$/, 32 | exclude: /node_modules/, 33 | loader: 'babel-loader', 34 | }, 35 | ], 36 | }, 37 | plugins: [ 38 | new webpack.ProvidePlugin({ 39 | $: 'jquery', 40 | jQuery: 'jquery', 41 | }), 42 | new WebpackNotifierPlugin({ alwaysNotify: true }), 43 | new CopyWebpackPlugin([ 44 | 45 | // Shopify Standard 46 | { from: 'src/core/shopify/assets', to: 'assets' }, 47 | { from: 'src/core/shopify/config', to: 'config' }, 48 | { from: 'src/core/shopify/layout', to: 'layout' }, 49 | { from: 'src/core/shopify/locales', to: 'locales' }, 50 | { from: 'src/core/shopify/sections', to: 'sections' }, 51 | { from: 'src/core/shopify/snippets', to: 'snippets' }, 52 | { from: 'src/core/shopify/templates', to: 'templates' }, 53 | 54 | // Shopify Modern 55 | { from: 'src/core/modern/layout', to: 'layout' }, 56 | { from: 'src/core/modern/snippets', to: 'snippets' }, 57 | { from: 'src/core/modern/templates', to: 'templates' }, 58 | ]) 59 | ], 60 | resolve: { 61 | extensions: ['.js', '.vue'], 62 | modules: [ 63 | path.join(__dirname, 'src'), 64 | 'node_modules', 65 | ], 66 | enforceExtension: false, 67 | }, 68 | externals: { 69 | }, 70 | } 71 | 72 | 73 | module.exports = base_config 74 | --------------------------------------------------------------------------------