zwite 1.0.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/README.md +4 -0
- data/bin/zwite +36 -0
- data/lib/zwite/core/app.rb +122 -0
- data/lib/zwite/core/dateformat.rb +339 -0
- data/lib/zwite/core/pagination.rb +100 -0
- data/lib/zwite/core/plugin.rb +50 -0
- data/lib/zwite/core/site.rb +134 -0
- data/lib/zwite/core/utils.rb +41 -0
- data/lib/zwite/ext/class.rb +16 -0
- data/lib/zwite/ext/fixnum.rb +16 -0
- data/lib/zwite/ext/hash.rb +15 -0
- data/lib/zwite/ext/integer.rb +16 -0
- data/lib/zwite/ext/string.rb +19 -0
- data/lib/zwite/ext/time.rb +5 -0
- data/lib/zwite/liquid/block.rb +31 -0
- data/lib/zwite/liquid/ext/date.rb +25 -0
- data/lib/zwite/liquid/ext/template.rb +86 -0
- data/lib/zwite/liquid/extends.rb +40 -0
- data/lib/zwite/liquid/filesystem.rb +35 -0
- data/lib/zwite/models/Template.rb +14 -0
- data/lib/zwite/plugins/appcast.rb +173 -0
- data/lib/zwite/plugins/blog.rb +347 -0
- data/lib/zwite/plugins/compass.rb +58 -0
- data/lib/zwite/plugins/staticfiles.rb +53 -0
- data/lib/zwite.rb +122 -0
- data/zwite.gemspec +54 -0
- metadata +104 -0
data/README.md
ADDED
data/bin/zwite
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env rvm-auto-ruby
|
2
|
+
|
3
|
+
$:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
|
4
|
+
|
5
|
+
help = <<HELP
|
6
|
+
HELP
|
7
|
+
|
8
|
+
require "optparse"
|
9
|
+
require "zwite"
|
10
|
+
|
11
|
+
options = {}
|
12
|
+
opts = OptionParser.new do |opts|
|
13
|
+
opts.banner = help
|
14
|
+
|
15
|
+
opts.on("--server [PORT]", "Start web server (default port 3030)") do |port|
|
16
|
+
options["server"] = true
|
17
|
+
unless port.nil?
|
18
|
+
options["server_port"] = port
|
19
|
+
else
|
20
|
+
options["server_port"] = "3030"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on("--path [PATH]", "Path to project folder") do |path|
|
25
|
+
unless path.nil?
|
26
|
+
options["path"] = File.absolute_path(path)
|
27
|
+
else
|
28
|
+
options["path"] = Dir.pwd
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.parse!
|
35
|
+
|
36
|
+
Zwite::Engine.sharedEngine.run(options)
|
@@ -0,0 +1,122 @@
|
|
1
|
+
module Zwite
|
2
|
+
|
3
|
+
class App
|
4
|
+
|
5
|
+
##
|
6
|
+
# Properties
|
7
|
+
##
|
8
|
+
|
9
|
+
attr_accessor :site
|
10
|
+
attr_accessor :path
|
11
|
+
attr_accessor :url
|
12
|
+
attr_accessor :static_url
|
13
|
+
attr_accessor :name
|
14
|
+
attr_accessor :output_path
|
15
|
+
attr_accessor :plugins
|
16
|
+
attr_accessor :liquid_file_system
|
17
|
+
|
18
|
+
def to_s
|
19
|
+
return "<Zwite::App> name: #{self.name}, mount: #{self.url}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_liquid
|
23
|
+
hash = {
|
24
|
+
"url" => self.url,
|
25
|
+
"static_url" => self.static_url,
|
26
|
+
"name" => self.name
|
27
|
+
}
|
28
|
+
self.plugins.each do |p|
|
29
|
+
hash[p.name] = p
|
30
|
+
end
|
31
|
+
return hash
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Initialization
|
36
|
+
##
|
37
|
+
|
38
|
+
def initialize(site, path, url)
|
39
|
+
self.site = site
|
40
|
+
self.path = path
|
41
|
+
self.url = url
|
42
|
+
self.static_url = self.url + "static/"
|
43
|
+
self.name = self.path.basename.to_s
|
44
|
+
self.output_path = self.site.output_path + self.url[1..self.url.length]
|
45
|
+
self.plugins = []
|
46
|
+
self.site.plugins.each do |p|
|
47
|
+
plugin = p.new(self)
|
48
|
+
if plugin.enabled?
|
49
|
+
self.plugins << plugin
|
50
|
+
end
|
51
|
+
end
|
52
|
+
self.liquid_file_system = Zwite::Liquid::FileSystem.new((self.path + "templates").to_s)
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Actions
|
57
|
+
##
|
58
|
+
|
59
|
+
def hash
|
60
|
+
return self.path.hash
|
61
|
+
end
|
62
|
+
|
63
|
+
def eql?(other)
|
64
|
+
return self.path.eql?(other.path)
|
65
|
+
end
|
66
|
+
|
67
|
+
def preprocess
|
68
|
+
self.plugins.each do |p|
|
69
|
+
p.preprocess
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def generate
|
74
|
+
self.plugins.each do |p|
|
75
|
+
p.generate
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def render(contents, context = {}, path = nil, validate = true)
|
80
|
+
::Liquid::Template.file_system = self.liquid_file_system
|
81
|
+
template = ::Liquid::Template.parse(contents)
|
82
|
+
ctx = self.site.liquid_context
|
83
|
+
ctx = ctx.merge_recursive(context)
|
84
|
+
|
85
|
+
output = template.render(ctx)
|
86
|
+
|
87
|
+
# # nokogiri validate
|
88
|
+
# if validate
|
89
|
+
# n = Nokogiri.parse(output)
|
90
|
+
# if n.errors.any?
|
91
|
+
# message = ["\n"]
|
92
|
+
# unless path.nil?
|
93
|
+
# message << "[VALIDATION ERROR]: #{path}"
|
94
|
+
#
|
95
|
+
# else
|
96
|
+
# message << "[VALIDATION ERROR]"
|
97
|
+
# end
|
98
|
+
# n.errors.each do |error|
|
99
|
+
# message << "\tline: #{error.line} error: #{error}"
|
100
|
+
# end
|
101
|
+
#
|
102
|
+
# message << "\n\n"
|
103
|
+
# raise message.join("\n")
|
104
|
+
#
|
105
|
+
# end
|
106
|
+
# end
|
107
|
+
|
108
|
+
return output
|
109
|
+
end
|
110
|
+
|
111
|
+
def render_file(path, context = {})
|
112
|
+
contents = path.read
|
113
|
+
return render(contents, context, path)
|
114
|
+
end
|
115
|
+
|
116
|
+
def render_template(template, context = {})
|
117
|
+
return render_file((self.path + "templates" + template), context)
|
118
|
+
end
|
119
|
+
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
@@ -0,0 +1,339 @@
|
|
1
|
+
module Zwite
|
2
|
+
|
3
|
+
module DateFormat
|
4
|
+
|
5
|
+
class Formatter < Object
|
6
|
+
|
7
|
+
WEEKDAYS = {
|
8
|
+
0 => "Sunday",
|
9
|
+
1 => "Monday",
|
10
|
+
2 => "Tuesday",
|
11
|
+
3 => "Wednesday",
|
12
|
+
4 => "Thursday",
|
13
|
+
5 => "Friday",
|
14
|
+
6 => "Saturday"
|
15
|
+
}
|
16
|
+
WEEKDAYS_ABBR = {
|
17
|
+
0 => "Sun",
|
18
|
+
1 => "Mon",
|
19
|
+
2 => "Tue",
|
20
|
+
3 => "Wed",
|
21
|
+
4 => "Thu",
|
22
|
+
5 => "Fri",
|
23
|
+
6 => "Sat"
|
24
|
+
}
|
25
|
+
WEEKDAYS_REV = {
|
26
|
+
"sunday" => 0,
|
27
|
+
"monday" => 1,
|
28
|
+
"tuesday" => 2,
|
29
|
+
"wednesday" => 3,
|
30
|
+
"thursday" => 4,
|
31
|
+
"friday" => 5,
|
32
|
+
"saturday" => 6
|
33
|
+
}
|
34
|
+
MONTHS = {
|
35
|
+
1 => "January",
|
36
|
+
2 => "February",
|
37
|
+
3 => "March",
|
38
|
+
4 => "April",
|
39
|
+
5 => "May",
|
40
|
+
6 => "June",
|
41
|
+
7 => "July",
|
42
|
+
8 => "August",
|
43
|
+
9 => "September",
|
44
|
+
10 => "October",
|
45
|
+
11 => "November",
|
46
|
+
12 => "December"
|
47
|
+
}
|
48
|
+
MONTHS_3 = {
|
49
|
+
1 => "Jan",
|
50
|
+
2 => "Feb",
|
51
|
+
3 => "Mar",
|
52
|
+
4 => "Apr",
|
53
|
+
5 => "May",
|
54
|
+
6 => "Jun",
|
55
|
+
7 => "Jul",
|
56
|
+
8 => "Aug",
|
57
|
+
9 => "Sep",
|
58
|
+
10 => "Oct",
|
59
|
+
11 => "Nov",
|
60
|
+
12 => "Dec"
|
61
|
+
}
|
62
|
+
MONTHS_3_REV = {
|
63
|
+
"Jan" => 1,
|
64
|
+
"Feb" => 2,
|
65
|
+
"Mar" => 3,
|
66
|
+
"Apr" => 4,
|
67
|
+
"May" => 5,
|
68
|
+
"Jun" => 6,
|
69
|
+
"Jul" => 7,
|
70
|
+
"Aug" => 8,
|
71
|
+
"Sep" => 9,
|
72
|
+
"Oct" => 10,
|
73
|
+
"Nov" => 11,
|
74
|
+
"Dec" => 12
|
75
|
+
}
|
76
|
+
MONTHS_AP = {
|
77
|
+
1 => "Jan.",
|
78
|
+
2 => "Feb.",
|
79
|
+
3 => "March",
|
80
|
+
4 => "April",
|
81
|
+
5 => "May",
|
82
|
+
6 => "June",
|
83
|
+
7 => "July",
|
84
|
+
8 => "Aug.",
|
85
|
+
9 => "Sept.",
|
86
|
+
10 => "Oct.",
|
87
|
+
11 => "Nov.",
|
88
|
+
12 => "Dec."
|
89
|
+
}
|
90
|
+
|
91
|
+
attr_accessor :data
|
92
|
+
|
93
|
+
def initialize(datetime)
|
94
|
+
self.data = datetime
|
95
|
+
end
|
96
|
+
|
97
|
+
def format(str)
|
98
|
+
pieces = []
|
99
|
+
str.each_char do |c|
|
100
|
+
if Formatter.method_defined?(c)
|
101
|
+
pieces << self.send(c)
|
102
|
+
elsif c
|
103
|
+
pieces << c
|
104
|
+
end
|
105
|
+
end
|
106
|
+
return pieces.join("")
|
107
|
+
end
|
108
|
+
|
109
|
+
# a.m or p.m
|
110
|
+
def a
|
111
|
+
if self.data.hour > 11
|
112
|
+
return "p.m."
|
113
|
+
end
|
114
|
+
return "a.m"
|
115
|
+
end
|
116
|
+
|
117
|
+
# 'AM' or 'PM'.
|
118
|
+
def A
|
119
|
+
if self.data.hour > 11
|
120
|
+
return "PM"
|
121
|
+
end
|
122
|
+
return "AM"
|
123
|
+
end
|
124
|
+
|
125
|
+
# Month, textual, 3 letters, lowercase.
|
126
|
+
def b
|
127
|
+
return MONTHS_3[self.data.month].downcase
|
128
|
+
end
|
129
|
+
|
130
|
+
# Unimplemented
|
131
|
+
def B
|
132
|
+
return "[B]Unimplemented"
|
133
|
+
end
|
134
|
+
|
135
|
+
# ISO 8601 format. (Note: unlike others formatters, such as "Z", "O" or "r", the "c" formatter will not add timezone offset if value is a naive datetime (see datetime.tzinfo).
|
136
|
+
def c
|
137
|
+
return self.data.iso8601
|
138
|
+
end
|
139
|
+
|
140
|
+
# Day of the month, 2 digits with leading zeros.
|
141
|
+
def d
|
142
|
+
return "%02d" % self.data.day
|
143
|
+
end
|
144
|
+
|
145
|
+
# Day of the week, textual, 3 letters.
|
146
|
+
def D
|
147
|
+
return WEEKDAYS_ABBR[self.data.weekday]
|
148
|
+
end
|
149
|
+
|
150
|
+
# Unimplemented
|
151
|
+
def e
|
152
|
+
return "[E]Unimplemented"
|
153
|
+
end
|
154
|
+
|
155
|
+
# Month, locale specific alternative representation usually used for long date representation
|
156
|
+
def E
|
157
|
+
return MONTHS_ALT[self.data.month]
|
158
|
+
end
|
159
|
+
|
160
|
+
# Time, in 12-hour hours and minutes, with minutes left off if they're zero. Proprietary extension.
|
161
|
+
def f
|
162
|
+
if self.data.minute == 0
|
163
|
+
return self.g
|
164
|
+
end
|
165
|
+
return "%s:%s" % self.g, self.i
|
166
|
+
end
|
167
|
+
|
168
|
+
# Month, textual, long.
|
169
|
+
def F
|
170
|
+
return MONTHS[self.data.month]
|
171
|
+
end
|
172
|
+
|
173
|
+
# Hour 12 hour format - without leading zeros
|
174
|
+
def g
|
175
|
+
if self.data.hour == 0
|
176
|
+
return 12
|
177
|
+
end
|
178
|
+
if self.data.hour > 12
|
179
|
+
return self.data.hour - 12
|
180
|
+
end
|
181
|
+
return self.data.hour
|
182
|
+
end
|
183
|
+
|
184
|
+
# Hour 24 hour format - without leading zeros
|
185
|
+
def G
|
186
|
+
return self.data.hour
|
187
|
+
end
|
188
|
+
|
189
|
+
# Hour 12 hour format
|
190
|
+
def h
|
191
|
+
return "%02d" % self.g
|
192
|
+
end
|
193
|
+
|
194
|
+
# Hour 24 hour format
|
195
|
+
def H
|
196
|
+
return "%02d" % self.G
|
197
|
+
end
|
198
|
+
|
199
|
+
# Minutes
|
200
|
+
def i
|
201
|
+
return "%02d" % self.data.minute
|
202
|
+
end
|
203
|
+
|
204
|
+
# Unimplemented
|
205
|
+
def I
|
206
|
+
return "[I]Unimplemented"
|
207
|
+
end
|
208
|
+
|
209
|
+
# Day of the month without leading zeros.
|
210
|
+
def j
|
211
|
+
return self.data.day
|
212
|
+
end
|
213
|
+
|
214
|
+
# Day of the week, textual, long.
|
215
|
+
def l
|
216
|
+
return WEEKDAYS[self.data.wday]
|
217
|
+
end
|
218
|
+
|
219
|
+
# Boolean for whether it's a leap year.
|
220
|
+
def L
|
221
|
+
return self.data.leap?
|
222
|
+
end
|
223
|
+
|
224
|
+
# Month, 2 digits with leading zeros.
|
225
|
+
def m
|
226
|
+
return "%02d" % self.data.month
|
227
|
+
end
|
228
|
+
|
229
|
+
# Month, textual, 3 letters.
|
230
|
+
def M
|
231
|
+
return MONTHS_3[self.data.month]
|
232
|
+
end
|
233
|
+
|
234
|
+
# Month without leading zero
|
235
|
+
def n
|
236
|
+
return self.data.month
|
237
|
+
end
|
238
|
+
|
239
|
+
# Month abbreviation in Associated Press style. Proprietary extension.
|
240
|
+
def N
|
241
|
+
return MONTHS_AP[self.data.month]
|
242
|
+
end
|
243
|
+
|
244
|
+
# ISO-8601 week-numbering year, corresponding to the ISO-8601 week number (W)
|
245
|
+
def o
|
246
|
+
return self.data.strftime("%G")
|
247
|
+
end
|
248
|
+
|
249
|
+
# Difference to Greenwich time in hours.
|
250
|
+
def O
|
251
|
+
return self.data.strftime("%z")
|
252
|
+
end
|
253
|
+
|
254
|
+
# Time, in 12-hour hours, minutes and 'a.m.'/'p.m.', with minutes left off if they're zero and the special-case strings 'midnight' and 'noon' if appropriate. Proprietary extension.
|
255
|
+
def P
|
256
|
+
if self.data.minute == 0 && self.data.hour == 0
|
257
|
+
return "midnight"
|
258
|
+
elsif self.data.minute == 0 and self.data.hour == 12
|
259
|
+
return "noon"
|
260
|
+
end
|
261
|
+
return "%s %s" % self.f, self.a
|
262
|
+
end
|
263
|
+
|
264
|
+
# RFC 2822 formatted date.
|
265
|
+
def r
|
266
|
+
return self.data.rfc2822
|
267
|
+
end
|
268
|
+
|
269
|
+
# Seconds, 2 digits with leading zeros.
|
270
|
+
def s
|
271
|
+
return "%02d" % self.data.second
|
272
|
+
end
|
273
|
+
|
274
|
+
# English ordinal suffix for day of the month, 2 characters.
|
275
|
+
def S
|
276
|
+
if (11..13).include?(self.data.day)
|
277
|
+
return "#{self}th"
|
278
|
+
end
|
279
|
+
last = self.data.day % 10
|
280
|
+
if last == 1
|
281
|
+
return "st"
|
282
|
+
elsif last == 2
|
283
|
+
return "nd"
|
284
|
+
elsif last == 3
|
285
|
+
return "rd"
|
286
|
+
end
|
287
|
+
return "th"
|
288
|
+
end
|
289
|
+
|
290
|
+
# Number of days in the given month
|
291
|
+
def t
|
292
|
+
return (Date.new(self.data.year, 12, 31) << (12 - self.data.month)).day
|
293
|
+
end
|
294
|
+
|
295
|
+
# Timezone of this machine
|
296
|
+
def T
|
297
|
+
return DateTime.now.strftime("%Z")
|
298
|
+
end
|
299
|
+
|
300
|
+
# Microseconds
|
301
|
+
def u
|
302
|
+
return self.data.strftime("%6N").to_i
|
303
|
+
end
|
304
|
+
|
305
|
+
# Seconds since the Unix Epoch (January 1 1970 00:00:00 UTC).
|
306
|
+
def U
|
307
|
+
return self.data.strftime("%s").to_i
|
308
|
+
end
|
309
|
+
|
310
|
+
# ISO-8601 week number of year, weeks starting on Monday
|
311
|
+
def W
|
312
|
+
return self.data.strftime("%-V").to_i
|
313
|
+
end
|
314
|
+
|
315
|
+
# Year 2 digits
|
316
|
+
def y
|
317
|
+
return self.data.year.to_s[2..3]
|
318
|
+
end
|
319
|
+
|
320
|
+
# Year 4 digits
|
321
|
+
def Y
|
322
|
+
return self.data.year
|
323
|
+
end
|
324
|
+
|
325
|
+
# Day of the year
|
326
|
+
def z
|
327
|
+
return self.data.yday - 1
|
328
|
+
end
|
329
|
+
|
330
|
+
# Time zone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive.
|
331
|
+
def Z
|
332
|
+
return self.data.offset.numerator * 60 *60
|
333
|
+
end
|
334
|
+
|
335
|
+
end
|
336
|
+
|
337
|
+
end
|
338
|
+
|
339
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
module Zwite
|
2
|
+
|
3
|
+
module Pagination
|
4
|
+
|
5
|
+
class Page < Object
|
6
|
+
|
7
|
+
##
|
8
|
+
# Properties
|
9
|
+
##
|
10
|
+
|
11
|
+
attr_accessor :paginator
|
12
|
+
attr_accessor :objects
|
13
|
+
attr_accessor :number
|
14
|
+
attr_accessor :has_next
|
15
|
+
attr_accessor :has_prev
|
16
|
+
attr_accessor :has_other_pages
|
17
|
+
attr_accessor :next_page_number
|
18
|
+
attr_accessor :prev_page_number
|
19
|
+
attr_accessor :start_index
|
20
|
+
attr_accessor :end_index
|
21
|
+
|
22
|
+
def to_liquid
|
23
|
+
return {
|
24
|
+
"objects" => self.objects,
|
25
|
+
"number" => self.number,
|
26
|
+
"has_next" => self.has_next,
|
27
|
+
"has_prev" => self.has_prev,
|
28
|
+
"has_other_pages" => self.has_other_pages,
|
29
|
+
"next_page_number" => self.next_page_number,
|
30
|
+
"prev_page_number" => self.prev_page_number,
|
31
|
+
"start_index" => self.start_index,
|
32
|
+
"end_index" => self.end_index
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Initialization
|
38
|
+
##
|
39
|
+
def initialize(paginator, objects, number)
|
40
|
+
self.paginator = paginator
|
41
|
+
self.objects = objects
|
42
|
+
self.number = number
|
43
|
+
|
44
|
+
self.has_next = (self.number < self.paginator.pages_count)
|
45
|
+
self.has_prev = (self.number > 1)
|
46
|
+
self.has_other_pages = (self.has_next || self.has_prev)
|
47
|
+
self.next_page_number = self.number + 1
|
48
|
+
self.prev_page_number = self.number - 1
|
49
|
+
self.start_index = (self.paginator.pages_count == 0) ? 0 : (self.paginator.per_page * (self.number - 1)) + 1
|
50
|
+
self.end_index = (self.paginator.pages_count == self.number) ? self.paginator.pages_count : self.number * self.paginator.per_page
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
class Paginator < Object
|
57
|
+
|
58
|
+
##
|
59
|
+
# Properties
|
60
|
+
##
|
61
|
+
|
62
|
+
attr_accessor :objects
|
63
|
+
attr_accessor :per_page
|
64
|
+
attr_accessor :pages
|
65
|
+
attr_accessor :pages_count
|
66
|
+
|
67
|
+
def to_liquid
|
68
|
+
return {
|
69
|
+
"objects" => self.objects,
|
70
|
+
"per_page" => self.per_page,
|
71
|
+
"pages" => self.pages,
|
72
|
+
"pages_count" => self.pages_count
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
##
|
77
|
+
# Initialization
|
78
|
+
##
|
79
|
+
def initialize(objects, per_page)
|
80
|
+
self.objects = objects
|
81
|
+
self.per_page = per_page
|
82
|
+
|
83
|
+
self.pages = []
|
84
|
+
unless objects.count == 0
|
85
|
+
self.pages_count = (self.objects.count / self.per_page.to_f).ceil
|
86
|
+
self.pages_count.times do |i|
|
87
|
+
page_start = self.per_page * i
|
88
|
+
page_objects = self.objects[page_start..page_start + self.per_page - 1]
|
89
|
+
page = Page.new(self, page_objects, i + 1)
|
90
|
+
self.pages << page
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Zwite
|
2
|
+
|
3
|
+
class Plugin
|
4
|
+
|
5
|
+
##
|
6
|
+
# properties
|
7
|
+
##
|
8
|
+
|
9
|
+
attr_accessor :app
|
10
|
+
attr_reader :name
|
11
|
+
attr_reader :enabled
|
12
|
+
|
13
|
+
def enabled?
|
14
|
+
return (self.app.path + self.name).exist?
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# class methods
|
19
|
+
##
|
20
|
+
|
21
|
+
def self.inherited(base_class)
|
22
|
+
self.subclasses << base_class
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.subclasses
|
26
|
+
@subclasses ||= []
|
27
|
+
return @subclasses
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# initialization
|
32
|
+
##
|
33
|
+
|
34
|
+
def initialize(app)
|
35
|
+
self.app = app
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# actions
|
40
|
+
##
|
41
|
+
|
42
|
+
def preprocess
|
43
|
+
end
|
44
|
+
|
45
|
+
def generate
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|