toto 0.2.7 → 0.2.8
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 +22 -6
- data/VERSION +1 -1
- data/lib/{ext.rb → ext/ext.rb} +10 -0
- data/lib/toto.rb +31 -19
- data/test/toto_test.rb +1 -1
- data/toto.gemspec +3 -3
- metadata +3 -3
data/README.md
CHANGED
@@ -9,6 +9,14 @@ introduction
|
|
9
9
|
toto is a git-powered, minimalist blog engine for the hackers of Oz. The engine weights around ~300 sloc at its worse.
|
10
10
|
There is no toto client, at least for now; everything goes through git.
|
11
11
|
|
12
|
+
blog in 10 seconds
|
13
|
+
------------------
|
14
|
+
|
15
|
+
$ git clone git://github.com/cloudhead/dorothy.git myblog
|
16
|
+
$ cd myblog
|
17
|
+
$ heroku create myblog
|
18
|
+
$ git push heroku master
|
19
|
+
|
12
20
|
philosophy
|
13
21
|
----------
|
14
22
|
|
@@ -24,7 +32,7 @@ Oh, and everything that can be done with git, _is_.
|
|
24
32
|
how it works
|
25
33
|
------------
|
26
34
|
|
27
|
-
- content is entirely managed
|
35
|
+
- content is entirely managed through **git**; you get full fledged version control for free.
|
28
36
|
- articles are stored as _.txt_ files, with embeded metadata (in yaml format).
|
29
37
|
- articles are processed through a markdown converter (rdiscount) by default.
|
30
38
|
- templating is done through **ERB**.
|
@@ -38,14 +46,21 @@ how it works
|
|
38
46
|
- summaries are generated intelligently by toto, following the `:max` setting you give it.
|
39
47
|
- you can also define how long your summary is, by adding `~` at the end of it (`:delim`).
|
40
48
|
|
49
|
+
dorothy
|
50
|
+
-------
|
51
|
+
|
52
|
+
Dorothy is toto's default template, you can get it at <http://github.com/cloudhead/dorothy>. It
|
53
|
+
comes with a very minimalistic but functional template, and a _config.ru_ file to get you started.
|
54
|
+
It also includes a _.gems_ file, for heroku.
|
55
|
+
|
41
56
|
synopsis
|
42
57
|
--------
|
43
58
|
|
44
|
-
One would start by
|
59
|
+
One would start by installing _toto_, with `sudo gem install toto`, and then forking or
|
60
|
+
cloning the `dorothy` repo, to get a basic skeleton:
|
45
61
|
|
46
|
-
$
|
62
|
+
$ git clone git://github.com/cloudhead/dorothy.git weblog
|
47
63
|
$ cd weblog/
|
48
|
-
$ git clone git://github.com/cloudhead/dorothy.git .
|
49
64
|
|
50
65
|
One would then edit the template at will, it has the following structure:
|
51
66
|
|
@@ -108,8 +123,7 @@ Toto was designed to work well with [heroku](http://heroku.com), it makes the mo
|
|
108
123
|
by setting the _Cache-Control_ and _Etag_ HTTP headers. Deploying on Heroku is really easy, just get the heroku gem,
|
109
124
|
create a heroku app with `heroku create`, and push with `git push heroku master`.
|
110
125
|
|
111
|
-
$ heroku create
|
112
|
-
$ heroku rename weblog
|
126
|
+
$ heroku create weblog
|
113
127
|
$ git push heroku master
|
114
128
|
$ heroku open
|
115
129
|
|
@@ -120,12 +134,14 @@ you could add `set :author, 'John Galt'` inside the `Toto::Server.new` block. He
|
|
120
134
|
|
121
135
|
set :author, ENV['USER'] # blog author
|
122
136
|
set :title, Dir.pwd.split('/').last # site title
|
137
|
+
set :url, 'http://example.com' # site root URL
|
123
138
|
set :root, "index" # page to load on /
|
124
139
|
set :date, lambda {|now| now.strftime("%d/%m/%Y") } # date format for articles
|
125
140
|
set :markdown, :smart # use markdown + smart-mode
|
126
141
|
set :disqus, false # disqus id, or false
|
127
142
|
set :summary, :max => 150, :delim => /~\n/ # length of article summary and delimiter
|
128
143
|
set :ext, 'txt' # file extension for articles
|
144
|
+
set :cache, 28800 # cache site for 8 hours
|
129
145
|
|
130
146
|
thanks
|
131
147
|
------
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.2.
|
1
|
+
0.2.8
|
data/lib/{ext.rb → ext/ext.rb}
RENAMED
@@ -6,6 +6,16 @@ class Object
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
+
class String
|
10
|
+
def slugize
|
11
|
+
self.downcase.gsub(/&/, 'and').gsub(/\s+/, '-').gsub(/[^a-z0-9-]/, '')
|
12
|
+
end
|
13
|
+
|
14
|
+
def humanize
|
15
|
+
self.capitalize.gsub(/[-_]+/, ' ')
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
9
19
|
class Fixnum
|
10
20
|
def ordinal
|
11
21
|
# 1 => 1st
|
data/lib/toto.rb
CHANGED
@@ -9,7 +9,7 @@ require 'builder'
|
|
9
9
|
|
10
10
|
$:.unshift File.dirname(__FILE__)
|
11
11
|
|
12
|
-
require 'ext'
|
12
|
+
require 'ext/ext'
|
13
13
|
|
14
14
|
module Toto
|
15
15
|
Paths = {
|
@@ -18,6 +18,14 @@ module Toto
|
|
18
18
|
:articles => "articles"
|
19
19
|
}
|
20
20
|
|
21
|
+
def self.env
|
22
|
+
ENV['RACK_ENV'] || 'production'
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.env= env
|
26
|
+
ENV['RACK_ENV'] = env
|
27
|
+
end
|
28
|
+
|
21
29
|
module Template
|
22
30
|
def to_html page, &blk
|
23
31
|
path = (page == :layout ? Paths[:templates] : Paths[:pages])
|
@@ -58,10 +66,10 @@ module Toto
|
|
58
66
|
end
|
59
67
|
end
|
60
68
|
|
61
|
-
def archives filter =
|
69
|
+
def archives filter = ""
|
62
70
|
entries = ! self.articles.empty??
|
63
71
|
self.articles.select do |a|
|
64
|
-
File.basename(a) =~ /^#{filter}/
|
72
|
+
filter !~ /^\d{4}/ || File.basename(a) =~ /^#{filter}/
|
65
73
|
end.reverse.map do |article|
|
66
74
|
Article.new File.new(article), @config
|
67
75
|
end : []
|
@@ -85,24 +93,24 @@ module Toto
|
|
85
93
|
if route.first =~ /\d{4}/
|
86
94
|
case route.size
|
87
95
|
when 1..3
|
88
|
-
|
96
|
+
Context.new(archives(route * '-'), @config, path).render(:archives, type)
|
89
97
|
when 4
|
90
|
-
|
98
|
+
Context.new(article(route), @config, path).render(:article, type)
|
91
99
|
else http 400
|
92
100
|
end
|
93
101
|
elsif respond_to?(route = route.first.to_sym)
|
94
|
-
|
102
|
+
Context.new(send(route, type), @config, path).render(route, type)
|
95
103
|
else
|
96
|
-
|
104
|
+
Context.new({}, @config, path).render(route.to_sym, type)
|
97
105
|
end
|
98
106
|
else
|
99
107
|
http 400
|
100
108
|
end
|
101
109
|
|
102
110
|
rescue Errno::ENOENT => e
|
103
|
-
body, status
|
104
|
-
|
105
|
-
return :body => body, :type => type, :status => status
|
111
|
+
return :body => http(404).first, :type => :html, :status => 404
|
112
|
+
else
|
113
|
+
return :body => body || "", :type => type, :status => status || 200
|
106
114
|
end
|
107
115
|
|
108
116
|
protected
|
@@ -195,17 +203,15 @@ module Toto
|
|
195
203
|
end
|
196
204
|
|
197
205
|
def slug
|
198
|
-
self[:slug] ||
|
199
|
-
self[:title].downcase.gsub(/&/, 'and').gsub(/\s+/, '-').gsub(/[^a-z0-9-]/, '')
|
206
|
+
self[:slug] || self[:title].slugize
|
200
207
|
end
|
201
208
|
|
202
209
|
def summary length = nil
|
203
|
-
|
204
|
-
|
210
|
+
config = @config[:summary]
|
205
211
|
sum = if self[:body] =~ config[:delim]
|
206
212
|
self[:body].split(config[:delim]).first
|
207
213
|
else
|
208
|
-
self[:body].match(/(.{1,#{length}}.*?)(\n|\Z)/m).to_s
|
214
|
+
self[:body].match(/(.{1,#{length || config[:length]}}.*?)(\n|\Z)/m).to_s
|
209
215
|
end
|
210
216
|
markdown(sum.length == self[:body].length ? sum : sum.strip.sub(/\.\Z/, '…'))
|
211
217
|
end
|
@@ -252,7 +258,8 @@ module Toto
|
|
252
258
|
:markdown => :smart, # use markdown
|
253
259
|
:disqus => false, # disqus name
|
254
260
|
:summary => {:max => 150, :delim => /~\n/}, # length of summary and delimiter
|
255
|
-
:ext => 'txt'
|
261
|
+
:ext => 'txt', # extension for articles
|
262
|
+
:cache => 28800 # cache duration (seconds)
|
256
263
|
}
|
257
264
|
def initialize obj
|
258
265
|
self.update Defaults
|
@@ -287,11 +294,16 @@ module Toto
|
|
287
294
|
response = Toto::Site.new(@config).go(route, *(mime ? mime : []))
|
288
295
|
|
289
296
|
@response.body = [response[:body]]
|
290
|
-
@response['Content-Length'] = response[:body].length.to_s
|
297
|
+
@response['Content-Length'] = response[:body].length.to_s unless response[:body].empty?
|
291
298
|
@response['Content-Type'] = Rack::Mime.mime_type(".#{response[:type]}")
|
292
299
|
|
293
|
-
#
|
294
|
-
@response['Cache-Control'] =
|
300
|
+
# Set http cache headers
|
301
|
+
@response['Cache-Control'] = if Toto.env == 'production'
|
302
|
+
"public, max-age=#{@config[:cache]}"
|
303
|
+
else
|
304
|
+
"no-cache, must-revalidate"
|
305
|
+
end
|
306
|
+
|
295
307
|
@response['Etag'] = Digest::SHA1.hexdigest(response[:body])
|
296
308
|
|
297
309
|
@response.status = response[:status]
|
data/test/toto_test.rb
CHANGED
data/toto.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{toto}
|
8
|
-
s.version = "0.2.
|
8
|
+
s.version = "0.2.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["cloudhead"]
|
12
|
-
s.date = %q{2010-02-
|
12
|
+
s.date = %q{2010-02-06}
|
13
13
|
s.description = %q{the tiniest blog-engine in Oz.}
|
14
14
|
s.email = %q{self@cloudhead.net}
|
15
15
|
s.extra_rdoc_files = [
|
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
"README.md",
|
24
24
|
"Rakefile",
|
25
25
|
"VERSION",
|
26
|
-
"lib/ext.rb",
|
26
|
+
"lib/ext/ext.rb",
|
27
27
|
"lib/toto.rb",
|
28
28
|
"test/articles/1900-05-17-the-wonderful-wizard-of-oz.txt",
|
29
29
|
"test/articles/2001-01-01-two-thousand-and-one.txt",
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: toto
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- cloudhead
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-06 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -68,7 +68,7 @@ files:
|
|
68
68
|
- README.md
|
69
69
|
- Rakefile
|
70
70
|
- VERSION
|
71
|
-
- lib/ext.rb
|
71
|
+
- lib/ext/ext.rb
|
72
72
|
- lib/toto.rb
|
73
73
|
- test/articles/1900-05-17-the-wonderful-wizard-of-oz.txt
|
74
74
|
- test/articles/2001-01-01-two-thousand-and-one.txt
|