dugway 0.5.0

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 (125) hide show
  1. data/.gitignore +7 -0
  2. data/.travis.yml +3 -0
  3. data/Gemfile +2 -0
  4. data/README.md +151 -0
  5. data/Rakefile +12 -0
  6. data/bin/dugway +7 -0
  7. data/dugway.gemspec +43 -0
  8. data/lib/dugway.rb +66 -0
  9. data/lib/dugway/application.rb +147 -0
  10. data/lib/dugway/cart.rb +144 -0
  11. data/lib/dugway/cli.rb +22 -0
  12. data/lib/dugway/cli/build.rb +56 -0
  13. data/lib/dugway/cli/create.rb +71 -0
  14. data/lib/dugway/cli/server.rb +37 -0
  15. data/lib/dugway/cli/templates/Gemfile.tt +2 -0
  16. data/lib/dugway/cli/templates/config.tt +24 -0
  17. data/lib/dugway/cli/templates/gitignore.tt +9 -0
  18. data/lib/dugway/cli/templates/source/cart.html +40 -0
  19. data/lib/dugway/cli/templates/source/checkout.html +33 -0
  20. data/lib/dugway/cli/templates/source/contact.html +37 -0
  21. data/lib/dugway/cli/templates/source/home.html +25 -0
  22. data/lib/dugway/cli/templates/source/images/badge.png +0 -0
  23. data/lib/dugway/cli/templates/source/javascripts/cart.js.coffee +7 -0
  24. data/lib/dugway/cli/templates/source/javascripts/product.js.coffee +7 -0
  25. data/lib/dugway/cli/templates/source/layout.html +101 -0
  26. data/lib/dugway/cli/templates/source/maintenance.html +20 -0
  27. data/lib/dugway/cli/templates/source/product.html +65 -0
  28. data/lib/dugway/cli/templates/source/products.html +25 -0
  29. data/lib/dugway/cli/templates/source/screenshot.jpg +0 -0
  30. data/lib/dugway/cli/templates/source/scripts.js +19 -0
  31. data/lib/dugway/cli/templates/source/settings.json +71 -0
  32. data/lib/dugway/cli/templates/source/styles.css +27 -0
  33. data/lib/dugway/cli/templates/source/stylesheets/cart.css.sass +38 -0
  34. data/lib/dugway/cli/templates/source/stylesheets/layout.css.sass +103 -0
  35. data/lib/dugway/cli/templates/source/stylesheets/product.css.sass +19 -0
  36. data/lib/dugway/cli/templates/source/stylesheets/products.css.sass +20 -0
  37. data/lib/dugway/cli/templates/source/stylesheets/vendor/normalize.css +396 -0
  38. data/lib/dugway/cli/templates/source/success.html +5 -0
  39. data/lib/dugway/controller.rb +148 -0
  40. data/lib/dugway/data/locales/cs.yml +26 -0
  41. data/lib/dugway/data/locales/da.yml +26 -0
  42. data/lib/dugway/data/locales/en-AU.yml +26 -0
  43. data/lib/dugway/data/locales/en-GB.yml +26 -0
  44. data/lib/dugway/data/locales/en-PH.yml +27 -0
  45. data/lib/dugway/data/locales/en-US.yml +26 -0
  46. data/lib/dugway/data/locales/es-MX.yml +26 -0
  47. data/lib/dugway/data/locales/eu.yml +26 -0
  48. data/lib/dugway/data/locales/gsw-CH.yml +26 -0
  49. data/lib/dugway/data/locales/hu.yml +26 -0
  50. data/lib/dugway/data/locales/il.yml +26 -0
  51. data/lib/dugway/data/locales/ja.yml +30 -0
  52. data/lib/dugway/data/locales/ms-MY.yml +26 -0
  53. data/lib/dugway/data/locales/nb.yml +22 -0
  54. data/lib/dugway/data/locales/pl.yml +27 -0
  55. data/lib/dugway/data/locales/pt-BR.yml +26 -0
  56. data/lib/dugway/data/locales/sv-SE.yml +26 -0
  57. data/lib/dugway/data/locales/th.yml +26 -0
  58. data/lib/dugway/data/locales/tr.yml +29 -0
  59. data/lib/dugway/data/locales/zh-TW.yml +30 -0
  60. data/lib/dugway/data/theme_fonts.yml +151 -0
  61. data/lib/dugway/extensions/time.rb +15 -0
  62. data/lib/dugway/liquid/drops/account_drop.rb +17 -0
  63. data/lib/dugway/liquid/drops/artist_drop.rb +9 -0
  64. data/lib/dugway/liquid/drops/artists_drop.rb +13 -0
  65. data/lib/dugway/liquid/drops/base_drop.rb +59 -0
  66. data/lib/dugway/liquid/drops/cart_drop.rb +13 -0
  67. data/lib/dugway/liquid/drops/cart_item_drop.rb +21 -0
  68. data/lib/dugway/liquid/drops/categories_drop.rb +13 -0
  69. data/lib/dugway/liquid/drops/category_drop.rb +9 -0
  70. data/lib/dugway/liquid/drops/contact_drop.rb +29 -0
  71. data/lib/dugway/liquid/drops/country_drop.rb +6 -0
  72. data/lib/dugway/liquid/drops/currency_drop.rb +6 -0
  73. data/lib/dugway/liquid/drops/image_drop.rb +6 -0
  74. data/lib/dugway/liquid/drops/page_drop.rb +13 -0
  75. data/lib/dugway/liquid/drops/pages_drop.rb +9 -0
  76. data/lib/dugway/liquid/drops/product_drop.rb +101 -0
  77. data/lib/dugway/liquid/drops/product_option_drop.rb +27 -0
  78. data/lib/dugway/liquid/drops/products_drop.rb +75 -0
  79. data/lib/dugway/liquid/drops/shipping_option_drop.rb +13 -0
  80. data/lib/dugway/liquid/drops/theme_drop.rb +23 -0
  81. data/lib/dugway/liquid/filters/comparison_filters.rb +48 -0
  82. data/lib/dugway/liquid/filters/core_filters.rb +138 -0
  83. data/lib/dugway/liquid/filters/default_pagination.rb +35 -0
  84. data/lib/dugway/liquid/filters/font_filters.rb +9 -0
  85. data/lib/dugway/liquid/filters/url_filters.rb +66 -0
  86. data/lib/dugway/liquid/filters/util_filters.rb +119 -0
  87. data/lib/dugway/liquid/tags/checkout_form.rb +9 -0
  88. data/lib/dugway/liquid/tags/get.rb +58 -0
  89. data/lib/dugway/liquid/tags/paginate.rb +129 -0
  90. data/lib/dugway/liquifier.rb +122 -0
  91. data/lib/dugway/logger.rb +16 -0
  92. data/lib/dugway/request.rb +36 -0
  93. data/lib/dugway/store.rb +166 -0
  94. data/lib/dugway/template.rb +44 -0
  95. data/lib/dugway/theme.rb +145 -0
  96. data/lib/dugway/theme_font.rb +68 -0
  97. data/lib/dugway/version.rb +3 -0
  98. data/spec/fixtures/store/page/about-us.js +1 -0
  99. data/spec/fixtures/store/products.js +1 -0
  100. data/spec/fixtures/store/store.js +1 -0
  101. data/spec/fixtures/theme/cart.html +33 -0
  102. data/spec/fixtures/theme/checkout.html +31 -0
  103. data/spec/fixtures/theme/contact.html +37 -0
  104. data/spec/fixtures/theme/home.html +38 -0
  105. data/spec/fixtures/theme/images/bc_badge.png +0 -0
  106. data/spec/fixtures/theme/javascripts/one.js +3 -0
  107. data/spec/fixtures/theme/javascripts/two.js.coffee +2 -0
  108. data/spec/fixtures/theme/layout.html +77 -0
  109. data/spec/fixtures/theme/maintenance.html +17 -0
  110. data/spec/fixtures/theme/product.html +73 -0
  111. data/spec/fixtures/theme/products.html +41 -0
  112. data/spec/fixtures/theme/screenshot.jpg +0 -0
  113. data/spec/fixtures/theme/scripts.js +2 -0
  114. data/spec/fixtures/theme/settings.json +55 -0
  115. data/spec/fixtures/theme/styles.css +4 -0
  116. data/spec/fixtures/theme/stylesheets/one.css +3 -0
  117. data/spec/fixtures/theme/stylesheets/two.css.sass +4 -0
  118. data/spec/fixtures/theme/success.html +5 -0
  119. data/spec/spec_helper.rb +24 -0
  120. data/spec/units/dugway/request_spec.rb +206 -0
  121. data/spec/units/dugway/store_spec.rb +194 -0
  122. data/spec/units/dugway/template_spec.rb +145 -0
  123. data/spec/units/dugway/theme_font_spec.rb +136 -0
  124. data/spec/units/dugway_spec.rb +9 -0
  125. metadata +549 -0
