serious 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Serious is a blog engine inspired by other filesystem-based engines like jekyll (http://jekyllrb.com/)
4
4
  and toto (http://cloudhead.io/toto) and is based upon Sinatra and rack, thus can be hosted
5
- very easily (and for free) on heroku (http://heroku.com).
5
+ very easily (and for free) on heroku (http://heroku.com).
6
6
 
7
7
  The articles are stored in plain text files with an opinionated naming scheme which is used for
8
8
  getting the date and permalink of your article: <code>articles/2010-02-14-will-you-be-my-valentine.txt</code>
@@ -39,10 +39,20 @@ Install the gem:
39
39
 
40
40
  sudo gem install serious
41
41
 
42
- Since a basic template and css are provided inside the gem, all you've got to do is set up a directory
43
- for your new blog, create an articles folder, a config.ru and (for heroku), a .gems file.
42
+ You can use the supplied generator using the <code>serious</code> executable provided with the gem.
43
+ Type <code>serious</code> in your shell to see the available options.
44
44
 
45
- The directory structure would be something like:
45
+ By default the generator will create the app with gem-based public and views directories and initialize
46
+ a git repository. To host your app on heroku instantly, supply the --heroku option, which will use
47
+ the heroku gem to create your app and push it to heroku via git. Type:
48
+
49
+ serious my-fancy-blog --heroku
50
+
51
+ And you can go to http://my-fancy-blog.heroku.com to see your new blog!
52
+
53
+ == The setup
54
+
55
+ The directory basic directory structure of your Serious site would be something like this:
46
56
 
47
57
  serious_blog/
48
58
  - articles
@@ -60,21 +70,26 @@ The config.ru is pretty straight-forward if you want to stick to the defaults:
60
70
 
61
71
  The .gems file if you want to host on heroku:
62
72
 
63
- stupid_formatter --version '>= 0.2.0'
64
- serious --version '>= 0.1.3'
73
+ stupid_formatter
74
+ serious
65
75
 
66
76
  Note that sinatra is not included in the gemfile since heroku has it installed by default, but serious
67
77
  will install it as a gem dependency on other systems as well.
68
78
 
79
+ == Creating heroku app manually
80
+
69
81
  Assuming you've got the heroku gem installed and set up and you've set up git for your blog with
70
- <code>git init</code>, you can now do:
82
+ <code>git init</code> or sticked with the generator, which created your git repo, you can now do:
71
83
 
72
84
  heroku create mysweetlittleblog
73
85
  git push heroku master
74
86
 
75
87
  Point your browser to the url, and bang, you're ready!
76
88
 
77
- You might also want to test your blog locally. Use thin (<code>sudo gem install thin</code>) with:
89
+ == Running with thin
90
+
91
+ You might also want to test your blog locally or host it with thin.
92
+ Use thin (<code>sudo gem install thin</code>) with:
78
93
 
79
94
  thin -R config.ru start
80
95
 
@@ -86,7 +101,24 @@ The whole archives can be accessed at <code>/archives</code>. Archives by year,
86
101
  are available at <code>/2009</code> (all of 2009), <code>/2009/05</code> (May 2009),
87
102
  <code>/2009/05/15</code> (May 15th 2009).
88
103
 
89
- == Configuration
104
+ == Comments with disqus
105
+
106
+ You can activate comments for articles very easily with disqus (http://disqus.com) by setting
107
+ the <code>disqus</code> property to your disqus-id (e.g. 'myfancysite'). Disqus developer mode will
108
+ be automatically activated for requests served by http://localhost so you can preview your settings
109
+ and layout properly.
110
+
111
+ Serious.set :disqus, 'yourid'
112
+
113
+ == Google Analytics
114
+
115
+ You can activate Google Analytics by setting the <code>google_analytics</code> property to your
116
+ tracker id (something like 'UA-123123-5'). The required code will then be included to your site.
117
+ For requests served from http://localhost, the inclusion is skipped.
118
+
119
+ Serious.set :google_analytics, 'UA-123123-5'
120
+
121
+ == Configuration options
90
122
 
91
123
  Inside your config.ru, you can customize the settings for your Serious site.
92
124
 
@@ -153,6 +185,37 @@ Well, your site has to know where it lives to provide proper links in your atom
153
185
  with the url setting, which defaults to 'http://localhost:3000'
154
186
 
155
187
  Serious.set :url, 'http://localhost:3000'
188
+
189
+ === The date format
190
+
191
+ There is a helper in the Date class for formatting dates according to the configuration specified
192
+ in Serious.date_format and which is used in the frontend. It defaults to "%B %o %Y", which expands
193
+ to (i.e.) 'December 24th, 2009'. Notice that %o is a custom flag that is not built-in in the default
194
+ strftime method of Date. It returns the ordinal name of the day. Customize with:
195
+
196
+ Serious.set :date_format, "%Y-%m-%d"
197
+
198
+ === Disqus comments
199
+
200
+ To enable disqus comments, specify your disqus id with the disqus property. Disqus is disabled
201
+ by default. See section above for more information on disqus and comments.
202
+
203
+ Serious.set :disqus, 'yourdisqusid'
204
+
205
+ === Google Analytics
206
+
207
+ To enable google analytics, specify your tracker id at the property <code>google_analytics</code>.
208
+ See section above for more information on Google Analytics.
209
+
210
+ Serious.set :google_analytics, 'UA-123123-5'
211
+
212
+ === Custom feed url in layout
213
+
214
+ If you want to specify a different feed url for the head link tag, for example to point your readers
215
+ to Feedburner, you can do so by specifiyng the <code>feed_url</code> option and setting up your
216
+ feed to be burned by feedburner based upon <code>http://yoururl.com/atom.xml</code>.
217
+
218
+ Serious.set :feed_url, 'http://feeds.feedburner.com/myfeedurl'
156
219
 
157
220
  === Displayed items
158
221
 
@@ -201,14 +264,10 @@ to learn how to add your own formatters or erb helpers.
201
264
 
202
265
  * static pages
203
266
  * make summary delim configurable
204
- * beautifuller date formatting in frontend
205
267
  * make caching better
206
268
  * make it possible to host in subdirectories
207
269
  * valid xhtml in demo setup
208
- * generator for basic app?
209
270
  * rake tasks for generating new posts and validating existing
210
- * disqus (optional)
211
- * google analytics (optional)
212
271
  * allow for choice between erb/haml templates
213
272
 
214
273
  == Note on Patches/Pull Requests
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.0
1
+ 0.2.1
data/lib/ruby_ext.rb ADDED
@@ -0,0 +1,29 @@
1
+ # A couple of Ruby extensions
2
+
3
+ class Date
4
+ # Returns the date formatted with the format defined in Serious.date_format
5
+ # and extended with the %o flag for ordinal day names.
6
+ def formatted
7
+ strftime(Serious.date_format.gsub("%o", day.ordinal))
8
+ end
9
+ end
10
+
11
+ class Fixnum
12
+ # Taken from toto
13
+ def ordinal
14
+ # 1 => 1st
15
+ # 2 => 2nd
16
+ # 3 => 3rd
17
+ # ...
18
+ case self % 100
19
+ when 11..13; "#{self}th"
20
+ else
21
+ case self % 10
22
+ when 1; "#{self}st"
23
+ when 2; "#{self}nd"
24
+ when 3; "#{self}rd"
25
+ else "#{self}th"
26
+ end
27
+ end
28
+ end
29
+ end
data/lib/serious.rb CHANGED
@@ -4,6 +4,8 @@ require 'sinatra/base'
4
4
  require 'stupid_formatter'
5
5
  require 'yaml'
6
6
  require 'builder'
7
+ $:.unshift File.dirname(__FILE__)
8
+ require 'ruby_ext'
7
9
 
8
10
  class Serious < Sinatra::Base
9
11
 
@@ -27,6 +29,10 @@ class Serious < Sinatra::Base
27
29
  def render_article(article, summary_only=false)
28
30
  render :erb, :'_article', :locals => { :article => article, :summary_only => summary_only }, :layout => !summary_only
29
31
  end
32
+
33
+ def render_partial(name)
34
+ render :erb, :"_#{name}", :layout => false
35
+ end
30
36
  end
31
37
 
32
38
  # Index page
@@ -60,7 +66,6 @@ class Serious < Sinatra::Base
60
66
  end
61
67
  end
62
68
 
63
- $:.unshift File.dirname(__FILE__)
64
69
  require 'serious/article'
65
70
  # Set up default stupid_formatter chain
66
71
  StupidFormatter.chain = [StupidFormatter::Erb, StupidFormatter::RDiscount]
@@ -76,4 +81,8 @@ Serious.set :archived_on_index, 10 # Number of items to display small (title onl
76
81
  Serious.set :cache_timeout, 300
77
82
  Serious.set :run, false
78
83
  Serious.set :environment, :production
84
+ Serious.set :date_format, "%B %o %Y"
85
+ Serious.set :disqus, false
86
+ Serious.set :google_analytics, false
87
+ Serious.set :feed_url, '/atom.xml'
79
88
 
@@ -27,14 +27,23 @@ h1, h2, h3, h4 {
27
27
 
28
28
  .author {
29
29
  color: #666;
30
+ font-size: 14px;
30
31
  }
31
32
 
32
33
  #header {
33
- margin: 25px 0px 50px 0px;
34
+ margin: 0px 0px 25px 0px;
35
+ padding: 25px;
36
+ text-align: center;
37
+ border-bottom: 3px solid #BE2805;
38
+ }
39
+
40
+ #header h1 {
41
+ font-family: 'Baskerville', Georgia, Times, serif;
42
+ font-size: 28px;
34
43
  }
35
44
 
36
45
  #header a {
37
- color: black;
46
+ color: #666;
38
47
  text-decoration: none;
39
48
  }
40
49
 
@@ -64,7 +73,25 @@ h1, h2, h3, h4 {
64
73
  }
65
74
 
66
75
  #container .article {
67
- margin-bottom: 50px;
76
+ margin-bottom: 80px;
77
+ }
78
+
79
+ #container .body a {
80
+ color: #BE2805;
81
+ }
82
+
83
+ #container .body a:hover {
84
+ color: black;
85
+ }
86
+
87
+ #container blockquote {
88
+ background-color: #fafafa;
89
+ margin: 0 0 25px 0;
90
+ padding: 25px;
91
+ }
92
+
93
+ #disqus_thread {
94
+ padding-top: 25px;
68
95
  }
