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,48 @@
1
+ module Dugway
2
+ module Filters
3
+ module ComparisonFilters
4
+ def num_gt(input, operand)
5
+ to_number(input) > to_number(operand)
6
+ end
7
+
8
+ def num_lt(input, operand)
9
+ to_number(input) < to_number(operand)
10
+ end
11
+
12
+ def num_eq(input, operand)
13
+ to_number(input) == to_number(operand)
14
+ end
15
+
16
+ def num_lte(input, operand)
17
+ num_eq(input, operand) || num_lt(input, operand)
18
+ end
19
+
20
+ def num_gte(input, operand)
21
+ num_eq(input, operand) || num_gt(input, operand)
22
+ end
23
+
24
+ private
25
+
26
+ def to_number(obj)
27
+ case obj
28
+ when Numeric
29
+ obj
30
+ when String
31
+ (obj.strip =~ /^\d+\.\d+$/) ? obj.to_f : obj.to_i
32
+ else
33
+ 0
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+ Liquid::Condition.send(:include, Dugway::Filters::ComparisonFilters)
41
+
42
+ Liquid::Condition.class_eval do
43
+ operators['num_lt'] = lambda { |cond, left, right| cond.num_lt(left, right) }
44
+ operators['num_lte'] = lambda { |cond, left, right| cond.num_lte(left, right) }
45
+ operators['num_gt'] = lambda { |cond, left, right| cond.num_gt(left, right) }
46
+ operators['num_gte'] = lambda { |cond, left, right| cond.num_gte(left, right) }
47
+ operators['num_eq'] = lambda { |cond, left, right| cond.num_eq(left, right) }
48
+ end
@@ -0,0 +1,138 @@
1
+ require 'htmlentities'
2
+
3
+ module Dugway
4
+ module Filters
5
+ module CoreFilters
6
+ # Text Filters
7
+
8
+ def pluralize(count, singular, plural = nil)
9
+ "#{count} " + if count == 1
10
+ singular
11
+ elsif plural
12
+ plural
13
+ else
14
+ singular + "s"
15
+ end
16
+ end
17
+
18
+ def paragraphs(text)
19
+ tags = '(table|thead|tfoot|caption|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr|script|embed|object|param|code|center|dir|fieldset|menu|noframes|noscript|frameset|applet|button|del|iframe|ins)'
20
+ text = text.to_s.gsub(/\r\n?/, "\n") # \r\n and \r -> \n
21
+ blocks = text.split(/\n\n+/) # split on double newlines
22
+ blocks.inject('') do | result, block |
23
+ block.strip!
24
+ if block =~ /<\s*(\/)?\s*#{tags}\s*(\/)?\s*>.*(<\s*\/\s*\1\s*>)?/i
25
+ result << block
26
+ else
27
+ block.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
28
+ result << "<p>#{block}</p>"
29
+ end
30
+ result << "\n"
31
+ end
32
+ end
33
+
34
+ # Money Filters
35
+
36
+ def money(amount)
37
+ number_to_currency(amount, :locale => nil, :precision => I18n.translate('number.currency.format.precision'), :unit => '', :separator => I18n.translate('number.currency.format.separator'), :delimiter => I18n.translate('number.currency.format.delimiter'), :format => I18n.translate('number.currency.format.format')).strip
38
+ end
39
+
40
+ def money_with_sign(amount)
41
+ unit = I18n.translate('number.currency.format.unit')
42
+ number_to_currency(amount).try(:gsub, unit, "<span class=\"currency_sign\">#{ HTMLEntities.new.encode(unit, :named) }</span>")
43
+ end
44
+
45
+ def money_with_code(amount)
46
+ %{#{ money(amount) } <span class="currency_code">#{ currency.code }</span>}
47
+ end
48
+
49
+ def money_with_sign_and_code(amount)
50
+ %{#{ money_with_sign(amount) } <span class="currency_code\">#{ currency.code }</span>}
51
+ end
52
+
53
+ # Shipping Filters
54
+
55
+ def shipping_name(area, everywhere = 'Everywhere', everywhere_else = 'Everywhere else')
56
+ if area.country.name.present?
57
+ area.country['name']
58
+ elsif area.strict
59
+ everywhere_else
60
+ else
61
+ everywhere
62
+ end
63
+ end
64
+
65
+ # Input Filters
66
+
67
+ def hidden_option_input(option, id = 'option', class_name = nil)
68
+ hidden_field_tag('cart[add][id]', option['id'], { :id => id, :class => class_name })
69
+ end
70
+
71
+ def options_select(options, id = 'option', class_name = nil)
72
+ options = options.present? ? options : []
73
+ option_tags = options.inject('') { |t,o| t += option_tag((o['name'] + (o['has_custom_price'] ? " - #{ money_with_sign(o['price']) }" : '')), o['id']) }
74
+ select_tag('cart[add][id]', option_tags, { :id => id, :class => class_name })
75
+ end
76
+
77
+ def options_radio(options, id = 'option', class_name = nil)
78
+ list = ''
79
+
80
+ for o in options
81
+ list += '<li>'
82
+ list += radio_button_tag('cart[add][id]', o['id'], o['default'], { :id => "option_#{o['id']}", :class => class_name })
83
+ list += %{ <label for="option_#{o['id']}">#{o['name']}}
84
+ list += %{ - #{ money_with_sign(o['price']) }} if o['has_custom_price']
85
+ list += %{</label>}
86
+ list += '</li>'
87
+ end
88
+
89
+ %{<ul id="#{id}">#{list}</ul>}
90
+ end
91
+
92
+ def product_quantity_input(product, quantity = 1, id = nil, class_name = nil)
93
+ text_field_tag("cart[add][quantity]", quantity, { :id => id || "quantity_#{product['id']}", :class => class_name, :autocomplete => 'off' })
94
+ end
95
+
96
+ def item_quantity_input(item, id = nil, class_name = nil)
97
+ text_field_tag("cart[update][#{ item['id'] }]", item['quantity'], { :id => id || "item_#{ item['id'] }_qty", :class => class_name, :autocomplete => 'off' })
98
+ end
99
+
100
+ def country_select(country, label = 'Select your country...', id = 'country', class_name = nil)
101
+ found = false
102
+ countries = [[label, ''], ['------------',''], [country['name'], country['id']], ['------------','']] + Country.options
103
+ options = countries.inject('') do |t,c|
104
+ select = !found && c[1] == cart.country_id
105
+ found = true if select
106
+ t += option_tag(c[0], c[1], select)
107
+ end
108
+ select_tag('cart[country_id]', options, { :id => id, :class => class_name })
109
+ end
110
+
111
+ def discount_code_input(discount, id = 'cart_discount_code', class_name = nil)
112
+ text_field_tag('cart[discount_code]', nil, { :id => id, :class => class_name, :autocomplete => 'off' })
113
+ end
114
+
115
+ # Contact Filters
116
+
117
+ def contact_input(contact, field, id = nil, class_name = nil)
118
+ field = field.downcase
119
+ id ||= field
120
+ case field
121
+ when 'message'
122
+ text_area_tag(field, contact['message'], :id => id, :class => class_name, :tabindex => contact_tab_index)
123
+ when 'captcha'
124
+ text_field_tag('captcha', '', :id => id, :class => class_name, :tabindex => contact_tab_index)
125
+ else
126
+ text_field_tag(field, contact[field], :id => id, :class => class_name, :tabindex => contact_tab_index)
127
+ end
128
+ end
129
+
130
+ private
131
+
132
+ def contact_tab_index
133
+ @contact_tab_index ||= 0
134
+ @contact_tab_index += 1
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,35 @@
1
+ module Dugway
2
+ module Filters
3
+ module DefaultPagination
4
+ def default_pagination(paginate, div_id = 'pagination', div_class = 'pagination', prev_label = nil, next_label = nil)
5
+ Array.new.tap { |html|
6
+ html << %(<div class="#{ div_class }" id="#{ div_id }">)
7
+
8
+ prev_label = prev_label.blank? ? paginate['previous']['title'] : prev_label
9
+ if paginate['previous']['is_link']
10
+ html << %(<a class="previous" href="#{ paginate['previous']['url'] }">#{ prev_label }</a>)
11
+ else
12
+ html << %(<span class="previous disabled">#{ prev_label }</span>)
13
+ end
14
+
15
+ paginate['parts'].each { |part|
16
+ if part['is_link']
17
+ html << %(<a href="#{ part['url'] }">#{ part['title'] }</a>)
18
+ else
19
+ html << %(<span class="#{ part['title'] == paginate['current_page'].to_s ? 'current' : 'gap' }">#{ part['title'] }</span>)
20
+ end
21
+ }
22
+
23
+ next_label = next_label.blank? ? paginate['next']['title'] : next_label
24
+ if paginate['next']['is_link']
25
+ html << %(<a class="next" href="#{ paginate['next']['url'] }">#{ next_label }</a>)
26
+ else
27
+ html << %(<span class="next disabled">#{ next_label }</span>)
28
+ end
29
+
30
+ html << %(</div>)
31
+ }.join(' ')
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ module Dugway
2
+ module Filters
3
+ module FontFilters
4
+ def font_family(font_name)
5
+ ThemeFont.find_family_by_name(font_name)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,66 @@
1
+ module Dugway
2
+ module Filters
3
+ module UrlFilters
4
+ def link_to(item, *args)
5
+ options = link_args_to_options(args)
6
+ text = options.delete(:text) || h(item['name'])
7
+ options = { :title => "View #{ text }", :href => item['url'] }.merge(options)
8
+ content_tag :a, text, options
9
+ end
10
+
11
+ def product_image_url(image=nil, size=nil)
12
+ unless image.blank?
13
+ url = image['url']
14
+
15
+ unless size.blank?
16
+ size = size.to_s.downcase
17
+
18
+ if thumb_size_in_pixels = thumb_size_in_pixels_for(size)
19
+ dir = url[0..url.rindex('/')]
20
+ ext = File.extname(url)
21
+ url = "#{ dir }#{ thumb_size_in_pixels }#{ ext }"
22
+ end
23
+ end
24
+ else
25
+ url = "http://bigcartel.com/images/common/noimage-#{ (size || 'large').to_s }.gif"
26
+ end
27
+
28
+ url
29
+ end
30
+
31
+ def theme_js_url(name)
32
+ if name.is_a?(Drops::ThemeDrop)
33
+ '/scripts.js'
34
+ elsif name == 'api'
35
+ 'http://cache0.bigcartel.com/api/1/api.usd.js'
36
+ else
37
+ name
38
+ end
39
+ end
40
+
41
+ def theme_css_url(theme)
42
+ '/styles.css'
43
+ end
44
+
45
+ def theme_image_url(filename)
46
+ "/images/#{ filename }"
47
+ end
48
+
49
+ private
50
+
51
+ def link_args_to_options(args)
52
+ options = {}
53
+
54
+ [:text, :title, :id, :class, :rel].zip(args) { |key, value|
55
+ options[key] = h(value) unless value.nil?
56
+ }
57
+
58
+ options
59
+ end
60
+
61
+ def thumb_size_in_pixels_for(size)
62
+ { 'thumb' => 75, 'medium' => 175, 'large' => 300 }[size]
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,119 @@
1
+ module Dugway
2
+ module Filters
3
+ module UtilFilters
4
+ private
5
+
6
+ # Registered Vars
7
+
8
+ def currency
9
+ @context.registers[:currency]
10
+ end
11
+
12
+ # Mimics
13
+
14
+ DEFAULT_CURRENCY_VALUES = { :format => "%u%n", :negative_format => "-%u%n", :unit => "$", :separator => ".", :delimiter => ",", :precision => 2, :significant => false, :strip_insignificant_zeros => false }
15
+
16
+ def number_to_currency(number, options={})
17
+ return unless number
18
+
19
+ options.symbolize_keys!
20
+
21
+ defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
22
+ currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :default => {})
23
+ currency[:negative_format] ||= "-" + currency[:format] if currency[:format]
24
+
25
+ defaults = DEFAULT_CURRENCY_VALUES.merge(defaults).merge!(currency)
26
+ defaults[:negative_format] = "-" + options[:format] if options[:format]
27
+ options = defaults.merge!(options)
28
+
29
+ unit = options.delete(:unit)
30
+ format = options.delete(:format)
31
+
32
+ if number.to_f < 0
33
+ format = options.delete(:negative_format)
34
+ number = number.respond_to?("abs") ? number.abs : number.sub(/^-/, '')
35
+ end
36
+
37
+ value = number_with_precision(number, options[:precision])
38
+ format.gsub(/%n/, value).gsub(/%u/, unit)
39
+ end
40
+
41
+ def number_with_delimiter(number, delimiter=",", separator=".")
42
+ begin
43
+ parts = number.to_s.split('.')
44
+ parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
45
+ parts.join separator
46
+ rescue
47
+ number
48
+ end
49
+ end
50
+
51
+ def number_with_precision(number, precision=3)
52
+ "%01.#{precision}f" % number
53
+ rescue
54
+ number
55
+ end
56
+
57
+ def tag(name, options = nil, open = false, escape = true)
58
+ "<#{name}#{tag_options(options, escape) if options}" + (open ? ">" : " />")
59
+ end
60
+
61
+ def tag_options(options, escape = true)
62
+ unless options.blank?
63
+ attrs = []
64
+ if escape
65
+ options.each do |key, value|
66
+ next unless value
67
+ key = h(key.to_s)
68
+ value = h(value)
69
+ attrs << %(#{key}="#{value}")
70
+ end
71
+ else
72
+ attrs = options.map { |key, value| %(#{key}="#{value}") }
73
+ end
74
+ " #{attrs.sort * ' '}" unless attrs.empty?
75
+ end
76
+ end
77
+
78
+ def content_tag(type, content, options = {})
79
+ result = tag(type, options, true)
80
+ result += content
81
+ result += "</#{type}>"
82
+ end
83
+
84
+ def select_tag(name, option_tags = nil, options = {})
85
+ content_tag :select, option_tags, { "name" => name, "id" => name }.update(options.stringify_keys)
86
+ end
87
+
88
+ def option_tag(name, value, selected=false)
89
+ content_tag :option, name, { :value => value, :selected => selected ? 'selected' : nil }
90
+ end
91
+
92
+ def text_field_tag(name, value = nil, options = {})
93
+ tag(:input, { "type" => "text", "name" => name, "id" => name, "value" => value }.update(options.stringify_keys))
94
+ end
95
+
96
+ def hidden_field_tag(name, value = nil, options = {})
97
+ text_field_tag(name, value, options.stringify_keys.update("type" => "hidden"))
98
+ end
99
+
100
+ def text_area_tag(name, content = nil, options = {})
101
+ options.stringify_keys!
102
+
103
+ if size = options.delete("size")
104
+ options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
105
+ end
106
+
107
+ content_tag :textarea, content, { "name" => name, "id" => name }.update(options)
108
+ end
109
+
110
+ def radio_button_tag(name, value, checked = false, options = {})
111
+ pretty_tag_value = value.to_s.gsub(/\s/, "_").gsub(/(?!-)\W/, "").downcase
112
+ pretty_name = name.to_s.gsub(/\[/, "_").gsub(/\]/, "")
113
+ html_options = { "type" => "radio", "name" => name, "id" => "#{pretty_name}_#{pretty_tag_value}", "value" => value }.update(options.stringify_keys)
114
+ html_options["checked"] = "checked" if checked
115
+ tag :input, html_options
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,9 @@
1
+ module Dugway
2
+ module Tags
3
+ class CheckoutForm < ::Liquid::Block
4
+ def render(context)
5
+ %{<form id="checkout_form" name="checkout_form" method="post" action="/success"></form>}
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,58 @@
1
+ module Dugway
2
+ module Tags
3
+ class Get < ::Liquid::Block
4
+ Syntax = /((#{ Liquid::QuotedFragment })\s+)?(\w+)\s+from\s+(#{ Liquid::QuotedFragment }+)/
5
+
6
+ def initialize(tag_name, markup, tokens)
7
+ if markup =~ Syntax
8
+ @number_to_get = $1.present? ? $2 : nil
9
+ @variable_name = $3
10
+ @collection_name = $4
11
+
12
+ @attributes = {}
13
+ markup.scan(Liquid::TagAttributes) { |key, value|
14
+ @attributes[key] = value
15
+ }
16
+ else
17
+ raise SyntaxError.new("Syntax Error in tag 'get' - Valid syntax: get [number] [items] from [collection] order:[order]")
18
+ end
19
+
20
+ super
21
+ end
22
+
23
+ def render(context)
24
+ @context = context
25
+
26
+ @number_to_get = if context[@number_to_get].present?
27
+ context[@number_to_get]
28
+ elsif @number_to_get.present?
29
+ @number_to_get.to_i
30
+ elsif @attributes['limit'].present?
31
+ if context[@attributes['limit']].present?
32
+ context[@attributes['limit']]
33
+ else
34
+ @attributes['limit'].to_i
35
+ end
36
+ else
37
+ nil
38
+ end
39
+
40
+ @order = context[@attributes['order']].present? ? context[@attributes['order']] : @attributes['order']
41
+
42
+ context.stack do
43
+ context['internal'] = {
44
+ 'per_page' => @number_to_get,
45
+ 'order' => @order,
46
+ 'page' => nil
47
+ }
48
+
49
+ context[@variable_name] = context[@collection_name]
50
+
51
+ raise ArgumentError.new("Cannot get array '#{ @collection_name }'. Not found.") if context[@variable_name].total_entries.nil?
52
+
53
+ render_all @nodelist, context
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end