liquor 0.1.1 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (176) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +3 -9
  5. data/Gemfile +7 -0
  6. data/Guardfile +11 -0
  7. data/MIT-LICENSE +6 -2
  8. data/README.md +4 -122
  9. data/Rakefile +20 -23
  10. data/doc/language-spec.html +768 -0
  11. data/doc/language-spec.md +698 -0
  12. data/lib/liquor.rb +39 -68
  13. data/lib/liquor/ast_tools.rb +28 -0
  14. data/lib/liquor/compiler.rb +110 -0
  15. data/lib/liquor/context.rb +76 -254
  16. data/lib/liquor/diagnostics.rb +151 -0
  17. data/lib/liquor/drop/drop.rb +168 -0
  18. data/lib/liquor/drop/drop_delegation.rb +24 -0
  19. data/lib/liquor/drop/drop_scope.rb +118 -0
  20. data/lib/liquor/drop/dropable.rb +17 -0
  21. data/lib/liquor/emitter.rb +313 -0
  22. data/lib/liquor/extensions/kaminari.rb +14 -0
  23. data/lib/liquor/extensions/pagination.rb +235 -0
  24. data/lib/liquor/extensions/rails.rb +97 -0
  25. data/lib/liquor/extensions/thinking_sphinx.rb +14 -0
  26. data/lib/liquor/extensions/tire.rb +30 -0
  27. data/lib/liquor/external.rb +79 -0
  28. data/lib/liquor/function.rb +94 -0
  29. data/lib/liquor/grammar/lexer.rb +1223 -0
  30. data/lib/liquor/grammar/lexer.rl +297 -0
  31. data/lib/liquor/grammar/parser.racc +288 -0
  32. data/lib/liquor/grammar/parser.rb +885 -0
  33. data/lib/liquor/library.rb +41 -0
  34. data/lib/liquor/manager.rb +146 -0
  35. data/lib/liquor/runtime.rb +167 -0
  36. data/lib/liquor/stdlib/builtin_functions.rb +315 -0
  37. data/lib/liquor/stdlib/builtin_tags.rb +228 -0
  38. data/lib/liquor/stdlib/html_truncater.rb +162 -0
  39. data/lib/liquor/stdlib/partial_tags.rb +76 -0
  40. data/lib/liquor/tag.rb +83 -14
  41. data/lib/liquor/version.rb +1 -1
  42. data/liquor.gemspec +29 -6
  43. data/spec/builtins_spec.rb +264 -0
  44. data/spec/compiler_spec.rb +136 -0
  45. data/spec/context_spec.rb +49 -0
  46. data/spec/drop_delegation_spec.rb +21 -0
  47. data/spec/drop_spec.rb +222 -0
  48. data/spec/errors_spec.rb +40 -0
  49. data/spec/external_spec.rb +207 -0
  50. data/spec/function_spec.rb +80 -0
  51. data/spec/lexer_spec.rb +173 -0
  52. data/spec/library_spec.rb +18 -0
  53. data/spec/manager_spec.rb +84 -0
  54. data/spec/parser_spec.rb +381 -0
  55. data/spec/partials_spec.rb +74 -0
  56. data/spec/runtime_spec.rb +97 -0
  57. data/spec/spec_helper.rb +94 -0
  58. data/spec/tag_spec.rb +7 -0
  59. metadata +216 -173
  60. data/AUTHORS +0 -2
  61. data/CHANGELOG +0 -48
  62. data/Gemfile.lock +0 -91
  63. data/History.txt +0 -44
  64. data/LICENSE +0 -23
  65. data/example/server/example_servlet.rb +0 -37
  66. data/example/server/liquid_servlet.rb +0 -28
  67. data/example/server/liquor_servlet.rb +0 -28
  68. data/example/server/server.rb +0 -12
  69. data/example/server/templates/index.liquid +0 -6
  70. data/example/server/templates/index.liquor +0 -6
  71. data/example/server/templates/products.liquid +0 -45
  72. data/example/server/templates/products.liquor +0 -45
  73. data/init.rb +0 -8
  74. data/lib/extras/liquid_view.rb +0 -51
  75. data/lib/extras/liquor_view.rb +0 -51
  76. data/lib/liquor/block.rb +0 -101
  77. data/lib/liquor/condition.rb +0 -120
  78. data/lib/liquor/document.rb +0 -17
  79. data/lib/liquor/drop.rb +0 -256
  80. data/lib/liquor/errors.rb +0 -11
  81. data/lib/liquor/extensions.rb +0 -72
  82. data/lib/liquor/file_system.rb +0 -62
  83. data/lib/liquor/htmltags.rb +0 -74
  84. data/lib/liquor/module_ex.rb +0 -60
  85. data/lib/liquor/standardfilters.rb +0 -315
  86. data/lib/liquor/strainer.rb +0 -58
  87. data/lib/liquor/tags/assign.rb +0 -33
  88. data/lib/liquor/tags/capture.rb +0 -35
  89. data/lib/liquor/tags/case.rb +0 -83
  90. data/lib/liquor/tags/comment.rb +0 -9
  91. data/lib/liquor/tags/content_for.rb +0 -54
  92. data/lib/liquor/tags/cycle.rb +0 -59
  93. data/lib/liquor/tags/for.rb +0 -136
  94. data/lib/liquor/tags/if.rb +0 -80
  95. data/lib/liquor/tags/ifchanged.rb +0 -20
  96. data/lib/liquor/tags/include.rb +0 -56
  97. data/lib/liquor/tags/unless.rb +0 -33
  98. data/lib/liquor/tags/yield.rb +0 -49
  99. data/lib/liquor/template.rb +0 -181
  100. data/lib/liquor/variable.rb +0 -52
  101. data/performance/shopify.rb +0 -92
  102. data/performance/shopify/comment_form.rb +0 -33
  103. data/performance/shopify/database.rb +0 -45
  104. data/performance/shopify/json_filter.rb +0 -7
  105. data/performance/shopify/liquid.rb +0 -18
  106. data/performance/shopify/liquor.rb +0 -18
  107. data/performance/shopify/money_filter.rb +0 -18
  108. data/performance/shopify/paginate.rb +0 -93
  109. data/performance/shopify/shop_filter.rb +0 -98
  110. data/performance/shopify/tag_filter.rb +0 -25
  111. data/performance/shopify/vision.database.yml +0 -945
  112. data/performance/shopify/weight_filter.rb +0 -11
  113. data/performance/tests/dropify/article.liquid +0 -74
  114. data/performance/tests/dropify/blog.liquid +0 -33
  115. data/performance/tests/dropify/cart.liquid +0 -66
  116. data/performance/tests/dropify/collection.liquid +0 -22
  117. data/performance/tests/dropify/index.liquid +0 -47
  118. data/performance/tests/dropify/page.liquid +0 -8
  119. data/performance/tests/dropify/product.liquid +0 -68
  120. data/performance/tests/dropify/theme.liquid +0 -105
  121. data/performance/tests/ripen/article.liquid +0 -74
  122. data/performance/tests/ripen/blog.liquid +0 -13
  123. data/performance/tests/ripen/cart.liquid +0 -54
  124. data/performance/tests/ripen/collection.liquid +0 -29
  125. data/performance/tests/ripen/index.liquid +0 -32
  126. data/performance/tests/ripen/page.liquid +0 -4
  127. data/performance/tests/ripen/product.liquid +0 -75
  128. data/performance/tests/ripen/theme.liquid +0 -85
  129. data/performance/tests/tribble/404.liquid +0 -56
  130. data/performance/tests/tribble/article.liquid +0 -98
  131. data/performance/tests/tribble/blog.liquid +0 -41
  132. data/performance/tests/tribble/cart.liquid +0 -134
  133. data/performance/tests/tribble/collection.liquid +0 -70
  134. data/performance/tests/tribble/index.liquid +0 -94
  135. data/performance/tests/tribble/page.liquid +0 -56
  136. data/performance/tests/tribble/product.liquid +0 -116
  137. data/performance/tests/tribble/search.liquid +0 -51
  138. data/performance/tests/tribble/theme.liquid +0 -90
  139. data/performance/tests/vogue/article.liquid +0 -66
  140. data/performance/tests/vogue/blog.liquid +0 -32
  141. data/performance/tests/vogue/cart.liquid +0 -58
  142. data/performance/tests/vogue/collection.liquid +0 -19
  143. data/performance/tests/vogue/index.liquid +0 -22
  144. data/performance/tests/vogue/page.liquid +0 -3
  145. data/performance/tests/vogue/product.liquid +0 -62
  146. data/performance/tests/vogue/theme.liquid +0 -122
  147. data/test/assign_test.rb +0 -11
  148. data/test/block_test.rb +0 -58
  149. data/test/capture_test.rb +0 -41
  150. data/test/condition_test.rb +0 -115
  151. data/test/content_for_test.rb +0 -15
  152. data/test/context_test.rb +0 -479
  153. data/test/drop_test.rb +0 -162
  154. data/test/error_handling_test.rb +0 -89
  155. data/test/extra/breakpoint.rb +0 -547
  156. data/test/extra/caller.rb +0 -80
  157. data/test/file_system_test.rb +0 -30
  158. data/test/filter_test.rb +0 -147
  159. data/test/helper.rb +0 -24
  160. data/test/html_tag_test.rb +0 -31
  161. data/test/if_else_test.rb +0 -139
  162. data/test/include_tag_test.rb +0 -129
  163. data/test/module_ex_test.rb +0 -89
  164. data/test/output_test.rb +0 -121
  165. data/test/parsing_quirks_test.rb +0 -54
  166. data/test/regexp_test.rb +0 -45
  167. data/test/security_test.rb +0 -41
  168. data/test/standard_filter_test.rb +0 -170
  169. data/test/standard_tag_test.rb +0 -405
  170. data/test/statements_test.rb +0 -137
  171. data/test/strainer_test.rb +0 -27
  172. data/test/template_test.rb +0 -82
  173. data/test/test_helper.rb +0 -28
  174. data/test/unless_else_test.rb +0 -27
  175. data/test/variable_test.rb +0 -173
  176. data/test/yield_test.rb +0 -24