69
96
 
70
97
 
@@ -2,7 +2,7 @@
2
2
  <% articles.each do |article| %>
3
3
  <li>
4
4
  <a href="<%= article.url %>"><%= article.title %></a>
5
- <span class="date"><%= article.date %></span>
5
+ <span class="date"><%= article.date.formatted %></span>
6
6
  </li>
7
7
  <% end %>
8
8
  </ul>
@@ -1,12 +1,15 @@
1
1
  <div class="article">
2
- <span class="date right"><%= article.date %></span>
2
+ <span class="date right"><%= article.date.formatted %></span>
3
3
  <h2><a href="<%= article.url %>"><%= article.title %></a></h2>
4
4
  <div class="body">
5
5
  <% if summary_only %>
6
6
  <%= article.summary.formatted %>
7
+ <span class="right date"><a href="<%= article.url %>">read on...</a></span>
7
8
  <% else %>
8
9
  <%= article.body.formatted %>
9
- <span class="author right">Written by <%= article.author %></span>
10
+ <span class="author right">Written by <%= article.author %></span>
11
+
12
+ <%= render_partial :disqus if Serious.disqus %>
10
13
  <% end %>
11
14
  </div>
12
15
 
@@ -0,0 +1,9 @@
1
+ <% if request.url =~ %r{http://localhost} %>
2
+ <script type="text/javascript"> var disqus_developer = true; </script>
3
+ <% end %>
4
+ <div id="disqus_thread" style="clear:both;"></div>
5
+ <script type="text/javascript" src="http://disqus.com/forums/<%= Serious.disqus %>/embed.js"></script>
6
+ <noscript>
7
+ <a href="http://disqus.com/forums/<%= Serious.disqus %>/?url=ref">View the discussion thread.</a>
8
+ </noscript>
9
+ <a href="http://disqus.com" class="dsq-brlink">blog comments powered by <span class="logo-disqus">Disqus</span></a>
@@ -0,0 +1,11 @@
1
+ <% unless request.url =~ %r{http://localhost} %>
2
+ <script type="text/javascript">
3
+ var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
4
+ document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
5
+ </script>
6
+ <script type="text/javascript">
7
+ try {
8
+ var pageTracker = _gat._getTracker("<%= Serious.google_analytics %>");
9
+ pageTracker._trackPageview();
10
+ } catch(err) {}</script>
11
+ <% end %>
@@ -2,7 +2,7 @@
2
2
  <head>
3
3
  <link rel="stylesheet" type="text/css" href="/css/serious.css">
4
4
  <link rel="stylesheet" type="text/css" href="/css/coderay.css">
5
- <link rel="alternate" type="application/atom+xml" title="Serious Test Layout" href="/atom.xml" />
5
+ <link rel="alternate" type="application/atom+xml" title="<%= Serious.title %>" href="<%= Serious.feed_url %>" />
6
6
  <title><%= @article ? @article.title + " - " : "" %><%= Serious.title %></title>
7
7
  </head>
8
8
 
@@ -17,6 +17,8 @@
17
17
  <div id="footer">
18
18
  This blog is <a href="http://github.com/colszowka/serious">serious</a>
19
19
  </div>
20
+
21
+ <%= render_partial :google_analytics if Serious.google_analytics %>
20
22
  </body>
21
23
  </html>
22
24
 
data/serious.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{serious}
8
- s.version = "0.2.0"
8
+ s.version = "0.2.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Christoph Olszowka"]
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
26
26
  "Rakefile",
27
27
  "VERSION",
28
28
  "bin/serious",
29
+ "lib/ruby_ext.rb",
29
30
  "lib/serious.rb",
30
31
  "lib/serious/article.rb",
31
32
  "lib/site/public/css/coderay.css",
@@ -33,6 +34,8 @@ Gem::Specification.new do |s|
33
34
  "lib/site/views/404.erb",
34
35
  "lib/site/views/_archives.erb",
35
36
  "lib/site/views/_article.erb",
37
+ "lib/site/views/_disqus.erb",
38
+ "lib/site/views/_google_analytics.erb",
36
39
  "lib/site/views/archives.erb",
37
40
  "lib/site/views/atom.builder",
38
41
  "lib/site/views/index.erb",
@@ -44,6 +47,7 @@ Gem::Specification.new do |s|
44
47
  "test/articles/2009-12-24-merry-christmas.txt",
45
48
  "test/helper.rb",
46
49
  "test/test_article.rb",
50
+ "test/test_ruby_ext.rb",
47
51
  "test/test_serious.rb"
48
52
  ]