@@ -0,0 +1,17 @@
1
+ <!DOCTYPE html>
2
+ <head>
3
+ <title>{{ store.name }} &mdash; {{ page.name }}</title>
4
+ <meta charset="utf-8">
5
+ <meta name="description" content="{{ page.meta_description }}">
6
+ <meta name="keywords" content="{{ page.meta_keywords }}">
7
+ <link href="{{ theme | theme_css_url }}" media="screen" rel="stylesheet" type="text/css">
8
+ {{ head_content }}
9
+ </head>
10
+
11
+ <body id="{{ page.permalink }}" class="{{ page.category }}">
12
+ <div>
13
+ <h1>We&#8217;re working our site at the moment.</h1>
14
+ <p>Please check back soon.</p>
15
+ </div>
16
+ </body>
17
+ </html>
@@ -0,0 +1,73 @@
1
+ <div>
2
+ <div>
3
+ <a href="{{ product.image | product_image_url }}"><img src="{{ product.image | product_image_url }}" alt="Image of {{ product.name | escape }}"></a>
4
+
5
+ <ul>
6
+ {% for image in product.images offset:1 %}
7
+ <li><a href="{{ image | product_image_url }}"><img src="{{ image | product_image_url size:"thumb" }}" alt="Image of {{ product.name | escape }}"></a></li>
8
+ {% endfor %}
9
+ </ul>
10
+ </div>
11
+
12
+ <div>
13
+ <h1>{{ product.name }}</h1>
14
+
15
+ {% for artist in product.artists %}
16
+ {% if forloop.first %}
17
+ <h5>by {{ artist.name }}</h5>
18
+ {% if forloop.length > 2 %}, {% endif %}
19
+ {% elsif forloop.last %}
20
+ <h5>and {{ artist.name }}</h5>
21
+ {% else %}
22
+ <h5>{{ artist.name }}</h5>,
23
+ {% endif %}
24
+ {% endfor %}
25
+
26
+ {% case product.status %}
27
+ {% when 'sold-out' %}
28
+ <h3 class="sold-out">{{ product.default_price | money_with_sign }} <span class="status">/ Sold Out</span></h3>
29
+ {% when 'coming-soon' %}
30
+ <h3 class="coming-soon">{{ product.default_price | money_with_sign }} <span class="status">/ Coming Soon</span></h3>
31
+ {% when 'active' %}
32
+ <h3 class="{% if product.on_sale %}sale{% endif %}">{{ product.default_price | money_with_sign }}{% if product.on_sale %} <span class="status">/ On Sale{% endif %}</span></h3>
33
+
34
+ <hr>
35
+
36
+ <form method="post" action="/cart">
37
+ {% if product.has_default_option %}
38
+ {{ product.option | hidden_option_input }}
39
+ {% else %}
40
+ <div>
41
+ {{ product.options_in_stock | options_select }}
42
+ </div>
43
+ {% endif %}
44
+
45
+ <button name="submit" type="submit" class="button">Add to Cart</button>
46
+ </form>
47
+ {% endcase %}
48
+
49
+ {% if product.description != blank %}
50
+ <div>
51
+ {{ product.description | paragraphs }}
52
+ </div>
53
+ {% endif %}
54
+
55
+ {% if theme.show_inventory_bars %}
56
+ {% case product.status %}
57
+ {% when 'active' %}
58
+ <div>
59
+ <h5>Availability</h5>
60
+
61
+ <ul>
62
+ {% for option in product.options %}
63
+ <li>
64
+ {% unless product.has_default_option %}<span>{{ option.name }}</span>{% endunless %}
65
+ <span>{% if option.sold_out %}Sold Out{% else %}{{ option.inventory }}%{% endif %}</span>
66
+ </li>
67
+ {% endfor %}
68
+ </ul>
69
+ </div>
70
+ {% endcase %}
71
+ {% endif %}
72
+ </div>
73
+ </div>
@@ -0,0 +1,41 @@
1
+ <div>
2
+ <h1>{{ page.name }}</h1>
3
+ {% paginate products from products.current by 20 %}
4
+ {% if products != blank %}
5
+ <ul>
6
+ {% for product in products %}
7
+ <li id="product_{{ product.id }}">
8
+ <a href="{{ product.url }}">
9
+ <img alt="Image of {{ product.name | escape }}" src="{{ product.image | product_image_url size: theme.product_list_size }}" />
10
+ <div class="product_info">
11
+ <div>
12
+ <p>
13
+ <span>{{ product.name }}</span>
14
+ <span class="{% if product.on_sale %}sale{% else %}price{% endif %} {{ product.status }}">{{ product.default_price | money_with_sign }}{% case product.status %}{% when 'sold-out' %} / Sold Out{% when 'coming-soon' %} / Coming Soon{% when 'active' %}{% if product.on_sale %} / On Sale{% endif %}{% endcase %}</span>
15
+ </p>
16
+ </div>
17
+ </div>
18
+ </a>
19
+ </li>
20
+ {% endfor %}
21
+ </ul>
22
+
23
+ <div class="pagination" id="pagination">
24
+ {% if paginate.previous %}
25
+ {% if paginate.previous.is_link %}
26
+ <a href="{{ paginate.previous.url }}" id="previous" class="circle">&larr;<em>Previous</em></a>
27
+ {% endif %}
28
+ {% endif %}
29
+
30
+ {% if paginate.next %}
31
+ {% if paginate.next.is_link %}
32
+ <a href="{{ paginate.next.url }}" id="next" class="circle">&rarr;<em>Next</em></a>
33
+ {% endif %}
34
+ {% endif %}
35
+ </div>
36
+
37
+ {% else %}
38
+ <p class="alert-noproducts"><span>No products found.</span></p>
39
+ {% endif %}
40
+ {% endpaginate %}
41
+ </div>
Binary file
@@ -0,0 +1,2 @@
1
+ //= require javascripts/one
2
+ //= require javascripts/two
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "Test Theme",
3
+ "images": [
4
+ {
5
+ "variable": "logo",
6
+ "label": "Logo",
7
+ "description": "Good for an image up to 150 pixels wide"
8
+ },
9
+ {
10
+ "variable": "background_image",
11
+ "label": "Background Image",
12
+ "description": "Adds a repeating background image"
13
+ }
14
+ ],
15
+ "fonts": [
16
+ {
17
+ "variable": "header_font",
18
+ "label": "Header Font",
19
+ "default": "Helvetica"
20
+ },
21
+ {
22
+ "variable": "font",
23
+ "label": "Font",
24
+ "default": "Georgia"
25
+ }
26
+ ],
27
+ "colors": [
28
+ {
29
+ "variable": "background_color",
30
+ "label": "Background",
31
+ "default": "#222222"
32
+ },
33
+ {
34
+ "variable": "link_color",
35
+ "label": "Link Color",
36
+ "default": "red"
37
+ }
38
+ ],
39
+ "options": [
40
+ {
41
+ "variable": "show_search",
42
+ "label": "Show search",
43
+ "type": "boolean",
44
+ "default": false,
45
+ "description": "Shows a search field"
46
+ },
47
+ {
48
+ "variable": "fixed_sidebar",
49
+ "label": "Fixed Sidebar",
50
+ "type": "boolean",
51
+ "default": true,
52
+ "description": "Keeps the sidebar stationary while the page scrolls"
53
+ }
54
+ ]
55
+ }
@@ -0,0 +1,4 @@
1
+ /*
2
+ *= require stylesheets/reset
3
+ *= require stylesheets/base
4
+ */
@@ -0,0 +1,3 @@
1
+ html, body {
2
+ height: 100%;
3
+ }
@@ -0,0 +1,4 @@
1
+ $link_color: {{ theme.link_color }}
2
+
3
+ a
4
+ color: $link_color
@@ -0,0 +1,5 @@
1
+ <div>
2
+ <h1>Thank You. Your order has been placed.</h1>
3
+ <p>We'll start working right away on getting your order out to you. Please <a href="/contact">contact us</a> if you have any questions or concerns.</p>
4
+ <a href="/" class="button">Continue Browsing</a>
5
+ </div>
@@ -0,0 +1,24 @@
1
+ require 'webmock/rspec'
2
+ require 'dugway'
3
+
4
+ RSpec.configure do |config|
5
+ config.add_setting :fixture_path
6
+ config.fixture_path = File.join(Dir.pwd, 'spec', 'fixtures')
7
+
8
+ config.before(:each) do
9
+ # Stub api calls
10
+ stub_request(:get, /.*api\.bigcartel\.com.*/).to_return(lambda { |request|
11
+ { :body => File.new(File.join(RSpec.configuration.fixture_path, 'store', request.uri.path.split('/', 3).last)), :status => 200, :headers => {} }
12
+ })
13
+
14
+ # Stub source directory
15
+ Dugway.stub(:source_dir) {
16
+ File.join(RSpec.configuration.fixture_path, 'theme')
17
+ }
18
+
19
+ # Stub theme
20
+ Dugway.stub(:theme) {
21
+ Dugway::Theme.new
22
+ }
23
+ end
24
+ end
@@ -0,0 +1,206 @@
1
+ require 'spec_helper'
2
+
3
+ describe Dugway::Request do
4
+ let(:path) { '/path/to/something' }
5
+ let(:params) { {} }
6
+
7
+ let(:env) {
8
+ Rack::MockRequest::DEFAULT_ENV.update({
9
+ 'PATH_INFO' => path.split('?').first,
10
+ 'QUERY_STRING' => path.split('?').last
11
+ })}
12
+
13
+ let(:request) { Dugway::Request.new(env) }
14
+
15
+ before(:each) do
16
+ request.stub(:params) { params }
17
+ end
18
+
19
+ describe "#page_permalink" do
20
+ describe "on the home page" do
21
+ let(:path) { '/' }
22
+
23
+ it "returns the correct page_permalink" do
24
+ request.page_permalink.should == 'home'
25
+ end
26
+ end
27
+
28
+ describe "on the products page" do
29
+ let(:path) { '/products' }
30
+
31
+ it "returns the correct page_permalink" do
32
+ request.page_permalink.should == 'products'
33
+ end
34
+ end
35
+
36
+ describe "on the products page with params" do
37
+ let(:path) { '/products?search=test' }
38
+
39
+ it "returns the correct page_permalink" do
40
+ request.page_permalink.should == 'products'
41
+ end
42
+ end
43
+
44
+ describe "on the categories page" do
45
+ let(:path) { '/category/tees' }
46
+
47
+ it "returns the correct page_permalink" do
48
+ request.page_permalink.should == 'products'
49
+ end
50
+ end
51
+
52
+ describe "on the artists page" do
53
+ let(:path) { '/artist/beatles' }
54
+
55
+ it "returns the correct page_permalink" do
56
+ request.page_permalink.should == 'products'
57
+ end
58
+ end
59
+
60
+ describe "on the product page" do
61
+ let(:path) { '/product/my-thing' }
62
+
63
+ it "returns the correct page_permalink" do
64
+ request.page_permalink.should == 'product'
65
+ end
66
+ end
67
+
68
+ describe "on the a known page" do
69
+ let(:path) { '/cart' }
70
+
71
+ it "returns the correct page_permalink" do
72
+ request.page_permalink.should == 'cart'
73
+ end
74
+ end
75
+
76
+ describe "on the a custom page" do
77
+ let(:path) { '/about-us' }
78
+
79
+ it "returns the correct page_permalink" do
80
+ request.page_permalink.should == 'about-us'
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "#extension" do
86
+ describe "on HTML with no extension" do
87
+ let(:path) { '/cart' }
88
+
89
+ it "returns the correct extension" do
90
+ request.extension.should == '.html'
91
+ end
92
+ end
93
+
94
+ describe "on HTML with an extension" do
95
+ let(:path) { '/cart.html' }
96
+
97
+ it "returns the correct extension" do
98
+ request.extension.should == '.html'
99
+ end
100
+ end
101
+
102
+ describe "on CSS" do
103
+ let(:path) { '/styles.css' }
104
+
105
+ it "returns the correct extension" do
106
+ request.extension.should == '.css'
107
+ end
108
+ end
109
+
110
+ describe "on JS" do
111
+ let(:path) { '/scripts.js' }
112
+
113
+ it "returns the correct extension" do
114
+ request.extension.should == '.js'
115
+ end
116
+ end
117
+ end
118
+
119
+ describe "#format" do
120
+ describe "when format is in the params" do
121
+ let(:params) { { :format => 'js' }}
122
+
123
+ it "should return the params format" do
124
+ request.format.should == 'js'
125
+ end
126
+ end
127
+
128
+ describe "when format is not in the params" do
129
+ describe "and there is no extension in the path" do
130
+ let(:path) { '/cart' }
131
+
132
+ it "should return html" do
133
+ request.format.should == 'html'
134
+ end
135
+ end
136
+
137
+ describe "and there is an extension in the path" do
138
+ let(:path) { '/styles.css' }
139
+
140
+ it "should return the extension" do
141
+ request.format.should == 'css'
142
+ end
143
+ end
144
+ end
145
+ end
146
+
147
+ describe "#html?" do
148
+ describe "on HTML with no extension" do
149
+ let(:path) { '/cart' }
150
+
151
+ it "returns true" do
152
+ request.html?.should be_true
153
+ end
154
+ end
155
+
156
+ describe "on HTML with an extension" do
157
+ let(:path) { '/cart.html' }
158
+
159
+ it "returns true" do
160
+ request.html?.should be_true
161
+ end
162
+ end
163
+
164
+ describe "on CSS" do
165
+ let(:path) { '/styles.css' }
166
+
167
+ it "returns false" do
168
+ request.html?.should be_false
169
+ end
170
+ end
171
+
172
+ describe "on JS" do
173
+ let(:path) { '/scripts.js' }
174
+
175
+ it "returns false" do
176
+ request.html?.should be_false
177
+ end
178
+ end
179
+ end
180
+
181
+ describe "#js?" do
182
+ describe "on JS" do
183
+ let(:path) { '/products.js' }
184
+
185
+ it "returns true" do
186
+ request.js?.should be_true
187
+ end
188
+ end
189
+
190
+ describe "on no extension" do
191
+ let(:path) { '/cart' }
192
+
193
+ it "returns false" do
194
+ request.js?.should be_false
195
+ end
196
+ end
197
+
198
+ describe "on non-JS extension" do
199
+ let(:path) { '/cart.html' }
200
+
201
+ it "returns false" do
202
+ request.js?.should be_false
203
+ end
204
+ end
205
+ end
206
+ end