toto 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|