glinda 0.1.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/.document +5 -0
- data/.rspec +2 -0
- data/Gemfile +16 -0
- data/Gemfile.lock +71 -0
- data/Glinda.gemspec +91 -0
- data/LICENSE +20 -0
- data/README.md +166 -0
- data/Rakefile +31 -0
- data/VERSION +1 -0
- data/lib/ext/ext.rb +52 -0
- data/lib/glinda.rb +358 -0
- data/spec/articles/1900-05-17-the-wonderful-wizard-of-oz.txt +5 -0
- data/spec/articles/2001-01-01-two-thousand-and-one.txt +5 -0
- data/spec/articles/2009-04-01-tilt-factor.txt +5 -0
- data/spec/articles/2009-12-04-some-random-article.txt +5 -0
- data/spec/articles/2009-12-11-the-dichotomy-of-design.txt +5 -0
- data/spec/glinda_spec.rb +466 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/templates/about.rhtml +1 -0
- data/spec/templates/archives.rhtml +5 -0
- data/spec/templates/article.rhtml +4 -0
- data/spec/templates/feed.builder +21 -0
- data/spec/templates/index.builder +21 -0
- data/spec/templates/index.rhtml +13 -0
- data/spec/templates/layout.rhtml +4 -0
- data/spec/templates/repo.rhtml +1 -0
- metadata +235 -0
data/spec/glinda_spec.rb
ADDED
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'date'
|
|
3
|
+
|
|
4
|
+
URL = "http://toto.oz"
|
|
5
|
+
AUTHOR = "Glinda"
|
|
6
|
+
|
|
7
|
+
include Capybara::DSL
|
|
8
|
+
include Capybara::RSpecMatchers
|
|
9
|
+
|
|
10
|
+
describe Glinda do
|
|
11
|
+
before(:each) do
|
|
12
|
+
@config = Glinda::Config.new(:markdown => true, :author => AUTHOR, :url => URL)
|
|
13
|
+
@glinda = Rack::MockRequest.new(Glinda::Server.new(@config))
|
|
14
|
+
Glinda::Paths[:articles] = "spec/articles"
|
|
15
|
+
Glinda::Paths[:pages] = "spec/templates"
|
|
16
|
+
Glinda::Paths[:templates] = "spec/templates"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
describe "GET /" do
|
|
20
|
+
let(:response) { @glinda.get('/') }
|
|
21
|
+
|
|
22
|
+
it "should return status code 200" do
|
|
23
|
+
response.status.should == 200
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should not have an empty body" do
|
|
27
|
+
response.body.should_not be_empty
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it "should set the content-type" do
|
|
31
|
+
response.content_type.should == "text/html"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it "should include 2 articles" do
|
|
35
|
+
visit '/'
|
|
36
|
+
page.all('#articles li').count.should == 3
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it "should include an archive" do
|
|
40
|
+
visit '/'
|
|
41
|
+
page.all('#archives li').count.should == 2
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "with no articles" do
|
|
45
|
+
let(:response) { Rack::MockRequest.new(Glinda::Server.new(@config.merge(:ext => 'oxo'))).get('/') }
|
|
46
|
+
|
|
47
|
+
it "should return status code 200" do
|
|
48
|
+
response.status.should == 200
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should not have an empty body" do
|
|
52
|
+
response.body.should_not be_empty
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context "with a user-defined to_html" do
|
|
57
|
+
let(:response) do
|
|
58
|
+
@config[:to_html] = lambda do |path, page, binding|
|
|
59
|
+
ERB.new(File.read("#{path}/#{page}.rhtml")).result(binding)
|
|
60
|
+
end
|
|
61
|
+
@glinda.get('/')
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should return status code 200" do
|
|
65
|
+
response.status.should == 200
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "should not have an empty body" do
|
|
69
|
+
response.body.should_not be_empty
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "should set the content-type" do
|
|
73
|
+
response.content_type.should == "text/html"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
it "should include 2 articles" do
|
|
77
|
+
visit '/'
|
|
78
|
+
page.all('#articles li').count.should == 3
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
it "should include an archive" do
|
|
82
|
+
visit '/'
|
|
83
|
+
page.all('#archives li').count.should == 2
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "should set Etag header" do
|
|
87
|
+
response.headers.should include "ETag"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it "should set the ETag value" do
|
|
91
|
+
response.headers["ETag"].should_not be_empty
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
context "GET /about" do
|
|
97
|
+
let(:response) { @glinda.get('/about') }
|
|
98
|
+
it "should return status code 200" do
|
|
99
|
+
response.status.should == 200
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "should not have an empty body" do
|
|
103
|
+
response.body.should_not be_empty
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "should set the content-type" do
|
|
107
|
+
response.content_type.should == "text/html"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
it "should have access to @articles" do
|
|
111
|
+
visit '/about'
|
|
112
|
+
page.find('#count').should have_content '5'
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
context "GET a single article" do
|
|
117
|
+
let(:response) { @glinda.get("/1900/05/17/the-wonderful-wizard-of-oz") }
|
|
118
|
+
|
|
119
|
+
it "should return status code 200" do
|
|
120
|
+
response.status.should == 200
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
it "should include the article" do
|
|
124
|
+
visit '/1900/05/17/the-wonderful-wizard-of-oz'
|
|
125
|
+
page.should have_content "Once upon a time"
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
it "should set the content-type" do
|
|
130
|
+
response.content_type.should == "text/html"
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
context "GET to the archive" do
|
|
135
|
+
context "through a year" do
|
|
136
|
+
before(:each) { visit '/2009' }
|
|
137
|
+
|
|
138
|
+
it "should return a 200" do
|
|
139
|
+
page.status_code.should == 200
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it "should return the articles for that year" do
|
|
143
|
+
page.all('li.entry').count.should == 3
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
context "through a year & month" do
|
|
148
|
+
before(:each) { visit '/2009/12' }
|
|
149
|
+
|
|
150
|
+
it "should return a 200" do
|
|
151
|
+
page.status_code.should == 200
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it "should return the articles for that year" do
|
|
155
|
+
page.all('li.entry').count.should == 2
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "should include the year and month" do
|
|
159
|
+
page.find("h1").should have_content("2009/12")
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
context "GET to an unknown route with a custom error" do
|
|
165
|
+
before(:each) do
|
|
166
|
+
@config[:error] = lambda {|code| "error: #{code}" }
|
|
167
|
+
Capybara.app = Glinda::Server.new(@config)
|
|
168
|
+
visit('/unknown')
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "should return a 404" do
|
|
172
|
+
page.status_code.should == 404
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it "should display the custom error" do
|
|
176
|
+
page.should have_content "error: 404"
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
context "Request is invalid" do
|
|
181
|
+
let(:response) { @glinda.delete('/invalid') }
|
|
182
|
+
it "should return status code 400" do
|
|
183
|
+
response.status.should == 400
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
context "GET /index.xml (atom feed)" do
|
|
188
|
+
before(:each) do
|
|
189
|
+
visit '/index.xml'
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
it "should set content-type" do
|
|
193
|
+
page.response_headers['content-type'].should == 'application/xml'
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it "be valid xml" do
|
|
197
|
+
page.all('feed entry').count.should > 0
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
it "should show a summary" do
|
|
201
|
+
page.should have_css 'feed entry summary'
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
context "GET /index?param=testparam (get parameter)" do
|
|
206
|
+
before :each do
|
|
207
|
+
visit 'index?param=testparam'
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
it "should return status code 200" do
|
|
211
|
+
page.status_code.should == 200
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
it "set content-type properly" do
|
|
215
|
+
page.response_headers['content-type'].should == 'text/html'
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
it "contain the env variable" do
|
|
219
|
+
page.should have_content 'env passed: true'
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
it "be able to access the HTTP GET Param" do
|
|
223
|
+
page.should have_content 'request method type: GET'
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
it "should access the http paramiter name value pair" do
|
|
227
|
+
page.should have_content 'request name value pair: param=testparam'
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
context "GET to a repo name" do
|
|
234
|
+
before(:all) do
|
|
235
|
+
class Glinda::Repo
|
|
236
|
+
def readme() "#{self[:name]}'s README" end
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
context "when the repo is in the :repos array" do
|
|
241
|
+
before(:each) do
|
|
242
|
+
@config[:github] = {:user => "cloudhead", :repos => ['the-repo']}
|
|
243
|
+
Capybara.app = Glinda::Server.new(@config)
|
|
244
|
+
visit '/the-repo'
|
|
245
|
+
end
|
|
246
|
+
it "should return the repo README" do
|
|
247
|
+
page.should have_content "the-repo's README"
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
context "when the repo is not in the :repos array" do
|
|
252
|
+
before :each do
|
|
253
|
+
@config[:github] = {:user => "cloudhead", :repos => []}
|
|
254
|
+
Capybara.app = Glinda::Server.new(@config)
|
|
255
|
+
visit '/the-repo'
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
it "should return a 404" do
|
|
259
|
+
page.status_code.should == 404
|
|
260
|
+
end
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
context "creating an article" do
|
|
265
|
+
before(:each) do
|
|
266
|
+
@config[:markdown] = true
|
|
267
|
+
@config[:date] = lambda {|t| "the time is #{t.strftime("%Y/%m/%d %H:%M")}" }
|
|
268
|
+
@config[:summary] = {:length => 50}
|
|
269
|
+
Capybara.app = Glinda::Server.new(@config)
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
context "with the bare essentials" do
|
|
273
|
+
|
|
274
|
+
let(:article) { Glinda::Article.new({ title: "Glinda & The Wizard of Oz.", body: "#Chapter I\nHello, *stranger*." }, @config) }
|
|
275
|
+
|
|
276
|
+
it { article.title.should == "Glinda & The Wizard of Oz." }
|
|
277
|
+
it "should parse the body as markdown" do
|
|
278
|
+
article.body.should == "<h1>Chapter I</h1>\n\n<p>Hello, <em>stranger</em>.</p>\n"
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
it "should create the appropriate slug" do
|
|
282
|
+
article.slug.should == "glinda-and-the-wizard-of-oz"
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
it "should set the date" do
|
|
286
|
+
article.date.should == "the time is #{Date.today.strftime("%Y/%m/%d %H:%M")}"
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
it "should create a summary" do
|
|
290
|
+
article.summary.should == article.body
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
it "should have an author" do
|
|
294
|
+
article.author.should == AUTHOR
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
it "should have a path" do
|
|
298
|
+
article.path.should == Date.today.strftime("/%Y/%m/%d/glinda-and-the-wizard-of-oz/")
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
it "should have a URL" do
|
|
302
|
+
article.url.should == Date.today.strftime("#{URL}/%Y/%m/%d/glinda-and-the-wizard-of-oz/")
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
context "with a user-defined summary" do
|
|
307
|
+
let(:article) do
|
|
308
|
+
Glinda::Article.new({
|
|
309
|
+
:title => "Glinda & The Wizard of Oz.",
|
|
310
|
+
:body => "Well,\nhello ~\n, *stranger*."
|
|
311
|
+
}, @config.merge(:markdown => false, :summary => {:max => 150, :delim => /~\n/}))
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
it "should split the article at the delmiter" do
|
|
315
|
+
article.summary.should == "Well,\nhello"
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
it "should not have the delimiter in the body" do
|
|
319
|
+
article.body. !~ /~/
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
context "with everything specified" do
|
|
324
|
+
let(:article) do
|
|
325
|
+
Glinda::Article.new({
|
|
326
|
+
:title => "The Wizard of Oz",
|
|
327
|
+
:body => ("a little bit of text." * 5) + "\n" + "filler" * 10,
|
|
328
|
+
:date => "19/10/1976",
|
|
329
|
+
:slug => "wizard-of-oz",
|
|
330
|
+
:author => "toetoe"
|
|
331
|
+
}, @config)
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
it "should parse the date" do
|
|
335
|
+
article[:date].month.should == 10
|
|
336
|
+
article[:date].year.should == 1976
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
it "should use the slug" do
|
|
340
|
+
article.slug.should == "wizard-of-oz"
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
it "should use the author" do
|
|
344
|
+
article.author.should == "toetoe"
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
context "and long first paragraph" do
|
|
349
|
+
it "should create a valid summary" do
|
|
350
|
+
article.summary.should == "<p>" + ("a little bit of text." * 5).chop + "…</p>\n"
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
context "and a short first paragraph" do
|
|
355
|
+
let(:article) do
|
|
356
|
+
@config[:markdown] = false
|
|
357
|
+
Glinda::Article.new({:body => "there ain't such thing as a free lunch\n" * 10}, @config)
|
|
358
|
+
end
|
|
359
|
+
|
|
360
|
+
it "should create a valid summary" do
|
|
361
|
+
article.summary.size.should <= 80
|
|
362
|
+
article.summary.size.should >= 75
|
|
363
|
+
end
|
|
364
|
+
end
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
context "in a subdirectory" do
|
|
368
|
+
context "with implicit leading forward slash" do
|
|
369
|
+
let(:article) do
|
|
370
|
+
conf = Glinda::Config.new({})
|
|
371
|
+
conf.set(:prefix, "blog")
|
|
372
|
+
Glinda::Article.new({
|
|
373
|
+
:title => "Glinda & The Wizard of Oz.",
|
|
374
|
+
:body => "#Chapter I\nhello, *stranger*."
|
|
375
|
+
}, conf)
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
it "should be in the directory" do
|
|
379
|
+
article.path.should == Date.today.strftime("/blog/%Y/%m/%d/glinda-and-the-wizard-of-oz/")
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
context "with explicit leading forward slash" do
|
|
385
|
+
let(:article) do
|
|
386
|
+
conf = Glinda::Config.new({})
|
|
387
|
+
conf.set(:prefix, "/blog")
|
|
388
|
+
Glinda::Article.new({
|
|
389
|
+
:title => "Glinda & The Wizard of Oz.",
|
|
390
|
+
:body => "#Chapter I\nhello, *stranger*."
|
|
391
|
+
}, conf)
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
it "should be in the directory do" do
|
|
395
|
+
article.path.should == Date.today.strftime("/blog/%Y/%m/%d/glinda-and-the-wizard-of-oz/")
|
|
396
|
+
end
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
context "with explicit trailing forward slash" do
|
|
400
|
+
let(:article) do
|
|
401
|
+
conf = Glinda::Config.new({})
|
|
402
|
+
conf.set(:prefix, "blog/")
|
|
403
|
+
Glinda::Article.new({
|
|
404
|
+
:title => "Glinda & The Wizard of Oz.",
|
|
405
|
+
:body => "#Chapter I\nhello, *stranger*."
|
|
406
|
+
}, conf)
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
it "should be in the directory do" do
|
|
410
|
+
article.path.should == Date.today.strftime("/blog/%Y/%m/%d/glinda-and-the-wizard-of-oz/")
|
|
411
|
+
end
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
context "using Config#set with a hash" do
|
|
417
|
+
let(:conf) do
|
|
418
|
+
conf = Glinda::Config.new({})
|
|
419
|
+
conf.set(:summary, {:delim => /%/})
|
|
420
|
+
conf
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
it "should set summary delim to /%/" do
|
|
424
|
+
conf[:summary][:delim].source.should == "%"
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
it "should leave :max intact" do
|
|
428
|
+
conf[:summary][:max].should == 150
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
context "using Config#set with a block" do
|
|
433
|
+
let(:conf) do
|
|
434
|
+
conf = Glinda::Config.new({})
|
|
435
|
+
conf.set(:to_html) {|path, p, _| path + p }
|
|
436
|
+
conf
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
subject { conf[:to_html] }
|
|
440
|
+
|
|
441
|
+
it { should respond_to :call }
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
context "testing individual configuration parameters" do
|
|
445
|
+
context "generate error pages" do
|
|
446
|
+
let(:conf) do
|
|
447
|
+
conf = Glinda::Config.new({})
|
|
448
|
+
conf.set(:error) {|code| "error code #{code}" }
|
|
449
|
+
conf
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
it "should create an error" do
|
|
453
|
+
conf[:error].call(400).should == "error code 400"
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
end
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
context "extensions to the core Ruby library" do
|
|
460
|
+
it "should respond to iso8601" do
|
|
461
|
+
Date.today.should respond_to :iso8601
|
|
462
|
+
end
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<span id="count"><%= @articles.length %></span>
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
xml.instruct!
|
|
2
|
+
xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
|
|
3
|
+
xml.title @config[:title]
|
|
4
|
+
xml.id @config[:url]
|
|
5
|
+
xml.updated articles.first[:date].iso8601 unless articles.empty?
|
|
6
|
+
xml.author { xml.name @config[:author] }
|
|
7
|
+
|
|
8
|
+
articles.each do |article|
|
|
9
|
+
xml.entry do
|
|
10
|
+
xml.title article.title
|
|
11
|
+
xml.link "rel" => "alternate", "href" => article.url
|
|
12
|
+
xml.id article.url
|
|
13
|
+
xml.published article[:date].iso8601
|
|
14
|
+
xml.updated article[:date].iso8601
|
|
15
|
+
xml.author { xml.name @config[:author] }
|
|
16
|
+
xml.summary article.summary, "type" => "html"
|
|
17
|
+
xml.content article.body, "type" => "html"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
xml.instruct!
|
|
2
|
+
xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do
|
|
3
|
+
xml.title @config[:title]
|
|
4
|
+
xml.id @config[:url]
|
|
5
|
+
xml.updated articles.first[:date].iso8601 unless articles.empty?
|
|
6
|
+
xml.author { xml.name @config[:author] }
|
|
7
|
+
|
|
8
|
+
articles.each do |article|
|
|
9
|
+
xml.entry do
|
|
10
|
+
xml.title article.title
|
|
11
|
+
xml.link "rel" => "alternate", "href" => article.url
|
|
12
|
+
xml.id article.url
|
|
13
|
+
xml.published article[:date].iso8601
|
|
14
|
+
xml.updated article[:date].iso8601
|
|
15
|
+
xml.author { xml.name @config[:author] }
|
|
16
|
+
xml.summary article.summary, "type" => "html"
|
|
17
|
+
xml.content article.body, "type" => "html"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<ul id="articles">
|
|
2
|
+
<% for article in articles[0...3] %>
|
|
3
|
+
<li><%= article %></li>
|
|
4
|
+
<% end %>
|
|
5
|
+
</ul>
|
|
6
|
+
<div id="archives">
|
|
7
|
+
<%= archives[3...5] %>
|
|
8
|
+
</div>
|
|
9
|
+
<!-- testing env variable passing -->
|
|
10
|
+
<p>env passed: <%= env != nil %><br/></p>
|
|
11
|
+
<!-- testing get/post parameter passing -->
|
|
12
|
+
<p>request method type: <%= env['REQUEST_METHOD'] %><br/></p>
|
|
13
|
+
<p>request name value pair: <%= env['QUERY_STRING'] %><br/></p>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<%= readme %>
|