liquor 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/.travis.yml +13 -0
  2. data/AUTHORS +2 -0
  3. data/CHANGELOG +46 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +91 -0
  6. data/History.txt +44 -0
  7. data/LICENSE +22 -0
  8. data/MIT-LICENSE +20 -0
  9. data/README.md +148 -0
  10. data/README.rdoc +114 -0
  11. data/Rakefile +33 -0
  12. data/example/server/example_servlet.rb +37 -0
  13. data/example/server/liquid_servlet.rb +28 -0
  14. data/example/server/liquor_servlet.rb +28 -0
  15. data/example/server/server.rb +12 -0
  16. data/example/server/templates/index.liquid +6 -0
  17. data/example/server/templates/index.liquor +6 -0
  18. data/example/server/templates/products.liquid +45 -0
  19. data/example/server/templates/products.liquor +45 -0
  20. data/init.rb +8 -0
  21. data/lib/extras/liquid_view.rb +51 -0
  22. data/lib/extras/liquor_view.rb +51 -0
  23. data/lib/liquor.rb +72 -0
  24. data/lib/liquor/block.rb +101 -0
  25. data/lib/liquor/condition.rb +120 -0
  26. data/lib/liquor/context.rb +294 -0
  27. data/lib/liquor/document.rb +17 -0
  28. data/lib/liquor/drop.rb +256 -0
  29. data/lib/liquor/errors.rb +11 -0
  30. data/lib/liquor/extensions.rb +72 -0
  31. data/lib/liquor/file_system.rb +62 -0
  32. data/lib/liquor/htmltags.rb +74 -0
  33. data/lib/liquor/module_ex.rb +60 -0
  34. data/lib/liquor/standardfilters.rb +315 -0
  35. data/lib/liquor/strainer.rb +58 -0
  36. data/lib/liquor/tag.rb +26 -0
  37. data/lib/liquor/tags/assign.rb +33 -0
  38. data/lib/liquor/tags/capture.rb +35 -0
  39. data/lib/liquor/tags/case.rb +83 -0
  40. data/lib/liquor/tags/comment.rb +9 -0
  41. data/lib/liquor/tags/content_for.rb +54 -0
  42. data/lib/liquor/tags/cycle.rb +59 -0
  43. data/lib/liquor/tags/for.rb +136 -0
  44. data/lib/liquor/tags/if.rb +80 -0
  45. data/lib/liquor/tags/ifchanged.rb +20 -0
  46. data/lib/liquor/tags/include.rb +56 -0
  47. data/lib/liquor/tags/unless.rb +33 -0
  48. data/lib/liquor/tags/yield.rb +49 -0
  49. data/lib/liquor/template.rb +181 -0
  50. data/lib/liquor/variable.rb +52 -0
  51. data/lib/liquor/version.rb +3 -0
  52. data/liquor.gemspec +19 -0
  53. data/performance/shopify.rb +92 -0
  54. data/performance/shopify/comment_form.rb +33 -0
  55. data/performance/shopify/database.rb +45 -0
  56. data/performance/shopify/json_filter.rb +7 -0
  57. data/performance/shopify/liquid.rb +18 -0
  58. data/performance/shopify/liquor.rb +18 -0
  59. data/performance/shopify/money_filter.rb +18 -0
  60. data/performance/shopify/paginate.rb +93 -0
  61. data/performance/shopify/shop_filter.rb +98 -0
  62. data/performance/shopify/tag_filter.rb +25 -0
  63. data/performance/shopify/vision.database.yml +945 -0
  64. data/performance/shopify/weight_filter.rb +11 -0
  65. data/performance/tests/dropify/article.liquid +74 -0
  66. data/performance/tests/dropify/blog.liquid +33 -0
  67. data/performance/tests/dropify/cart.liquid +66 -0
  68. data/performance/tests/dropify/collection.liquid +22 -0
  69. data/performance/tests/dropify/index.liquid +47 -0
  70. data/performance/tests/dropify/page.liquid +8 -0
  71. data/performance/tests/dropify/product.liquid +68 -0
  72. data/performance/tests/dropify/theme.liquid +105 -0
  73. data/performance/tests/ripen/article.liquid +74 -0
  74. data/performance/tests/ripen/blog.liquid +13 -0
  75. data/performance/tests/ripen/cart.liquid +54 -0
  76. data/performance/tests/ripen/collection.liquid +29 -0
  77. data/performance/tests/ripen/index.liquid +32 -0
  78. data/performance/tests/ripen/page.liquid +4 -0
  79. data/performance/tests/ripen/product.liquid +75 -0
  80. data/performance/tests/ripen/theme.liquid +85 -0
  81. data/performance/tests/tribble/404.liquid +56 -0
  82. data/performance/tests/tribble/article.liquid +98 -0
  83. data/performance/tests/tribble/blog.liquid +41 -0
  84. data/performance/tests/tribble/cart.liquid +134 -0
  85. data/performance/tests/tribble/collection.liquid +70 -0
  86. data/performance/tests/tribble/index.liquid +94 -0
  87. data/performance/tests/tribble/page.liquid +56 -0
  88. data/performance/tests/tribble/product.liquid +116 -0
  89. data/performance/tests/tribble/search.liquid +51 -0
  90. data/performance/tests/tribble/theme.liquid +90 -0
  91. data/performance/tests/vogue/article.liquid +66 -0
  92. data/performance/tests/vogue/blog.liquid +32 -0
  93. data/performance/tests/vogue/cart.liquid +58 -0
  94. data/performance/tests/vogue/collection.liquid +19 -0
  95. data/performance/tests/vogue/index.liquid +22 -0
  96. data/performance/tests/vogue/page.liquid +3 -0
  97. data/performance/tests/vogue/product.liquid +62 -0
  98. data/performance/tests/vogue/theme.liquid +122 -0
  99. data/test/assign_test.rb +11 -0
  100. data/test/block_test.rb +58 -0
  101. data/test/capture_test.rb +41 -0
  102. data/test/condition_test.rb +115 -0
  103. data/test/content_for_test.rb +15 -0
  104. data/test/context_test.rb +479 -0
  105. data/test/drop_test.rb +162 -0
  106. data/test/error_handling_test.rb +89 -0
  107. data/test/extra/breakpoint.rb +547 -0
  108. data/test/extra/caller.rb +80 -0
  109. data/test/file_system_test.rb +30 -0
  110. data/test/filter_test.rb +147 -0
  111. data/test/helper.rb +24 -0
  112. data/test/html_tag_test.rb +31 -0
  113. data/test/if_else_test.rb +139 -0
  114. data/test/include_tag_test.rb +129 -0
  115. data/test/module_ex_test.rb +89 -0
  116. data/test/output_test.rb +121 -0
  117. data/test/parsing_quirks_test.rb +54 -0
  118. data/test/regexp_test.rb +45 -0
  119. data/test/security_test.rb +41 -0
  120. data/test/standard_filter_test.rb +170 -0
  121. data/test/standard_tag_test.rb +405 -0
  122. data/test/statements_test.rb +137 -0
  123. data/test/strainer_test.rb +27 -0
  124. data/test/template_test.rb +82 -0
  125. data/test/test_helper.rb +28 -0
  126. data/test/unless_else_test.rb +27 -0
  127. data/test/variable_test.rb +173 -0
  128. data/test/yield_test.rb +24 -0
  129. metadata +237 -0
