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,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