ceilingfish-toto 0.4.0 → 0.4.2
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 +16 -1
- data/Rakefile +0 -1
- data/VERSION +1 -1
- data/lib/toto.rb +32 -30
- data/test/toto_test.rb +55 -30
- metadata +2 -3
- data/ceilingfish-toto.gemspec +0 -79
data/README.md
CHANGED
|
@@ -6,7 +6,7 @@ the tiniest blogging engine in Oz!
|
|
|
6
6
|
introduction
|
|
7
7
|
------------
|
|
8
8
|
|
|
9
|
-
toto is a git-powered, minimalist blog engine for the hackers of Oz. The engine
|
|
9
|
+
toto is a git-powered, minimalist blog engine for the hackers of Oz. The engine weighs around ~300 sloc at its worse.
|
|
10
10
|
There is no toto client, at least for now; everything goes through git.
|
|
11
11
|
|
|
12
12
|
blog in 10 seconds
|
|
@@ -29,6 +29,18 @@ This makes it an ideal candidate for [heroku](http://heroku.com).
|
|
|
29
29
|
|
|
30
30
|
Oh, and everything that can be done with git, _is_.
|
|
31
31
|
|
|
32
|
+
ceilingfish extensions
|
|
33
|
+
----------------------
|
|
34
|
+
|
|
35
|
+
The ceilingfish fork of toto attempts to add a set of useful helpers to the core toto engine. Specifically it provides the following functions to all pages:
|
|
36
|
+
|
|
37
|
+
- an `import` function to allow layouts to be pared down into more manageable chunks
|
|
38
|
+
- an `archives` function to allow access to a historical list of articles
|
|
39
|
+
- a `title` function to return the title of the current page
|
|
40
|
+
- a `root` function to get a link to the base url
|
|
41
|
+
|
|
42
|
+
Most of these were in there in some form or other, they've just been moved around to ensure they're available for every page.
|
|
43
|
+
|
|
32
44
|
how it works
|
|
33
45
|
------------
|
|
34
46
|
|
|
@@ -142,6 +154,9 @@ you could add `set :author, 'John Galt'` inside the `Toto::Server.new` block. He
|
|
|
142
154
|
set :summary, :max => 150, :delim => /~\n/ # length of article summary and delimiter
|
|
143
155
|
set :ext, 'txt' # file extension for articles
|
|
144
156
|
set :cache, 28800 # cache site for 8 hours
|
|
157
|
+
set :to_html do |path, page, ctx| # returns an html, from a path & context
|
|
158
|
+
ERB.new(File.read("#{path}/#{page}.rhtml")).result(ctx)
|
|
159
|
+
end
|
|
145
160
|
|
|
146
161
|
thanks
|
|
147
162
|
------
|
data/Rakefile
CHANGED
|
@@ -10,7 +10,6 @@ begin
|
|
|
10
10
|
gem.email = "ceilingfish@gmail.com"
|
|
11
11
|
gem.homepage = "http://github.com/ceilingfish/toto"
|
|
12
12
|
gem.authors = ["cloudhead", "ceilingfish"]
|
|
13
|
-
# gem.files = FileList["{bin,lib}/**/*"]
|
|
14
13
|
gem.add_development_dependency "riot"
|
|
15
14
|
gem.add_dependency "builder"
|
|
16
15
|
gem.add_dependency "rack"
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.4.
|
|
1
|
+
0.4.2
|
data/lib/toto.rb
CHANGED
|
@@ -28,9 +28,9 @@ module Toto
|
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
module Template
|
|
31
|
-
def to_html page, &blk
|
|
31
|
+
def to_html page, config, &blk
|
|
32
32
|
path = ([:layout, :repo].include?(page) ? Paths[:templates] : Paths[:pages])
|
|
33
|
-
|
|
33
|
+
config[:to_html].call(path, page, binding)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def markdown text
|
|
@@ -71,7 +71,7 @@ module Toto
|
|
|
71
71
|
filter !~ /^\d{4}/ || a.path =~ /^\/#{filter}/
|
|
72
72
|
end : []
|
|
73
73
|
|
|
74
|
-
return Archives.new(entries)
|
|
74
|
+
return Archives.new(entries, @config)
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def title
|
|
@@ -80,7 +80,7 @@ module Toto
|
|
|
80
80
|
|
|
81
81
|
def articles ext = self[:ext]
|
|
82
82
|
Dir["#{Paths[:articles]}/*.#{ext}"].reverse.map do |article|
|
|
83
|
-
Article.new
|
|
83
|
+
Article.new article, @config
|
|
84
84
|
end
|
|
85
85
|
end
|
|
86
86
|
|
|
@@ -112,7 +112,7 @@ module Toto
|
|
|
112
112
|
end
|
|
113
113
|
|
|
114
114
|
def article route
|
|
115
|
-
Article.new(
|
|
115
|
+
Article.new("#{Paths[:articles]}/#{route}.#{self[:ext]}", @config).load
|
|
116
116
|
end
|
|
117
117
|
|
|
118
118
|
def /
|
|
@@ -178,7 +178,7 @@ module Toto
|
|
|
178
178
|
end
|
|
179
179
|
|
|
180
180
|
def render page, type
|
|
181
|
-
type == :html ? to_html(:layout, &Proc.new { to_html page }) : send(:"to_#{type}", :feed)
|
|
181
|
+
type == :html ? to_html(:layout, @config, &Proc.new { to_html page, @config }) : send(:"to_#{type}", :feed)
|
|
182
182
|
end
|
|
183
183
|
|
|
184
184
|
def to_xml page
|
|
@@ -214,12 +214,17 @@ module Toto
|
|
|
214
214
|
class Archives < Array
|
|
215
215
|
include Template
|
|
216
216
|
|
|
217
|
-
def initialize articles
|
|
217
|
+
def initialize articles, config
|
|
218
218
|
self.replace articles
|
|
219
|
+
@config = config
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
def [] a
|
|
223
|
+
a.is_a?(Range) ? self.class.new(self.slice(a) || [], @config) : super
|
|
219
224
|
end
|
|
220
225
|
|
|
221
226
|
def to_html
|
|
222
|
-
super(:archives)
|
|
227
|
+
super(:archives, @config)
|
|
223
228
|
end
|
|
224
229
|
alias :to_s to_html
|
|
225
230
|
alias :archive archives
|
|
@@ -234,9 +239,8 @@ module Toto
|
|
|
234
239
|
end
|
|
235
240
|
|
|
236
241
|
def load
|
|
237
|
-
data = if @obj.is_a?
|
|
238
|
-
meta, self[:body] = @obj.
|
|
239
|
-
@obj.close
|
|
242
|
+
data = if @obj.is_a? String
|
|
243
|
+
meta, self[:body] = File.read(@obj).split(/\n\n/, 2)
|
|
240
244
|
YAML.load(meta)
|
|
241
245
|
elsif @obj.is_a? Hash
|
|
242
246
|
@obj
|
|
@@ -277,10 +281,10 @@ module Toto
|
|
|
277
281
|
end
|
|
278
282
|
|
|
279
283
|
def title() self[:title] || "an article" end
|
|
280
|
-
def date() @config[:date
|
|
284
|
+
def date() @config[:date].call(self[:date]) end
|
|
281
285
|
def path() self[:date].strftime("/%Y/%m/%d/#{slug}/") end
|
|
282
286
|
def author() self[:author] || @config[:author] end
|
|
283
|
-
def to_html() self.load; super(:article)
|
|
287
|
+
def to_html() self.load; super(:article, @config) end
|
|
284
288
|
|
|
285
289
|
alias :to_s to_html
|
|
286
290
|
|
|
@@ -288,35 +292,33 @@ module Toto
|
|
|
288
292
|
|
|
289
293
|
class Config < Hash
|
|
290
294
|
Defaults = {
|
|
291
|
-
:author => ENV['USER'],
|
|
292
|
-
:title => Dir.pwd.split('/').last,
|
|
293
|
-
:root => "index",
|
|
295
|
+
:author => ENV['USER'], # blog author
|
|
296
|
+
:title => Dir.pwd.split('/').last, # site title
|
|
297
|
+
:root => "index", # site index
|
|
294
298
|
:url => "http://127.0.0.1",
|
|
295
|
-
:date => lambda {|now| now.strftime("%d/%m/%Y") },
|
|
296
|
-
:markdown => :smart,
|
|
297
|
-
:disqus => false,
|
|
298
|
-
:summary => {:max => 150, :delim => /~\n/},
|
|
299
|
-
:ext => 'txt',
|
|
300
|
-
:cache => 28800,
|
|
301
|
-
:github => {:user => "", :repos => [], :ext => 'md'}# Github username and list of repos
|
|
299
|
+
:date => lambda {|now| now.strftime("%d/%m/%Y") }, # date function
|
|
300
|
+
:markdown => :smart, # use markdown
|
|
301
|
+
:disqus => false, # disqus name
|
|
302
|
+
:summary => {:max => 150, :delim => /~\n/}, # length of summary and delimiter
|
|
303
|
+
:ext => 'txt', # extension for articles
|
|
304
|
+
:cache => 28800, # cache duration (seconds)
|
|
305
|
+
:github => {:user => "", :repos => [], :ext => 'md'}, # Github username and list of repos
|
|
306
|
+
:to_html => lambda {|path, page, ctx| # returns an html, from a path & context
|
|
307
|
+
ERB.new(File.read("#{path}/#{page}.rhtml")).result(ctx)
|
|
308
|
+
}
|
|
302
309
|
}
|
|
303
310
|
def initialize obj
|
|
304
311
|
self.update Defaults
|
|
305
312
|
self.update obj
|
|
306
313
|
end
|
|
307
314
|
|
|
308
|
-
def set key, val
|
|
315
|
+
def set key, val = nil, &blk
|
|
309
316
|
if val.is_a? Hash
|
|
310
317
|
self[key].update val
|
|
311
318
|
else
|
|
312
|
-
self[key] = val
|
|
319
|
+
self[key] = block_given?? blk : val
|
|
313
320
|
end
|
|
314
321
|
end
|
|
315
|
-
|
|
316
|
-
def [] key, *args
|
|
317
|
-
val = super(key)
|
|
318
|
-
val.respond_to?(:call) ? val.call(*args) : val
|
|
319
|
-
end
|
|
320
322
|
end
|
|
321
323
|
|
|
322
324
|
class Server
|
data/test/toto_test.rb
CHANGED
|
@@ -12,36 +12,51 @@ context Toto do
|
|
|
12
12
|
Toto::Paths[:templates] = "test/templates"
|
|
13
13
|
end
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
15
|
+
context "GET /" do
|
|
16
|
+
setup { @toto.get('/') }
|
|
17
|
+
|
|
18
|
+
asserts("returns a 200") { topic.status }.equals 200
|
|
19
|
+
asserts("body is not empty") { not topic.body.empty? }
|
|
20
|
+
asserts("content type is set properly") { topic.content_type }.equals "text/html"
|
|
21
|
+
should("include a couple of article") { topic.body }.includes_elements("#articles li", 3)
|
|
22
|
+
should("include an archive") { topic.body }.includes_elements("#archives li", 2)
|
|
23
|
+
|
|
24
|
+
context "with no articles" do
|
|
25
|
+
setup { Rack::MockRequest.new(Toto::Server.new(@config.merge(:ext => 'oxo'))).get('/') }
|
|
26
|
+
|
|
27
|
+
asserts("body is not empty") { not topic.body.empty? }
|
|
28
|
+
asserts("returns a 200") { topic.status }.equals 200
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context "with a user-defined to_html" do
|
|
32
|
+
setup do
|
|
33
|
+
@config[:to_html] = lambda do |path, page, binding|
|
|
34
|
+
ERB.new(File.read("#{path}/#{page}.rhtml")).result(binding)
|
|
35
|
+
end
|
|
36
|
+
@toto.get('/')
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
asserts("returns a 200") { topic.status }.equals 200
|
|
40
|
+
asserts("body is not empty") { not topic.body.empty? }
|
|
41
|
+
asserts("content type is set properly") { topic.content_type }.equals "text/html"
|
|
42
|
+
should("include a couple of article") { topic.body }.includes_elements("#articles li", 3)
|
|
43
|
+
should("include an archive") { topic.body }.includes_elements("#archives li", 2)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
context "GET /about" do
|
|
48
|
+
setup { @toto.get('/about') }
|
|
49
|
+
asserts("returns a 200") { topic.status }.equals 200
|
|
50
|
+
asserts("body is not empty") { not topic.body.empty? }
|
|
51
|
+
should("have access to @articles") { topic.body }.includes_html("#count" => /5/)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
context "GET a single article" do
|
|
55
|
+
setup { @toto.get("/1900/05/17/the-wonderful-wizard-of-oz") }
|
|
56
|
+
asserts("returns a 200") { topic.status }.equals 200
|
|
57
|
+
asserts("content type is set properly") { topic.content_type }.equals "text/html"
|
|
58
|
+
should("contain the article") { topic.body }.includes_html("p" => /<em>Once upon a time<\/em>/)
|
|
59
|
+
end
|
|
45
60
|
|
|
46
61
|
context "GET to the archive" do
|
|
47
62
|
context "through a year" do
|
|
@@ -180,6 +195,16 @@ context Toto do
|
|
|
180
195
|
should("set summary[:delim] to /%/") { topic[:summary][:delim].source }.equals "%"
|
|
181
196
|
should("leave the :max intact") { topic[:summary][:max] }.equals 150
|
|
182
197
|
end
|
|
198
|
+
|
|
199
|
+
context "using Config#set with a block" do
|
|
200
|
+
setup do
|
|
201
|
+
conf = Toto::Config.new({})
|
|
202
|
+
conf.set(:to_html) {|path, p, _| path + p }
|
|
203
|
+
conf
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
should("set the value to a proc") { topic[:to_html] }.respond_to :call
|
|
207
|
+
end
|
|
183
208
|
end
|
|
184
209
|
|
|
185
210
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ceilingfish-toto
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- cloudhead
|
|
@@ -10,7 +10,7 @@ autorequire:
|
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
12
|
|
|
13
|
-
date: 2010-02-
|
|
13
|
+
date: 2010-02-23 00:00:00 +00:00
|
|
14
14
|
default_executable:
|
|
15
15
|
dependencies:
|
|
16
16
|
- !ruby/object:Gem::Dependency
|
|
@@ -69,7 +69,6 @@ files:
|
|
|
69
69
|
- README.md
|
|
70
70
|
- Rakefile
|
|
71
71
|
- VERSION
|
|
72
|
-
- ceilingfish-toto.gemspec
|
|
73
72
|
- lib/ceilingfish-toto.rb
|
|
74
73
|
- lib/ext/ext.rb
|
|
75
74
|
- lib/toto.rb
|
data/ceilingfish-toto.gemspec
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# Generated by jeweler
|
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
|
4
|
-
# -*- encoding: utf-8 -*-
|
|
5
|
-
|
|
6
|
-
Gem::Specification.new do |s|
|
|
7
|
-
s.name = %q{ceilingfish-toto}
|
|
8
|
-
s.version = "0.4.0"
|
|
9
|
-
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
|
11
|
-
s.authors = ["cloudhead", "ceilingfish"]
|
|
12
|
-
s.date = %q{2010-02-22}
|
|
13
|
-
s.description = %q{the tiniest blog-engine in Oz.}
|
|
14
|
-
s.email = %q{ceilingfish@gmail.com}
|
|
15
|
-
s.extra_rdoc_files = [
|
|
16
|
-
"LICENSE",
|
|
17
|
-
"README.md"
|
|
18
|
-
]
|
|
19
|
-
s.files = [
|
|
20
|
-
".document",
|
|
21
|
-
".gitignore",
|
|
22
|
-
"LICENSE",
|
|
23
|
-
"README.md",
|
|
24
|
-
"Rakefile",
|
|
25
|
-
"VERSION",
|
|
26
|
-
"ceilingfish-toto.gemspec",
|
|
27
|
-
"lib/ceilingfish-toto.rb",
|
|
28
|
-
"lib/ext/ext.rb",
|
|
29
|
-
"lib/toto.rb",
|
|
30
|
-
"test/articles/some-random-article.txt",
|
|
31
|
-
"test/articles/the-dichotomy-of-design.txt",
|
|
32
|
-
"test/articles/the-wonderful-wizard-of-oz.txt",
|
|
33
|
-
"test/articles/tilt-factor.txt",
|
|
34
|
-
"test/articles/two-thousand-and-one.txt",
|
|
35
|
-
"test/autotest.rb",
|
|
36
|
-
"test/templates/about.rhtml",
|
|
37
|
-
"test/templates/archives.rhtml",
|
|
38
|
-
"test/templates/article.rhtml",
|
|
39
|
-
"test/templates/feed.builder",
|
|
40
|
-
"test/templates/index.rhtml",
|
|
41
|
-
"test/templates/layout.rhtml",
|
|
42
|
-
"test/templates/repo.rhtml",
|
|
43
|
-
"test/test_helper.rb",
|
|
44
|
-
"test/toto_test.rb"
|
|
45
|
-
]
|
|
46
|
-
s.homepage = %q{http://github.com/ceilingfish/toto}
|
|
47
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
|
48
|
-
s.require_paths = ["lib"]
|
|
49
|
-
s.rubygems_version = %q{1.3.5}
|
|
50
|
-
s.summary = %q{the tiniest blog-engine in Oz}
|
|
51
|
-
s.test_files = [
|
|
52
|
-
"test/autotest.rb",
|
|
53
|
-
"test/test_helper.rb",
|
|
54
|
-
"test/toto_test.rb"
|
|
55
|
-
]
|
|
56
|
-
|
|
57
|
-
if s.respond_to? :specification_version then
|
|
58
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
|
59
|
-
s.specification_version = 3
|
|
60
|
-
|
|
61
|
-
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
|
62
|
-
s.add_development_dependency(%q<riot>, [">= 0"])
|
|
63
|
-
s.add_runtime_dependency(%q<builder>, [">= 0"])
|
|
64
|
-
s.add_runtime_dependency(%q<rack>, [">= 0"])
|
|
65
|
-
s.add_runtime_dependency(%q<rdiscount>, [">= 0"])
|
|
66
|
-
else
|
|
67
|
-
s.add_dependency(%q<riot>, [">= 0"])
|
|
68
|
-
s.add_dependency(%q<builder>, [">= 0"])
|
|
69
|
-
s.add_dependency(%q<rack>, [">= 0"])
|
|
70
|
-
s.add_dependency(%q<rdiscount>, [">= 0"])
|
|
71
|
-
end
|
|
72
|
-
else
|
|
73
|
-
s.add_dependency(%q<riot>, [">= 0"])
|
|
74
|
-
s.add_dependency(%q<builder>, [">= 0"])
|
|
75
|
-
s.add_dependency(%q<rack>, [">= 0"])
|
|
76
|
-
s.add_dependency(%q<rdiscount>, [">= 0"])
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|