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 ADDED
@@ -0,0 +1,4 @@
1
+ # Introducing Zwite
2
+ ### the static site generator
3
+
4
+ Zwite is a static site generator that is -very- pluggable built in ruby. It is very pluggable and works with apps/plugins instead of one monolithic site.
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