dugway 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.travis.yml +3 -0
- data/Gemfile +2 -0
- data/README.md +151 -0
- data/Rakefile +12 -0
- data/bin/dugway +7 -0
- data/dugway.gemspec +43 -0
- data/lib/dugway.rb +66 -0
- data/lib/dugway/application.rb +147 -0
- data/lib/dugway/cart.rb +144 -0
- data/lib/dugway/cli.rb +22 -0
- data/lib/dugway/cli/build.rb +56 -0
- data/lib/dugway/cli/create.rb +71 -0
- data/lib/dugway/cli/server.rb +37 -0
- data/lib/dugway/cli/templates/Gemfile.tt +2 -0
- data/lib/dugway/cli/templates/config.tt +24 -0
- data/lib/dugway/cli/templates/gitignore.tt +9 -0
- data/lib/dugway/cli/templates/source/cart.html +40 -0
- data/lib/dugway/cli/templates/source/checkout.html +33 -0
- data/lib/dugway/cli/templates/source/contact.html +37 -0
- data/lib/dugway/cli/templates/source/home.html +25 -0
- data/lib/dugway/cli/templates/source/images/badge.png +0 -0
- data/lib/dugway/cli/templates/source/javascripts/cart.js.coffee +7 -0
- data/lib/dugway/cli/templates/source/javascripts/product.js.coffee +7 -0
- data/lib/dugway/cli/templates/source/layout.html +101 -0
- data/lib/dugway/cli/templates/source/maintenance.html +20 -0
- data/lib/dugway/cli/templates/source/product.html +65 -0
- data/lib/dugway/cli/templates/source/products.html +25 -0
- data/lib/dugway/cli/templates/source/screenshot.jpg +0 -0
- data/lib/dugway/cli/templates/source/scripts.js +19 -0
- data/lib/dugway/cli/templates/source/settings.json +71 -0
- data/lib/dugway/cli/templates/source/styles.css +27 -0
- data/lib/dugway/cli/templates/source/stylesheets/cart.css.sass +38 -0
- data/lib/dugway/cli/templates/source/stylesheets/layout.css.sass +103 -0
- data/lib/dugway/cli/templates/source/stylesheets/product.css.sass +19 -0
- data/lib/dugway/cli/templates/source/stylesheets/products.css.sass +20 -0
- data/lib/dugway/cli/templates/source/stylesheets/vendor/normalize.css +396 -0
- data/lib/dugway/cli/templates/source/success.html +5 -0
- data/lib/dugway/controller.rb +148 -0
- data/lib/dugway/data/locales/cs.yml +26 -0
- data/lib/dugway/data/locales/da.yml +26 -0
- data/lib/dugway/data/locales/en-AU.yml +26 -0
- data/lib/dugway/data/locales/en-GB.yml +26 -0
- data/lib/dugway/data/locales/en-PH.yml +27 -0
- data/lib/dugway/data/locales/en-US.yml +26 -0
- data/lib/dugway/data/locales/es-MX.yml +26 -0
- data/lib/dugway/data/locales/eu.yml +26 -0
- data/lib/dugway/data/locales/gsw-CH.yml +26 -0
- data/lib/dugway/data/locales/hu.yml +26 -0
- data/lib/dugway/data/locales/il.yml +26 -0
- data/lib/dugway/data/locales/ja.yml +30 -0
- data/lib/dugway/data/locales/ms-MY.yml +26 -0
- data/lib/dugway/data/locales/nb.yml +22 -0
- data/lib/dugway/data/locales/pl.yml +27 -0
- data/lib/dugway/data/locales/pt-BR.yml +26 -0
- data/lib/dugway/data/locales/sv-SE.yml +26 -0
- data/lib/dugway/data/locales/th.yml +26 -0
- data/lib/dugway/data/locales/tr.yml +29 -0
- data/lib/dugway/data/locales/zh-TW.yml +30 -0
- data/lib/dugway/data/theme_fonts.yml +151 -0
- data/lib/dugway/extensions/time.rb +15 -0
- data/lib/dugway/liquid/drops/account_drop.rb +17 -0
- data/lib/dugway/liquid/drops/artist_drop.rb +9 -0
- data/lib/dugway/liquid/drops/artists_drop.rb +13 -0
- data/lib/dugway/liquid/drops/base_drop.rb +59 -0
- data/lib/dugway/liquid/drops/cart_drop.rb +13 -0
- data/lib/dugway/liquid/drops/cart_item_drop.rb +21 -0
- data/lib/dugway/liquid/drops/categories_drop.rb +13 -0
- data/lib/dugway/liquid/drops/category_drop.rb +9 -0
- data/lib/dugway/liquid/drops/contact_drop.rb +29 -0
- data/lib/dugway/liquid/drops/country_drop.rb +6 -0
- data/lib/dugway/liquid/drops/currency_drop.rb +6 -0
- data/lib/dugway/liquid/drops/image_drop.rb +6 -0
- data/lib/dugway/liquid/drops/page_drop.rb +13 -0
- data/lib/dugway/liquid/drops/pages_drop.rb +9 -0
- data/lib/dugway/liquid/drops/product_drop.rb +101 -0
- data/lib/dugway/liquid/drops/product_option_drop.rb +27 -0
- data/lib/dugway/liquid/drops/products_drop.rb +75 -0
- data/lib/dugway/liquid/drops/shipping_option_drop.rb +13 -0
- data/lib/dugway/liquid/drops/theme_drop.rb +23 -0
- data/lib/dugway/liquid/filters/comparison_filters.rb +48 -0
- data/lib/dugway/liquid/filters/core_filters.rb +138 -0
- data/lib/dugway/liquid/filters/default_pagination.rb +35 -0
- data/lib/dugway/liquid/filters/font_filters.rb +9 -0
- data/lib/dugway/liquid/filters/url_filters.rb +66 -0
- data/lib/dugway/liquid/filters/util_filters.rb +119 -0
- data/lib/dugway/liquid/tags/checkout_form.rb +9 -0
- data/lib/dugway/liquid/tags/get.rb +58 -0
- data/lib/dugway/liquid/tags/paginate.rb +129 -0
- data/lib/dugway/liquifier.rb +122 -0
- data/lib/dugway/logger.rb +16 -0
- data/lib/dugway/request.rb +36 -0
- data/lib/dugway/store.rb +166 -0
- data/lib/dugway/template.rb +44 -0
- data/lib/dugway/theme.rb +145 -0
- data/lib/dugway/theme_font.rb +68 -0
- data/lib/dugway/version.rb +3 -0
- data/spec/fixtures/store/page/about-us.js +1 -0
- data/spec/fixtures/store/products.js +1 -0
- data/spec/fixtures/store/store.js +1 -0
- data/spec/fixtures/theme/cart.html +33 -0
- data/spec/fixtures/theme/checkout.html +31 -0
- data/spec/fixtures/theme/contact.html +37 -0
- data/spec/fixtures/theme/home.html +38 -0
- data/spec/fixtures/theme/images/bc_badge.png +0 -0
- data/spec/fixtures/theme/javascripts/one.js +3 -0
- data/spec/fixtures/theme/javascripts/two.js.coffee +2 -0
- data/spec/fixtures/theme/layout.html +77 -0
- data/spec/fixtures/theme/maintenance.html +17 -0
- data/spec/fixtures/theme/product.html +73 -0
- data/spec/fixtures/theme/products.html +41 -0
- data/spec/fixtures/theme/screenshot.jpg +0 -0
- data/spec/fixtures/theme/scripts.js +2 -0
- data/spec/fixtures/theme/settings.json +55 -0
- data/spec/fixtures/theme/styles.css +4 -0
- data/spec/fixtures/theme/stylesheets/one.css +3 -0
- data/spec/fixtures/theme/stylesheets/two.css.sass +4 -0
- data/spec/fixtures/theme/success.html +5 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/units/dugway/request_spec.rb +206 -0
- data/spec/units/dugway/store_spec.rb +194 -0
- data/spec/units/dugway/template_spec.rb +145 -0
- data/spec/units/dugway/theme_font_spec.rb +136 -0
- data/spec/units/dugway_spec.rb +9 -0
- 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,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,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
|