data/.travis.yml ADDED
@@ -0,0 +1,13 @@
1
+ language: ruby
2
+ script: "rake test"
3
+ rvm:
4
+ - 1.8.7
5
+ - 1.9.2
6
+ - 1.9.3
7
+ gemfile:
8
+ - Gemfile
9
+ branches:
10
+ only:
11
+ - master
12
+ - rails
13
+ - rails32
data/AUTHORS ADDED
@@ -0,0 +1,2 @@
1
+ Liquid was originally developed by Tobias Luetke
2
+ This fork was developed at Evil Martians by Timothy N. Tsvetkov <timothy.tsvetkov@gmail.com>
data/CHANGELOG ADDED
@@ -0,0 +1,46 @@
1
+ * Forked and added powerful Drops with relations and some new tags. See more in docs [Timothy N. Tsvetkov]
2
+
3
+ * Ruby 1.9.1 bugfixes
4
+
5
+ * Fix LiquidView for Rails 2.2. Fix local assigns for all versions of Rails
6
+
7
+ * Fixed gem install rake task
8
+ * Improve Error encapsulation in liquid by maintaining a own set of exceptions instead of relying on ruby build ins
9
+
10
+ * Added If with or / and expressions
11
+
12
+ * Implemented .to_liquid for all objects which can be passed to liquid like Strings Arrays Hashes Numerics and Booleans. To export new objects to liquid just implement .to_liquid on them and return objects which themselves have .to_liquid methods.
13
+
14
+ * Added more tags to standard library
15
+
16
+ * Added include tag ( like partials in rails )
17
+
18
+ * [...] Gazillion of detail improvements
19
+
20
+ * Added strainers as filter hosts for better security [Tobias Luetke]
21
+
22
+ * Fixed that rails integration would call filter with the wrong "self" [Michael Geary]
23
+
24
+ * Fixed bad error reporting when a filter called a method which doesn't exist. Liquid told you that it couldn't find the filter which was obviously misleading [Tobias Luetke]
25
+
26
+ * Removed count helper from standard lib. use size [Tobias Luetke]
27
+
28
+ * Fixed bug with string filter parameters failing to tolerate commas in strings. [Paul Hammond]
29
+
30
+ * Improved filter parameters. Filter parameters are now context sensitive; Types are resolved according to the rules of the context. Multiple parameters are now separated by the Liquid::ArgumentSeparator: , by default [Paul Hammond]
31
+
32
+ {{ 'Typo' | link_to: 'http://typo.leetsoft.com', 'Typo - a modern weblog engine' }}
33
+
34
+
35
+ * Added Liquid::Drop. A base class which you can use for exporting proxy objects to liquid which can acquire more data when used in liquid. [Tobias Luetke]
36
+
37
+ class ProductDrop < Liquid::Drop
38
+ def top_sales
39
+ Shop.current.products.find(:all, :order => 'sales', :limit => 10 )
40
+ end
41
+ end
42
+ t = Liquid::Template.parse( ' {% for product in product.top_sales %} {{ product.name }} {% endfor %} ' )
43
+ t.render('product' => ProductDrop.new )
44
+
45
+
46
+ * Added filter parameters support. Example: {{ date | format_date: "%Y" }} [Paul Hammond]
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in liquor.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,91 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ liquor (0.1.0)
5
+ rails (~> 3.2.0)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ actionmailer (3.2.3)
11
+ actionpack (= 3.2.3)
12
+ mail (~> 2.4.4)
13
+ actionpack (3.2.3)
14
+ activemodel (= 3.2.3)
15
+ activesupport (= 3.2.3)
16
+ builder (~> 3.0.0)
17
+ erubis (~> 2.7.0)
18
+ journey (~> 1.0.1)
19
+ rack (~> 1.4.0)
20
+ rack-cache (~> 1.2)
21
+ rack-test (~> 0.6.1)
22
+ sprockets (~> 2.1.2)
23
+ activemodel (3.2.3)
24
+ activesupport (= 3.2.3)
25
+ builder (~> 3.0.0)
26
+ activerecord (3.2.3)
27
+ activemodel (= 3.2.3)
28
+ activesupport (= 3.2.3)
29
+ arel (~> 3.0.2)
30
+ tzinfo (~> 0.3.29)
31
+ activeresource (3.2.3)
32
+ activemodel (= 3.2.3)
33
+ activesupport (= 3.2.3)
34
+ activesupport (3.2.3)
35
+ i18n (~> 0.6)
36
+ multi_json (~> 1.0)
37
+ arel (3.0.2)
38
+ builder (3.0.0)
39
+ erubis (2.7.0)
40
+ hike (1.2.1)
41
+ i18n (0.6.0)
42
+ journey (1.0.3)
43
+ json (1.7.1)
44
+ mail (2.4.4)
45
+ i18n (>= 0.4.0)
46
+ mime-types (~> 1.16)
47
+ treetop (~> 1.4.8)
48
+ mime-types (1.18)
49
+ multi_json (1.3.4)
50
+ polyglot (0.3.3)
51
+ rack (1.4.1)
52
+ rack-cache (1.2)
53
+ rack (>= 0.4)
54
+ rack-ssl (1.3.2)
55
+ rack
56
+ rack-test (0.6.1)
57
+ rack (>= 1.0)
58
+ rails (3.2.3)
59
+ actionmailer (= 3.2.3)
60
+ actionpack (= 3.2.3)
61
+ activerecord (= 3.2.3)
62
+ activeresource (= 3.2.3)
63
+ activesupport (= 3.2.3)
64
+ bundler (~> 1.0)
65
+ railties (= 3.2.3)
66
+ railties (3.2.3)
67
+ actionpack (= 3.2.3)
68
+ activesupport (= 3.2.3)
69
+ rack-ssl (~> 1.3.2)
70
+ rake (>= 0.8.7)
71
+ rdoc (~> 3.4)
72
+ thor (~> 0.14.6)
73
+ rake (0.9.2.2)
74
+ rdoc (3.12)
75
+ json (~> 1.4)
76
+ sprockets (2.1.3)
77
+ hike (~> 1.2)
78
+ rack (~> 1.0)
79
+ tilt (~> 1.1, != 1.3.0)
80
+ thor (0.14.6)
81
+ tilt (1.3.3)
82
+ treetop (1.4.10)
83
+ polyglot
84
+ polyglot (>= 0.3.1)
85
+ tzinfo (0.3.33)
86
+
87
+ PLATFORMS
88
+ ruby
89
+
90
+ DEPENDENCIES
91
+ liquor!
data/History.txt ADDED
@@ -0,0 +1,44 @@
1
+ 1.9.0 / 2008-03-04
2
+
3
+ * Fixed gem install rake task
4
+ * Improve Error encapsulation in liquid by maintaining a own set of exceptions instead of relying on ruby build ins
5
+
6
+ Before 1.9.0
7
+
8
+ * Added If with or / and expressions
9
+
10
+ * Implemented .to_liquid for all objects which can be passed to liquid like Strings Arrays Hashes Numerics and Booleans. To export new objects to liquid just implement .to_liquid on them and return objects which themselves have .to_liquid methods.
11
+
12
+ * Added more tags to standard library
13
+
14
+ * Added include tag ( like partials in rails )
15
+
16
+ * [...] Gazillion of detail improvements
17
+
18
+ * Added strainers as filter hosts for better security [Tobias Luetke]
19
+
20
+ * Fixed that rails integration would call filter with the wrong "self" [Michael Geary]
21
+
22
+ * Fixed bad error reporting when a filter called a method which doesn't exist. Liquid told you that it couldn't find the filter which was obviously misleading [Tobias Luetke]
23
+
24
+ * Removed count helper from standard lib. use size [Tobias Luetke]
25
+
26
+ * Fixed bug with string filter parameters failing to tolerate commas in strings. [Paul Hammond]
27
+
28
+ * Improved filter parameters. Filter parameters are now context sensitive; Types are resolved according to the rules of the context. Multiple parameters are now separated by the Liquid::ArgumentSeparator: , by default [Paul Hammond]
29
+
30
+ {{ 'Typo' | link_to: 'http://typo.leetsoft.com', 'Typo - a modern weblog engine' }}
31
+
32
+
33
+ * Added Liquid::Drop. A base class which you can use for exporting proxy objects to liquid which can acquire more data when used in liquid. [Tobias Luetke]
34
+
35
+ class ProductDrop < Liquid::Drop
36
+ def top_sales
37
+ Shop.current.products.find(:all, :order => 'sales', :limit => 10 )
38
+ end
39
+ end
40
+ t = Liquid::Template.parse( ' {% for product in product.top_sales %} {{ product.name }} {% endfor %} ' )
41
+ t.render('product' => ProductDrop.new )
42
+
43
+
44
+ * Added filter parameters support. Example: {{ date | format_date: "%Y" }} [Paul Hammond]
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Ivan Evtukhovich
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2005, 2006 Tobias Luetke
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,148 @@
1
+ [https://secure.travis-ci.org/evilmartians/liquor.png](http://travis-ci.org/evilmartians/liquor)
2
+
3
+
4
+ # Liquor template engine
5
+
6
+ Liquor is a safe (not evaling) template language based on Liquid template language. Safe means that templates cannot affect security of the server they are rendered on. So it is usable when you need to give an ability to edit templates to your users (HTML or email).
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'liquor'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install liquor
21
+
22
+ ## What does it look like?
23
+
24
+ ````
25
+ <ul id="products">
26
+ {% for product in products %}
27
+ <li>
28
+ <h2>{{product.name}}</h2>
29
+ Only {{product.price | price }}
30
+
31
+ {{product.description | prettyprint | paragraph }}
32
+ </li>
33
+ {% endfor %}
34
+ </ul>
35
+ ````
36
+
37
+ ## Howto use Liquor
38
+
39
+ Liquid supports a very simple API based around the Liquor::Template class.
40
+ For standard use you can just pass it the content of a file and call render with a parameters hash.
41
+
42
+ ````
43
+ @template = Liquid::Template.parse("hi {{name}}") # Parses and compiles the template
44
+ @template.render( 'name' => '2kan' ) # => "hi 2kan"
45
+ ````
46
+
47
+ ## Differs from Liquid
48
+
49
+ You can find Liquid docs here: http://github.com/tobi/liquid/wiki
50
+
51
+ ### Liquor Drops
52
+ Liquor drops are really powerful now. Now you can define access to methods, named scopes and relations.
53
+
54
+ #### Attributes
55
+ To define attributes you need just add line with with attributes you want to provide access to:
56
+
57
+ ````
58
+ class MyDrop < Liquor::Drop
59
+ self.liquor_attributes << :title << :body
60
+ end
61
+ ````
62
+
63
+ #### Named Scopes
64
+ To define access to named scopes (result automatically will be converted to array of liquor drops):
65
+
66
+ ````
67
+ class MyDrop < Liquor::Drop
68
+ self.liquor_scopes << :recent << :limit << :scoped_to_user
69
+ end
70
+ ````
71
+
72
+ Named scopes works like filters in templates. Don't worry about passing drop objects in templates as params in real calls they will be converted back to objects and then result will be converted to array of drops.
73
+
74
+ #### Relations
75
+
76
+ We have now has_many, has_one and belongs_to relations. You don't need to pass any additional parameters to has_one or belongs_to relations because you just define ability to call real methods (results will be converted to liquid drops).
77
+
78
+ But has_many method a bit more complicated since it defines a special proxy object from which you can call your named_scopes. There are several options for has_many relation:
79
+
80
+ * class_name — A drop class name (ex. PostDrop)
81
+ * sort_scope — Default scope for sorting objects in relations. If you class responds_to recent it will be used as the default one.
82
+ * source_class_name — Class name of the source class (ex. Post)
83
+ * with_scope — this scope always will be used for this relation
84
+
85
+ ### Named Scope
86
+
87
+ Sometimes you need to pass a Named Scope object to a template. Now it is possible. When you assign a NamedScope to a template it assigns as is. But you are not able to execute any methods except array methods and paginate method, the last one was added for for better integration with will_paginate plugin.
88
+
89
+ ### Tags
90
+
91
+ Two new tags were added: content_for and yield.
92
+
93
+ Within the context of a layout, yield identifies a section where content from the view should be inserted.
94
+ The simplest way to use this is to have a single yield, into which the entire contents of the view currently being rendered is inserted.
95
+
96
+ In your layout:
97
+ ````
98
+ <title>{% yield title %}</title>
99
+ <body>{% yield %}</body>
100
+ ````
101
+
102
+ In the view:
103
+ ````
104
+ {% content_for title %} The title {% end_content_for %}
105
+ The body
106
+ ````
107
+
108
+ Will produce:
109
+ ````
110
+ <title>The title</title>
111
+ <body>The body</body>
112
+ ````
113
+
114
+ ### Filters
115
+
116
+ Few filters were added:
117
+
118
+ * yield — yield for content_for tag
119
+ * in_groups_of — splits over the array in groups of size num padding any remaining slots with fill_with unless it is false
120
+ * in_groups — splits or iterates over the array in number of groups, padding any remaining slots with fill_with unless it is false
121
+ * include — returns true if the given object is present in self (that is, if any object == anObject), false otherwise.
122
+ * to_json — return a JSON string representing the model drop (using accepted attributes, methods and named_scopes) to_include is a list of related drops through associations
123
+ * url_escape — escape url
124
+ * reverse — returns a new array containing self’s elements in reverse order.
125
+ * decode_html_entities — decodes html entities
126
+ * split — divides str into substrings based on a delimiter, returning an array of these substrings.
127
+ * compact — returns a copy of self with all nil elements removed.
128
+ * concat — concatenates two arrays
129
+
130
+ ### Expressions
131
+
132
+ You can execute expressions in tags using standard filters syntax but spaces around separator are not allowed.
133
+ This is correct expression:
134
+ {% assign playlist_array = site.playlists|by_name:artist.name %}
135
+
136
+ And this is not:
137
+ {% assign playlist_array = site.playlists | by_name:artist.name %}
138
+
139
+ You can use expressions in other tags for example in for loops:
140
+ {% for artist in site.artists.active.with_orders|scoped_to:genre %}
141
+
142
+ ## Contributing
143
+
144
+ 1. Fork it
145
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
146
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
147
+ 4. Push to the branch (`git push origin my-new-feature`)
148
+ 5. Create new Pull Request
data/README.rdoc ADDED
@@ -0,0 +1,114 @@
1
+ https://secure.travis-ci.org/evilmartians/liquor.png
2
+
3
+ Travis[http://travis-ci.org/evilmartians/liquor]
4
+
5
+ =Liquor template engine
6
+
7
+ Liquor is a safe (not evaling) template language based on Liquid template language. Safe means that templates cannot affect security of the server they are rendered on. So it is usable when you need to give an ability to edit templates to your users (HTML or email).
8
+
9
+ ==What does it look like?
10
+
11
+ <ul id="products">
12
+ {% for product in products %}
13
+ <li>
14
+ <h2>{{product.name}}</h2>
15
+ Only {{product.price | price }}
16
+
17
+ {{product.description | prettyprint | paragraph }}
18
+ </li>
19
+ {% endfor %}
20
+ </ul>
21
+
22
+ ==Howto use Liquor
23
+
24
+ Liquid supports a very simple API based around the Liquor::Template class.
25
+ For standard use you can just pass it the content of a file and call render with a parameters hash.
26
+
27
+ @template = Liquid::Template.parse("hi {{name}}") # Parses and compiles the template
28
+ @template.render( 'name' => '2kan' ) # => "hi 2kan"
29
+
30
+ ==Differs from Liquid
31
+
32
+ You can find Liquid docs here: http://github.com/tobi/liquid/wiki
33
+
34
+ ===Liquor Drops
35
+ Liquor drops are really powerful now. Now you can define access to methods, named scopes and relations.
36
+
37
+ ====Attributes
38
+ To define attributes you need just add line with with attributes you want to provide access to:
39
+
40
+ class MyDrop < Liquor::Drop
41
+ self.liquor_attributes << :title << :body
42
+ end
43
+
44
+ ====Named Scopes
45
+ To define access to named scopes (result automatically will be converted to array of liquor drops):
46
+
47
+ class MyDrop < Liquor::Drop
48
+ self.liquor_scopes << :recent << :limit << :scoped_to_user
49
+ end
50
+
51
+ Named scopes works like filters in templates. Don't worry about passing drop objects in templates as params in real calls they will be converted back to objects and then result will be converted to array of drops.
52
+
53
+ ====Relations
54
+
55
+ We have now has_many, has_one and belongs_to relations. You don't need to pass any additional parameters to has_one or belongs_to relations because you just define ability to call real methods (results will be converted to liquid drops).
56
+
57
+ But has_many method a bit more complicated since it defines a special proxy object from which you can call your named_scopes. There are several options for has_many relation:
58
+
59
+ * class_name — A drop class name (ex. PostDrop)
60
+ * sort_scope — Default scope for sorting objects in relations. If you class responds_to recent it will be used as the default one.
61
+ * source_class_name — Class name of the source class (ex. Post)
62
+ * with_scope — this scope always will be used for this relation
63
+
64
+ ===Named Scope
65
+
66
+ Sometimes you need to pass a Named Scope object to a template. Now it is possible. When you assign a NamedScope to a template it assigns as is. But you are not able to execute any methods except array methods and paginate method, the last one was added for for better integration with will_paginate plugin.
67
+
68
+ ===Tags
69
+
70
+ Two new tags were added: content_for and yield.
71
+
72
+ Within the context of a layout, yield identifies a section where content from the view should be inserted.
73
+ The simplest way to use this is to have a single yield, into which the entire contents of the view currently being rendered is inserted.
74
+
75
+ In your layout:
76
+ <title>{% yield title %}</title>
77
+ <body>{% yield %}</body>
78
+
79
+ In the view:
80
+ {% content_for title %} The title {% end_content_for %}
81
+ The body
82
+
83
+
84
+ Will produce:
85
+ <title>The title</title>
86
+ <body>The body</body>
87
+
88
+ ===Filters
89
+
90
+ Few filters were added:
91
+
92
+ * yield — yield for content_for tag
93
+ * in_groups_of — splits over the array in groups of size num padding any remaining slots with fill_with unless it is false
94
+ * in_groups — splits or iterates over the array in number of groups, padding any remaining slots with fill_with unless it is false
95
+ * include — returns true if the given object is present in self (that is, if any object == anObject), false otherwise.
96
+ * to_json — return a JSON string representing the model drop (using accepted attributes, methods and named_scopes) to_include is a list of related drops through associations
97
+ * url_escape — escape url
98
+ * reverse — returns a new array containing self’s elements in reverse order.
99
+ * decode_html_entities — decodes html entities
100
+ * split — divides str into substrings based on a delimiter, returning an array of these substrings.
101
+ * compact — returns a copy of self with all nil elements removed.
102
+ * concat — concatenates two arrays
103
+
104
+ ===Expressions
105
+
106
+ You can execute expressions in tags using standard filters syntax but spaces around separator are not allowed.
107
+ This is correct expression:
108
+ {% assign playlist_array = site.playlists|by_name:artist.name %}
109
+
110
+ And this is not:
111
+ {% assign playlist_array = site.playlists | by_name:artist.name %}
112
+
113
+ You can use expressions in other tags for example in for loops:
114
+ {% for artist in site.artists.active.with_orders|scoped_to:genre %}