@@ -1,11 +0,0 @@
1
- module Liquor
2
- class Error < ::StandardError; end
3
-
4
- class ArgumentError < Error; end
5
- class ContextError < Error; end
6
- class FilterNotFound < Error; end
7
- class FileSystemError < Error; end
8
- class StandardError < Error; end
9
- class SyntaxError < Error; end
10
- class StackLevelError < Error; end
11
- end
@@ -1,72 +0,0 @@
1
- require 'time'
2
- require 'date'
3
-
4
- class String # :nodoc:
5
- def to_liquor
6
- self
7
- end
8
- end
9
-
10
- class Array # :nodoc:
11
- def to_liquor
12
- self
13
- end
14
- end
15
-
16
- class Hash # :nodoc:
17
- def to_liquor
18
- self
19
- end
20
- end
21
-
22
- class Numeric # :nodoc:
23
- def to_liquor
24
- self
25
- end
26
- end
27
-
28
- class Time # :nodoc:
29
- def to_liquor
30
- self
31
- end
32
- end
33
-
34
- class DateTime < Date # :nodoc:
35
- def to_liquor
36
- self
37
- end
38
- end
39
-
40
- class Date # :nodoc:
41
- def to_liquor
42
- self
43
- end
44
- end
45
-
46
- def true.to_liquor # :nodoc:
47
- self
48
- end
49
-
50
- def false.to_liquor # :nodoc:
51
- self
52
- end
53
-
54
- def nil.to_liquor # :nodoc:
55
- self
56
- end
57
-
58
- class ActiveRecord::Relation
59
- def to_liquor
60
- self
61
- end
62
- end
63
-
64
- class ActionDispatch::Request
65
- def to_liquor
66
- Liquor::RequestDrop.new self
67
- end
68
- end
69
-
70
- class Liquor::RequestDrop < Liquor::Drop
71
- allow_all_methods
72
- end
@@ -1,62 +0,0 @@
1
- module Liquor
2
- # A liquor file system is way to let your templates retrieve other templates for use with the include tag.
3
- #
4
- # You can implement subclasses that retrieve templates from the database, from the file system using a different
5
- # path structure, you can provide them as hard-coded inline strings, or any manner that you see fit.
6
- #
7
- # You can add additional instance variables, arguments, or methods as needed.
8
- #
9
- # Example:
10
- #
11
- # Liquor::Template.file_system = Liquor::LocalFileSystem.new(template_path)
12
- # liquor = Liquor::Template.parse(template)
13
- #
14
- # This will parse the template with a LocalFileSystem implementation rooted at 'template_path'.
15
- class BlankFileSystem
16
- # Called by Liquor to retrieve a template file
17
- def read_template_file(template_path)
18
- raise FileSystemError, "This liquor context does not allow includes."
19
- end
20
- end
21
-
22
- # This implements an abstract file system which retrieves template files named in a manner similar to Rails partials,
23
- # ie. with the template name prefixed with an underscore. The extension ".liquor" is also added.
24
- #
25
- # For security reasons, template paths are only allowed to contain letters, numbers, and underscore.
26
- #
27
- # Example:
28
- #
29
- # file_system = Liquor::LocalFileSystem.new("/some/path")
30
- #
31
- # file_system.full_path("mypartial") # => "/some/path/_mypartial.liquor"
32
- # file_system.full_path("dir/mypartial") # => "/some/path/dir/_mypartial.liquor"
33
- #
34
- class LocalFileSystem
35
- attr_accessor :root
36
-
37
- def initialize(root)
38
- @root = root
39
- end
40
-
41
- def read_template_file(template_path)
42
- full_path = full_path(template_path)
43
- raise FileSystemError, "No such template '#{template_path}'" unless File.exists?(full_path)
44
-
45
- File.read(full_path)
46
- end
47
-
48
- def full_path(template_path)
49
- raise FileSystemError, "Illegal template name '#{template_path}'" unless template_path =~ /^[^.\/][a-zA-Z0-9_\/]+$/
50
-
51
- full_path = if template_path.include?('/')
52
- File.join(root, File.dirname(template_path), "_#{File.basename(template_path)}.liquor")
53
- else
54
- File.join(root, "_#{template_path}.liquor")
55
- end
56
-
57
- raise FileSystemError, "Illegal template path '#{File.expand_path(full_path)}'" unless File.expand_path(full_path) =~ /^#{File.expand_path(root)}/
58
-
59
- full_path
60
- end
61
- end
62
- end
@@ -1,74 +0,0 @@
1
- module Liquor
2
- class TableRow < Block
3
- Syntax = /(\w+)\s+in\s+(#{VariableSignature}+)/
4
-
5
- def initialize(tag_name, markup, tokens)
6
- if markup =~ Syntax
7
- @variable_name = $1
8
- @collection_name = $2
9
- @attributes = {}
10
- markup.scan(TagAttributes) do |key, value|
11
- @attributes[key] = value
12
- end
13
- else
14
- raise SyntaxError.new("Syntax Error in 'table_row loop' - Valid syntax: table_row [item] in [collection] cols=3")
15
- end
16
-
17
- super
18
- end
19
-
20
- def render(context)
21
- collection = context[@collection_name] or return ''
22
-
23
- if @attributes['limit'] or @attributes['offset']
24
- limit = context[@attributes['limit']] || -1
25
- offset = context[@attributes['offset']] || 0
26
- collection = collection[offset.to_i..(limit.to_i + offset.to_i - 1)]
27
- end
28
-
29
- length = collection.length
30
-
31
- cols = context[@attributes['cols']].to_i
32
-
33
- row = 1
34
- col = 0
35
-
36
- result = ["<tr class=\"row1\">\n"]
37
- context.stack do
38
-
39
- collection.each_with_index do |item, index|
40
- context[@variable_name] = item
41
- context['tablerowloop'] = {
42
- 'length' => length,
43
- 'index' => index + 1,
44
- 'index0' => index,
45
- 'col' => col + 1,
46
- 'col0' => col,
47
- 'index0' => index,
48
- 'rindex' => length - index,
49
- 'rindex0' => length - index -1,
50
- 'first' => (index == 0),
51
- 'last' => (index == length - 1),
52
- 'col_first' => (col == 0),
53
- 'col_last' => (col == cols - 1)
54
- }
55
-
56
-
57
- col += 1
58
-
59
- result << ["<td class=\"col#{col}\">"] + render_all(@nodelist, context) + ['</td>']
60
-
61
- if col == cols and not (index == length - 1)
62
- col = 0
63
- row += 1
64
- result << ["</tr>\n<tr class=\"row#{row}\">"]
65
- end
66
-
67
- end
68
- end
69
- result + ["</tr>\n"]
70
- end
71
- end
72
-
73
- Template.register_tag('tablerow', TableRow)
74
- end
@@ -1,60 +0,0 @@
1
- # Copyright 2007 by Domizio Demichelis
2
- # This library is free software. It may be used, redistributed and/or modified
3
- # under the same terms as Ruby itself
4
- #
5
- # This extension is usesd in order to expose the object of the implementing class
6
- # to liquor as it were a Drop. It also limits the liquor-callable methods of the instance
7
- # to the allowed method passed with the liquor_methods call
8
- # Example:
9
- #
10
- # class SomeClass
11
- # liquor_methods :an_allowed_method
12
- #
13
- # def an_allowed_method
14
- # 'this comes from an allowed method'
15
- # end
16
- # def unallowed_method
17
- # 'this will never be an output'
18
- # end
19
- # end
20
- #
21
- # if you want to extend the drop to other methods you can defines more methods
22
- # in the class <YourClass>::LiquorDropClass
23
- #
24
- # class SomeClass::LiquorDropClass
25
- # def another_allowed_method
26
- # 'and this from another allowed method'
27
- # end
28
- # end
29
- # end
30
- #
31
- # usage:
32
- # @something = SomeClass.new
33
- #
34
- # template:
35
- # {{something.an_allowed_method}}{{something.unallowed_method}} {{something.another_allowed_method}}
36
- #
37
- # output:
38
- # 'this comes from an allowed method and this from another allowed method'
39
- #
40
- # You can also chain associations, by adding the liquor_method call in the
41
- # association models.
42
- #
43
- class Module
44
-
45
- def liquor_methods(*allowed_methods)
46
- drop_class_str = "class #{self.to_s}::LiquorDropClass < Liquor::Drop\n"
47
- drop_class_str += "class_attribute :liquor_attributes\n"
48
- drop_class_str += "self.liquor_attributes = []\n"
49
- drop_class_str += "liquor_attributes << #{allowed_methods.collect{|meth| ":#{meth}"}.join(" << ") }\n" if allowed_methods.present?
50
- drop_class_str += "self\n"
51
- drop_class_str += "end"
52
-
53
- drop_class = eval drop_class_str
54
-
55
- define_method :to_liquor do
56
- drop_class.new(self)
57
- end
58
- end
59
-
60
- end
@@ -1,315 +0,0 @@
1
- require 'cgi'
2
-
3
- module Liquor
4
-
5
- module StandardFilters
6
-
7
- # Return the size of an array or of a string
8
- def size(input)
9
-
10
- input.respond_to?(:size) ? input.size : 0
11
- end
12
-
13
- # convert a input string to DOWNCASE
14
- def downcase(input)
15
- input.to_s.downcase
16
- end
17
-
18
- # convert a input string to UPCASE
19
- def upcase(input)
20
- input.to_s.upcase
21
- end
22
-
23
- # capitalize words in the input sentence
24
- def capitalize(input)
25
- input.to_s.capitalize
26
- end
27
-
28
- def escape(input)
29
- CGI.escapeHTML(input) rescue input
30
- end
31
-
32
- # escape_once
33
- def escape_once(input)
34
- ActionView::Helpers::TagHelper.escape_once(input) rescue input
35
- end
36
-
37
- alias_method :h, :escape
38
-
39
- # Truncate a string down to x characters
40
- def truncate(input, length = 50, truncate_string = "...")
41
- if input.nil? then return end
42
- l = length.to_i - truncate_string.length
43
- l = 0 if l < 0
44
- input.length > length.to_i ? input.mb_chars[0...l].to_s + truncate_string : input
45
- end
46
-
47
- def truncatewords(input, words = 15, truncate_string = "...")
48
- if input.nil? then return end
49
- wordlist = input.to_s.split
50
- l = words.to_i - 1
51
- l = 0 if l < 0
52
- wordlist.length > l ? wordlist[0..l].join(" ") + truncate_string : input
53
- end
54
-
55
- def strip_html(input)
56
- input.to_s.gsub(/<script.*?<\/script>/, '').gsub(/<.*?>/, '')
57
- end
58
-
59
- # Remove all newlines from the string
60
- def strip_newlines(input)
61
- input.to_s.gsub(/\n/, '')
62
- end
63
-
64
-
65
- # Join elements of the array with certain character between them
66
- def join(input, glue = ' ')
67
- [input].flatten.join(glue)
68
- end
69
-
70
- # Sort elements of the array
71
- # provide optional property with which to sort an array of hashes or drops
72
- def sort(input, property = nil)
73
- ary = [input].flatten
74
- if property.nil?
75
- ary.sort
76
- elsif ary.first.respond_to?('[]') and !ary.first[property].nil?
77
- ary.sort {|a,b| a[property] <=> b[property] }
78
- elsif ary.first.respond_to?(property)
79
- ary.sort {|a,b| a.send(property) <=> b.send(property) }
80
- end
81
- end
82
-
83
- # map/collect on a given property
84
- def map(input, property)
85
- ary = [input].flatten
86
- if ary.first.respond_to?('[]') and !ary.first[property].nil?
87
- ary.map {|e| e[property] }
88
- elsif ary.first.respond_to?(property)
89
- ary.map {|e| e.send(property) }
90
- end
91
- end
92
-
93
- # Replace occurrences of a string with another
94
- def replace(input, string, replacement = '')
95
- input.to_s.gsub(string, replacement)
96
- end
97
-
98
- # Replace the first occurrences of a string with another
99
- def replace_first(input, string, replacement = '')
100
- input.to_s.sub(string, replacement)
101
- end
102
-
103
- # remove a substring
104
- def remove(input, string)
105
- input.to_s.gsub(string, '')
106
- end
107
-
108
- # remove the first occurrences of a substring
109
- def remove_first(input, string)
110
- input.to_s.sub(string, '')
111
- end
112
-
113
- # add one string to another
114
- def append(input, string)
115
- input.to_s + string.to_s
116
- end
117
-
118
- # prepend a string to another
119
- def prepend(input, string)
120
- string.to_s + input.to_s
121
- end
122
-
123
- # Add <br /> tags in front of all newlines in input string
124
- def newline_to_br(input)
125
- input.to_s.gsub(/\n/, "<br />\n")
126
- end
127
-
128
- # Reformat a date
129
- #
130
- # %a - The abbreviated weekday name (``Sun'')
131
- # %A - The full weekday name (``Sunday'')
132
- # %b - The abbreviated month name (``Jan'')
133
- # %B - The full month name (``January'')
134
- # %c - The preferred local date and time representation
135
- # %d - Day of the month (01..31)
136
- # %H - Hour of the day, 24-hour clock (00..23)
137
- # %I - Hour of the day, 12-hour clock (01..12)
138
- # %j - Day of the year (001..366)
139
- # %m - Month of the year (01..12)
140
- # %M - Minute of the hour (00..59)
141
- # %p - Meridian indicator (``AM'' or ``PM'')
142
- # %S - Second of the minute (00..60)
143
- # %U - Week number of the current year,
144
- # starting with the first Sunday as the first
145
- # day of the first week (00..53)
146
- # %W - Week number of the current year,
147
- # starting with the first Monday as the first
148
- # day of the first week (00..53)
149
- # %w - Day of the week (Sunday is 0, 0..6)
150
- # %x - Preferred representation for the date alone, no time
151
- # %X - Preferred representation for the time alone, no date
152
- # %y - Year without a century (00..99)
153
- # %Y - Year with century
154
- # %Z - Time zone name
155
- # %% - Literal ``%'' character
156
- def date(input, format)
157
-
158
- if format.to_s.empty?
159
- return input.to_s
160
- end
161
-
162
- date = input.is_a?(String) ? Time.parse(input) : input
163
-
164
- if date.respond_to?(:strftime)
165
- date.strftime(format.to_s)
166
- else
167
- input
168
- end
169
- rescue => e
170
- input
171
- end
172
-
173
- # Get the first element of the passed in array
174
- #
175
- # Example:
176
- # {{ product.images | first | to_img }}
177
- #
178
- def first(array)
179
- array.first if array.respond_to?(:first)
180
- end
181
-
182
- # Get the last element of the passed in array
183
- #
184
- # Example:
185
- # {{ product.images | last | to_img }}
186
- #
187
- def last(array)
188
- array.last if array.respond_to?(:last)
189
- end
190
-
191
- # addition
192
- def plus(input, operand)
193
- input + operand if input.respond_to?('+')
194
- end
195
-
196
- # subtraction
197
- def minus(input, operand)
198
- input - operand if input.respond_to?('-')
199
- end
200
-
201
- # multiplication
202
- def times(input, operand)
203
- input * operand if input.respond_to?('*')
204
- end
205
-
206
- # division
207
- def divided_by(input, operand)
208
- input / operand if input.respond_to?('/')
209
- end
210
-
211
- # to_number / to_i
212
- def to_number(obj)
213
- case obj
214
- when Numeric
215
- obj
216
- when String
217
- (obj.strip =~ /^\d+\.\d+$/) ? obj.to_f : obj.to_i
218
- else
219
- 0
220
- end
221
- end
222
- alias :to_i :to_number
223
-
224
- # to_string / to_s, supposed to be used against Numeric objects
225
- def to_string(obj)
226
- case obj
227
- when Numeric
228
- obj.to_s
229
- else
230
- obj
231
- end
232
- end
233
- alias :to_s :to_string
234
-
235
- # yeild for content_for tag
236
- def yield(name)
237
- return '' if name.blank?
238
-
239
- res = @context["content_for"][name]
240
- if res.present? && res.is_a?(Array)
241
- res = res.first
242
- elsif res.blank?
243
- res = ''
244
- end
245
-
246
- res
247
- end
248
-
249
- # splits over the array in groups of size num padding any remaining slots with fill_with unless it is false
250
- def in_groups_of(array, num, fill_with = nil)
251
- array.in_groups_of(num.to_i, fill_with)
252
- end
253
-
254
- # splits or iterates over the array in number of groups, padding any remaining slots with fill_with unless it is false
255
- def in_groups(array, num, fill_with = nil)
256
- array.in_groups(num.to_i)
257
- end
258
-
259
- # returns true if the given object is present in self (that is, if any object == anObject), false otherwise.
260
- def include(array, element)
261
- array.include? element
262
- end
263
-
264
- # return a JSON string representing the model drop (using accepted attributes, methods and named_scopes)
265
- # to_include is a list of related drops through associations
266
- def to_json(array, to_include = nil)
267
- to_include = to_include.to_sym if to_include
268
- options = { :include => to_include }
269
-
270
- array.to_json(options)
271
- end
272
-
273
- # escape url
274
- def url_escape(input)
275
- CGI.escape(input) rescue input
276
- end
277
-
278
- # returns a new array containing self’s elements in reverse order.
279
- def reverse(array)
280
- array.reverse
281
- end
282
-
283
- # decodes html entities
284
- def decode_html_entities(string)
285
- coder = HTMLEntities.new
286
- coder.decode(string)
287
- end
288
-
289
- # divides str into substrings based on a delimiter, returning an array of these substrings.
290
- def split(string, delimetr)
291
- string.split(delimetr)
292
- end
293
-
294
- # returns a copy of self with all nil elements removed.
295
- def compact(array)
296
- array.compact
297
- end
298
-
299
- # concatenates two arrays
300
- def concat(array1, array2)
301
- array1 + array2
302
- end
303
-
304
- def even(input)
305
- (input % 2) == 0
306
- end
307
-
308
- def odd(input)
309
- (input % 2) == 1
310
- end
311
-
312
- end
313
-
314
- Template.register_filter(StandardFilters)
315
- end