solidify 0.0.1.alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +40 -0
  5. data/.travis.yml +10 -0
  6. data/CODE_OF_CONDUCT.md +74 -0
  7. data/Gemfile +3 -0
  8. data/Guardfile +51 -0
  9. data/LICENSE.txt +21 -0
  10. data/README.md +75 -0
  11. data/Rakefile +42 -0
  12. data/app/controllers/concerns/solidify/liquid.rb +26 -0
  13. data/app/controllers/solidify/addresses_controller.rb +15 -0
  14. data/app/controllers/solidify/carts_controller.rb +15 -0
  15. data/app/controllers/solidify/collections_controller.rb +26 -0
  16. data/app/controllers/solidify/customers_controller.rb +16 -0
  17. data/app/controllers/solidify/home_controller.rb +15 -0
  18. data/app/controllers/solidify/liquid_controller.rb +25 -0
  19. data/app/controllers/solidify/orders_controller.rb +19 -0
  20. data/app/controllers/solidify/pages_controller.rb +22 -0
  21. data/app/controllers/solidify/products_controller.rb +34 -0
  22. data/app/controllers/solidify/registrations_controller.rb +25 -0
  23. data/app/controllers/solidify/responders/solidify/liquid_responder.rb +29 -0
  24. data/app/controllers/solidify/search_controller.rb +41 -0
  25. data/app/controllers/solidify/sessions_controller.rb +15 -0
  26. data/app/drops/rails_settings/scoped_settings_drop.rb +11 -0
  27. data/app/drops/solidify/errors_drop.rb +14 -0
  28. data/app/drops/solidify/link_drop.rb +15 -0
  29. data/app/drops/solidify/link_list_drop.rb +7 -0
  30. data/app/drops/solidify/nil_drop.rb +7 -0
  31. data/app/drops/solidify/page_drop.rb +7 -0
  32. data/app/drops/solidify/search_drop.rb +7 -0
  33. data/app/drops/spree/address_drop.rb +28 -0
  34. data/app/drops/spree/image_drop.rb +32 -0
  35. data/app/drops/spree/line_item_drop.rb +98 -0
  36. data/app/drops/spree/option_type_drop.rb +4 -0
  37. data/app/drops/spree/order_drop.rb +64 -0
  38. data/app/drops/spree/product_drop.rb +97 -0
  39. data/app/drops/spree/taxon_drop.rb +53 -0
  40. data/app/drops/spree/user_drop.rb +54 -0
  41. data/app/drops/spree/variant_drop.rb +111 -0
  42. data/app/fields/spree/address_fields.rb +18 -0
  43. data/app/fields/spree/image_fields.rb +12 -0
  44. data/app/fields/spree/line_item_fields.rb +21 -0
  45. data/app/fields/spree/order_fields.rb +22 -0
  46. data/app/fields/spree/product_fields.rb +22 -0
  47. data/app/fields/spree/taxon_fields.rb +18 -0
  48. data/app/fields/spree/user_fields.rb +14 -0
  49. data/app/fields/spree/variant_fields.rb +19 -0
  50. data/app/filters/solidify/additional_filters.rb +22 -0
  51. data/app/filters/solidify/html_filters.rb +16 -0
  52. data/app/filters/solidify/money_filters.rb +39 -0
  53. data/app/filters/solidify/string_filters.rb +47 -0
  54. data/app/filters/solidify/url_filters.rb +59 -0
  55. data/app/helpers/solidify/liquid_helper.rb +111 -0
  56. data/app/helpers/solidify/shop_helper.rb +7 -0
  57. data/app/models/concerns/solidify/address.rb +15 -0
  58. data/app/models/concerns/solidify/full_name.rb +11 -0
  59. data/app/models/concerns/solidify/handle.rb +25 -0
  60. data/app/models/concerns/solidify/inventory_policy.rb +7 -0
  61. data/app/models/concerns/solidify/validation_cancel.rb +33 -0
  62. data/app/models/concerns/spree/order_state.rb +19 -0
  63. data/app/models/solidify/asset.rb +12 -0
  64. data/app/models/solidify/link.rb +10 -0
  65. data/app/models/solidify/link_list.rb +7 -0
  66. data/app/models/solidify/page.rb +5 -0
  67. data/app/models/solidify/setting.rb +8 -0
  68. data/app/models/solidify/theme.rb +19 -0
  69. data/app/models/spree/address_decorator.rb +13 -0
  70. data/app/models/spree/image_decorator.rb +7 -0
  71. data/app/models/spree/line_item_decorator.rb +7 -0
  72. data/app/models/spree/order_decorator.rb +10 -0
  73. data/app/models/spree/product_decorator.rb +8 -0
  74. data/app/models/spree/taxon_decorator.rb +20 -0
  75. data/app/models/spree/user_decorator.rb +9 -0
  76. data/app/models/spree/variant_decorator.rb +11 -0
  77. data/app/poro/solidify/search.rb +14 -0
  78. data/app/services/solidify/app_specific_string_io.rb +15 -0
  79. data/app/services/solidify/asset_compiler.rb +11 -0
  80. data/app/services/solidify/asset_postprocessor.rb +53 -0
  81. data/app/services/solidify/collections_all_builder.rb +12 -0
  82. data/app/services/solidify/link_list_seeder.rb +26 -0
  83. data/app/services/solidify/liquid_asset_compiler.rb +19 -0
  84. data/app/services/solidify/scss_asset_compiler.rb +15 -0
  85. data/app/services/solidify/shop_settings_seeder.rb +26 -0
  86. data/app/services/solidify/theme_mechanic.rb +30 -0
  87. data/app/uploaders/solidify/asset_uploader.rb +10 -0
  88. data/app/views/solidify/global/content_for_header.html.erb +0 -0
  89. data/app/views/solidify/themes/skeleton-theme/README.md +54 -0
  90. data/app/views/solidify/themes/skeleton-theme/assets/arrow-down.svg.liquid +3 -0
  91. data/app/views/solidify/themes/skeleton-theme/assets/cart.svg.liquid +4 -0
  92. data/app/views/solidify/themes/skeleton-theme/assets/shop.js.liquid +75 -0
  93. data/app/views/solidify/themes/skeleton-theme/assets/shopify_common.js +14 -0
  94. data/app/views/solidify/themes/skeleton-theme/assets/style.scss.liquid +768 -0
  95. data/app/views/solidify/themes/skeleton-theme/config/settings.html +217 -0
  96. data/app/views/solidify/themes/skeleton-theme/config/settings_data.json +26 -0
  97. data/app/views/solidify/themes/skeleton-theme/layout/theme.liquid +181 -0
  98. data/app/views/solidify/themes/skeleton-theme/snippets/article-grid-item.liquid +73 -0
  99. data/app/views/solidify/themes/skeleton-theme/snippets/collection-grid-item.liquid +46 -0
  100. data/app/views/solidify/themes/skeleton-theme/snippets/collection-listing.liquid +46 -0
  101. data/app/views/solidify/themes/skeleton-theme/snippets/open-graph-tags.liquid +35 -0
  102. data/app/views/solidify/themes/skeleton-theme/snippets/product-grid-item.liquid +70 -0
  103. data/app/views/solidify/themes/skeleton-theme/snippets/site-nav.liquid +57 -0
  104. data/app/views/solidify/themes/skeleton-theme/snippets/social-links.liquid +42 -0
  105. data/app/views/solidify/themes/skeleton-theme/snippets/twitter-card.liquid +41 -0
  106. data/app/views/solidify/themes/skeleton-theme/templates/404.liquid +2 -0
  107. data/app/views/solidify/themes/skeleton-theme/templates/article.liquid +160 -0
  108. data/app/views/solidify/themes/skeleton-theme/templates/blog.grid.liquid +30 -0
  109. data/app/views/solidify/themes/skeleton-theme/templates/blog.liquid +92 -0
  110. data/app/views/solidify/themes/skeleton-theme/templates/cart.liquid +123 -0
  111. data/app/views/solidify/themes/skeleton-theme/templates/collection.liquid +102 -0
  112. data/app/views/solidify/themes/skeleton-theme/templates/customers/account.liquid +57 -0
  113. data/app/views/solidify/themes/skeleton-theme/templates/customers/activate_account.liquid +26 -0
  114. data/app/views/solidify/themes/skeleton-theme/templates/customers/addresses.liquid +173 -0
  115. data/app/views/solidify/themes/skeleton-theme/templates/customers/login.liquid +90 -0
  116. data/app/views/solidify/themes/skeleton-theme/templates/customers/order.liquid +103 -0
  117. data/app/views/solidify/themes/skeleton-theme/templates/customers/register.liquid +32 -0
  118. data/app/views/solidify/themes/skeleton-theme/templates/customers/reset_password.liquid +27 -0
  119. data/app/views/solidify/themes/skeleton-theme/templates/index.liquid +39 -0
  120. data/app/views/solidify/themes/skeleton-theme/templates/list-collections.liquid +19 -0
  121. data/app/views/solidify/themes/skeleton-theme/templates/page.liquid +16 -0
  122. data/app/views/solidify/themes/skeleton-theme/templates/product.liquid +202 -0
  123. data/app/views/solidify/themes/skeleton-theme/templates/search.liquid +72 -0
  124. data/bin/rails +12 -0
  125. data/config/app.yml +0 -0
  126. data/config/initializers/carrierwave.rb +25 -0
  127. data/config/initializers/devise.rb +286 -0
  128. data/config/initializers/form_tag.rb +43 -0
  129. data/config/initializers/liquid.rb +213 -0
  130. data/config/initializers/sass.rb +15 -0
  131. data/config/initializers/spree.rb +7 -0
  132. data/config/initializers/theme_settings.rb +29 -0
  133. data/config/routes.rb +52 -0
  134. data/config/spring.rb +2 -0
  135. data/db/migrate/20170223064316_create_solidify_assets.solidify.rb +14 -0
  136. data/db/migrate/20170223064317_create_solidify_themes.solidify.rb +10 -0
  137. data/db/migrate/20170223064318_create_solidify_link_lists.solidify.rb +12 -0
  138. data/db/migrate/20170223064319_create_solidify_links.solidify.rb +13 -0
  139. data/db/migrate/20170223064320_create_solidify_settings.solidify.rb +22 -0
  140. data/db/migrate/20170223064321_create_solidify_pages.solidify.rb +16 -0
  141. data/db/migrate/20170223064322_add_attributes_to_spree_users.solidify.rb +7 -0
  142. data/db/migrate/20170223064323_add_handle_to_spree_taxons.solidify.rb +7 -0
  143. data/db/migrate/20170228115149_add_state_and_country_fields_to_spree_addresses.solidify.rb +7 -0
  144. data/lib/generators/solidify/install/install_generator.rb +23 -0
  145. data/lib/solidify.rb +11 -0
  146. data/lib/solidify/configuration.rb +21 -0
  147. data/lib/solidify/engine.rb +24 -0
  148. data/lib/solidify/testing_support/factories.rb +5 -0
  149. data/lib/solidify/testing_support/factories/assets.rb +75 -0
  150. data/lib/solidify/testing_support/factories/solidify_pages.rb +10 -0
  151. data/lib/solidify/testing_support/factories/spree_addresses.rb +9 -0
  152. data/lib/solidify/testing_support/factories/spree_line_items.rb +10 -0
  153. data/lib/solidify/testing_support/factories/spree_orders.rb +9 -0
  154. data/lib/solidify/testing_support/factories/spree_products.rb +8 -0
  155. data/lib/solidify/testing_support/factories/spree_taxons.rb +7 -0
  156. data/lib/solidify/testing_support/factories/spree_variants.rb +7 -0
  157. data/lib/solidify/testing_support/factories/themes.rb +7 -0
  158. data/lib/solidify/version.rb +3 -0
  159. data/lib/tasks/download_theme.rake +18 -0
  160. data/lib/tasks/seed_default_theme.rake +8 -0
  161. data/lib/tasks/seed_everything.rake +12 -0
  162. data/lib/tasks/seed_link_list.rake +8 -0
  163. data/lib/tasks/seed_shop_settings.rake +8 -0
  164. data/solidify.gemspec +61 -0
  165. metadata +668 -0