49
53
  s.homepage = %q{http://github.com/colszowka/serious}
@@ -54,6 +58,7 @@ Gem::Specification.new do |s|
54
58
  s.test_files = [
55
59
  "test/test_serious.rb",
56
60
  "test/helper.rb",
61
+ "test/test_ruby_ext.rb",
57
62
  "test/test_article.rb"
58
63
  ]
59
64
 
data/test/helper.rb CHANGED
@@ -47,6 +47,13 @@ class Test::Unit::TestCase
47
47
  end
48
48
  end
49
49
 
50
+ def self.should_contain_attribute(attribute, text, selector)
51
+ should "contain '#{text}' in '#{selector}' #{attribute}" do
52
+ doc = Hpricot.parse(last_response.body)
53
+ assert_equal text, (doc/selector).first[attribute]
54
+ end
55
+ end
56
+
50
57
  def self.should_set_cache_control_to(seconds)
51
58
  should "set Cache-Control header with timeout of #{seconds} seconds" do
52
59
  assert_equal "public, max-age=#{Serious.cache_timeout}", last_response.headers['Cache-Control']
@@ -0,0 +1,69 @@
1
+ require 'helper'
2
+
3
+ #
4
+ # Tests for the Ruby Extensions
5
+ #
6
+ class TestRubyExt < Test::Unit::TestCase
7
+ # ========================================================================
8
+ # Tests for formatted date
9
+ # ========================================================================
10
+ context "With Serious.date_format set to '%Y-%m-%d'" do
11
+ setup do
12
+ @original_format = Serious.date_format
13
+ Serious.set :date_format, "%Y-%m-%d"
14
+ end
15
+
16
+ should "return '2009-12-13' for Date.new(2009, 12, 13).formatted" do
17
+ assert_equal '2009-12-13', Date.new(2009, 12, 13).formatted
18
+ end
19
+
20
+ should "return '2010-01-09' for Date.new(2010, 1, 9).formatted" do
21
+ assert_equal '2010-01-09', Date.new(2010, 1, 9).formatted
22
+ end
23
+
24
+ teardown do
25
+ Serious.set :date_format, @original_format
26
+ end
27
+ end
28
+
29
+ context "With Serious.date_format set to '%a, %B %d, %Y'" do
30
+ setup do
31
+ @original_format = Serious.date_format
32
+ Serious.set :date_format, "%a, %B %d, %Y"
33
+ end
34
+
35
+ should "return 'Sat, February 13 2010' for Date.new(2010, 2, 13).formatted" do
36
+ assert_equal 'Sat, February 13, 2010', Date.new(2010, 2, 13).formatted
37
+ end
38
+
39
+ teardown do
40
+ Serious.set :date_format, @original_format
41
+ end
42
+ end
43
+
44
+ context 'With Serious.date_format set to "%B %o %Y"' do
45
+ setup do
46
+ @original_format = Serious.date_format
47
+ Serious.set :date_format, "%B %o %Y"
48
+ end
49
+
50
+ should "return 'February 12th 2010' for Date.new(2010, 2, 12).formatted" do
51
+ assert_equal 'February 12th 2010', Date.new(2010, 2, 12).formatted
52
+ end
53
+
54
+ teardown do
55
+ Serious.set :date_format, @original_format
56
+ end
57
+ end
58
+
59
+ # ========================================================================
60
+ # Tests for ordinal
61
+ # ========================================================================
62
+
63
+ should("return '1st' for 1.ordinal") { assert_equal '1st', 1.ordinal}
64
+ should("return '2nd' for 2.ordinal") { assert_equal '2nd', 2.ordinal}
65
+ should("return '3rd' for 3.ordinal") { assert_equal '3rd', 3.ordinal}
66
+ should("return '4th' for 4.ordinal") { assert_equal '4th', 4.ordinal}
67
+ should("return '31st' for 31.ordinal") { assert_equal '31st', 31.ordinal}
68
+
69
+ end
data/test/test_serious.rb CHANGED
@@ -16,6 +16,8 @@ class TestSerious < Test::Unit::TestCase
16
16
  should_contain_elements 3, "ul#articles li"
17
17
  should_contain_text "Merry Christmas!", "ul#articles li:first"
18
18
  should_contain_text "Merry christmas, dear reader!", "ul#articles li:first"
19
+ should_contain_text "December 24th 2009", "ul#articles li:first .date"
20
+
19
21
  should_not_contain_text "Lorem ipsum dolor...", "ul#articles li:first"
20
22
 
21
23
  should_contain_text "Ruby is the shit!", "ul#articles"
@@ -50,6 +52,7 @@ class TestSerious < Test::Unit::TestCase
50
52
  should_respond_with 200
51
53
  should_set_cache_control_to 300
52
54
  should_contain_text "Archives for 2009-12", "#container h2:first"
55
+ should_contain_text 'December 24th 2009', "ul.archives li"
53
56
  should_contain_elements 2, "ul.archives li"
54
57
  should_contain_text "Merry Christmas!", "ul.archives li:first"
55
58
  should_contain_text "Ruby is the shit!", "ul.archives"
@@ -187,4 +190,79 @@ class TestSerious < Test::Unit::TestCase
187
190
  should_contain_text "Merry Christmas!", "feed entry:first title"
188
191
  should_contain_text "Christoph Olszowka", "feed entry:first author name:first"
189
192
  end
193
+
194
+ # ===================================================================
195
+ # Tests for disqus integration
196
+ # ===================================================================
197
+ context "With disqus id set" do
198
+ setup { Serious.set :disqus, 'foobar' }
199
+ teardown { Serious.set :disqus, false}
200
+
201
+ context "GET /2009/12/24/merry-christmas" do
202
+ setup { get '/2009/12/24/merry-christmas' }
203
+
204
+ should_contain_text "View the discussion thread.", "#container .article noscript"
205
+ should_contain_elements 1, "#container #disqus_thread"
206
+ end
207
+ end
208
+
209
+ context "With disqus inactive" do
210
+ setup { Serious.set :disqus, false }
211
+
212
+ context "GET /2009/12/24/merry-christmas" do
213
+ setup { get '/2009/12/24/merry-christmas' }
214
+
215
+ should_not_contain_text "View the discussion thread.", "#container .article noscript"
216
+ should_contain_elements 0, "#container #disqus_thread"
217
+ end
218
+ end
219
+
220
+ # ===================================================================
221
+ # Tests for google analytics integration
222
+ # ===================================================================
223
+ context "With google analytics active" do
224
+ setup { Serious.set :google_analytics, 'analyticsid' }
225
+
226
+ context "GET /" do
227
+ setup { get '/' }
228
+
229
+ should_contain_elements 2, "body script"
230
+ end
231
+ end
232
+
233
+ context "With google analytics inactive" do
234
+ setup { Serious.set :google_analytics, false }
235
+
236
+ context "GET /" do
237
+ setup { get '/' }
238
+
239
+ should_contain_elements 0, "body script"
240
+ end
241
+ end
242
+
243
+ # ===================================================================
244
+ # Tests for feed url setting
245
+ # ===================================================================
246
+ context "With default feed url" do
247
+ context "GET /" do
248
+ setup { get '/' }
249
+
250
+ should_contain_attribute "href", "/atom.xml", "head link:last"
251
+ end
252
+ end
253
+
254
+ context "With custom feed url" do
255
+ setup do
256
+ @original_feed_url = Serious.feed_url
257
+ Serious.set :feed_url, 'http://feeds.feedburner.com/myfeedurl'
258
+ end
259
+ teardown { Serious.set :feed_url, @original_feed_url }
260
+
261
+ context "GET /" do
262
+ setup { get '/' }
263
+
264
+ should_contain_attribute "href", "http://feeds.feedburner.com/myfeedurl", "head link:last"
265
+ end
266
+ end
267
+
190
268
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serious
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christoph Olszowka
@@ -89,6 +89,7 @@ files:
89
89
  - Rakefile
90
90
  - VERSION
91
91
  - bin/serious
92
+ - lib/ruby_ext.rb
92
93
  - lib/serious.rb
93
94
  - lib/serious/article.rb
94
95
  - lib/site/public/css/coderay.css
@@ -96,6 +97,8 @@ files:
96
97
  - lib/site/views/404.erb
97
98
  - lib/site/views/_archives.erb
98
99
  - lib/site/views/_article.erb
100
+ - lib/site/views/_disqus.erb
101
+ - lib/site/views/_google_analytics.erb
99
102
  - lib/site/views/archives.erb
100
103
  - lib/site/views/atom.builder
101
104
  - lib/site/views/index.erb
@@ -107,6 +110,7 @@ files:
107
110
  - test/articles/2009-12-24-merry-christmas.txt
108
111
  - test/helper.rb
109
112
  - test/test_article.rb
113
+ - test/test_ruby_ext.rb
110
114
  - test/test_serious.rb
111
115
  has_rdoc: true
112
116
  homepage: http://github.com/colszowka/serious
@@ -139,4 +143,5 @@ summary: Serious is a simple, file-driven blog engine inspired by toto and drive
139
143
  test_files:
140
144
  - test/test_serious.rb
141
145
  - test/helper.rb
146
+ - test/test_ruby_ext.rb
142
147
  - test/test_article.rb