dugway 0.5.0

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