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,37 @@
1
+ {% if contact.sent %}
2
+
3
+ <p>Your message has been sent and we&#8217;ll get back to you soon.</p>
4
+
5
+ {% else %}
6
+
7
+ <form method="post" action="/contact">
8
+ <ul>
9
+ <li>
10
+ <label for="name">Name</label>
11
+ {{ contact | contact_input: 'name' }}
12
+ </li>
13
+ <li>
14
+ <label for="email">Email</label>
15
+ {{ contact | contact_input: 'email' }}
16
+ </li>
17
+ <li>
18
+ <label for="subject">Subject</label>
19
+ {{ contact | contact_input: 'subject' }}
20
+ </li>
21
+ <li>
22
+ <label for="message">Message</label>
23
+ {{ contact | contact_input: 'message' }}
24
+ </li>
25
+ <li>
26
+ <label for="captcha">Spam check</label>
27
+ <p>Please enter the characters from the image.</p>
28
+ <div>{{ contact.captcha }}</div>
29
+ {{ contact | contact_input: 'captcha' }}
30
+ </li>
31
+ <li>
32
+ <button type="submit" name="submit" title="Send us an email">Send</button>
33
+ </li>
34
+ </ul>
35
+ </form>
36
+
37
+ {% endif %}
@@ -0,0 +1,25 @@
1
+ {% paginate products from products.current by theme.products_per_page %}
2
+
3
+ {% if products != blank %}
4
+ <ul>
5
+ {% for product in products %}
6
+ <li class="{{ product.css_class }}">
7
+ <a href="{{ product.url }}">
8
+ <img alt="Image of {{ product.name | escape }}" src="{{ product.image | product_image_url size: theme.product_image_size }}">
9
+ <b>{{ product.name }}</b>
10
+ <i>{{ product.default_price | money_with_sign }}</i>
11
+ {% if product.on_sale %}
12
+ <em>On Sale</em>
13
+ {% endif %}
14
+ </a>
15
+ </li>
16
+ {% endfor %}
17
+ </ul>
18
+
19
+ {{ paginate | default_pagination }}
20
+
21
+ {% else %}
22
+ <p>No products found.</p>
23
+ {% endif %}
24
+
25
+ {% endpaginate %}
@@ -0,0 +1,7 @@
1
+ $ ->
2
+ $('body#cart').on 'click', '.remove', (event) ->
3
+ event.preventDefault()
4
+
5
+ $(this)
6
+ .closest('li').find('input[id$=_qty]').val(0)
7
+ .closest('form').submit()
@@ -0,0 +1,7 @@
1
+ $ ->
2
+ $('.product_images').on 'click', 'a', (event) ->
3
+ event.preventDefault()
4
+
5
+ $('.primary_image').prop 'src', $(this).prop('href')
6
+ $('.product_images li.selected').removeClass 'selected'
7
+ $(this).closest('li').addClass 'selected'
@@ -0,0 +1,101 @@
1
+ <!DOCTYPE html>
2
+ <head>
3
+ <title>{{ store.name }} &mdash; {{ page.name }}</title>
4
+
5
+ <meta charset="utf-8">
6
+ <meta name="description" content="{{ page.meta_description }}">
7
+ <meta name="keywords" content="{{ page.meta_keywords }}">
8
+
9
+ <link href="{{ theme | theme_css_url }}" media="screen" rel="stylesheet" type="text/css">
10
+
11
+ <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js" type="text/javascript"></script>
12
+ <script src="{{ theme | theme_js_url }}" type="text/javascript"></script>
13
+
14
+ {{ head_content }}
15
+ </head>
16
+
17
+ <body id="{{ page.permalink }}" class="{{ page.category }}">
18
+ <header>
19
+ <a href="/" title="{{ store.name | escape }}">
20
+ {% if theme.logo != blank %}
21
+ <img src="{{ theme.logo.url }}" alt="{{ store.name }}">
22
+ {% else %}
23
+ {{ store.name }}
24
+ {% endif %}
25
+ </a>
26
+ </header>
27
+
28
+ <div class="wrap">
29
+ <aside>
30
+ <section>
31
+ <a href="/cart">Cart ({{ cart.total | money_with_sign }})</a>
32
+ </section>
33
+
34
+ {% if theme.show_search %}
35
+ <section>
36
+ <form action="/products" method="get">
37
+ <label>Search: <input type="text" name="search"></label>
38
+ </form>
39
+ </section>
40
+ {% endif %}
41
+
42
+ <nav>
43
+ <h3>Products</h3>
44
+ <ul>
45
+ <li><a href="/products">All</a></li>
46
+ {% for category in categories.active %}
47
+ <li>{{ category | link_to }}</li>
48
+ {% endfor %}
49
+ </ul>
50
+
51
+ {% if artists.active != blank %}
52
+ <h3>Artists</h3>
53
+ <ul>
54
+ <li><a href="/products">All</a></li>
55
+ {% for artist in artists.active %}
56
+ <li>{{ artist | link_to }}</li>
57
+ {% endfor %}
58
+ </ul>
59
+ {% endif %}
60
+
61
+ <h3>Info</h3>
62
+ <ul>
63
+ {% for page in pages.all %}
64
+ <li>{{ page | link_to }}</li>
65
+ {% endfor %}
66
+ <li><a href="/contact">Contact Us</a></li>
67
+ {% if store.website != blank %}
68
+ <li><a href="{{ store.website }}">Back to Site</a></li>
69
+ {% endif %}
70
+ </ul>
71
+ </nav>
72
+
73
+ <cite>{{ bigcartel_credit }}</cite>
74
+ </aside>
75
+
76
+ <section class="content">
77
+ <h1>{{ page.name }}</h1>
78
+
79
+ {% if errors != blank %}
80
+ <ul class="errors">
81
+ {% for error in errors %}
82
+ <li>{{ error }}</li>
83
+ {% endfor %}
84
+ </ul>
85
+ {% endif %}
86
+
87
+ {% if page.category == 'custom' %}
88
+ {{ page_content | paragraphs }}
89
+ {% else %}
90
+ {{ page_content }}
91
+ {% endif %}
92
+ </section>
93
+ </div>
94
+
95
+ <footer>
96
+ {% if theme.twitter_username != blank %}
97
+ <p><a href="http://twitter/{{ theme.twitter_username }}">Follow @{{ theme.twitter_username }}</a></p>
98
+ {% endif %}
99
+ </footer>
100
+ </body>
101
+ </html>
@@ -0,0 +1,20 @@
1
+ <!DOCTYPE html>
2
+ <head>
3
+ <title>{{ store.name }} &mdash; {{ page.name }}</title>
4
+
5
+ <meta charset="utf-8">
6
+ <meta name="description" content="{{ page.meta_description }}">
7
+ <meta name="keywords" content="{{ page.meta_keywords }}">
8
+
9
+ <link href="{{ theme | theme_css_url }}" media="screen" rel="stylesheet" type="text/css">
10
+
11
+ {{ head_content }}
12
+ </head>
13
+
14
+ <body id="{{ page.permalink }}" class="{{ page.category }}">
15
+ <div>
16
+ <h1>We&#8217;re working our site at the moment.</h1>
17
+ <p>Please check back soon.</p>
18
+ </div>
19
+ </body>
20
+ </html>
@@ -0,0 +1,65 @@
1
+ <section class="product_images">
2
+ <img src="{{ product.image | product_image_url }}" alt="Image of {{ product.name | escape }}" class="primary_image">
3
+
4
+ {% if product.images.size > 1 %}
5
+ <ul>
6
+ {% for image in product.images %}
7
+ <li{% if forloop.first %} class="selected"{% endif %}><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
+ {% endif %}
11
+ </section>
12
+
13
+ <section>
14
+ <aside>
15
+ {% case product.status %}
16
+
17
+ {% when 'sold-out' %}
18
+ <h5>{{ product.default_price | money_with_sign }} <em>Sold Out</em></h5>
19
+
20
+ {% when 'coming-soon' %}
21
+ <h5>{{ product.default_price | money_with_sign }} <em>Coming Soon</em></h5>
22
+
23
+ {% when 'active' %}
24
+ <h5>{{ product.default_price | money_with_sign }}{% if product.on_sale %} <em>On Sale{% endif %}</em></h5>
25
+ <h5>Availability</h5>
26
+
27
+ <ul>
28
+ {% for option in product.options %}
29
+ <li>
30
+ {% unless product.has_default_option %}<span>{{ option.name }}</span>{% endunless %}
31
+ <span>{% if option.sold_out %}Sold Out{% else %}{{ option.inventory }}%{% endif %}</span>
32
+ <div style="width:{{ option.inventory }}%"></div>
33
+ </li>
34
+ {% endfor %}
35
+ </ul>
36
+
37
+ <form method="post" action="/cart">
38
+ {% if product.has_default_option %}
39
+ {{ product.option | hidden_option_input }}
40
+ {% else %}
41
+ <div>
42
+ {{ product.options_in_stock | options_select }}
43
+ </div>
44
+ {% endif %}
45
+
46
+ <button name="submit" type="submit" title="Add to Cart">Add to Cart</button>
47
+ </form>
48
+ {% endcase %}
49
+ </aside>
50
+
51
+ {% for artist in product.artists %}
52
+ {% if forloop.first %}
53
+ <h5>by {{ artist.name }}</h5>
54
+ {% if forloop.length > 2 %}, {% endif %}
55
+ {% elsif forloop.last %}
56
+ <h5>and {{ artist.name }}</h5>
57
+ {% else %}
58
+ <h5>{{ artist.name }}</h5>,
59
+ {% endif %}
60
+ {% endfor %}
61
+
62
+ {% if product.description != blank %}
63
+ {{ product.description | paragraphs }}
64
+ {% endif %}
65
+ </div>
@@ -0,0 +1,25 @@
1
+ {% paginate products from products.current by theme.products_per_page %}
2
+
3
+ {% if products != blank %}
4
+ <ul>
5
+ {% for product in products %}
6
+ <li class="{{ product.css_class }}">
7
+ <a href="{{ product.url }}">
8
+ <img alt="Image of {{ product.name | escape }}" src="{{ product.image | product_image_url size: theme.product_image_size }}">
9
+ <b>{{ product.name }}</b>
10
+ <p>{{ product.default_price | money_with_sign }}</p>
11
+ {% if product.on_sale %}
12
+ <em>On Sale</em>
13
+ {% endif %}
14
+ </a>
15
+ </li>
16
+ {% endfor %}
17
+ </ul>
18
+
19
+ {{ paginate | default_pagination }}
20
+
21
+ {% else %}
22
+ <p>No products found.</p>
23
+ {% endif %}
24
+
25
+ {% endpaginate %}
@@ -0,0 +1,19 @@
1
+ // ------------------------------------------------------------------------------------------------
2
+ //
3
+ // This is where all of the JavaScript code is handled for your theme.
4
+ //
5
+ // We recommend you break your JavaScript into multiple files and put them in a separate
6
+ // directory. We've used a "javascripts" directory in our example below. After that we'll use
7
+ // Sprockets (getsprockets.org) to package them into one file. Sprockets also allows you to
8
+ // use CoffeeScript (coffeescript.org) by ending your file name with .coffee.
9
+ //
10
+ // However, if you don't have much JavaScript, or you're just a glutton for punishment,
11
+ // you could simply put all of your JavaScript in this file. It's up to you.
12
+ //
13
+ // ------------------------------------------------------------------------------------------------
14
+ //
15
+ // Here we're including a couple CoffeeScript files written for different areas of the store, we're
16
+ // also including jQuery in our layout.html from Google so that it can be better cached by users.
17
+ //
18
+ //= require javascripts/product
19
+ //= require javascripts/cart
@@ -0,0 +1,71 @@
1
+ {
2
+ "name": "Sample",
3
+ "version": "0.0.1",
4
+ "images": [
5
+ {
6
+ "variable": "logo",
7
+ "label": "Logo",
8
+ "description": "Adds your logo to the header"
9
+ },
10
+ {
11
+ "variable": "background_image",
12
+ "label": "Background Image",
13
+ "description": "Adds a repeating background image"
14
+ }
15
+ ],
16
+ "fonts": [
17
+ {
18
+ "variable": "header_font",
19
+ "label": "Header Font",
20
+ "default": "Inconsolata"
21
+ },
22
+ {
23
+ "variable": "text_font",
24
+ "label": "Text Font",
25
+ "default": "Helvetica"
26
+ }
27
+ ],
28
+ "colors": [
29
+ {
30
+ "variable": "background_color",
31
+ "label": "Background",
32
+ "default": "#FAFAFA"
33
+ },
34
+ {
35
+ "variable": "text_color",
36
+ "label": "Text Color",
37
+ "default": "#222222"
38
+ }
39
+ ],
40
+ "options": [
41
+ {
42
+ "variable": "show_search",
43
+ "label": "Show search",
44
+ "type": "boolean",
45
+ "default": false,
46
+ "description": "Shows a search field"
47
+ },
48
+ {
49
+ "variable": "product_image_size",
50
+ "label": "Product image size",
51
+ "type": "select",
52
+ "options": [["Small", "thumb"], ["Medium", "medium"], ["Large", "large"], ["Huge", ""]],
53
+ "default": "large",
54
+ "description": "The size of your product images"
55
+ },
56
+ {
57
+ "variable": "products_per_page",
58
+ "label": "Products per page",
59
+ "type": "select",
60
+ "options": "1..100",
61
+ "default": 9,
62
+ "description": "The number of products shown per page"
63
+ },
64
+ {
65
+ "variable": "twitter_username",
66
+ "label": "Twitter username",
67
+ "type": "text",
68
+ "description": "Ex: @bigcartel"
69
+ }
70
+ ]
71
+ }
@@ -0,0 +1,27 @@
1
+ /* ------------------------------------------------------------------------------------------------
2
+ *
3
+ * This is where all of the CSS code is handled for your theme.
4
+ *
5
+ * We recommend you break your CSS into multiple files and put them in a separate
6
+ * directory. We've used a "stylesheets" directory in our example below. After that we'll use
7
+ * Sprockets (getsprockets.org) to package them into one file. Sprockets also allows you to
8
+ * use Sass/SCSS (sass-lang.com) by ending your file name with .sass or .scss, and you can also
9
+ * use LESS (lesscss.org) by ending your file with .less.
10
+ *
11
+ * However, if you don't have much CSS, or you're just a glutton for punishment,
12
+ * you could simply put all of your CSS in this file. It's up to you.
13
+ *
14
+ * ------------------------------------------------------------------------------------------------
15
+ */
16
+
17
+ /*
18
+ * Here we're including a 3rd-party stylesheet we put in stylesheets/vendor written in normal CSS,
19
+ * as well as a few custom Sass stylesheets we've written for different areas of the store
20
+ *
21
+ *= require_directory ./stylesheets/vendor
22
+ *= require stylesheets/layout
23
+ *= require stylesheets/products
24
+ *= require stylesheets/product
25
+ *= require stylesheets/cart
26
+ *
27
+ */
@@ -0,0 +1,38 @@
1
+ body#cart
2
+ form
3
+ ul
4
+ margin-bottom: 2em
5
+
6
+ li
7
+ overflow: hidden
8
+
9
+ img
10
+ display: block
11
+ float: left
12
+ margin-right: 30px
13
+
14
+ h2
15
+ float: left
16
+ width: 60%
17
+
18
+ p
19
+ float: left
20
+ padding-top: 7px
21
+
22
+ input
23
+ margin-right: 10px
24
+ text-align: center
25
+ width: 15px
26
+
27
+ a.remove
28
+ display: inline-block
29
+ background: #ddd + 20
30
+ border-radius: 20px
31
+ height: 20px
32
+ line-height: 18px
33
+ margin-left: 20px
34
+ text-align: center
35
+ width: 20px
36
+
37
+ &:hover
38
+ background: #ddd