georgi-shinmun 0.4.1 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +23 -31
- data/assets/print.css +76 -0
- data/assets/styles.css +91 -0
- data/bin/shinmun +16 -8
- data/config.ru +16 -0
- data/lib/shinmun.rb +1 -4
- data/lib/shinmun/blog.rb +110 -100
- data/lib/shinmun/comment.rb +1 -1
- data/lib/shinmun/handlers.rb +19 -0
- data/lib/shinmun/helpers.rb +1 -1
- data/lib/shinmun/routes.rb +25 -36
- data/templates/404.rhtml +4 -0
- data/templates/_comment_form.rhtml +21 -0
- data/{test/templates → templates}/_comments.rhtml +0 -0
- data/{example/templates → templates}/archive.rhtml +0 -1
- data/{example/templates → templates}/category.rhtml +1 -2
- data/{example/templates → templates}/category.rxml +0 -0
- data/{example/templates → templates}/index.rhtml +0 -1
- data/{example/templates → templates}/index.rxml +0 -0
- data/templates/layout.rhtml +44 -0
- data/{example/templates → templates}/page.rhtml +0 -2
- data/{example/templates → templates}/post.rhtml +6 -21
- data/test/blog_spec.rb +48 -81
- metadata +17 -44
- data/example/Rakefile +0 -41
- data/example/assets/images/favicon.ico +0 -0
- data/example/assets/images/loading.gif +0 -0
- data/example/assets/javascripts/1-jquery.min.js +0 -32
- data/example/assets/javascripts/2-jquery-form.min.js +0 -5
- data/example/assets/javascripts/3-comments.js +0 -45
- data/example/assets/javascripts/4-coderay.js +0 -13
- data/example/assets/print.css +0 -76
- data/example/assets/stylesheets/1-reset.css +0 -23
- data/example/assets/stylesheets/2-typo.css +0 -40
- data/example/assets/stylesheets/3-table.css +0 -23
- data/example/assets/stylesheets/4-article.css +0 -15
- data/example/assets/stylesheets/5-comments.css +0 -20
- data/example/assets/stylesheets/6-diff.css +0 -25
- data/example/assets/stylesheets/7-blog.css +0 -33
- data/example/config.ru +0 -6
- data/example/config/blog.yml +0 -10
- data/example/pages/about.md +0 -7
- data/example/templates/_comment_form.rhtml +0 -90
- data/example/templates/_comments.rhtml +0 -11
- data/example/templates/_pagination.rhtml +0 -10
- data/example/templates/comments.rhtml +0 -1
- data/example/templates/layout.rhtml +0 -82
- data/lib/shinmun/aggregations/delicious.rb +0 -57
- data/lib/shinmun/aggregations/flickr.rb +0 -81
- data/lib/shinmun/post_handler.rb +0 -16
- data/test/templates/archive.rhtml +0 -6
- data/test/templates/category.rhtml +0 -6
- data/test/templates/category.rxml +0 -20
- data/test/templates/index.rhtml +0 -4
- data/test/templates/index.rxml +0 -21
- data/test/templates/layout.rhtml +0 -9
- data/test/templates/page.rhtml +0 -2
- data/test/templates/post.rhtml +0 -3
data/lib/shinmun/comment.rb
CHANGED
data/lib/shinmun/helpers.rb
CHANGED
data/lib/shinmun/routes.rb
CHANGED
@@ -9,12 +9,27 @@ Shinmun::Blog.map do
|
|
9
9
|
end
|
10
10
|
|
11
11
|
tag '/tags/(.*)' do |tag|
|
12
|
-
render 'category.rhtml', :name => "Tag: #{tag}", :posts =>
|
12
|
+
render 'category.rhtml', :name => "Tag: #{tag}", :posts => posts_with_tags(tag)
|
13
|
+
end
|
14
|
+
|
15
|
+
comments '/(\d+)/(\d+)/(.*)/comments' do |year, month, name|
|
16
|
+
post = find_post(year.to_i, month.to_i, name) or raise "post not found #{request.path_info}"
|
17
|
+
|
18
|
+
if params['preview']
|
19
|
+
comments = comments_for(post).push(Shinmun::Comment.new(params))
|
20
|
+
render 'post.rhtml', :post => post, :comments => comments
|
21
|
+
else
|
22
|
+
create_comment(post, params)
|
23
|
+
redirect post_path(post)
|
24
|
+
end
|
13
25
|
end
|
14
26
|
|
15
27
|
post '/(\d+)/(\d+)/(.*)' do |year, month, name|
|
16
|
-
post = find_post(year.to_i, month.to_i, name)
|
17
|
-
|
28
|
+
if post = find_post(year.to_i, month.to_i, name)
|
29
|
+
render 'post.rhtml', :post => post, :comments => comments_for(post)
|
30
|
+
else
|
31
|
+
render '404.rhtml', :path => request.path_info
|
32
|
+
end
|
18
33
|
end
|
19
34
|
|
20
35
|
archive '/(\d+)/(\d+)' do |year, month|
|
@@ -25,47 +40,21 @@ Shinmun::Blog.map do
|
|
25
40
|
render 'index.rxml', :layout => false
|
26
41
|
end
|
27
42
|
|
28
|
-
|
29
|
-
if params['preview'] == 'true'
|
30
|
-
render 'comments.rhtml', :comments => [Shinmun::Comment.new(params)], :layout => false
|
31
|
-
else
|
32
|
-
post_comment(params['path'], params)
|
33
|
-
render 'comments.rhtml', :comments => comments_for(params['path']), :layout => false
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
javascripts '/assets/javascripts\.js' do
|
38
|
-
scripts = assets['javascripts'].to_a.join
|
39
|
-
if_none_match(etag(scripts)) do
|
40
|
-
text scripts
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
stylesheets '/assets/stylesheets\.css' do
|
45
|
-
styles = assets['stylesheets'].to_a.join
|
46
|
-
if_none_match(etag(styles)) do
|
47
|
-
text styles
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
assets '/assets/(.*)' do |path|
|
52
|
-
file = assets[path] or raise "#{path} not found"
|
53
|
-
if_none_match(etag(file)) do
|
54
|
-
text file
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
get '/$' do
|
43
|
+
index '/$' do
|
59
44
|
render 'index.rhtml'
|
60
45
|
end
|
61
46
|
|
62
|
-
|
47
|
+
page '/(.*)' do |path|
|
48
|
+
path = path.gsub('..', '')
|
63
49
|
page = find_page(path)
|
64
50
|
|
65
51
|
if page
|
66
52
|
render 'page.rhtml', :page => page
|
53
|
+
|
54
|
+
elsif file = store[path]
|
55
|
+
text file
|
67
56
|
else
|
68
|
-
|
57
|
+
render '404.rhtml', :path => path
|
69
58
|
end
|
70
59
|
end
|
71
60
|
|
data/templates/404.rhtml
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
<div class="comment-form">
|
2
|
+
<form action="<%= post_path @post %>/comments" method="POST">
|
3
|
+
<p>
|
4
|
+
<label>Name</label><br/>
|
5
|
+
<input type="text" name="name" size="40" value="<%= @params['name'] %>"/>
|
6
|
+
</p>
|
7
|
+
<p>
|
8
|
+
<label>Website</label><br/>
|
9
|
+
<input type="text" name="website" size="40" value="<%= @params['website'] %>"/>
|
10
|
+
</p>
|
11
|
+
<p>
|
12
|
+
<label>Comment</label><br/>
|
13
|
+
<textarea name="text" cols="60" rows="10"><%= @params['text'] %></textarea>
|
14
|
+
</p>
|
15
|
+
<p>
|
16
|
+
<input type="submit" value="Post comment"/>
|
17
|
+
<input type="checkbox" name="preview" value="1"/>
|
18
|
+
Preview
|
19
|
+
</p>
|
20
|
+
</form>
|
21
|
+
</div>
|
File without changes
|
@@ -1,12 +1,11 @@
|
|
1
1
|
<h1><%= @name %></h1>
|
2
2
|
|
3
3
|
<div class="articles">
|
4
|
-
<% for post in @posts
|
4
|
+
<% for post in @posts %>
|
5
5
|
<div class="article">
|
6
6
|
<div class="date"><%= human_date post.date %></div>
|
7
7
|
<h2><%= post_link post %></h2>
|
8
8
|
<%= post.summary %>
|
9
9
|
</div>
|
10
|
-
<hr/>
|
11
10
|
<% end %>
|
12
11
|
</div>
|
File without changes
|
File without changes
|
@@ -0,0 +1,44 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
2
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
3
|
+
<head>
|
4
|
+
<title><%= @blog.title %></title>
|
5
|
+
<meta http-equiv="Content-Language" content="English" />
|
6
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
7
|
+
<link rel="alternate" type="application/rss+xml" title="RSS" href="/index.rss" />
|
8
|
+
<link rel="stylesheet" media="screen" type="text/css" href="/assets/styles.css" />
|
9
|
+
<link rel="stylesheet" media="print" type="text/css" href="/assets/print.css" />
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<div class="container">
|
13
|
+
<h3><a href="/"><%= @blog.title %></a> - <%= @blog.description %></h3>
|
14
|
+
|
15
|
+
<div class="menu">
|
16
|
+
<%= link_to 'Home', '/' %> -
|
17
|
+
<%= link_to 'About', '/about' %> -
|
18
|
+
<%= link_to 'Subscribe RSS', '/index.rss' %>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<%= @content %>
|
22
|
+
|
23
|
+
<hr/>
|
24
|
+
|
25
|
+
<p>
|
26
|
+
<h4>Categories</h4>
|
27
|
+
<ul>
|
28
|
+
<li><%= link_to 'Ruby', '/categories/ruby' %></li>
|
29
|
+
<li><%= link_to 'Javascript', '/categories/javascript' %></li>
|
30
|
+
</ul>
|
31
|
+
</p>
|
32
|
+
|
33
|
+
<p>
|
34
|
+
<h4>Archive</h4>
|
35
|
+
<ul>
|
36
|
+
<% for year, month in @blog.archives %>
|
37
|
+
<li><%= archive_link year, month %></li>
|
38
|
+
<% end %>
|
39
|
+
</ul>
|
40
|
+
</p>
|
41
|
+
|
42
|
+
</div>
|
43
|
+
</body>
|
44
|
+
</html>
|
@@ -8,28 +8,15 @@
|
|
8
8
|
|
9
9
|
<%= @post.body_html %>
|
10
10
|
|
11
|
-
<
|
12
|
-
|
13
|
-
<div style="margin:1em 0em 1em 0em; color:#666">
|
11
|
+
<p>
|
14
12
|
<% if @post.category %>
|
15
|
-
Posted in category <%= link_to @post.category, "/categories/#{urlify @post.category}"
|
13
|
+
Posted in category <%= link_to @post.category, "/categories/#{urlify @post.category}" %>.
|
16
14
|
<% end %>
|
17
|
-
Tagged with <%= @post.tag_list.map {|tag| link_to tag, "/tags/#{tag}" }.join(', ') %>.
|
18
|
-
</div>
|
19
|
-
|
20
|
-
<h6>Similar Posts</h6>
|
21
15
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
<li><%= post_link post %></li>
|
27
|
-
<% end %>
|
28
|
-
<% end %>
|
29
|
-
|
30
|
-
</ul>
|
31
|
-
|
32
|
-
<hr/>
|
16
|
+
<% unless @post.tag_list.empty? %>
|
17
|
+
Tagged with <%= @post.tag_list.map {|tag| link_to tag, "/tags/#{tag}" }.join(', ') %>.
|
18
|
+
<% end %>
|
19
|
+
</p>
|
33
20
|
|
34
21
|
<% if @comments %>
|
35
22
|
<h2>Comments</h2>
|
@@ -44,5 +31,3 @@
|
|
44
31
|
<%= render '_comment_form.rhtml', :post => @post %>
|
45
32
|
|
46
33
|
</div>
|
47
|
-
|
48
|
-
<hr/>
|
data/test/blog_spec.rb
CHANGED
@@ -1,70 +1,53 @@
|
|
1
1
|
require 'shinmun'
|
2
2
|
require 'rack/mock'
|
3
|
+
require 'rexml/document'
|
3
4
|
require 'rexml/xpath'
|
4
5
|
require 'pp'
|
5
6
|
|
6
7
|
describe Shinmun::Blog do
|
7
8
|
|
8
|
-
|
9
|
-
REPO = '/tmp/shinmun-test'
|
9
|
+
DIR = '/tmp/shinmun-test'
|
10
10
|
|
11
|
-
|
12
|
-
FileUtils.rm_rf REPO
|
13
|
-
Dir.mkdir REPO
|
14
|
-
Dir.chdir REPO
|
15
|
-
initialize_blog
|
16
|
-
end
|
17
|
-
|
18
|
-
def file(file, data)
|
19
|
-
FileUtils.mkpath(File.dirname(file))
|
20
|
-
open(file, 'w') { |io| io << data }
|
21
|
-
`git add #{file}`
|
22
|
-
end
|
23
|
-
|
24
|
-
def initialize_blog
|
25
|
-
`git init`
|
26
|
-
|
27
|
-
file 'config/blog.yml', {
|
28
|
-
'title' => 'Title',
|
29
|
-
'description' => 'Description',
|
30
|
-
'language' => 'en',
|
31
|
-
'author' => 'The Author',
|
32
|
-
'url' => 'http://www.my-blog-url.com',
|
33
|
-
'categories' => ['Ruby', 'Javascript']
|
34
|
-
}.to_yaml
|
11
|
+
attr_reader :blog
|
35
12
|
|
13
|
+
before do
|
36
14
|
ENV['RACK_ENV'] = 'production'
|
37
|
-
@blog = Shinmun::Blog.new(REPO)
|
38
|
-
@request = Rack::MockRequest.new(@blog)
|
39
|
-
|
40
|
-
Dir.mkdir 'templates'
|
41
15
|
|
42
|
-
|
43
|
-
unless path.include?('~')
|
44
|
-
file 'templates/' + File.basename(path), File.read(path)
|
45
|
-
end
|
46
|
-
end
|
16
|
+
FileUtils.rm_rf DIR
|
47
17
|
|
48
|
-
|
18
|
+
Shinmun::Blog.init(DIR)
|
19
|
+
|
20
|
+
@blog = Shinmun::Blog.new(DIR)
|
21
|
+
|
22
|
+
blog.config = {
|
23
|
+
:title => 'Title',
|
24
|
+
:description => 'Description',
|
25
|
+
:language => 'en',
|
26
|
+
:author => 'The Author',
|
27
|
+
:categories => ['Ruby', 'Javascript']
|
28
|
+
}
|
49
29
|
|
50
|
-
@blog.
|
30
|
+
@posts = [blog.create_post(:title => 'New post', :date => '2008-10-10', :category => 'Ruby', :body => 'Body1'),
|
31
|
+
blog.create_post(:title => 'And this', :date => '2008-10-11', :category => 'Ruby', :body => 'Body2'),
|
32
|
+
blog.create_post(:title => 'Again', :date => '2008-11-10', :category => 'Javascript', :body => 'Body3')]
|
51
33
|
|
52
|
-
@
|
53
|
-
|
54
|
-
@blog.create_post(:title => 'Again', :date => '2008-11-10', :category => 'Javascript', :body => 'Body3')]
|
34
|
+
@pages = [blog.create_page(:title => 'Page 1', :body => 'Body1'),
|
35
|
+
blog.create_page(:title => 'Page 2', :body => 'Body2')]
|
55
36
|
|
56
|
-
|
57
|
-
|
37
|
+
blog.store.load
|
38
|
+
end
|
58
39
|
|
59
|
-
|
40
|
+
def request(method, uri, options={})
|
41
|
+
@request = Rack::MockRequest.new(blog)
|
42
|
+
@response = @request.request(method, uri, options)
|
60
43
|
end
|
61
44
|
|
62
45
|
def get(*args)
|
63
|
-
|
46
|
+
request(:get, *args)
|
64
47
|
end
|
65
48
|
|
66
49
|
def post(*args)
|
67
|
-
|
50
|
+
request(:post, *args)
|
68
51
|
end
|
69
52
|
|
70
53
|
def xpath(xml, path)
|
@@ -83,51 +66,35 @@ describe Shinmun::Blog do
|
|
83
66
|
titles[i].text.should == title
|
84
67
|
summaries[i].text.to_s.strip.should == summary
|
85
68
|
end
|
86
|
-
end
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should load templates" do
|
72
|
+
blog.load_template("index.rhtml").should be_kind_of(ERB)
|
73
|
+
end
|
87
74
|
|
88
75
|
it "should find posts for a category" do
|
89
|
-
category =
|
76
|
+
category = blog.find_category('ruby')
|
90
77
|
category[:name].should == 'Ruby'
|
91
78
|
|
92
79
|
category[:posts].should include(@posts[0])
|
93
80
|
category[:posts].should include(@posts[1])
|
94
81
|
|
95
|
-
category =
|
82
|
+
category = blog.find_category('javascript')
|
96
83
|
category[:name].should == 'Javascript'
|
97
84
|
category[:posts].should include(@posts[2])
|
98
85
|
end
|
99
86
|
|
100
87
|
it "should create a post" do
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
post =
|
88
|
+
post = blog.create_post(:title => 'New post', :date => '2008-10-10')
|
89
|
+
blog.store.load
|
90
|
+
|
91
|
+
post = blog.find_post(2008, 10, 'new-post')
|
105
92
|
post.should_not be_nil
|
106
93
|
post.title.should == 'New post'
|
107
94
|
post.date.should == Date.new(2008, 10, 10)
|
108
95
|
post.name.should == 'new-post'
|
109
96
|
end
|
110
97
|
|
111
|
-
it "should update a post" do
|
112
|
-
post = @blog.create_post(:title => 'New post', :date => '2008-10-10')
|
113
|
-
@blog.update_post(post, "---\ndate: 2008-11-11\ntitle: The title\n---")
|
114
|
-
@blog.store.load
|
115
|
-
|
116
|
-
post = @blog.find_post(2008, 11, 'new-post')
|
117
|
-
post.should_not be_nil
|
118
|
-
post.title.should == 'The title'
|
119
|
-
post.date.should == Date.new(2008, 11, 11)
|
120
|
-
post.name.should == 'new-post'
|
121
|
-
end
|
122
|
-
|
123
|
-
it "should delete a post" do
|
124
|
-
post = @blog.create_post(:title => 'New post', :date => '2008-10-10')
|
125
|
-
@blog.delete_post(post)
|
126
|
-
@blog.store.load
|
127
|
-
|
128
|
-
@blog.find_post(2008, 10, 'new-post').should be_nil
|
129
|
-
end
|
130
|
-
|
131
98
|
it "should render posts" do
|
132
99
|
xml = get('/2008/10/new-post').body
|
133
100
|
|
@@ -143,17 +110,17 @@ describe Shinmun::Blog do
|
|
143
110
|
xpath(xml, '/rss/channel/title')[0].text.should == 'Ruby'
|
144
111
|
xpath(xml, '/rss/channel/item/title')[0].text.should == 'And this'
|
145
112
|
xpath(xml, '/rss/channel/item/pubDate')[0].text.should == "Sat, 11 Oct 2008 00:00:00 +0000"
|
146
|
-
xpath(xml, '/rss/channel/item/link')[0].text.should == "http://
|
113
|
+
xpath(xml, '/rss/channel/item/link')[0].text.should == "http://example.org/2008/10/and-this"
|
147
114
|
xpath(xml, '/rss/channel/item/title')[1].text.should == 'New post'
|
148
115
|
xpath(xml, '/rss/channel/item/pubDate')[1].text.should == "Fri, 10 Oct 2008 00:00:00 +0000"
|
149
|
-
xpath(xml, '/rss/channel/item/link')[1].text.should == "http://
|
116
|
+
xpath(xml, '/rss/channel/item/link')[1].text.should == "http://example.org/2008/10/new-post"
|
150
117
|
|
151
118
|
assert_listing(get('/categories/ruby').body, [['And this', 'Body2'], ['New post', 'Body1']])
|
152
119
|
end
|
153
120
|
|
154
121
|
it "should render index and archives" do
|
155
|
-
|
156
|
-
|
122
|
+
blog.posts_for_month(2008, 10).should_not be_empty
|
123
|
+
blog.posts_for_month(2008, 11).should_not be_empty
|
157
124
|
|
158
125
|
assert_listing(get('/2008/10').body, [['And this', 'Body2'], ['New post', 'Body1']])
|
159
126
|
assert_listing(get('/').body, [['Again', 'Body3'], ['And this', 'Body2'], ['New post', 'Body1']])
|
@@ -170,12 +137,12 @@ describe Shinmun::Blog do
|
|
170
137
|
end
|
171
138
|
|
172
139
|
it "should post a comment" do
|
173
|
-
post "/
|
174
|
-
post "/
|
175
|
-
|
176
|
-
@blog.store.load
|
140
|
+
post "/2008/10/new-post/comments?name=Hans&text=Hallo"
|
141
|
+
post "/2008/10/new-post/comments?name=Peter&text=Servus"
|
177
142
|
|
178
|
-
|
143
|
+
blog.store.load
|
144
|
+
|
145
|
+
comments = blog.comments_for(@posts[0])
|
179
146
|
|
180
147
|
comments[0].should_not be_nil
|
181
148
|
comments[0].name.should == 'Hans'
|