slim 1.3.4 → 1.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES +7 -0
- data/Gemfile +1 -1
- data/README.md +24 -8
- data/lib/slim/logic_less.rb +1 -1
- data/lib/slim/logic_less/context.rb +119 -0
- data/lib/slim/logic_less/filter.rb +28 -46
- data/lib/slim/version.rb +1 -1
- data/test/logic_less/test_logic_less.rb +157 -14
- metadata +60 -22
- data/lib/slim/logic_less/wrapper.rb +0 -64
- data/test/logic_less/test_wrapper.rb +0 -31
data/CHANGES
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -93,7 +93,7 @@ Indentation matters, but the indentation depth can be chosen as you like. If you
|
|
93
93
|
### Text `|`
|
94
94
|
|
95
95
|
The pipe tells Slim to just copy the line. It essentially escapes any processing.
|
96
|
-
Each following line that is indented greater than the
|
96
|
+
Each following line that is indented greater than the pipe is copied over.
|
97
97
|
|
98
98
|
body
|
99
99
|
p
|
@@ -104,7 +104,7 @@ Each following line that is indented greater than the backtick is copied over.
|
|
104
104
|
|
105
105
|
<body><p>This is a test of the text block.</p></body>
|
106
106
|
|
107
|
-
The left margin is set at the indent of the
|
107
|
+
The left margin is set at the indent of the pipe + one space.
|
108
108
|
Any additional spaces will be copied over.
|
109
109
|
|
110
110
|
body
|
@@ -657,18 +657,34 @@ If the object is an array, the section will iterate
|
|
657
657
|
- articles
|
658
658
|
tr: td = title
|
659
659
|
|
660
|
-
####
|
660
|
+
#### Lambdas
|
661
|
+
|
662
|
+
Like mustache, Slim supports lambdas.
|
663
|
+
|
664
|
+
= person
|
665
|
+
= name
|
666
|
+
|
667
|
+
The lambda method could be defined like this
|
668
|
+
|
669
|
+
def lambda_method
|
670
|
+
"<div class='person'>#{yield(:name => 'Andrew')}</div>"
|
671
|
+
end
|
672
|
+
|
673
|
+
You can optionally pass one or more hashes to `yield`. If you pass multiple hashes, the block will be iterated as described above.
|
674
|
+
|
675
|
+
#### Dictionary access
|
661
676
|
|
662
677
|
Example code:
|
663
678
|
|
664
679
|
- article
|
665
680
|
h1 = title
|
666
681
|
|
667
|
-
|
682
|
+
The dictionary object is accessed in the order given by the `:dictionary_access`. Default order:
|
668
683
|
|
669
|
-
1. If `article.respond_to?(:title)`, Slim will execute `article
|
670
|
-
2. If `article.respond_to?(:has_key?)` and `article.has_key?(
|
671
|
-
3. If `article.
|
684
|
+
1. `:symbol` - If `article.respond_to?(:has_key?)` and `article.has_key?(:title)`, Slim will execute `article[:title]`
|
685
|
+
2. `:string` - If `article.respond_to?(:has_key?)` and `article.has_key?('title')`, Slim will execute `article['title']`
|
686
|
+
3. `:method` - If `article.respond_to?(:title)`, Slim will execute `article.send(:title)`
|
687
|
+
4. `:instance_variable` - If `article.instance_variable_defined?(@title)`, Slim will execute `article.instance_variable_get @title`
|
672
688
|
|
673
689
|
If all the above fails, Slim will try to resolve the title reference in the same order against the parent object. In this example, the parent would be the dictionary object you are rendering the template against.
|
674
690
|
|
@@ -723,7 +739,7 @@ and activate logic less mode per render call in your application
|
|
723
739
|
<tbody>
|
724
740
|
<tr><td>Boolean</td><td>:logic_less</td><td>true</td><td>Enable logic less mode (Enabled if 'slim/logic_less' is required)</td></tr>
|
725
741
|
<tr><td>String</td><td>:dictionary</td><td>"self"</td><td>Dictionary where variables are looked up</td></tr>
|
726
|
-
<tr><td>Symbol</td><td>:dictionary_access</td><td
|
742
|
+
<tr><td>Symbol/Array of Symbols</td><td>:dictionary_access</td><td>[:symbol, :string, :method, :instance_variable]</td><td>Dictionary access order (:symbol, :string, :method, :instance_variable)</td></tr>
|
727
743
|
</tbody>
|
728
744
|
</table>
|
729
745
|
|
data/lib/slim/logic_less.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'slim'
|
2
2
|
require 'slim/logic_less/filter'
|
3
|
-
require 'slim/logic_less/
|
3
|
+
require 'slim/logic_less/context'
|
4
4
|
|
5
5
|
# Insert plugin filter into Slim engine chain
|
6
6
|
Slim::Engine.after(Slim::Interpolation, Slim::LogicLess, :logic_less, :dictionary, :dictionary_access)
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Slim
|
2
|
+
class LogicLess
|
3
|
+
# @api private
|
4
|
+
class Context
|
5
|
+
def initialize(dict, lookup)
|
6
|
+
@scope = [Scope.new(dict, lookup)]
|
7
|
+
end
|
8
|
+
|
9
|
+
def [](name)
|
10
|
+
scope[name]
|
11
|
+
end
|
12
|
+
|
13
|
+
def lambda(name)
|
14
|
+
scope.lambda(name) do |*dict|
|
15
|
+
if dict.empty?
|
16
|
+
yield
|
17
|
+
else
|
18
|
+
new_scope do
|
19
|
+
dict.inject('') do |result, d|
|
20
|
+
scope.dict = d
|
21
|
+
result << yield
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def section(name)
|
29
|
+
if dict = scope[name]
|
30
|
+
if !dict.respond_to?(:has_key?) && dict.respond_to?(:each)
|
31
|
+
new_scope do
|
32
|
+
dict.each do |d|
|
33
|
+
scope.dict = d
|
34
|
+
yield
|
35
|
+
end
|
36
|
+
end
|
37
|
+
else
|
38
|
+
new_scope(dict) { yield }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def inverted_section(name)
|
44
|
+
value = scope[name]
|
45
|
+
yield if !value || (value.respond_to?(:empty?) && value.empty?)
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
class Scope
|
51
|
+
attr_reader :lookup
|
52
|
+
attr_writer :dict
|
53
|
+
|
54
|
+
def initialize(dict, lookup, parent = nil)
|
55
|
+
@dict, @lookup, @parent = dict, lookup, parent
|
56
|
+
end
|
57
|
+
|
58
|
+
def lambda(name, &block)
|
59
|
+
@lookup.each do |lookup|
|
60
|
+
case lookup
|
61
|
+
when :method
|
62
|
+
return @dict.send(name, &block) if @dict.respond_to?(name)
|
63
|
+
when :symbol
|
64
|
+
return @dict[name].call(&block) if has_key?(name)
|
65
|
+
when :string
|
66
|
+
return @dict[name.to_s].call(&block) if has_key?(name.to_s)
|
67
|
+
when :instance_variable
|
68
|
+
var_name = "@#{name}"
|
69
|
+
return @dict.instance_variable_get(var_name).call(&block) if instance_variable?(var_name)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
@parent.lambda(name) if @parent
|
73
|
+
end
|
74
|
+
|
75
|
+
def [](name)
|
76
|
+
@lookup.each do |lookup|
|
77
|
+
case lookup
|
78
|
+
when :method
|
79
|
+
return @dict.send(name) if @dict.respond_to?(name)
|
80
|
+
when :symbol
|
81
|
+
return @dict[name] if has_key?(name)
|
82
|
+
when :string
|
83
|
+
return @dict[name.to_s] if has_key?(name.to_s)
|
84
|
+
when :instance_variable
|
85
|
+
var_name = "@#{name}"
|
86
|
+
return @dict.instance_variable_get(var_name) if instance_variable?(var_name)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
@parent[name] if @parent
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def has_key?(name)
|
95
|
+
@dict.respond_to?(:has_key?) && @dict.has_key?(name)
|
96
|
+
end
|
97
|
+
|
98
|
+
def instance_variable?(name)
|
99
|
+
begin
|
100
|
+
@dict.instance_variable_defined?(name)
|
101
|
+
rescue NameError
|
102
|
+
false
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def scope
|
108
|
+
@scope.last
|
109
|
+
end
|
110
|
+
|
111
|
+
def new_scope(dict = nil)
|
112
|
+
@scope << Scope.new(dict, scope.lookup, scope)
|
113
|
+
yield
|
114
|
+
ensure
|
115
|
+
@scope.pop
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -3,24 +3,34 @@ module Slim
|
|
3
3
|
# This filter can be activated with the option "logic_less"
|
4
4
|
# @api private
|
5
5
|
class LogicLess < Filter
|
6
|
+
# Default dictionary access order, change it with the option :dictionary_access
|
7
|
+
DEFAULT_ACCESS_ORDER = [:symbol, :string, :method, :instance_variable].freeze
|
8
|
+
|
6
9
|
define_options :logic_less => true,
|
7
10
|
:dictionary => 'self',
|
8
|
-
:dictionary_access =>
|
11
|
+
:dictionary_access => DEFAULT_ACCESS_ORDER
|
9
12
|
|
10
13
|
def initialize(opts = {})
|
11
14
|
super
|
12
|
-
|
13
|
-
|
15
|
+
access = options[:dictionary_access]
|
16
|
+
if access == :wrapped
|
17
|
+
puts 'Slim::LogicLess - Wrapped dictionary access is deprecated'
|
18
|
+
access = DEFAULT_ACCESS_ORDER
|
19
|
+
else
|
20
|
+
access = [access].flatten.compact
|
21
|
+
access.each do |type|
|
22
|
+
raise ArgumentError, "Invalid dictionary access #{type.inspect}" unless DEFAULT_ACCESS_ORDER.include?(type)
|
23
|
+
end
|
24
|
+
raise ArgumentError, 'Option dictionary access is missing' if access.empty?
|
14
25
|
end
|
26
|
+
@access = access.inspect
|
15
27
|
end
|
16
28
|
|
17
29
|
def call(exp)
|
18
30
|
if options[:logic_less]
|
19
|
-
@
|
20
|
-
dictionary = options[:dictionary]
|
21
|
-
dictionary = "::Slim::LogicLess::Wrapper.new(#{dictionary})" if options[:dictionary_access] == :wrapped
|
31
|
+
@context = unique_name
|
22
32
|
[:multi,
|
23
|
-
[:code, "#{@
|
33
|
+
[:code, "#{@context} = ::Slim::LogicLess::Context.new(#{options[:dictionary]}, #{@access})"],
|
24
34
|
super]
|
25
35
|
else
|
26
36
|
exp
|
@@ -29,16 +39,19 @@ module Slim
|
|
29
39
|
|
30
40
|
# Interpret control blocks as sections or inverted sections
|
31
41
|
def on_slim_control(name, content)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
42
|
+
method =
|
43
|
+
if name =~ /\A!\s*(.*)/
|
44
|
+
name = $1
|
45
|
+
'inverted_section'
|
46
|
+
else
|
47
|
+
'section'
|
48
|
+
end
|
49
|
+
[:block, "#{@context}.#{method}(#{name.to_sym.inspect}) do", compile(content)]
|
37
50
|
end
|
38
51
|
|
39
52
|
def on_slim_output(escape, name, content)
|
40
|
-
|
41
|
-
|
53
|
+
[:slim, :output, escape, empty_exp?(content) ? access(name) :
|
54
|
+
"#{@context}.lambda(#{name.to_sym.inspect}) do", compile(content)]
|
42
55
|
end
|
43
56
|
|
44
57
|
def on_slim_attrvalue(escape, value)
|
@@ -57,41 +70,10 @@ module Slim
|
|
57
70
|
raise Temple::FilterError, 'Embedded code is forbidden in logic less mode'
|
58
71
|
end
|
59
72
|
|
60
|
-
protected
|
61
|
-
|
62
|
-
def on_slim_inverted_section(name, content)
|
63
|
-
tmp = unique_name
|
64
|
-
[:multi,
|
65
|
-
[:code, "#{tmp} = #{access name}"],
|
66
|
-
[:if, "!#{tmp} || #{tmp}.respond_to?(:empty) && #{tmp}.empty?",
|
67
|
-
compile(content)]]
|
68
|
-
end
|
69
|
-
|
70
|
-
def on_slim_section(name, content)
|
71
|
-
content = compile(content)
|
72
|
-
tmp1, tmp2 = unique_name, unique_name
|
73
|
-
|
74
|
-
[:if, "#{tmp1} = #{access name}",
|
75
|
-
[:if, "#{tmp1} == true",
|
76
|
-
content,
|
77
|
-
[:multi,
|
78
|
-
# Wrap map in array because maps implement each
|
79
|
-
[:code, "#{tmp1} = [#{tmp1}] if #{tmp1}.respond_to?(:has_key?) || !#{tmp1}.respond_to?(:map)"],
|
80
|
-
[:code, "#{tmp2} = #{@dict}"],
|
81
|
-
[:block, "#{tmp1}.each do |#{@dict}|", content],
|
82
|
-
[:code, "#{@dict} = #{tmp2}"]]]]
|
83
|
-
end
|
84
|
-
|
85
73
|
private
|
86
74
|
|
87
75
|
def access(name)
|
88
|
-
|
89
|
-
case options[:dictionary_access]
|
90
|
-
when :string
|
91
|
-
"#{@dict}[#{name.to_s.inspect}]"
|
92
|
-
else
|
93
|
-
"#{@dict}[#{name.to_sym.inspect}]"
|
94
|
-
end
|
76
|
+
name == 'yield' ? name : "#{@context}[#{name.to_sym.inspect}]"
|
95
77
|
end
|
96
78
|
end
|
97
79
|
end
|
data/lib/slim/version.rb
CHANGED
@@ -13,6 +13,70 @@ class TestSlimLogicLess < TestSlim
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
def test_lambda
|
17
|
+
source = %q{
|
18
|
+
p
|
19
|
+
== person
|
20
|
+
.name = name
|
21
|
+
== simple
|
22
|
+
.hello= hello
|
23
|
+
== list
|
24
|
+
li = key
|
25
|
+
}
|
26
|
+
|
27
|
+
hash = {
|
28
|
+
:hello => 'Hello!',
|
29
|
+
:person => lambda do |&block|
|
30
|
+
%w(Joe Jack).map do |name|
|
31
|
+
"<b>#{block.call(:name => name)}</b>"
|
32
|
+
end.join
|
33
|
+
end,
|
34
|
+
:simple => lambda do |&block|
|
35
|
+
"<div class=\"simple\">#{block.call}</div>"
|
36
|
+
end,
|
37
|
+
:list => lambda do |&block|
|
38
|
+
list = [{:key => 'First'}, {:key => 'Second'}]
|
39
|
+
"<ul>#{block.call(*list)}</ul>"
|
40
|
+
end
|
41
|
+
}
|
42
|
+
|
43
|
+
assert_html '<p><b><div class="name">Joe</div></b><b><div class="name">Jack</div></b><div class="simple"><div class="hello">Hello!</div></div><ul><li>First</li><li>Second</li></ul></p>', source, :scope => hash
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_symbol_hash
|
47
|
+
source = %q{
|
48
|
+
p
|
49
|
+
- person
|
50
|
+
.name = name
|
51
|
+
}
|
52
|
+
|
53
|
+
hash = {
|
54
|
+
:person => [
|
55
|
+
{ :name => 'Joe', },
|
56
|
+
{ :name => 'Jack', }
|
57
|
+
]
|
58
|
+
}
|
59
|
+
|
60
|
+
assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_string_access
|
64
|
+
source = %q{
|
65
|
+
p
|
66
|
+
- person
|
67
|
+
.name = name
|
68
|
+
}
|
69
|
+
|
70
|
+
hash = {
|
71
|
+
'person' => [
|
72
|
+
{ 'name' => 'Joe', },
|
73
|
+
{ 'name' => 'Jack', }
|
74
|
+
]
|
75
|
+
}
|
76
|
+
|
77
|
+
assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash, :dictionary_access => :string
|
78
|
+
end
|
79
|
+
|
16
80
|
def test_symbol_access
|
17
81
|
source = %q{
|
18
82
|
p
|
@@ -30,17 +94,46 @@ p
|
|
30
94
|
assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash, :dictionary_access => :symbol
|
31
95
|
end
|
32
96
|
|
33
|
-
def
|
97
|
+
def test_method_access
|
34
98
|
source = %q{
|
35
99
|
p
|
36
100
|
- person
|
37
101
|
.name = name
|
38
102
|
}
|
39
103
|
|
40
|
-
|
104
|
+
object = Object.new
|
105
|
+
def object.person
|
106
|
+
%w(Joe Jack).map do |name|
|
107
|
+
person = Object.new
|
108
|
+
person.instance_variable_set(:@name, name)
|
109
|
+
def person.name
|
110
|
+
@name
|
111
|
+
end
|
112
|
+
person
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => object, :dictionary_access => :method
|
41
117
|
end
|
42
118
|
|
43
|
-
def
|
119
|
+
def test_instance_variable_access
|
120
|
+
source = %q{
|
121
|
+
p
|
122
|
+
- person
|
123
|
+
.name = name
|
124
|
+
}
|
125
|
+
|
126
|
+
object = Object.new
|
127
|
+
object.instance_variable_set(:@person, %w(Joe Jack).map do |name|
|
128
|
+
person = Object.new
|
129
|
+
person.instance_variable_set(:@name, name)
|
130
|
+
person
|
131
|
+
end)
|
132
|
+
|
133
|
+
assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => object, :dictionary_access => :instance_variable
|
134
|
+
end
|
135
|
+
|
136
|
+
def test_string_hash
|
44
137
|
source = %q{
|
45
138
|
p
|
46
139
|
- person
|
@@ -54,7 +147,17 @@ p
|
|
54
147
|
]
|
55
148
|
}
|
56
149
|
|
57
|
-
assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash
|
150
|
+
assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => hash
|
151
|
+
end
|
152
|
+
|
153
|
+
def test_dictionary_option
|
154
|
+
source = %q{
|
155
|
+
p
|
156
|
+
- person
|
157
|
+
.name = name
|
158
|
+
}
|
159
|
+
|
160
|
+
assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :scope => Scope.new, :dictionary => '@hash'
|
58
161
|
end
|
59
162
|
|
60
163
|
def test_flag_section
|
@@ -94,14 +197,6 @@ p
|
|
94
197
|
assert_html '<p>No person No person 2</p>', source, :scope => hash
|
95
198
|
end
|
96
199
|
|
97
|
-
def test_output_with_content
|
98
|
-
source = %{
|
99
|
-
p = method_with_block do
|
100
|
-
block
|
101
|
-
}
|
102
|
-
assert_runtime_error 'Output statements with content are forbidden in logic less mode', source
|
103
|
-
end
|
104
|
-
|
105
200
|
def test_escaped_interpolation
|
106
201
|
source = %q{
|
107
202
|
p text with \#{123} test
|
@@ -120,7 +215,7 @@ p
|
|
120
215
|
Person
|
121
216
|
}
|
122
217
|
|
123
|
-
assert_html '<p><b name="Joe">Person</b><a id="Joe">1</a><span class="Joe"><Person></Person></span><b name="Jack">Person</b><a id="Jack">2</a><span class="Jack"><Person></Person></span></p>', source, :scope => Scope.new, :dictionary => '@hash'
|
218
|
+
assert_html '<p><b name="Joe">Person</b><a id="Joe">1</a><span class="Joe"><Person></Person></span><b name="Jack">Person</b><a id="Jack">2</a><span class="Jack"><Person></Person></span></p>', source, :scope => Scope.new, :dictionary => '@hash'
|
124
219
|
end
|
125
220
|
|
126
221
|
def test_boolean_attributes
|
@@ -130,6 +225,54 @@ p
|
|
130
225
|
input checked=selected = name
|
131
226
|
}
|
132
227
|
|
133
|
-
assert_html '<p><input checked="checked">Joe</input><input>Jack</input></p>', source, :scope => Scope.new, :dictionary => '@hash'
|
228
|
+
assert_html '<p><input checked="checked">Joe</input><input>Jack</input></p>', source, :scope => Scope.new, :dictionary => '@hash'
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_sections
|
232
|
+
source = %q{
|
233
|
+
p
|
234
|
+
- person
|
235
|
+
.name = name
|
236
|
+
}
|
237
|
+
assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :dictionary => 'ViewEnv.new'
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_with_array
|
241
|
+
source = %q{
|
242
|
+
ul
|
243
|
+
- people_with_locations
|
244
|
+
li = name
|
245
|
+
li = city
|
246
|
+
}
|
247
|
+
assert_html '<ul><li>Andy</li><li>Atlanta</li><li>Fred</li><li>Melbourne</li><li>Daniel</li><li>Karlsruhe</li></ul>', source, :dictionary => 'ViewEnv.new'
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_method
|
251
|
+
source = %q{
|
252
|
+
a href=output_number Link
|
253
|
+
}
|
254
|
+
assert_html '<a href="1337">Link</a>', source, :dictionary => 'ViewEnv.new'
|
255
|
+
end
|
256
|
+
|
257
|
+
def test_conditional_parent
|
258
|
+
source = %q{
|
259
|
+
- prev_page
|
260
|
+
li.previous
|
261
|
+
a href=prev_page Older
|
262
|
+
- next_page
|
263
|
+
li.next
|
264
|
+
a href=next_page Newer}
|
265
|
+
assert_html'<li class="previous"><a href="prev">Older</a></li><li class="next"><a href="next">Newer</a></li>', source, :scope => {:prev_page => 'prev', :next_page => 'next'}
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_render_with_yield
|
269
|
+
source = %q{
|
270
|
+
div
|
271
|
+
== yield
|
272
|
+
}
|
273
|
+
|
274
|
+
assert_html '<div>This is the menu</div>', source do
|
275
|
+
'This is the menu'
|
276
|
+
end
|
134
277
|
end
|
135
278
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: slim
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,11 +11,11 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2012-
|
14
|
+
date: 2012-12-19 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: temple
|
18
|
-
requirement:
|
18
|
+
requirement: !ruby/object:Gem::Requirement
|
19
19
|
none: false
|
20
20
|
requirements:
|
21
21
|
- - ~>
|
@@ -23,10 +23,15 @@ dependencies:
|
|
23
23
|
version: 0.5.5
|
24
24
|
type: :runtime
|
25
25
|
prerelease: false
|
26
|
-
version_requirements:
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
none: false
|
28
|
+
requirements:
|
29
|
+
- - ~>
|
30
|
+
- !ruby/object:Gem::Version
|
31
|
+
version: 0.5.5
|
27
32
|
- !ruby/object:Gem::Dependency
|
28
33
|
name: tilt
|
29
|
-
requirement:
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
30
35
|
none: false
|
31
36
|
requirements:
|
32
37
|
- - ~>
|
@@ -34,10 +39,15 @@ dependencies:
|
|
34
39
|
version: 1.3.3
|
35
40
|
type: :runtime
|
36
41
|
prerelease: false
|
37
|
-
version_requirements:
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 1.3.3
|
38
48
|
- !ruby/object:Gem::Dependency
|
39
49
|
name: rake
|
40
|
-
requirement:
|
50
|
+
requirement: !ruby/object:Gem::Requirement
|
41
51
|
none: false
|
42
52
|
requirements:
|
43
53
|
- - ! '>='
|
@@ -45,10 +55,15 @@ dependencies:
|
|
45
55
|
version: 0.8.7
|
46
56
|
type: :development
|
47
57
|
prerelease: false
|
48
|
-
version_requirements:
|
58
|
+
version_requirements: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 0.8.7
|
49
64
|
- !ruby/object:Gem::Dependency
|
50
65
|
name: sass
|
51
|
-
requirement:
|
66
|
+
requirement: !ruby/object:Gem::Requirement
|
52
67
|
none: false
|
53
68
|
requirements:
|
54
69
|
- - ! '>='
|
@@ -56,10 +71,15 @@ dependencies:
|
|
56
71
|
version: 3.1.0
|
57
72
|
type: :development
|
58
73
|
prerelease: false
|
59
|
-
version_requirements:
|
74
|
+
version_requirements: !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ! '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 3.1.0
|
60
80
|
- !ruby/object:Gem::Dependency
|
61
81
|
name: minitest
|
62
|
-
requirement:
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
63
83
|
none: false
|
64
84
|
requirements:
|
65
85
|
- - ! '>='
|
@@ -67,10 +87,15 @@ dependencies:
|
|
67
87
|
version: '0'
|
68
88
|
type: :development
|
69
89
|
prerelease: false
|
70
|
-
version_requirements:
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
71
96
|
- !ruby/object:Gem::Dependency
|
72
97
|
name: kramdown
|
73
|
-
requirement:
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
74
99
|
none: false
|
75
100
|
requirements:
|
76
101
|
- - ! '>='
|
@@ -78,10 +103,15 @@ dependencies:
|
|
78
103
|
version: '0'
|
79
104
|
type: :development
|
80
105
|
prerelease: false
|
81
|
-
version_requirements:
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
none: false
|
108
|
+
requirements:
|
109
|
+
- - ! '>='
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
82
112
|
- !ruby/object:Gem::Dependency
|
83
113
|
name: creole
|
84
|
-
requirement:
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
85
115
|
none: false
|
86
116
|
requirements:
|
87
117
|
- - ! '>='
|
@@ -89,10 +119,15 @@ dependencies:
|
|
89
119
|
version: '0'
|
90
120
|
type: :development
|
91
121
|
prerelease: false
|
92
|
-
version_requirements:
|
122
|
+
version_requirements: !ruby/object:Gem::Requirement
|
123
|
+
none: false
|
124
|
+
requirements:
|
125
|
+
- - ! '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
93
128
|
- !ruby/object:Gem::Dependency
|
94
129
|
name: builder
|
95
|
-
requirement:
|
130
|
+
requirement: !ruby/object:Gem::Requirement
|
96
131
|
none: false
|
97
132
|
requirements:
|
98
133
|
- - ! '>='
|
@@ -100,7 +135,12 @@ dependencies:
|
|
100
135
|
version: '0'
|
101
136
|
type: :development
|
102
137
|
prerelease: false
|
103
|
-
version_requirements:
|
138
|
+
version_requirements: !ruby/object:Gem::Requirement
|
139
|
+
none: false
|
140
|
+
requirements:
|
141
|
+
- - ! '>='
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '0'
|
104
144
|
description: Slim is a template language whose goal is reduce the syntax to the essential
|
105
145
|
parts without becoming cryptic.
|
106
146
|
email:
|
@@ -141,8 +181,8 @@ files:
|
|
141
181
|
- lib/slim/grammar.rb
|
142
182
|
- lib/slim/interpolation.rb
|
143
183
|
- lib/slim/logic_less.rb
|
184
|
+
- lib/slim/logic_less/context.rb
|
144
185
|
- lib/slim/logic_less/filter.rb
|
145
|
-
- lib/slim/logic_less/wrapper.rb
|
146
186
|
- lib/slim/parser.rb
|
147
187
|
- lib/slim/splat_attributes.rb
|
148
188
|
- lib/slim/template.rb
|
@@ -170,7 +210,6 @@ files:
|
|
170
210
|
- test/literate/helper.rb
|
171
211
|
- test/literate/run.rb
|
172
212
|
- test/logic_less/test_logic_less.rb
|
173
|
-
- test/logic_less/test_wrapper.rb
|
174
213
|
- test/rails/Rakefile
|
175
214
|
- test/rails/app/controllers/application_controller.rb
|
176
215
|
- test/rails/app/controllers/parents_controller.rb
|
@@ -232,9 +271,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
232
271
|
version: '0'
|
233
272
|
requirements: []
|
234
273
|
rubyforge_project: slim
|
235
|
-
rubygems_version: 1.8.
|
274
|
+
rubygems_version: 1.8.24
|
236
275
|
signing_key:
|
237
276
|
specification_version: 3
|
238
277
|
summary: Slim is a template language.
|
239
278
|
test_files: []
|
240
|
-
has_rdoc:
|
@@ -1,64 +0,0 @@
|
|
1
|
-
module Slim
|
2
|
-
class LogicLess
|
3
|
-
# For logic less mode, objects can be encased in the Wrapper class.
|
4
|
-
# @api private
|
5
|
-
class Wrapper
|
6
|
-
attr_reader :value, :parent
|
7
|
-
|
8
|
-
def initialize(value, parent = nil)
|
9
|
-
@value, @parent = value, parent
|
10
|
-
end
|
11
|
-
|
12
|
-
# To find the reference, first check for standard method
|
13
|
-
# access by using respond_to?.
|
14
|
-
#
|
15
|
-
# If not found, check to see if the value is a hash and if the
|
16
|
-
# the name is a key on the hash.
|
17
|
-
#
|
18
|
-
# Not a hash, or not a key on the hash, then check to see if there
|
19
|
-
# is an instance variable with the name.
|
20
|
-
#
|
21
|
-
# If the instance variable doesn't exist and there is a parent object,
|
22
|
-
# go through the same steps on the parent object. This is useful when
|
23
|
-
# you are iterating over objects.
|
24
|
-
def [](name)
|
25
|
-
return wrap(value.send(name)) if value.respond_to?(name)
|
26
|
-
if value.respond_to?(:has_key?)
|
27
|
-
return wrap(value[name.to_sym]) if value.has_key?(name.to_sym)
|
28
|
-
return wrap(value[name.to_s]) if value.has_key?(name.to_s)
|
29
|
-
end
|
30
|
-
begin
|
31
|
-
var_name = "@#{name}"
|
32
|
-
return wrap(value.instance_variable_get(var_name)) if value.instance_variable_defined?(var_name)
|
33
|
-
rescue NameError
|
34
|
-
# Do nothing
|
35
|
-
end
|
36
|
-
parent[name] if parent
|
37
|
-
end
|
38
|
-
|
39
|
-
# Empty objects must appear empty for inverted sections
|
40
|
-
def empty?
|
41
|
-
value.respond_to?(:empty) && value.empty?
|
42
|
-
end
|
43
|
-
|
44
|
-
# Used for output
|
45
|
-
def to_s
|
46
|
-
value.to_s
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
def wrap(response)
|
52
|
-
# Primitives are not wrapped
|
53
|
-
if [String, Numeric, TrueClass, FalseClass, NilClass].any? {|primitive| primitive === response }
|
54
|
-
response
|
55
|
-
# Enumerables are mapped with wrapped values (except Hash-like objects)
|
56
|
-
elsif !response.respond_to?(:has_key?) && response.respond_to?(:map)
|
57
|
-
response.map {|v| wrap(v) }
|
58
|
-
else
|
59
|
-
Wrapper.new(response, self)
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'helper'
|
2
|
-
require 'slim/logic_less'
|
3
|
-
|
4
|
-
class TestSlimWrapper < TestSlim
|
5
|
-
def test_sections
|
6
|
-
source = %q{
|
7
|
-
p
|
8
|
-
- person
|
9
|
-
.name = name
|
10
|
-
}
|
11
|
-
assert_html '<p><div class="name">Joe</div><div class="name">Jack</div></p>', source, :dictionary => 'ViewEnv.new'
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_with_array
|
15
|
-
source = %q{
|
16
|
-
ul
|
17
|
-
- people_with_locations
|
18
|
-
li = name
|
19
|
-
li = city
|
20
|
-
}
|
21
|
-
assert_html '<ul><li>Andy</li><li>Atlanta</li><li>Fred</li><li>Melbourne</li><li>Daniel</li><li>Karlsruhe</li></ul>', source, :dictionary => 'ViewEnv.new'
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_method
|
25
|
-
source = %q{
|
26
|
-
a href=output_number Link
|
27
|
-
}
|
28
|
-
assert_html '<a href="1337">Link</a>', source, :dictionary => 'ViewEnv.new'
|
29
|
-
end
|
30
|
-
|
31
|
-
end
|