georgi-shinmun 0.3 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +110 -187
- data/bin/shinmun +8 -0
- data/lib/shinmun/blog.rb +6 -5
- data/lib/shinmun/post.rb +12 -44
- data/lib/shinmun/post_handler.rb +1 -3
- data/lib/shinmun.rb +1 -4
- data/test/blog_spec.rb +17 -15
- metadata +1 -1
data/README.md
CHANGED
@@ -1,43 +1,38 @@
|
|
1
|
-
Shinmun,
|
1
|
+
Shinmun, the git-based blog engine
|
2
2
|
==========================================
|
3
3
|
|
4
4
|
Shinmun is a **minimalist blog engine**. You just write posts as text
|
5
|
-
files and serve your blog
|
6
|
-
|
7
|
-
|
8
|
-
VI and use a VCS like git.
|
9
|
-
|
10
|
-
Your layout can be customized by a set of *ERB templates*. These
|
11
|
-
templates have access to `Post` objects and *helper methods* so that
|
12
|
-
anybody who knows *Rails* should feel comfortable with it.
|
13
|
-
|
5
|
+
files and serve your blog straight from a git repository. You write
|
6
|
+
posts in your favorite editor like Emacs or VI and deploy via
|
7
|
+
`git push`.
|
14
8
|
|
15
9
|
### Features
|
16
10
|
|
17
|
-
* Index
|
18
|
-
*
|
19
|
-
*
|
20
|
-
*
|
21
|
-
*
|
22
|
-
* Phusion Passenger compatible
|
23
|
-
* Compression of javascript files with PackR
|
24
|
-
* Syntax highlighting for many languages provided by CodeRay
|
11
|
+
* Index, category and archive listings
|
12
|
+
* RSS feeds
|
13
|
+
* Flickr and Delicious aggregations
|
14
|
+
* Runs on Rack via [Kontrol][3]
|
15
|
+
* Syntax highlighting provided by CodeRay
|
25
16
|
* AJAX comment system with Markdown preview
|
26
17
|
|
27
|
-
|
28
18
|
### Quickstart
|
29
19
|
|
30
|
-
Install the
|
20
|
+
Install the gems:
|
31
21
|
|
32
|
-
gem
|
22
|
+
$ gem sources -a http://gems.github.com
|
23
|
+
$ gem install rack BlueCloth rubypants coderay mojombo-grit georgi-git_store georgi-kontrol georgi-shinmun
|
33
24
|
|
34
|
-
|
25
|
+
Create a sample blog (this step requires the git executable):
|
35
26
|
|
36
|
-
|
37
|
-
|
38
|
-
|
27
|
+
$ shinmun init myblog
|
28
|
+
|
29
|
+
This will create a directory with all necessary files. Now start the
|
30
|
+
web server:
|
31
|
+
|
32
|
+
$ cd myblog
|
33
|
+
$ rackup
|
39
34
|
|
40
|
-
|
35
|
+
Browse to the following url:
|
41
36
|
|
42
37
|
http://localhost:9292
|
43
38
|
|
@@ -49,7 +44,7 @@ Voilà, your first blog is up and running!
|
|
49
44
|
Posts can be created by using the `shinmun` command inside your blog
|
50
45
|
folder:
|
51
46
|
|
52
|
-
shinmun
|
47
|
+
shinmun post 'The title of the post'
|
53
48
|
|
54
49
|
Shinmun will then create a post file in the right place, for example
|
55
50
|
in `posts/2008/9/the-title-of-the-post.md`. After creating you will
|
@@ -59,55 +54,35 @@ your new article.
|
|
59
54
|
|
60
55
|
### Post Format
|
61
56
|
|
62
|
-
Each blog post is just a text file with
|
63
|
-
|
57
|
+
Each blog post is just a text file with a YAML header and a body. The
|
58
|
+
YAML header is surrounded with 2 lines of 3 dashes.
|
64
59
|
|
65
|
-
The
|
66
|
-
YAML header.
|
60
|
+
The YAML header has following attributes:
|
67
61
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
The yaml header may have following attributes:
|
73
|
-
|
74
|
-
* `title`: if you have no title inside the markup, you have to define it here
|
75
|
-
* `date`: needed for chronological order and for archive pages
|
76
|
-
* `category`: needed for category pages
|
77
|
-
* `tags`: used to determine similar posts
|
62
|
+
* `title`: mandatory
|
63
|
+
* `date`: posts need one, pages not
|
64
|
+
* `category`: a post belongs to one category
|
65
|
+
* `tags`: a comma separated list of tags
|
78
66
|
|
79
67
|
Example post:
|
80
68
|
|
81
69
|
---
|
82
70
|
date: 2008-09-05
|
83
71
|
category: Ruby
|
84
|
-
tags: bluecloth, markdown
|
85
|
-
|
86
|
-
|
87
|
-
=============================
|
88
|
-
|
72
|
+
tags: bluecloth, markdown
|
73
|
+
title: BlueCloth, a Markdown library
|
74
|
+
---
|
89
75
|
This is the summary, which is by definition the first paragraph of the
|
90
76
|
article. The summary shows up in category listings or the index listing.
|
91
77
|
|
92
78
|
|
93
79
|
### Syntax highlighting
|
94
80
|
|
95
|
-
Thanks to the fantastic highlighting library [CodeRay][4], highlighted
|
96
|
-
blocks can be embedded easily in Markdown. For Textile support
|
97
|
-
have to require `coderay/for_redcloth`. These languages are
|
98
|
-
|
99
|
-
|
100
|
-
* Diff
|
101
|
-
* Javascript
|
102
|
-
* Scheme
|
103
|
-
* CSS
|
104
|
-
* HTML
|
105
|
-
* XML
|
106
|
-
* Java
|
107
|
-
* JSON
|
108
|
-
* RHTML
|
109
|
-
* YAML
|
110
|
-
* Delphi
|
81
|
+
Thanks to the fantastic highlighting library [CodeRay][4], highlighted
|
82
|
+
code blocks can be embedded easily in Markdown. For Textile support
|
83
|
+
you have to require `coderay/for_redcloth`. These languages are
|
84
|
+
supported: C, Diff, Javascript, Scheme, CSS, HTML, XML, Java, JSON,
|
85
|
+
RHTML, YAML, Delphi
|
111
86
|
|
112
87
|
To activate CodeRay for a code block, you have to declare the language
|
113
88
|
in lower case:
|
@@ -123,21 +98,18 @@ in lower case:
|
|
123
98
|
|
124
99
|
### Directory layout
|
125
100
|
|
126
|
-
* `assets`:
|
127
|
-
|
128
|
-
* `
|
129
|
-
|
130
|
-
* `config`: configuration of blog, aggregations, assets and categories
|
131
|
-
|
101
|
+
* `assets`: contains images, stylesheets and javascripts
|
102
|
+
* `comments`: comments are stored as yaml files
|
103
|
+
* `config`: configuration of blog, aggregations and assets
|
132
104
|
* `posts`: post files sorted by year/month.
|
133
|
-
|
134
105
|
* `pages`: contains static pages
|
135
|
-
|
136
106
|
* `templates`: ERB templates for layout, posts and others
|
137
107
|
|
138
|
-
|
139
108
|
An example tree:
|
140
109
|
|
110
|
+
+ config.ru
|
111
|
+
+ map.rb
|
112
|
+
+ helpers.rb
|
141
113
|
+ assets
|
142
114
|
+ images
|
143
115
|
+ stylesheets
|
@@ -146,7 +118,6 @@ An example tree:
|
|
146
118
|
+ aggregations.yml
|
147
119
|
+ assets.yml
|
148
120
|
+ blog.yml
|
149
|
-
+ categories.yml
|
150
121
|
+ pages
|
151
122
|
+ about.md
|
152
123
|
+ posts
|
@@ -157,72 +128,45 @@ An example tree:
|
|
157
128
|
+ templates
|
158
129
|
+ category.rhtml
|
159
130
|
+ category.rxml
|
160
|
-
+
|
131
|
+
+ _comments.rhtml
|
132
|
+
+ _comment_form.rhtml
|
161
133
|
+ feed.rxml
|
162
134
|
+ helpers.rb
|
163
135
|
+ index.rhtml
|
164
136
|
+ index.rxml
|
165
137
|
+ layout.rhtml
|
166
138
|
+ post.rhtml
|
139
|
+
+ page.rhtml
|
167
140
|
|
168
141
|
|
169
142
|
### Blog configuation
|
170
143
|
|
171
|
-
Inside `config/blog.yml` you
|
144
|
+
Inside `config/blog.yml` you set the properties of your blog:
|
172
145
|
|
173
146
|
* title: the title of your blog, used inside templates
|
174
|
-
|
175
147
|
* description: used for RSS
|
176
|
-
|
177
148
|
* language: used for RSS
|
178
|
-
|
179
149
|
* author: used for RSS
|
180
|
-
|
181
150
|
* url: used for RSS
|
151
|
+
* categories: a list of categories
|
182
152
|
|
183
|
-
|
184
|
-
|
185
|
-
* base_path: if your blog should not be rendered to your site
|
186
|
-
root, you can define a sub path here (like `blog`)
|
187
|
-
|
188
|
-
|
189
|
-
### Asset configuation
|
190
|
-
|
191
|
-
If you set the variables `javascripts_files` or `stylesheets_files`,
|
192
|
-
Shinmun will compress the javascripts to `all.js` and concatenate all
|
193
|
-
stylesheets to `all.css` automatically.
|
194
|
-
|
195
|
-
* images_path: used for templates helper
|
196
|
-
|
197
|
-
* javascripts_path: used for templates helper
|
198
|
-
|
199
|
-
* stylesheets_path: used for templates helper
|
153
|
+
### Assets
|
200
154
|
|
201
|
-
|
155
|
+
By default Shinmun serves asset files from your assets directory. If
|
156
|
+
you want some other behaviour, you can tweak the `map.rb` file in your
|
157
|
+
blog folder, which contains all routes.
|
202
158
|
|
203
|
-
|
159
|
+
If you set the variables `javascripts_files` or `stylesheets_files` in
|
160
|
+
`config/asstes.yml`, Shinmun will serve the javascripts as
|
161
|
+
`assets/javascripts.js` and stylesheets as `assets/stylesheets.css`
|
162
|
+
automatically. Both variables should be arrays of the filenames
|
163
|
+
without extension.
|
204
164
|
|
205
|
-
|
206
|
-
### Categories
|
207
|
-
|
208
|
-
You have to list your categories in `config/categories.yml`. This will
|
209
|
-
look like:
|
210
|
-
|
211
|
-
---
|
212
|
-
categories:
|
213
|
-
- { name: Ruby }
|
214
|
-
- { name: Javascript }
|
215
|
-
|
216
|
-
You may define arbitrary properties for each category, which then can
|
217
|
-
be accessed inside the templates. For example you could add a
|
218
|
-
description and use it inside the `templates/category.rhtml`.
|
219
|
-
|
220
|
-
|
221
|
-
### Layout
|
165
|
+
### Templates
|
222
166
|
|
223
167
|
Layout and templates are rendered by *ERB*. The layout is defined in
|
224
168
|
`templates/layout.rhtml`. The content will be provided in the variable
|
225
|
-
`@content`. A minimal
|
169
|
+
`@content`. A minimal example:
|
226
170
|
|
227
171
|
<html>
|
228
172
|
<head>
|
@@ -234,105 +178,65 @@ Layout and templates are rendered by *ERB*. The layout is defined in
|
|
234
178
|
</body>
|
235
179
|
</html>
|
236
180
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
There are also helper methods, which work the same way like the *Rails*
|
241
|
-
helpers. The most important ones are these:
|
242
|
-
|
243
|
-
* `stylesheet_link_tag(*names)` links a stylesheet with a timestamp
|
244
|
-
|
245
|
-
* `javascript_tag(*names)` includes a javascript with a timestamp
|
246
|
-
|
247
|
-
* `image_tag(src, options = {})` renders an image tag
|
248
|
-
|
249
|
-
* `link_to(text, path, options = {})` renders a link
|
250
|
-
|
251
|
-
Stylesheets, javascripts and images should be included by using theses
|
252
|
-
helpers. The helper methods will include a timestamp of the
|
253
|
-
modification time as `querystring`, so that the browser will fetch the
|
254
|
-
new resource if it has been changed.
|
255
|
-
|
256
|
-
If you want to define your own helpers, just define a file named
|
257
|
-
`templates/helpers.rb` with a module named `Shinmun::Helpers`. This
|
258
|
-
module will be included into the `Shinmun::Template` class.
|
259
|
-
|
260
|
-
|
261
|
-
### Post Template
|
262
|
-
|
263
|
-
The attributes of a post are accessible as instance variables in a template:
|
181
|
+
The attributes of a post are accessible as instance variables in a
|
182
|
+
template:
|
264
183
|
|
265
184
|
<div class="article">
|
266
|
-
|
267
185
|
<div class="date">
|
268
186
|
<%= date @date %>
|
269
187
|
</div>
|
270
|
-
|
271
188
|
<h2><%= @title %></h2>
|
272
|
-
|
273
189
|
<%= @body %>
|
274
|
-
|
275
190
|
<h3>Comments</h3>
|
276
|
-
|
277
191
|
<!-- comment form -->
|
278
192
|
</div>
|
279
193
|
|
280
194
|
|
281
195
|
### Commenting System
|
282
196
|
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
197
|
+
Comments are stored as flat files and encoded as YAML objects. Each
|
198
|
+
post has a corresponding comment file located at `comments/<path to
|
199
|
+
post>`. So administration of comments is possible by editing the YAML
|
200
|
+
file, which can be done on your local machine, as you can just pull
|
201
|
+
the comments from your live server.
|
288
202
|
|
203
|
+
### Deployment
|
289
204
|
|
290
|
-
|
205
|
+
Shinmun can server the blog straight from the git repository. So on
|
206
|
+
your webserver initialize a new git repo like:
|
291
207
|
|
292
|
-
|
293
|
-
|
294
|
-
|
208
|
+
$ cd /var/www
|
209
|
+
$ mkdir myblog
|
210
|
+
$ cd myblog
|
211
|
+
$ git init
|
295
212
|
|
296
|
-
|
297
|
-
|
298
|
-
variable inside `config/blog.yml`. It should contain something like
|
299
|
-
`user@myhost.com:/var/www/my-site/`.
|
213
|
+
Now on your local machine, you add a new remote repository and push
|
214
|
+
your blog to your server:
|
300
215
|
|
216
|
+
$ cd ~/myblog
|
217
|
+
$ git remote add live ssh://myserver.com/var/www/myblog
|
218
|
+
$ git push live
|
301
219
|
|
302
|
-
### Realtime Rendering
|
303
220
|
|
304
|
-
|
305
|
-
|
306
|
-
rackup file called `config.ru`. To start the standalone server just
|
307
|
-
run:
|
221
|
+
On your production server, you just need the rackup file `config.ru`
|
222
|
+
to run the blog:
|
308
223
|
|
309
|
-
$
|
224
|
+
$ git checkout config.ru
|
310
225
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
stylesheets will be packed at runtime if you configured it. Shinmun
|
315
|
-
caches all files, so that everything get served from memory.
|
226
|
+
Now you can run just a pure ruby server or something like Phusion
|
227
|
+
Passenger. Anytime you want to publish a post on your blog, you
|
228
|
+
just write, commit and finally push a post by:
|
316
229
|
|
230
|
+
$ git commit -a -m 'new post'
|
231
|
+
$ git push live
|
317
232
|
|
318
233
|
### Phusion Passenger
|
319
234
|
|
320
|
-
Shinmun is
|
235
|
+
Shinmun is compatible with [Phusion Passenger][5]. Install Phusion
|
321
236
|
Passenger as described in my [blog post][2].
|
322
237
|
|
323
|
-
|
324
|
-
|
325
|
-
your assets folders:
|
326
|
-
|
327
|
-
# cd public
|
328
|
-
# ln -s ../assets/images
|
329
|
-
# ln -s ../assets/javascripts
|
330
|
-
# ln -s ../assets/stylesheets
|
331
|
-
|
332
|
-
This is just to ensure that static files will be served by Apache.
|
333
|
-
|
334
|
-
Assuming that you are on a Debian or Ubuntu system, you can now create
|
335
|
-
a file named `/etc/apache2/sites-available/blog`:
|
238
|
+
Assuming that you are on a Debian or Ubuntu system, you can create a
|
239
|
+
file named `/etc/apache2/sites-available/blog`:
|
336
240
|
|
337
241
|
<VirtualHost *:80>
|
338
242
|
ServerName myblog.com
|
@@ -349,13 +253,32 @@ domain:
|
|
349
253
|
$ /etc/init.d/apache2 restart
|
350
254
|
|
351
255
|
|
256
|
+
### Web Frontend
|
257
|
+
|
258
|
+
The example blog has a builtin web frontend. To activate you have to
|
259
|
+
create a file named `password` with a single password inside. Now
|
260
|
+
browse to `/admin` and login using some arbitrary username and your
|
261
|
+
password.
|
262
|
+
|
263
|
+
The frontend allows you to create, edit, read or delete posts or
|
264
|
+
pages. Editing a post shows up a form with the [wmd editor][6]. You
|
265
|
+
have to look yourself for a correct YAML header, otherwise you will
|
266
|
+
get incorrect results.
|
267
|
+
|
268
|
+
One nice thing about the frontend is the *Commits* page, where you can
|
269
|
+
look at a list of recent commits. Clicking on a commit brings you to a
|
270
|
+
single commit overview, where you can inspect changes introduced by
|
271
|
+
this particular commit.
|
272
|
+
|
273
|
+
|
352
274
|
### Download
|
353
275
|
|
354
276
|
Download or fork the package at my [github repository][1]
|
355
277
|
|
356
278
|
|
357
|
-
[1]: http://github.com/georgi/shinmun
|
279
|
+
[1]: http://github.com/georgi/shinmun
|
358
280
|
[2]: http://www.matthias-georgi.de/2008/9/quick-guide-for-passenger-on-ubuntu-hardy.html
|
359
|
-
[3]: http://github.com/georgi/
|
281
|
+
[3]: http://github.com/georgi/kontrol
|
360
282
|
[4]: http://coderay.rubychan.de/
|
361
283
|
[5]: http://www.modrails.com/
|
284
|
+
[6]: http://wmd-editor.com/
|
data/bin/shinmun
CHANGED
@@ -7,6 +7,14 @@ when 'init'
|
|
7
7
|
Shinmun::Blog.init ARGV[1]
|
8
8
|
|
9
9
|
when 'post'
|
10
|
+
Shinmun::Blog.new.create_post(:title => ARGV[1], :date => Date.today)
|
11
|
+
|
12
|
+
when 'page'
|
10
13
|
Shinmun::Blog.new.create_post(:title => ARGV[1])
|
11
14
|
|
15
|
+
else
|
16
|
+
puts "Usage:"
|
17
|
+
puts " shinmun init dir - creates a new blog"
|
18
|
+
puts " shinmun post 'Title of the post' - create a new post"
|
19
|
+
puts " shinmun page 'Title of the page' - create a new page"
|
12
20
|
end
|
data/lib/shinmun/blog.rb
CHANGED
@@ -11,7 +11,7 @@ module Shinmun
|
|
11
11
|
config_reader 'blog.yml', :title, :description, :language, :author, :url, :repository, :base_path, :categories
|
12
12
|
|
13
13
|
# Initialize the blog
|
14
|
-
def initialize
|
14
|
+
def initialize
|
15
15
|
super
|
16
16
|
|
17
17
|
@aggregations = {}
|
@@ -51,11 +51,11 @@ module Shinmun
|
|
51
51
|
end
|
52
52
|
|
53
53
|
def recent_posts
|
54
|
-
posts.sort_by { |post| post.date }.reverse[0, 20]
|
54
|
+
posts.sort_by { |post| post.date.to_s }.reverse[0, 20]
|
55
55
|
end
|
56
56
|
|
57
57
|
def posts_by_date
|
58
|
-
posts.sort_by { |post| post.date }.reverse
|
58
|
+
posts.sort_by { |post| post.date.to_s }.reverse
|
59
59
|
end
|
60
60
|
|
61
61
|
# Return all posts for a given month.
|
@@ -98,10 +98,11 @@ module Shinmun
|
|
98
98
|
store.commit(message)
|
99
99
|
end
|
100
100
|
|
101
|
-
# Create a new post with given
|
101
|
+
# Create a new post with given attributes.
|
102
102
|
def create_post(atts = {})
|
103
103
|
atts = { :type => 'md' }.merge(symbolize_keys(atts))
|
104
|
-
|
104
|
+
title = atts[:title] or raise "no title given"
|
105
|
+
atts[:name] ||= urlify(title)
|
105
106
|
post = Post.new(atts)
|
106
107
|
tree_for(post)[post.filename] = post
|
107
108
|
commit "created `#{post.title}`"
|
data/lib/shinmun/post.rb
CHANGED
@@ -7,10 +7,8 @@ module Shinmun
|
|
7
7
|
# ---
|
8
8
|
# category: Ruby
|
9
9
|
# date: 2008-09-05
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# =============================
|
13
|
-
#
|
10
|
+
# title: BlueCloth, a Markdown library
|
11
|
+
# ---
|
14
12
|
# This is the summary, which is by definition the first paragraph of the
|
15
13
|
# article. The summary shows up in list views and rss feeds.
|
16
14
|
#
|
@@ -25,15 +23,15 @@ module Shinmun
|
|
25
23
|
end
|
26
24
|
end
|
27
25
|
|
28
|
-
attr_accessor :name, :type, :
|
29
|
-
head_accessor :author, :date, :category, :tags
|
26
|
+
attr_accessor :name, :type, :src, :head, :body, :summary, :body_html, :tag_list
|
27
|
+
head_accessor :title, :author, :date, :category, :tags
|
30
28
|
|
31
29
|
# Initialize empty post and set specified attributes.
|
32
30
|
def initialize(attributes={})
|
33
31
|
@head = {}
|
34
32
|
@body = ''
|
35
33
|
|
36
|
-
|
34
|
+
attributes.each do |k, v|
|
37
35
|
send "#{k}=", v
|
38
36
|
end
|
39
37
|
|
@@ -80,60 +78,30 @@ module Shinmun
|
|
80
78
|
end
|
81
79
|
|
82
80
|
# Split up the source into header and body. Load the header as
|
83
|
-
# yaml document
|
81
|
+
# yaml document if present.
|
84
82
|
def parse(src)
|
85
|
-
src
|
86
|
-
|
87
|
-
# Parse YAML header if present
|
88
|
-
if src =~ /\A(---.*?)\n\n(.*)/m
|
83
|
+
if src =~ /\A(---.*?)---(.*)/m
|
89
84
|
@head = YAML.load($1)
|
90
85
|
@body = $2
|
91
86
|
else
|
92
87
|
@body = src
|
93
88
|
end
|
94
89
|
|
95
|
-
@
|
96
|
-
@body_html = transform(body)
|
90
|
+
@body_html = transform(@body)
|
97
91
|
@summary = body_html.split("\n\n")[0]
|
98
92
|
@tag_list = tags.to_s.split(",").map { |s| s.strip }
|
99
93
|
|
100
94
|
self
|
101
95
|
end
|
102
96
|
|
103
|
-
#
|
104
|
-
def
|
105
|
-
|
106
|
-
|
107
|
-
return if lines.empty?
|
108
|
-
|
109
|
-
case type
|
110
|
-
when 'md'
|
111
|
-
@title = lines.shift.sub(/(^#+|#+$)/,'').strip
|
112
|
-
lines.shift if lines.first.match(/^(=|-)+$/)
|
113
|
-
|
114
|
-
when 'html'
|
115
|
-
@title = lines.shift.sub(/(<h1>|\<\/h1>)/,'').strip
|
116
|
-
|
117
|
-
when 'tt'
|
118
|
-
@title = lines.shift.sub(/(^h1.)/,'').strip
|
119
|
-
end
|
120
|
-
|
121
|
-
@body = lines.join("\n")
|
97
|
+
# The header as yaml string.
|
98
|
+
def dump_head
|
99
|
+
head.empty? ? '' : head.to_yaml + "---\n"
|
122
100
|
end
|
123
101
|
|
124
102
|
# Convert to string representation
|
125
103
|
def dump
|
126
|
-
|
127
|
-
unless head['title']
|
128
|
-
str << \
|
129
|
-
case type
|
130
|
-
when 'md' : "#{title}\n#{'=' * title.size}\n"
|
131
|
-
when 'html' : "<h1>#{title}</h1>\n"
|
132
|
-
when 'tt' : "h1.#{title}\n"
|
133
|
-
else raise
|
134
|
-
end
|
135
|
-
end
|
136
|
-
str + body
|
104
|
+
dump_head + body
|
137
105
|
end
|
138
106
|
|
139
107
|
# Transform the body of this post. Defaults to Markdown.
|
data/lib/shinmun/post_handler.rb
CHANGED
data/lib/shinmun.rb
CHANGED
@@ -1,15 +1,12 @@
|
|
1
1
|
require 'rubygems'
|
2
2
|
require 'fileutils'
|
3
|
-
|
4
3
|
require 'bluecloth'
|
5
4
|
require 'rubypants'
|
6
5
|
require 'coderay'
|
7
|
-
require '
|
8
|
-
require 'grit'
|
6
|
+
require 'kontrol'
|
9
7
|
|
10
8
|
begin; require 'redcloth'; rescue LoadError; end
|
11
9
|
|
12
|
-
require 'kontrol'
|
13
10
|
require 'shinmun/bluecloth_coderay'
|
14
11
|
require 'shinmun/helpers'
|
15
12
|
require 'shinmun/blog'
|
data/test/blog_spec.rb
CHANGED
@@ -31,11 +31,13 @@ describe Shinmun::Blog do
|
|
31
31
|
file 'map.rb', File.read(TEST_DIR + '/map.rb')
|
32
32
|
|
33
33
|
Dir.mkdir 'templates'
|
34
|
+
|
34
35
|
Dir[TEMPLATES_DIR + '/*'].each do |path|
|
35
36
|
unless path.include?('~')
|
36
37
|
file 'templates/' + File.basename(path), File.read(path)
|
37
38
|
end
|
38
|
-
end
|
39
|
+
end
|
40
|
+
|
39
41
|
@blog.store.load
|
40
42
|
|
41
43
|
@posts = [@blog.create_post(:title => 'New post', :date => '2008-10-10', :category => 'Ruby', :body => 'Body1'),
|
@@ -44,7 +46,7 @@ describe Shinmun::Blog do
|
|
44
46
|
|
45
47
|
@pages = [@blog.create_post(:title => 'Page 1', :body => 'Body1'),
|
46
48
|
@blog.create_post(:title => 'Page 2', :body => 'Body2')]
|
47
|
-
|
49
|
+
|
48
50
|
@blog.store.load
|
49
51
|
end
|
50
52
|
|
@@ -66,7 +68,17 @@ describe Shinmun::Blog do
|
|
66
68
|
|
67
69
|
def xpath(xml, path)
|
68
70
|
REXML::XPath.match(REXML::Document.new(xml), path)
|
69
|
-
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def assert_listing(xml, list)
|
74
|
+
titles = xpath(xml, "//h2/a")
|
75
|
+
summaries = xpath(xml, "//p")
|
76
|
+
|
77
|
+
list.each_with_index do |(title, summary), i|
|
78
|
+
titles[i].text.should == title
|
79
|
+
summaries[i].text.strip.should == summary
|
80
|
+
end
|
81
|
+
end
|
70
82
|
|
71
83
|
it "should find posts for a category" do
|
72
84
|
category = @blog.find_category('ruby')
|
@@ -92,7 +104,7 @@ describe Shinmun::Blog do
|
|
92
104
|
|
93
105
|
it "should update a post" do
|
94
106
|
post = @blog.create_post(:title => 'New post', :date => '2008-10-10')
|
95
|
-
@blog.update_post(post, "---\ndate: 2008-11-11\
|
107
|
+
@blog.update_post(post, "---\ndate: 2008-11-11\ntitle: The title\n---")
|
96
108
|
@blog.store.load
|
97
109
|
|
98
110
|
post = @blog.find_post(2008, 11, 'new-post')
|
@@ -117,16 +129,6 @@ describe Shinmun::Blog do
|
|
117
129
|
xpath(xml, "//p")[0].text.should == 'Body1'
|
118
130
|
end
|
119
131
|
|
120
|
-
def assert_listing(xml, list)
|
121
|
-
titles = xpath(xml, "//h2/a")
|
122
|
-
summaries = xpath(xml, "//p")
|
123
|
-
|
124
|
-
list.each_with_index do |(title, summary), i|
|
125
|
-
titles[i].text.should == title
|
126
|
-
summaries[i].text.strip.should == summary
|
127
|
-
end
|
128
|
-
end
|
129
|
-
|
130
132
|
it "should render categories" do
|
131
133
|
get('/categories/ruby.rss')['Content-Type'].should == 'application/rss+xml'
|
132
134
|
|
@@ -149,7 +151,7 @@ describe Shinmun::Blog do
|
|
149
151
|
end
|
150
152
|
|
151
153
|
it "should render pages" do
|
152
|
-
xml = get('/page-1').body
|
154
|
+
xml = get('/page-1').body
|
153
155
|
xpath(xml, "//h1")[0].text.should == 'Page 1'
|
154
156
|
xpath(xml, "//p")[0].text.should == 'Body1'
|
155
157
|
|