georgi-shinmun 0.3

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.
Files changed (86) hide show
  1. data/.gitignore +3 -0
  2. data/LICENSE +18 -0
  3. data/README.md +361 -0
  4. data/Rakefile +17 -0
  5. data/bin/shinmun +12 -0
  6. data/example/Rakefile +41 -0
  7. data/example/assets/images/favicon.ico +0 -0
  8. data/example/assets/images/loading.gif +0 -0
  9. data/example/assets/javascripts/coderay.js +13 -0
  10. data/example/assets/javascripts/comments.js +45 -0
  11. data/example/assets/javascripts/jquery-form.min.js +5 -0
  12. data/example/assets/javascripts/jquery.min.js +32 -0
  13. data/example/assets/stylesheets/article.css +15 -0
  14. data/example/assets/stylesheets/coderay.css +100 -0
  15. data/example/assets/stylesheets/comments.css +20 -0
  16. data/example/assets/stylesheets/form.css +12 -0
  17. data/example/assets/stylesheets/list.css +13 -0
  18. data/example/assets/stylesheets/print.css +76 -0
  19. data/example/assets/stylesheets/reset.css +23 -0
  20. data/example/assets/stylesheets/style.css +83 -0
  21. data/example/assets/stylesheets/table.css +24 -0
  22. data/example/assets/stylesheets/typo.css +40 -0
  23. data/example/assets/wmd/images/bg-fill.png +0 -0
  24. data/example/assets/wmd/images/bg.png +0 -0
  25. data/example/assets/wmd/images/blockquote.png +0 -0
  26. data/example/assets/wmd/images/bold.png +0 -0
  27. data/example/assets/wmd/images/code.png +0 -0
  28. data/example/assets/wmd/images/h1.png +0 -0
  29. data/example/assets/wmd/images/hr.png +0 -0
  30. data/example/assets/wmd/images/img.png +0 -0
  31. data/example/assets/wmd/images/italic.png +0 -0
  32. data/example/assets/wmd/images/link.png +0 -0
  33. data/example/assets/wmd/images/ol.png +0 -0
  34. data/example/assets/wmd/images/redo.png +0 -0
  35. data/example/assets/wmd/images/separator.png +0 -0
  36. data/example/assets/wmd/images/ul.png +0 -0
  37. data/example/assets/wmd/images/undo.png +0 -0
  38. data/example/assets/wmd/images/wmd-on.png +0 -0
  39. data/example/assets/wmd/images/wmd.png +0 -0
  40. data/example/assets/wmd/showdown.js +421 -0
  41. data/example/assets/wmd/wmd-base.js +1799 -0
  42. data/example/assets/wmd/wmd-plus.js +311 -0
  43. data/example/assets/wmd/wmd.js +73 -0
  44. data/example/config.ru +8 -0
  45. data/example/config/aggregations.yml +1 -0
  46. data/example/config/assets.yml +13 -0
  47. data/example/config/blog.yml +10 -0
  48. data/example/map.rb +100 -0
  49. data/example/pages/about.md +6 -0
  50. data/example/password +1 -0
  51. data/example/templates/_comment_form.rhtml +90 -0
  52. data/example/templates/_comments.rhtml +11 -0
  53. data/example/templates/_pagination.rhtml +10 -0
  54. data/example/templates/admin/commit.rhtml +27 -0
  55. data/example/templates/admin/commits.rhtml +9 -0
  56. data/example/templates/admin/edit.rhtml +17 -0
  57. data/example/templates/admin/pages.rhtml +19 -0
  58. data/example/templates/admin/posts.rhtml +24 -0
  59. data/example/templates/category.rhtml +12 -0
  60. data/example/templates/category.rxml +20 -0
  61. data/example/templates/index.rhtml +12 -0
  62. data/example/templates/index.rxml +21 -0
  63. data/example/templates/layout.rhtml +82 -0
  64. data/example/templates/page.rhtml +7 -0
  65. data/example/templates/post.rhtml +48 -0
  66. data/lib/shinmun.rb +21 -0
  67. data/lib/shinmun/aggregations/delicious.rb +57 -0
  68. data/lib/shinmun/aggregations/flickr.rb +81 -0
  69. data/lib/shinmun/blog.rb +165 -0
  70. data/lib/shinmun/bluecloth_coderay.rb +21 -0
  71. data/lib/shinmun/comment.rb +17 -0
  72. data/lib/shinmun/helpers.rb +64 -0
  73. data/lib/shinmun/post.rb +161 -0
  74. data/lib/shinmun/post_handler.rb +17 -0
  75. data/templates/_comments.rhtml +11 -0
  76. data/templates/archive.rhtml +6 -0
  77. data/templates/category.rhtml +6 -0
  78. data/templates/category.rxml +20 -0
  79. data/templates/index.rhtml +4 -0
  80. data/templates/index.rxml +21 -0
  81. data/templates/layout.rhtml +9 -0
  82. data/templates/page.rhtml +2 -0
  83. data/templates/post.rhtml +3 -0
  84. data/test/blog_spec.rb +177 -0
  85. data/test/map.rb +51 -0
  86. metadata +172 -0
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *~
2
+ doc/*
3
+ pkg/*
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (c) 2008 Matthias Georgi <http://www.matthias-georgi.de>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to
5
+ deal in the Software without restriction, including without limitation the
6
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,361 @@
1
+ Shinmun, a small and beautiful blog engine
2
+ ==========================================
3
+
4
+ Shinmun is a **minimalist blog engine**. You just write posts as text
5
+ files and serve your blog via rack handler or static files.
6
+
7
+ This allows you to write posts in your favorite editor like Emacs or
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
+
14
+
15
+ ### Features
16
+
17
+ * Index listing
18
+ * Category listing
19
+ * Archive listings for each month
20
+ * RSS feeds for index and category pages
21
+ * Rack handler for realtime rendering
22
+ * Phusion Passenger compatible
23
+ * Compression of javascript files with PackR
24
+ * Syntax highlighting for many languages provided by CodeRay
25
+ * AJAX comment system with Markdown preview
26
+
27
+
28
+ ### Quickstart
29
+
30
+ Install the gem:
31
+
32
+ gem install shinmun
33
+
34
+ Download shinmun-example from my [github repository][3] and type:
35
+
36
+ tar xvzf shinmun-example.tar.gz
37
+ cd shinmun-example
38
+ rackup
39
+
40
+ Now browse to the following url:
41
+
42
+ http://localhost:9292
43
+
44
+ Voilà, your first blog is up and running!
45
+
46
+
47
+ ### Writing Posts
48
+
49
+ Posts can be created by using the `shinmun` command inside your blog
50
+ folder:
51
+
52
+ shinmun new 'The title of the post'
53
+
54
+ Shinmun will then create a post file in the right place, for example
55
+ in `posts/2008/9/the-title-of-the-post.md`. After creating you will
56
+ probably open the file, set the category and tags and start writing
57
+ your new article.
58
+
59
+
60
+ ### Post Format
61
+
62
+ Each blog post is just a text file with an header section and a markup
63
+ body, which are separated by a newline.
64
+
65
+ The **first line** of a post should consist of 3 dashes to mark the
66
+ YAML header.
67
+
68
+ The title of your post will be parsed from your first heading
69
+ according to the document type. Shinmun will try to figure out the
70
+ title for Markdown, Textile and HTML files.
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
78
+
79
+ Example post:
80
+
81
+ ---
82
+ date: 2008-09-05
83
+ category: Ruby
84
+ tags: bluecloth, markdown, ruby
85
+
86
+ BlueCloth, a Markdown library
87
+ =============================
88
+
89
+ This is the summary, which is by definition the first paragraph of the
90
+ article. The summary shows up in category listings or the index listing.
91
+
92
+
93
+ ### Syntax highlighting
94
+
95
+ Thanks to the fantastic highlighting library [CodeRay][4], highlighted code
96
+ blocks can be embedded easily in Markdown. For Textile support you
97
+ have to require `coderay/for_redcloth`. These languages are supported:
98
+
99
+ * C
100
+ * Diff
101
+ * Javascript
102
+ * Scheme
103
+ * CSS
104
+ * HTML
105
+ * XML
106
+ * Java
107
+ * JSON
108
+ * RHTML
109
+ * YAML
110
+ * Delphi
111
+
112
+ To activate CodeRay for a code block, you have to declare the language
113
+ in lower case:
114
+
115
+ @@ruby
116
+
117
+ def method_missing(id, *args, &block)
118
+ puts "#{id} was called with #{args.inspect}"
119
+ end
120
+
121
+ **Note that the declaration MUST be followed by a blank line!**
122
+
123
+
124
+ ### Directory layout
125
+
126
+ * `assets`: like images, stylesheets and javascripts
127
+
128
+ * `comments`: comments stored as yaml files
129
+
130
+ * `config`: configuration of blog, aggregations, assets and categories
131
+
132
+ * `posts`: post files sorted by year/month.
133
+
134
+ * `pages`: contains static pages
135
+
136
+ * `templates`: ERB templates for layout, posts and others
137
+
138
+
139
+ An example tree:
140
+
141
+ + assets
142
+ + images
143
+ + stylesheets
144
+ + javascripts
145
+ + config
146
+ + aggregations.yml
147
+ + assets.yml
148
+ + blog.yml
149
+ + categories.yml
150
+ + pages
151
+ + about.md
152
+ + posts
153
+ + 2007
154
+ + 2008
155
+ + 9
156
+ + my-article.md
157
+ + templates
158
+ + category.rhtml
159
+ + category.rxml
160
+ + comments.rhtml
161
+ + feed.rxml
162
+ + helpers.rb
163
+ + index.rhtml
164
+ + index.rxml
165
+ + layout.rhtml
166
+ + post.rhtml
167
+
168
+
169
+ ### Blog configuation
170
+
171
+ Inside `config/blog.yml` you will set the properties of your blog:
172
+
173
+ * title: the title of your blog, used inside templates
174
+
175
+ * description: used for RSS
176
+
177
+ * language: used for RSS
178
+
179
+ * author: used for RSS
180
+
181
+ * url: used for RSS
182
+
183
+ * blog_repository: path for rsync, used for `shinmun push` command
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
200
+
201
+ * javascripts_files: a list of scripts to be compressed to `all.js`
202
+
203
+ * stylesheets_files: a list of stylesheets to be concatenated to `all.css`
204
+
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
222
+
223
+ Layout and templates are rendered by *ERB*. The layout is defined in
224
+ `templates/layout.rhtml`. The content will be provided in the variable
225
+ `@content`. A minimal but functional example:
226
+
227
+ <html>
228
+ <head>
229
+ <title><%= @blog.title %></title>
230
+ <%= stylesheet_link_tag 'style' %>
231
+ </head>
232
+ <body>
233
+ <%= @content %>
234
+ </body>
235
+ </html>
236
+
237
+
238
+ ### Helpers
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:
264
+
265
+ <div class="article">
266
+
267
+ <div class="date">
268
+ <%= date @date %>
269
+ </div>
270
+
271
+ <h2><%= @title %></h2>
272
+
273
+ <%= @body %>
274
+
275
+ <h3>Comments</h3>
276
+
277
+ <!-- comment form -->
278
+ </div>
279
+
280
+
281
+ ### Commenting System
282
+
283
+ Commenting is only available in the rack handler. Comments are stored
284
+ as flat files and encoded as YAML objects. Each post has a
285
+ corresponding comment file located at `comments/<path to post>`. So
286
+ administration of comments is possible by editing the YAML file, you
287
+ can even version control your comments if you want.
288
+
289
+
290
+ ### Static Output
291
+
292
+ To render your complete blog you may run `shinmun render` and the
293
+ output will be rendered to the `public` folder. Note that in this case
294
+ you will miss some dynamic features like the commenting system.
295
+
296
+ By issuing the `shinmun push` command your blog will be pushed to your
297
+ server using rsync. This works only, if you define the `repository`
298
+ variable inside `config/blog.yml`. It should contain something like
299
+ `user@myhost.com:/var/www/my-site/`.
300
+
301
+
302
+ ### Realtime Rendering
303
+
304
+ Shinmun features a lightweight rack handler, which lets you run your
305
+ blog in almost any environment. In `shinmun-example` you will find a
306
+ rackup file called `config.ru`. To start the standalone server just
307
+ run:
308
+
309
+ $ rackup
310
+
311
+ Browse to `http://localhost:9292` and you will see your blog served in
312
+ realtime. Just change any of your posts, templates or settings and you
313
+ will see the new output in your browser. Even the javascripts and
314
+ stylesheets will be packed at runtime if you configured it. Shinmun
315
+ caches all files, so that everything get served from memory.
316
+
317
+
318
+ ### Phusion Passenger
319
+
320
+ Shinmun is already compatible with [Phusion Passenger][5]. Install Phusion
321
+ Passenger as described in my [blog post][2].
322
+
323
+ Now copy your blog folder to some folder like `/var/www/blog` and
324
+ create a sub directory `public`. Inside this directory you should link
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`:
336
+
337
+ <VirtualHost *:80>
338
+ ServerName myblog.com
339
+ DocumentRoot /var/www/blog/public
340
+ </VirtualHost>
341
+
342
+ Enable the new virtual host:
343
+
344
+ $ a2ensite myapp
345
+
346
+ After restarting Apache your blog should run on Apache on your desired
347
+ domain:
348
+
349
+ $ /etc/init.d/apache2 restart
350
+
351
+
352
+ ### Download
353
+
354
+ Download or fork the package at my [github repository][1]
355
+
356
+
357
+ [1]: http://github.com/georgi/shinmun/tree/master
358
+ [2]: http://www.matthias-georgi.de/2008/9/quick-guide-for-passenger-on-ubuntu-hardy.html
359
+ [3]: http://github.com/georgi/shinmun-example/tree/master
360
+ [4]: http://coderay.rubychan.de/
361
+ [5]: http://www.modrails.com/
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'rake'
2
+ require 'rake/rdoctask'
3
+
4
+ desc "Generate RDoc documentation"
5
+ Rake::RDocTask.new(:rdoc) do |rdoc|
6
+ rdoc.options << '--line-numbers' << '--inline-source' <<
7
+ '--main' << 'README.md' <<
8
+ '--title' << 'Shinmun Documentation' <<
9
+ '--charset' << 'utf-8'
10
+ rdoc.rdoc_dir = "doc"
11
+ rdoc.rdoc_files.include 'README.md'
12
+ Dir['lib/**/*.rb'].each do |file|
13
+ rdoc.rdoc_files.include file
14
+ end
15
+ end
16
+
17
+
data/bin/shinmun ADDED
@@ -0,0 +1,12 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ require 'shinmun'
4
+
5
+ case ARGV[0]
6
+ when 'init'
7
+ Shinmun::Blog.init ARGV[1]
8
+
9
+ when 'post'
10
+ Shinmun::Blog.new.create_post(:title => ARGV[1])
11
+
12
+ end
data/example/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ require 'shinmun'
2
+
3
+ blog = Shinmun::Blog.new
4
+
5
+ task :index do
6
+ blog.write "index.html", "index.rhtml"
7
+ blog.write "index.rss", "index.rxml"
8
+ end
9
+
10
+ blog.pages.each do |page|
11
+ task page.path do
12
+ blog.write page.path, "page.rhtml", :page => page
13
+ end
14
+ end
15
+
16
+ blog.posts.each do |post|
17
+ task "#{post.path}.html" do
18
+ blog.write "#{post.path}.html", "post.rhtml", :post => post
19
+ end
20
+ end
21
+
22
+ blog.archives.each do |year, month|
23
+ task "#{year}/#{month}" do
24
+ blog.write "#{year}/#{month}/index.html", "archive.rhtml", :year => year, :month => month
25
+ end
26
+ end
27
+
28
+ blog.categories.each do |name|
29
+ category = blog.find_category(name)
30
+ task "categories/#{category[:permalink]}" do
31
+ blog.write "categories/#{category[:permalink]}.html", "category.rhtml", category
32
+ blog.write "categories/#{category[:permalink]}.rss", "category.rxml", category
33
+ end
34
+ end
35
+
36
+ task :pages => blog.pages.map { |p| p.path }
37
+ task :posts => blog.posts.map { |p| p.path }
38
+ task :archives => blog.archives.map { |y,m| "#{y}/#{m}" }
39
+ task :categories => blog.categories.map { |name| "categories/#{blog.urlify name}" }
40
+
41
+ task :default => [:index, :pages, :posts, :archives, :categories]