georgi-shinmun 0.3 → 0.3.1
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 +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
|
|