@@ -0,0 +1,90 @@
1
+ <div class="page-width">
2
+ <div class="grid">
3
+
4
+ <div class="grid__item medium-up--one-half medium-up--push-one-quarter">
5
+ <div class="note form-success hide" id="ResetSuccess">
6
+ {{ 'customer.recover_password.success' | t }}
7
+ </div>
8
+
9
+ <div id="CustomerLoginForm" class="form-vertical">
10
+ {% form 'customer_login' %}
11
+
12
+ <h1 class="text-center">{{ 'customer.login.title' | t }}</h1>
13
+
14
+ {{ form.errors | default_errors }}
15
+
16
+ <label for="CustomerEmail">{{ 'customer.login.email' | t }}</label>
17
+ <input type="email" name="customer[email]" id="CustomerEmail" class="{% if form.errors contains 'email' %} input--error{% endif %}" autocorrect="off" autocapitalize="off" autofocus>
18
+
19
+ {% if form.password_needed %}
20
+ <label for="CustomerPassword">{{ 'customer.login.password' | t }}</label>
21
+ <input type="password" value="" name="customer[password]" id="CustomerPassword" class="{% if form.errors contains 'password' %} input--error{% endif %}">
22
+ {% endif %}
23
+
24
+ <div class="text-center">
25
+ {% if form.password_needed %}
26
+ <p><a href="#recover" id="RecoverPassword">{{ 'customer.login.forgot_password' | t }}</a></p>
27
+ {% endif %}
28
+
29
+ <input type="submit" class="btn" value="{{ 'customer.login.sign_in' | t }}">
30
+
31
+ <p>
32
+ {{ 'layout.customer.create_account' | t | customer_register_link }}
33
+ </p>
34
+ </div>
35
+
36
+ {% endform %}
37
+ </div>
38
+
39
+ <div id="RecoverPasswordForm" class="hide">
40
+
41
+ <div class="text-center">
42
+ <h2>{{ 'customer.recover_password.title' | t }}</h2>
43
+ <p>{{ 'customer.recover_password.subtext' | t }}</p>
44
+ </div>
45
+
46
+ <div class="form-vertical">
47
+ {% form 'recover_customer_password' %}
48
+
49
+ {{ form.errors | default_errors }}
50
+
51
+ {% comment %}
52
+ Add a hidden span to indicate the form was submitted succesfully.
53
+ {% endcomment %}
54
+ {% if form.posted_successfully? %}
55
+ <span class="hide reset-password-success"></span>
56
+ {% endif %}
57
+
58
+ <label for="RecoverEmail">{{ 'customer.recover_password.email' | t }}</label>
59
+ <input type="email" value="" name="email" id="RecoverEmail" class="input-full"autocorrect="off" autocapitalize="off">
60
+
61
+ <div class="text-center">
62
+ <p>
63
+ <input type="submit" class="btn" value="{{ 'customer.recover_password.submit' | t }}">
64
+ </p>
65
+
66
+ <button type="button" id="HideRecoverPasswordLink" class="text-link">{{ 'customer.recover_password.cancel' | t }}</button>
67
+ </div>
68
+ {% endform %}
69
+ </div>
70
+
71
+ </div>
72
+
73
+ {% comment %}
74
+ If accounts are set as optional, the following will be shown as an option
75
+ during checkout, not on the default /login page.
76
+ {% endcomment %}
77
+ {% if shop.checkout.guest_login %}
78
+ <div class="text-center">
79
+ <hr class="hr--invisible">
80
+ <h2>{{ 'customer.login.guest_title' | t }}</h2>
81
+
82
+ {% form 'guest_login' %}
83
+ <input type="submit" class="btn" value="{{ 'customer.login.guest_continue' | t }}">
84
+ {% endform %}
85
+ </div>
86
+ {% endif %}
87
+ </div>
88
+
89
+ </div>
90
+ </div>
@@ -0,0 +1,103 @@
1
+ <div class="page-width">
2
+ <div class="section-header text-center">
3
+ <h1>{{ 'customer.account.title' | t }}</h1>
4
+ <p><a href="/account">{{ 'customer.account.return' | t }}</a></p>
5
+ </div>
6
+
7
+ <div class="grid">
8
+ <div class="grid__item medium-up--two-thirds">
9
+ <h2>{{ 'customer.order.title' | t: name: order.name }}</h2>
10
+
11
+ {%- assign order_date = order.created_at | date: "%B %d, %Y %I:%M%p" -%}
12
+ <p>{{ 'customer.order.date' | t: date: order_date }}</p>
13
+
14
+ {% if order.cancelled %}
15
+ <div class="order--cancelled">
16
+ {%- assign cancelled_at = order.cancelled_at | date: "%B %d, %Y %I:%M%p" -%}
17
+ <p>{{ 'customer.order.cancelled' | t: date: cancelled_at }}</p>
18
+ <p>{{ 'customer.order.cancelled_reason' | t: reason: order.cancel_reason }}</p>
19
+ </div>
20
+ {% endif %}
21
+
22
+ <table class="responsive-table">
23
+ <thead>
24
+ <tr>
25
+ <th>{{ 'customer.order.product' | t }}</th>
26
+ <th>{{ 'customer.order.sku' | t }}</th>
27
+ <th>{{ 'customer.order.price' | t }}</th>
28
+ <th>{{ 'customer.order.quantity' | t }}</th>
29
+ <th>{{ 'customer.order.total' | t }}</th>
30
+ </tr>
31
+ </thead>
32
+ <tbody>
33
+ {% for line_item in order.line_items %}
34
+ <tr id="{{ line_item.key }}" class="responsive-table__row" >
35
+ <td data-label="{{ 'customer.order.product' | t }}">
36
+ {{ line_item.title | link_to: line_item.product.url }}
37
+ {% if line_item.fulfillment %}
38
+ <div class="note">
39
+ {%- assign created_at = line_item.fulfillment.created_at | date: format: 'month_day_year' -%}
40
+ {{ 'customer.order.fulfilled_at' | t: date: created_at }}
41
+ {% if line_item.fulfillment.tracking_number %}
42
+ <a href="{{ line_item.fulfillment.tracking_url }}">{{ line_item.fulfillment.tracking_company }} #{{ line_item.fulfillment.tracking_number}}</a>
43
+ {% endif %}
44
+ </div>
45
+ {% endif %}
46
+ </td>
47
+ <td data-label="{{ 'customer.order.sku' | t }}">{{ line_item.sku }}</td>
48
+ <td data-label="{{ 'customer.order.price' | t }}">{{ line_item.price | money }}</td>
49
+ <td data-label="{{ 'customer.order.quantity' | t }}">{{ line_item.quantity }}</td>
50
+ <td data-label="{{ 'customer.order.total' | t }}">{{ line_item.quantity | times: line_item.price | money }}</td>
51
+ </tr>
52
+ {% endfor %}
53
+ </tbody>
54
+ <tfoot>
55
+ <tr class="responsive-table__row">
56
+ <td colspan="4" class="small--hide">{{ 'customer.order.subtotal' | t }}</td>
57
+ <td data-label="{{ 'customer.order.subtotal' | t }}">{{ order.subtotal_price | money }}</td>
58
+ </tr>
59
+
60
+ {% for discount in order.discounts %}
61
+ <tr class="order_summary discount">
62
+ <td colspan="4" class="small--hide">{{ discount.code }} {{ 'customer.order.discount' | t }}</td>
63
+ <td data-label="{{ 'customer.order.discount' | t }}">{{ discount.savings | money }}</td>
64
+ </tr>
65
+ {% endfor %}
66
+
67
+ {% for shipping_method in order.shipping_methods %}
68
+ <tr>
69
+ <td colspan="4" class="small--hide">{{ 'customer.order.shipping' | t }} ({{ shipping_method.title }})</td>
70
+ <td data-label="{{ 'customer.order.shipping' | t }} ({{ shipping_method.title }})">{{ shipping_method.price | money }}</td>
71
+ </tr>
72
+ {% endfor %}
73
+
74
+ {% for tax_line in order.tax_lines %}
75
+ <tr>
76
+ <td colspan="4" class="small--hide">{{ 'customer.order.tax' | t }} ({{ tax_line.title }} {{ tax_line.rate | times: 100 }}%)</td>
77
+ <td data-label="{{ 'customer.order.tax' | t }} ({{ tax_line.title }} {{ tax_line.rate | times: 100 }}%)">{{ tax_line.price | money }}</td>
78
+ </tr>
79
+ {% endfor %}
80
+
81
+ <tr>
82
+ <td colspan="4" class="small--hide"><strong>{{ 'customer.order.total' | t }}</strong></td>
83
+ <td data-label="{{ 'customer.order.total' | t }}"><strong>{{ order.total_price | money }} {{ order.currency }}</strong></td>
84
+ </tr>
85
+ </tfoot>
86
+ </table>
87
+ </div>
88
+ <div class="grid__item medium-up--one-third">
89
+ <hr class="medium-up--hide">
90
+ <h3>{{ 'customer.order.billing_address' | t }}</h3>
91
+
92
+ <p><strong>{{ 'customer.order.payment_status' | t }}:</strong> {{ order.financial_status_label }}</p>
93
+
94
+ {{ order.billing_address | format_address }}
95
+
96
+ <h3>{{ 'customer.order.shipping_address' | t }}</h3>
97
+
98
+ <p><strong>{{ 'customer.order.fulfillment_status' | t }}:</strong> {{ order.fulfillment_status_label }}</p>
99
+
100
+ {{ order.shipping_address | format_address }}
101
+ </div>
102
+ </div>
103
+ </div>
@@ -0,0 +1,32 @@
1
+ <div class="page-width">
2
+ <div class="grid">
3
+ <div class="grid__item medium-up--one-half medium-up--push-one-quarter">
4
+
5
+ <div class="form-vertical">
6
+ {% form 'create_customer' %}
7
+
8
+ <h1 class="text-center">{{ 'customer.register.title' | t }}</h1>
9
+
10
+ {{ form.errors | default_errors }}
11
+
12
+ <label for="FirstName">{{ 'customer.register.first_name' | t }}</label>
13
+ <input type="text" name="customer[first_name]" id="FirstName" {% if form.first_name %}value="{{ form.first_name }}"{% endif %} autofocus>
14
+
15
+ <label for="LastName">{{ 'customer.register.last_name' | t }}</label>
16
+ <input type="text" name="customer[last_name]" id="LastName" {% if form.last_name %}value="{{ form.last_name }}"{% endif %}>
17
+
18
+ <label for="Email">{{ 'customer.register.email' | t }}</label>
19
+ <input type="email" name="customer[email]" id="Email" class="{% if form.errors contains 'email' %} input--error{% endif %}" {% if form.email %} value="{{ form.email }}"{% endif %} autocorrect="off" autocapitalize="off">
20
+
21
+ <label for="CreatePassword">{{ 'customer.register.password' | t }}</label>
22
+ <input type="password" name="customer[password]" id="CreatePassword" class="{% if form.errors contains 'password' %} input--error{% endif %}">
23
+
24
+ <p class="text-center">
25
+ <input type="submit" value="{{ 'customer.register.submit' | t }}" class="btn">
26
+ </p>
27
+
28
+ {% endform %}
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </div>
@@ -0,0 +1,27 @@
1
+ <div class="page-width">
2
+ <div class="grid">
3
+ <div class="grid__item medium-up--one-half medium-up--push-one-quarter">
4
+ <div class="section-header">
5
+ <div class="form-vertical">
6
+ {% form 'reset_customer_password' %}
7
+
8
+ <h1 class="text-center">{{ 'customer.reset_password.title' | t }}</h1>
9
+
10
+ <p class="text-center">{{ 'customer.reset_password.subtext' | t: email: email }}</p>
11
+
12
+ {{ form.errors | default_errors }}
13
+
14
+ <label for="ResetPassword">{{ 'customer.reset_password.password' | t }}</label>
15
+ <input type="password" value="" name="customer[password]" id="ResetPassword" class="{% if form.errors contains 'password' %} input--error{% endif %}">
16
+
17
+ <label for="PasswordConfirmation">{{ 'customer.reset_password.password_confirm' | t }}</label>
18
+ <input type="password" value="" name="customer[password_confirmation]" id="PasswordConfirmation" class="{% if form.errors contains 'password_confirmation' %} input--error{% endif %}">
19
+
20
+ <input type="submit" class="btn text-center" value="{{ 'customer.reset_password.submit' | t }}">
21
+ {% endform %}
22
+ </div>
23
+
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </div>
@@ -0,0 +1,39 @@
1
+ {% comment %}
2
+ Re-use the 'rte' class wherever you output content that was added by a merchant using the Rich Text Editor ( 'rte' stands for rich text editor ).
3
+ Style all HTML elements in that content the same way across the board.
4
+ Use the 'rte' class in your CSS to help maintain that consistency.
5
+ Example: the h2 element should have the same size and color in:
6
+ - product descriptions
7
+ - collection descriptions
8
+ - page content
9
+ - blog posts
10
+ {% endcomment %}
11
+
12
+ {% comment %}
13
+ Very important reading:
14
+ http://docs.shopify.com/themes/liquid-basics/what-is-true-and-false-in-liquid
15
+ Learn how to read theme settings in your theme.
16
+ {% endcomment %}
17
+
18
+ {% unless settings.homepage_page == blank or pages[settings.homepage_page].empty? %}
19
+ {% assign page = pages[settings.homepage_page] %}
20
+ <div class="rte grid-margins">
21
+ {{ page.content }}
22
+ </div>
23
+ {% endunless %}
24
+
25
+ {% unless settings.homepage_collection == blank or collections[settings.homepage_collection].empty? %}
26
+ {% assign collection = collections[settings.homepage_collection] %}
27
+ <ul class="grid clearfix">
28
+ {% for product in collection.products %}
29
+ {% include 'product-grid-item' with 'three-per-row' %}
30
+ {% else %}
31
+ <li>
32
+ <p>
33
+ You have no products in your {{ collections[settings.homepage_collection].title }} collection.
34
+ <a href="http://www.shopify.com/admin/collections">Add some.</a>
35
+ <p>
36
+ </li>
37
+ {% endfor %}
38
+ </ul>
39
+ {% endunless %}
@@ -0,0 +1,19 @@
1
+ {% include 'collection-listing' %}
2
+
3
+ {% comment %}
4
+ <!-- Alternatively, if not using a snippet, use the code below.
5
+ To use the code below, get rid of the above 'include', and get rid of the comment tags, and you're in business. -->
6
+ {% paginate collections by 6 %}
7
+ <h1>Collections</h1>
8
+ <ul class="grid clearfix">
9
+ {% for collection in collections %}
10
+ {% include 'collection-grid-item' with 'three-per-row' %}
11
+ {% endfor %}
12
+ </ul>
13
+ {% if paginate.pages > 1 %}
14
+ <div id="pagination">
15
+ {{ paginate | default_pagination }}
16
+ </div>
17
+ {% endif %}
18
+ {% endpaginate %}
19
+ {% endcomment %}
@@ -0,0 +1,16 @@
1
+ {% comment %}
2
+ Re-use the 'rte' class wherever you output content that was added by a merchant using
3
+ the Rich Text Editor ( 'rte' stands for rich text editor ).
4
+ Style all HTML elements in that content the same way across the board.
5
+ Use the 'rte' class in your CSS to help maintain that consistency.
6
+ Example: the h2 element should have the same size and color in:
7
+ - product descriptions
8
+ - collection descriptions
9
+ - 'page' pages' content
10
+ - blog post
11
+ {% endcomment %}
12
+
13
+ <h1>{{ page.title }}</h1>
14
+ <div class="rte">
15
+ {{ page.content }}
16
+ </div>
@@ -0,0 +1,202 @@
1
+ {% assign add_to_cart = 'Add to cart' %}
2
+ {% assign sold_out = 'Sold Out' %}
3
+ {% assign unavailable = 'Unavailable' %}
4
+
5
+ <div class="product" itemscope itemtype="http://schema.org/Product">
6
+
7
+ <meta itemprop="url" content="{{ shop.url }}{{ product.url }}" />
8
+ <meta itemprop="image" content="{{ product | img_url: 'grande' }}" />
9
+
10
+ <form action="/cart/add" method="post" enctype="multipart/form-data">
11
+
12
+ <div class="product-photos">
13
+
14
+ {% if product.images.size == 0 %}
15
+
16
+ <div class="product-photo-container">
17
+ <img src="{{ '' | img_url: 'grande' }}" alt="" />
18
+ </div>
19
+
20
+ {% else %}
21
+
22
+ {% assign featured_image = product.selected_or_first_available_variant.featured_image | default: product.featured_image %}
23
+ <div class="product-photo-container">
24
+ <a href="{{ featured_image | img_url: '1024x1024' }}">
25
+ <img src="{{ featured_image | img_url: 'grande' }}" alt="{{ product.title | escape }}" />
26
+ </a>
27
+ </div>
28
+
29
+ {% if product.images.size > 1 %}
30
+ <ul class="product-photo-thumbs clearfix grid">
31
+ {% for image in product.images %}
32
+ <li class="product-photo-thumb two-per-row">
33
+ <a href="{{ image | img_url: '1024x1024' }}">
34
+ <img src="{{ image | img_url: 'large' }}" alt="{{ image.alt | escape }}" />
35
+ </a>
36
+ </li>
37
+ {% endfor %}
38
+ </ul>
39
+ {% endif %}
40
+
41
+ {% endif %}
42
+
43
+ </div><!-- .product-photos -->
44
+
45
+ <div class="product-details">
46
+
47
+ <h1 itemprop="name">{{ product.title }}</h1>
48
+
49
+ {% assign product_vendor_handle = product.vendor | handle %}
50
+ {% comment %}
51
+ Do we have a collection that has the same name as our product vendor name?
52
+ If we do, let's have the vendor link point to it.
53
+ If not, we will point to the automatic vendor collection.
54
+ {% endcomment %}
55
+ {% if collections[product_vendor_handle].handle == product_vendor_handle %}
56
+ {% assign vendor_url = collections[product_vendor_handle].url %}
57
+ {% else %}
58
+ {% assign vendor_url = product.vendor | url_for_vendor %}
59
+ {% endif %}
60
+ <h2 itemprop="brand" class="delta">{{ product.vendor | link_to: vendor_url }}</h2>
61
+
62
+ <div id="product-description" class="rte" itemprop="description">
63
+ {{ product.description }}
64
+ </div>
65
+
66
+ {% comment %}
67
+ All themes by Shopify should support the Product Reviews app out of the box.
68
+ https://apps.shopify.com/product-reviews
69
+ {% endcomment %}
70
+ <div id="shopify-product-reviews" data-id="{{ product.id }}">{{ product.metafields.spr.reviews }}</div>
71
+
72
+ <div id="product-price" itemprop="offers" itemscope itemtype="http://schema.org/Offer" class="delta">
73
+ <meta itemprop="priceCurrency" content="{{ shop.currency }}" />
74
+ {% if product.available %}
75
+ <link itemprop="availability" href="http://schema.org/InStock" />
76
+ {% else %}
77
+ <link itemprop="availability" href="http://schema.org/OutOfStock" />
78
+ {% endif %}
79
+ <p>
80
+ {% assign variant = product.selected_or_first_available_variant %}
81
+ {% if product.compare_at_price > product.price %}
82
+ <span class="product-price on-sale" itemprop="price">{{ variant.price | money }}</span>
83
+ <s class="product-compare-price">{{ variant.compare_at_price | money }}</s>
84
+ {% else %}
85
+ <span class="product-price" itemprop="price">{{ variant.price | money }}</span>
86
+ {% endif %}
87
+ </p>
88
+ </div>
89
+
90
+ {% assign hide_default_title = false %}
91
+ {% if product.variants.size == 1 and product.variants.first.title contains 'Default' %}
92
+ {% assign hide_default_title = true %}
93
+ {% endif %}
94
+
95
+ <div id="product-variants" class="{% if hide_default_title %} hidden{% endif %}">
96
+ <select id="product-select" name="id">
97
+ {% for variant in product.variants %}
98
+ <option{% if variant == product.selected_or_first_available_variant %} selected{% endif %} value="{{ variant.id }}">
99
+ {{ variant.title }} - {{ variant.price | money }}
100
+ </option>
101
+ {% endfor %}
102
+ </select>
103
+ </div>
104
+
105
+ <div id="backorder" class="hidden">
106
+ <p>{{ '%s is back-ordered. We will ship it separately in 10 to 15 days.' | replace: '%s', '<span id="selected-variant"></span>' }}</p>
107
+ </div>
108
+
109
+ <div id="product-add">
110
+ <input type="submit" name="add" id="add" class="primary button" value="{{ add_to_cart | escape }}">
111
+ </div>
112
+
113
+ {% if collection %}
114
+ {% if collection.previous_product or collection.next_product %}
115
+ <div>
116
+ {% if collection.previous_product %}
117
+ {% capture prev_url %}{{ collection.previous_product}}#content{% endcapture %}
118
+ <span class="left">{{ '&larr; Previous Product' | link_to: prev_url }}</span>
119
+ {% endif %}
120
+ {% if collection.next_product %}
121
+ {% capture next_url %}{{ collection.next_product}}#content{% endcapture %}
122
+ <span class="right">{{ 'Next Product &rarr;' | link_to: next_url }}</span>
123
+ {% endif %}
124
+ </div>
125
+ {% endif %}
126
+ {% endif %}
127
+
128
+ </div><!-- .product-details -->
129
+
130
+ </form>
131
+
132
+ </div>
133
+
134
+ {% comment %}
135
+ Adding support for product options. See here for details:
136
+ http://docs.shopify.com/support/your-website/themes/can-i-make-my-theme-use-products-with-multiple-options
137
+ {% endcomment %}
138
+
139
+ <script>
140
+
141
+ var selectCallback = function(variant, selector) {
142
+
143
+ if (variant) {
144
+
145
+ // Swap image.
146
+ if (variant.featured_image) {
147
+ var newImage = variant.featured_image; // New image object.
148
+ var mainImageDomEl = jQuery('.product-photo-container img')[0]; // DOM element of main image we need to swap.
149
+ Shopify.Image.switchImage(newImage, mainImageDomEl, switchImage); // Define switchImage (the callback) in your theme's JavaScript file.
150
+ }
151
+
152
+ // Selected a valid variant that is available.
153
+ if (variant.available) {
154
+
155
+ // Enabling add to cart button.
156
+ jQuery('#add').removeClass('disabled').prop('disabled', false).val({{ add_to_cart | json }});
157
+
158
+ // If item is backordered yet can still be ordered, we'll show special message.
159
+ if (variant.inventory_management && variant.inventory_quantity <= 0) {
160
+ jQuery('#selected-variant').html({{ product.title | json }}{% unless hide_default_title %} + ' - ' + variant.title{% endunless %});
161
+ jQuery('#backorder').removeClass("hidden");
162
+ } else {
163
+ jQuery('#backorder').addClass("hidden");
164
+ }
165
+
166
+ } else {
167
+ // Variant is sold out.
168
+ jQuery('#backorder').addClass('hidden');
169
+ jQuery('#add').val({{ sold_out | json }}).addClass('disabled').prop('disabled', true);
170
+ }
171
+
172
+ // Whether the variant is in stock or not, we can update the price and compare at price.
173
+ if ( variant.compare_at_price > variant.price ) {
174
+ jQuery('#product-price').html('<span class="product-price on-sale">'+ Shopify.formatMoney(variant.price, "{{ shop.money_format }}") +'</span>'+'&nbsp;<s class="product-compare-price">'+Shopify.formatMoney(variant.compare_at_price, "{{ shop.money_format }}")+ '</s>');
175
+ } else {
176
+ jQuery('#product-price').html('<span class="product-price">'+ Shopify.formatMoney(variant.price, "{{ shop.money_format }}") + '</span>' );
177
+ }
178
+
179
+ } else {
180
+ // variant doesn't exist.
181
+ jQuery('#product-price').empty();
182
+ jQuery('#backorder').addClass('hidden');
183
+ jQuery('#add').val({{ unavailable | json }}).addClass('disabled').prop('disabled', true);
184
+ }
185
+
186
+ };
187
+
188
+ jQuery(function($) {
189
+
190
+ new Shopify.OptionSelectors('product-select', { product: {{ product | json }}, onVariantSelected: selectCallback, enableHistoryState: true });
191
+
192
+ // Add label if only one product option and it isn't 'Title'.
193
+ {% if product.options.size == 1 and product.options.first != 'Title' %}
194
+ $('.selector-wrapper:eq(0)').prepend('<label>{{ product.options.first }}</label>');
195
+ {% endif %}
196
+
197
+ });
198
+
199
+ Shopify.Image.preload({{ product.images | json }}, 'grande');
200
+ Shopify.Image.preload({{ product.images | json }}, '1024x1024');
201
+
202
+ </script>