nitro 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ChangeLog +4 -2201
- data/ChangeLog.1 +2344 -0
- data/README +4 -4
- data/RELEASES +22 -0
- data/bin/new_app.rb +17 -3
- data/bin/proto/README +34 -0
- data/bin/proto/apache.conf +1 -0
- data/bin/proto/app.rb +20 -0
- data/bin/proto/config.rb +77 -0
- data/bin/proto/root/index.xhtml +43 -0
- data/bin/proto/root/style.css +218 -0
- data/bin/proto/root/style.xsl +130 -0
- data/examples/blog/app.rb +1 -2
- data/examples/blog/config.rb +20 -18
- data/examples/blog/env.rb +22 -0
- data/examples/blog/lib/blog.rb +43 -15
- data/examples/blog/root/entry_form.xhtml +1 -1
- data/examples/blog/root/index.xhtml +5 -0
- data/examples/blog/root/login.xhtml +2 -0
- data/examples/blog/root/m/nitro.gif +0 -0
- data/examples/blog/root/style.css +83 -0
- data/examples/blog/root/style.xsl +7 -3
- data/examples/og/run.rb +41 -2
- data/examples/tiny/app.rb +1 -2
- data/examples/tiny/root/index.xhtml +8 -2
- data/examples/tiny/root/nitro-small.png +0 -0
- data/lib/glue.rb +1 -1
- data/lib/glue/property.rb +9 -3
- data/lib/nitro/application.rb +18 -1
- data/lib/nitro/builders/form.rb +84 -0
- data/lib/nitro/builders/rss.rb +4 -5
- data/lib/nitro/builders/table.rb +23 -0
- data/lib/nitro/filters.rb +157 -0
- data/lib/nitro/l10n.rb +11 -3
- data/lib/nitro/scaffold.rb +1 -1
- data/lib/nitro/server/render.rb +101 -4
- data/lib/nitro/server/shaders.rb +17 -5
- data/lib/nitro/service.rb +5 -5
- data/lib/nitro/ui/pager.rb +35 -11
- data/lib/nitro/version.rb +2 -2
- data/lib/og.rb +25 -17
- data/lib/og/backend.rb +15 -3
- data/lib/og/backends/mysql.rb +30 -3
- data/lib/og/backends/psql.rb +44 -3
- data/lib/og/meta.rb +117 -10
- data/lib/og/version.rb +1 -1
- data/lib/xsl/base.xsl +75 -6
- data/lib/xsl/ui.xsl +51 -0
- data/test/nitro/ui/tc_pager.rb +6 -0
- metadata +23 -2
@@ -7,7 +7,7 @@ code:
|
|
7
7
|
* George Moschovitis <gm@navel.gr>
|
8
8
|
|
9
9
|
(c) 2004 Navel, all rights reserved.
|
10
|
-
$Id: style.xsl
|
10
|
+
$Id: style.xsl 185 2004-12-10 13:29:09Z gmosx $
|
11
11
|
-->
|
12
12
|
|
13
13
|
<!DOCTYPE shader
|
@@ -26,6 +26,7 @@ $Id: style.xsl 167 2004-11-23 14:03:10Z gmosx $
|
|
26
26
|
exclude-result-prefixes="x xl">
|
27
27
|
|
28
28
|
<xsl:include href="../../lib/xsl/base.xsl" />
|
29
|
+
<xsl:include href="../../lib/xsl/ui.xsl" />
|
29
30
|
|
30
31
|
<xsl:output method="xml" indent="yes" encoding="iso-8859-1" />
|
31
32
|
|
@@ -51,7 +52,7 @@ $Id: style.xsl 167 2004-11-23 14:03:10Z gmosx $
|
|
51
52
|
|
52
53
|
<xsl:template name="x:header">
|
53
54
|
<div id="header">
|
54
|
-
<h1>#$name</h1>
|
55
|
+
<h1><a href="/">#$name</a></h1>
|
55
56
|
</div>
|
56
57
|
</xsl:template>
|
57
58
|
|
@@ -108,7 +109,10 @@ $Id: style.xsl 167 2004-11-23 14:03:10Z gmosx $
|
|
108
109
|
|
109
110
|
<br />
|
110
111
|
<p>
|
111
|
-
|
112
|
+
powered by:<br />
|
113
|
+
<div style="padding: 5px; background: #fff; text-align: center; border: 1px solid #ccc">
|
114
|
+
<a href="http://www.navel.gr/nitro"><img src="m/nitro.gif" style="border: none" /></a>
|
115
|
+
</div>
|
112
116
|
<br />
|
113
117
|
skin from <a href="http://www.blogger.com">Blogger.com</a>
|
114
118
|
</p>
|
data/examples/og/run.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
# * George Moschovitis <gm@navel.gr>
|
7
7
|
#
|
8
8
|
# (c) 2004 Navel, all rights reserved.
|
9
|
-
# $Id: run.rb
|
9
|
+
# $Id: run.rb 185 2004-12-10 13:29:09Z gmosx $
|
10
10
|
|
11
11
|
$:.unshift "../../lib"
|
12
12
|
|
@@ -55,6 +55,7 @@ class User
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
+
|
58
59
|
# = A parent class
|
59
60
|
#
|
60
61
|
class Article
|
@@ -95,6 +96,21 @@ class Article
|
|
95
96
|
end
|
96
97
|
end
|
97
98
|
|
99
|
+
# = A parent class
|
100
|
+
#
|
101
|
+
class Category
|
102
|
+
prop_accessor :title, String
|
103
|
+
prop_accessor :body, String
|
104
|
+
|
105
|
+
# define a 'many to many' relation.
|
106
|
+
many_to_many Article
|
107
|
+
|
108
|
+
def initialize(title = nil)
|
109
|
+
@title = title
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
|
98
114
|
# = Article comment
|
99
115
|
#
|
100
116
|
class ArticleComment < Comment
|
@@ -127,7 +143,6 @@ end
|
|
127
143
|
$log = Logger.new(STDERR);
|
128
144
|
|
129
145
|
# Og configuration.
|
130
|
-
|
131
146
|
config = {
|
132
147
|
:address => "localhost",
|
133
148
|
:database => "test",
|
@@ -249,3 +264,27 @@ part.save!
|
|
249
264
|
|
250
265
|
article.parts.each { |pa| puts pa }
|
251
266
|
|
267
|
+
puts "\n\n"
|
268
|
+
puts '---'
|
269
|
+
|
270
|
+
c1 = Category.new("Category1").save!
|
271
|
+
c2 = Category.new("Category2").save!
|
272
|
+
|
273
|
+
article.add_category(c1)
|
274
|
+
article.add_category(c2)
|
275
|
+
|
276
|
+
puts '---'
|
277
|
+
|
278
|
+
article.categories.each { |c| puts c.title }
|
279
|
+
|
280
|
+
puts '---'
|
281
|
+
|
282
|
+
c2.articles.each { |a| puts a.title }
|
283
|
+
|
284
|
+
article.del_category(c1)
|
285
|
+
|
286
|
+
puts '---'
|
287
|
+
|
288
|
+
article.categories.each { |c| puts c.title }
|
289
|
+
|
290
|
+
|
data/examples/tiny/app.rb
CHANGED
@@ -8,11 +8,10 @@
|
|
8
8
|
# * George Moschovitis <gm@navel.gr>
|
9
9
|
#
|
10
10
|
# (c) 2004 Navel, all rights reserved.
|
11
|
-
# $Id: app.rb
|
11
|
+
# $Id: app.rb 185 2004-12-10 13:29:09Z gmosx $
|
12
12
|
|
13
13
|
$DBG = false
|
14
14
|
|
15
|
-
$LOAD_PATH.unshift "lib"
|
16
15
|
$LOAD_PATH.unshift "../../lib"
|
17
16
|
|
18
17
|
require "config"
|
@@ -15,11 +15,16 @@
|
|
15
15
|
|
16
16
|
<!-- the template comes here -->
|
17
17
|
|
18
|
-
<
|
18
|
+
<p>
|
19
|
+
<img src="nitro-small.png" />
|
20
|
+
</p>
|
21
|
+
|
22
|
+
|
23
|
+
<strong>Hello #{name}</strong>
|
19
24
|
|
20
25
|
<p>
|
21
26
|
<form id="my_form">
|
22
|
-
<
|
27
|
+
<strong>Enter your name:</strong>
|
23
28
|
<input type="text" name="name" />
|
24
29
|
<br />
|
25
30
|
<input type="submit" />
|
@@ -29,4 +34,5 @@
|
|
29
34
|
Counter: #{session[:counter]}
|
30
35
|
</p>
|
31
36
|
|
37
|
+
|
32
38
|
</html>
|
Binary file
|
data/lib/glue.rb
CHANGED
data/lib/glue/property.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# * Elias Karakoulakis <ekarak@ktismata.com>
|
6
6
|
#
|
7
7
|
# (c) 2004 Navel, all rights reserved.
|
8
|
-
# $Id: property.rb
|
8
|
+
# $Id: property.rb 185 2004-12-10 13:29:09Z gmosx $
|
9
9
|
|
10
10
|
require "glue/array"
|
11
11
|
require "glue/hash"
|
@@ -48,6 +48,10 @@ class Property
|
|
48
48
|
def ==(other)
|
49
49
|
return @symbol == other.symbol
|
50
50
|
end
|
51
|
+
|
52
|
+
def to_s
|
53
|
+
return name
|
54
|
+
end
|
51
55
|
end
|
52
56
|
|
53
57
|
end # module
|
@@ -236,6 +240,8 @@ class Module
|
|
236
240
|
}
|
237
241
|
end
|
238
242
|
|
243
|
+
# gmosx: __force_xxx reuses xxx= to allow for easier
|
244
|
+
# overrides.
|
239
245
|
if writer
|
240
246
|
module_eval %{
|
241
247
|
def #{s}=(val)
|
@@ -243,7 +249,7 @@ class Module
|
|
243
249
|
end
|
244
250
|
|
245
251
|
def __force_#{s}(val)
|
246
|
-
|
252
|
+
self.#{s}=(} + case klass.name
|
247
253
|
when Fixnum.name
|
248
254
|
"val.to_i()"
|
249
255
|
when String.name
|
@@ -256,7 +262,7 @@ class Module
|
|
256
262
|
"val.to_i() > 0"
|
257
263
|
else
|
258
264
|
"val"
|
259
|
-
end + %{
|
265
|
+
end + %{)
|
260
266
|
end
|
261
267
|
}
|
262
268
|
end
|
data/lib/nitro/application.rb
CHANGED
@@ -9,7 +9,7 @@
|
|
9
9
|
# Elias Karakoulakis <ekarak@ktismata.com>
|
10
10
|
#
|
11
11
|
# (c) 2004 Navel, all rights reserved.
|
12
|
-
# $Id: application.rb
|
12
|
+
# $Id: application.rb 174 2004-11-26 16:00:21Z gmosx $
|
13
13
|
|
14
14
|
require 'optparse'
|
15
15
|
require 'ostruct'
|
@@ -161,6 +161,7 @@ class Application
|
|
161
161
|
# FIXME: handle logging for daemons.
|
162
162
|
# ???: How does this work !?!?
|
163
163
|
#
|
164
|
+
=begin
|
164
165
|
def daemonize
|
165
166
|
unless @daemonized
|
166
167
|
trap "SIGCLD", "IGNORE"
|
@@ -183,6 +184,22 @@ class Application
|
|
183
184
|
|
184
185
|
return self
|
185
186
|
end
|
187
|
+
=end
|
188
|
+
def daemonize
|
189
|
+
unless @daemonized
|
190
|
+
exit!(0) if fork
|
191
|
+
Process::setsid
|
192
|
+
exit!(0) if fork
|
193
|
+
File::umask(0)
|
194
|
+
[ STDIN, STDOUT, STDERR ].each do |io|
|
195
|
+
io.reopen("/dev/null", "r+")
|
196
|
+
end
|
197
|
+
end
|
198
|
+
@daemonized = true
|
199
|
+
|
200
|
+
return self
|
201
|
+
end
|
202
|
+
|
186
203
|
|
187
204
|
# Returns the pid of the running daemon
|
188
205
|
#
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# code:
|
2
|
+
# * George Moschovitis <gm@navel.gr>
|
3
|
+
#
|
4
|
+
# (c) 2004 Navel, all rights reserved.
|
5
|
+
# $Id: form.rb 187 2004-12-10 13:34:28Z gmosx $
|
6
|
+
|
7
|
+
module N
|
8
|
+
|
9
|
+
# = FormBuilder
|
10
|
+
#
|
11
|
+
class FormBuilder
|
12
|
+
|
13
|
+
@@forms_cache = G::SafeHash.new
|
14
|
+
|
15
|
+
# Render a standard form for the given managed object.
|
16
|
+
# If show_all is false then apply field filtering.
|
17
|
+
#
|
18
|
+
# Example:
|
19
|
+
#
|
20
|
+
# <p>
|
21
|
+
# <form name="test">
|
22
|
+
# #{N::FormBuilder.render(entry)}
|
23
|
+
# </form>
|
24
|
+
# </p>
|
25
|
+
#
|
26
|
+
def self.render(obj, lc = nil, show_all = false)
|
27
|
+
str = '<dl>'
|
28
|
+
|
29
|
+
for p in obj.class.__props
|
30
|
+
unless show_all
|
31
|
+
next if :oid == p.symbol
|
32
|
+
end
|
33
|
+
|
34
|
+
if p.klass.ancestors.include?(Integer) or
|
35
|
+
p.klass.ancestors.include?(Float)
|
36
|
+
str << %{
|
37
|
+
<dt><label for="#{p.name}">#{p.name}</label></dt>
|
38
|
+
<dd>
|
39
|
+
<input type="text" name="#{p.name}" value="#{obj.send(p.symbol)}" />
|
40
|
+
</dd>
|
41
|
+
}
|
42
|
+
elsif p.klass.ancestors.include?(String)
|
43
|
+
str << %{
|
44
|
+
<dt><label for="#{p.name}">#{p.name}</label></dt>
|
45
|
+
<dd>
|
46
|
+
}
|
47
|
+
if :textarea == p.meta[:form]
|
48
|
+
str << %{
|
49
|
+
<textarea name="#{p.name}">#{obj.send(p.symbol)}</textarea>
|
50
|
+
}
|
51
|
+
else
|
52
|
+
str << %{
|
53
|
+
<input type="text" name="#{p.name}" value="#{obj.send(p.symbol)}" />
|
54
|
+
}
|
55
|
+
end
|
56
|
+
str << %{
|
57
|
+
</dd>
|
58
|
+
}
|
59
|
+
elsif p.klass.ancestors.include?(TrueClass)
|
60
|
+
str << %{
|
61
|
+
<dt><label for="#{p.name}">#{p.name}</label></dt>
|
62
|
+
<dd>
|
63
|
+
<input type="checkbox" name="${p.name}" />
|
64
|
+
</dd>
|
65
|
+
}
|
66
|
+
=begin
|
67
|
+
elsif p.klass.ancestors.include?(Time)
|
68
|
+
return %|#\{@#{p.symbol} ? "'#\{Og::Utils.timestamp(@#{p.symbol})\}'" : 'NULL'\}|
|
69
|
+
elsif p.klass.ancestors.include?(Date)
|
70
|
+
return %|#\{@#{p.symbol} ? "'#\{Og::Utils.date(@#{p.symbol})\}'" : 'NULL'\}|
|
71
|
+
else
|
72
|
+
return %|#\{@#{p.symbol} ? "'#\{Og::Utils.escape(@#{p.symbol}.to_yaml)\}'" : "''"\}|
|
73
|
+
=end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
str << '</dl>'
|
78
|
+
|
79
|
+
return str
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end # module
|
data/lib/nitro/builders/rss.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
# * George Moschovitis <gm@navel.gr>
|
3
3
|
#
|
4
4
|
# (c) 2004 Navel, all rights reserved.
|
5
|
-
# $Id$
|
5
|
+
# $Id: rss.rb 185 2004-12-10 13:29:09Z gmosx $
|
6
6
|
|
7
7
|
require 'rss/0.9'
|
8
8
|
|
@@ -15,8 +15,7 @@ module N
|
|
15
15
|
#--
|
16
16
|
# TODO: add more options here, 1.0/2.0 support and more.
|
17
17
|
#++
|
18
|
-
|
19
|
-
include RSS
|
18
|
+
class RssBuilder
|
20
19
|
|
21
20
|
def self.render(objects)
|
22
21
|
channel = RSS::Rss::Channel.new
|
@@ -24,14 +23,14 @@ module RssBuilder
|
|
24
23
|
channel.link = $srv_url
|
25
24
|
|
26
25
|
for obj in objects
|
27
|
-
item = Rss::Channel::Item.new
|
26
|
+
item = RSS::Rss::Channel::Item.new
|
28
27
|
item.title = obj.title if obj.respond_to?(:title)
|
29
28
|
item.description = G::StringUtils.head(obj.body, 256) if obj.respond_to?(:body)
|
30
29
|
item.link = "#$srv_url/#{obj.view_uri}" if obj.respond_to?(:view_uri)
|
31
30
|
channel.items << item
|
32
31
|
end
|
33
32
|
|
34
|
-
rss = Rss.new '0.9'
|
33
|
+
rss = RSS::Rss.new '0.9'
|
35
34
|
rss.channel = channel
|
36
35
|
|
37
36
|
return rss.to_s
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# code:
|
2
|
+
# * George Moschovitis <gm@navel.gr>
|
3
|
+
#
|
4
|
+
# (c) 2004 Navel, all rights reserved.
|
5
|
+
# $Id: table.rb 185 2004-12-10 13:29:09Z gmosx $
|
6
|
+
|
7
|
+
module N
|
8
|
+
|
9
|
+
# = TableBuilder
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# users = User.all
|
14
|
+
# header = ['Username', 'First name', 'Last name', 'Email']
|
15
|
+
# N::TableBuilder.render(users, header)
|
16
|
+
#
|
17
|
+
class TableBuilder
|
18
|
+
end
|
19
|
+
|
20
|
+
end # module
|
21
|
+
|
22
|
+
|
23
|
+
|
@@ -0,0 +1,157 @@
|
|
1
|
+
# code:
|
2
|
+
# * George Moschovitis <gm@navel.gr>
|
3
|
+
#
|
4
|
+
# (c) 2004 Navel, all rights reserved.
|
5
|
+
# $Id: filters.rb 184 2004-12-07 14:42:22Z gmosx $
|
6
|
+
|
7
|
+
module N
|
8
|
+
|
9
|
+
# = Filtering
|
10
|
+
#
|
11
|
+
# Filtering functionality for renders/services. The design
|
12
|
+
# and implementation is HEAVILY influenced by Rails.
|
13
|
+
#
|
14
|
+
# Examples:
|
15
|
+
#
|
16
|
+
# Filter as class:
|
17
|
+
#
|
18
|
+
# class TouchFilter
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# Filter
|
22
|
+
# before
|
23
|
+
# filter
|
24
|
+
# after
|
25
|
+
#
|
26
|
+
# TODO:
|
27
|
+
# implement inheritable filters.
|
28
|
+
#
|
29
|
+
module Filtering
|
30
|
+
|
31
|
+
# Ruby is sometimes VERY surprising, the following trick is needed
|
32
|
+
# to include singleton methods in other classes.
|
33
|
+
#
|
34
|
+
def self.append_features(base)
|
35
|
+
super; base.extend(ClassMethods)
|
36
|
+
end
|
37
|
+
|
38
|
+
module ClassMethods
|
39
|
+
# the filters to be evaluated before the method
|
40
|
+
@@before_filters = []
|
41
|
+
|
42
|
+
# the filters to be evaluated after the method
|
43
|
+
@@after_filters = []
|
44
|
+
|
45
|
+
#
|
46
|
+
#
|
47
|
+
def before_filters
|
48
|
+
@@before_filters
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
#
|
53
|
+
def after_filters
|
54
|
+
@@after_filters
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
#
|
59
|
+
def prepend_before_filter(*filters, &block)
|
60
|
+
filters << block if block_given?
|
61
|
+
@@before_filters = filters + @@before_filters
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
#
|
66
|
+
def append_before_filter(*filters, &block)
|
67
|
+
filters << block if block_given?
|
68
|
+
@@before_filters = @@before_filters + filters
|
69
|
+
end
|
70
|
+
|
71
|
+
# Alias for the most common case.
|
72
|
+
alias :before_filter :prepend_before_filter
|
73
|
+
|
74
|
+
#
|
75
|
+
#
|
76
|
+
def prepend_after_filter(*filters, &block)
|
77
|
+
filters << block if block_given?
|
78
|
+
@@after_filters = filters + @@after_filters
|
79
|
+
end
|
80
|
+
|
81
|
+
#
|
82
|
+
#
|
83
|
+
def append_after_filter(*filters, &block)
|
84
|
+
filters << block if block_given?
|
85
|
+
@@after_filters = @@after_filters + filters
|
86
|
+
end
|
87
|
+
|
88
|
+
# Alias for the most common case.
|
89
|
+
alias :after_filter :append_after_filter
|
90
|
+
|
91
|
+
# Install an arround Filter. A filter is a class that responds
|
92
|
+
# to the before and after methods. Both methods are prepended to
|
93
|
+
# the respective lists.
|
94
|
+
#
|
95
|
+
def prepend_arround_filter(*filters)
|
96
|
+
filters = [filters].flatten
|
97
|
+
|
98
|
+
for filter in filters
|
99
|
+
if filter.respond_to?(:before)
|
100
|
+
prepend_before_filter { |c| filter.before(c) }
|
101
|
+
elsif filter.respond_to?(:filter)
|
102
|
+
# consider 'filter' as synonym of before.
|
103
|
+
prepend_before_filter { |c| filter.filter(c) }
|
104
|
+
end
|
105
|
+
prepend_after_filter { |c| filter.after(c) } if filter.respond_to?(:after)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Install an arround Filter. A filter is a class that responds
|
110
|
+
# to the before and after methods. Both methods are appended to
|
111
|
+
# the respective lists.
|
112
|
+
#
|
113
|
+
def append_arround_filter(*filters)
|
114
|
+
filters = [filters].flatten
|
115
|
+
|
116
|
+
for filter in filters
|
117
|
+
if filter.respond_to?(:before)
|
118
|
+
append_before_filter { |c| filter.before(c) }
|
119
|
+
elsif filter.respond_to?(:filter)
|
120
|
+
# consider 'filter' as synonym of before.
|
121
|
+
append_before_filter { |c| filter.filter(c) }
|
122
|
+
end
|
123
|
+
append_after_filter { |c| filter.after(c) } if filter.respond_to?(:after)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
# Alias for the most common case.
|
128
|
+
alias :filter :append_arround_filter
|
129
|
+
|
130
|
+
#
|
131
|
+
#
|
132
|
+
def gen_filters_call_code(filters)
|
133
|
+
code = ""
|
134
|
+
|
135
|
+
filters.each do |filter|
|
136
|
+
if Symbol === filter
|
137
|
+
code << "if #{filter} == false then return false end;"
|
138
|
+
elsif filter.respond_to?('call') && (filter.arity == 1 || filter.arity == -1)
|
139
|
+
code << 'if filter.call(self) == false then return false end;'
|
140
|
+
elsif filter.is_a?(Module) and filter.instance_methods.size > 0
|
141
|
+
class_eval "include #{filter};"
|
142
|
+
meth = filter.instance_methods[0]
|
143
|
+
code << "if #{meth} == false then return false end;"
|
144
|
+
elsif filter.respond_to?('filter')
|
145
|
+
code << "if #{filter}.filter(self) == false then return false end"
|
146
|
+
else
|
147
|
+
raise 'Valid filters are either a symbol or a proc/method.'
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
return code
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
end
|
156
|
+
|
157
|
+
end # module
|