solidify 0.0.1.alpha

Sign up to get free protection for your applications and to get access to all the features.
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>