schnitzelpress 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.md +20 -3
- data/README.md +4 -2
- data/bin/schnitzelpress +1 -1
- data/lib/assets/js/jquery-1.7.1.js +673 -0
- data/lib/assets/js/jquery-ujs.js +373 -0
- data/lib/assets/js/jquery.cookie.js +47 -0
- data/lib/{public → assets}/js/schnitzelpress.js +7 -2
- data/lib/public/font/fontawesome-webfont.eot +0 -0
- data/lib/public/font/fontawesome-webfont.svg +175 -0
- data/lib/public/font/fontawesome-webfont.svgz +0 -0
- data/lib/public/font/fontawesome-webfont.ttf +0 -0
- data/lib/public/font/fontawesome-webfont.woff +0 -0
- data/lib/schnitzelpress.rb +21 -5
- data/lib/schnitzelpress/actions/admin.rb +21 -1
- data/lib/schnitzelpress/actions/assets.rb +36 -0
- data/lib/schnitzelpress/actions/auth.rb +16 -3
- data/lib/schnitzelpress/actions/blog.rb +10 -12
- data/lib/schnitzelpress/app.rb +16 -19
- data/lib/schnitzelpress/cache_control.rb +17 -0
- data/lib/schnitzelpress/cli.rb +40 -9
- data/lib/schnitzelpress/config.rb +43 -0
- data/lib/schnitzelpress/env.rb +5 -0
- data/lib/schnitzelpress/helpers.rb +168 -4
- data/lib/schnitzelpress/markdown_renderer.rb +2 -2
- data/lib/schnitzelpress/post.rb +2 -6
- data/lib/schnitzelpress/static.rb +1 -1
- data/lib/schnitzelpress/version.rb +2 -2
- data/lib/templates/new_blog/Gemfile +4 -5
- data/lib/templates/new_blog/Gemfile.lock.tt +137 -0
- data/lib/templates/new_blog/Procfile +1 -1
- data/lib/templates/new_blog/config.ru.tt +6 -17
- data/lib/views/admin/admin.haml +3 -2
- data/lib/views/admin/config.haml +27 -0
- data/lib/views/atom.haml +3 -3
- data/lib/views/index.haml +1 -1
- data/lib/views/layout.haml +15 -11
- data/lib/views/login.haml +4 -0
- data/lib/views/partials/_admin_post_list.haml +8 -8
- data/lib/views/partials/_disqus.haml +1 -1
- data/lib/views/partials/_gauges.haml +1 -1
- data/lib/views/partials/_google_analytics.haml +1 -1
- data/lib/views/partials/_post.haml +6 -5
- data/lib/views/partials/_post_form.haml +3 -1
- data/lib/views/post.haml +4 -1
- data/lib/views/schnitzelpress.scss +67 -3
- data/schnitzelpress.gemspec +5 -2
- data/spec/app_spec.rb +5 -11
- data/spec/assets_spec.rb +26 -0
- data/spec/factories.rb +1 -1
- data/spec/post_spec.rb +9 -2
- data/spec/spec_helper.rb +2 -1
- metadata +115 -71
- data/lib/schnitzelpress/rake.rb +0 -20
- data/lib/templates/new_blog/Rakefile +0 -2
- data/lib/templates/new_blog/app.rb.tt +0 -34
- data/lib/templates/new_blog/config/unicorn.rb +0 -5
- data/lib/templates/new_blog/public/.gitkeep +0 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
- set_page_title "Configuration"
|
2
|
+
|
3
|
+
%section
|
4
|
+
%form.post{:action => '/admin/config', :method => 'post'}
|
5
|
+
%h2 Blog
|
6
|
+
= form_field config, :blog_title
|
7
|
+
= form_field config, :blog_description
|
8
|
+
= form_field config, :blog_footer
|
9
|
+
|
10
|
+
%h2 Author
|
11
|
+
= form_field config, :author_name
|
12
|
+
|
13
|
+
%h2 External Services
|
14
|
+
= form_field config, :blog_feed_url, :label => "ATOM Feed URL", :hint => "This is what the /feed URL will redirect to. You can change this to eg. your FeedBurner URL."
|
15
|
+
.row
|
16
|
+
.six.columns
|
17
|
+
= form_field config, :disqus_id, :label => "Disqus shortname"
|
18
|
+
.six.columns
|
19
|
+
= form_field config, :twitter_id, :label => "Twitter user name"
|
20
|
+
.row
|
21
|
+
.six.columns
|
22
|
+
= form_field config, :google_analytics_id, :label => "Google Analytics ID"
|
23
|
+
.six.columns
|
24
|
+
= form_field config, :gauges_id, :label => "Gauges ID"
|
25
|
+
|
26
|
+
.buttons
|
27
|
+
%input{:type => 'submit', :value => 'Update Configuration'}
|
data/lib/views/atom.haml
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
!!! XML
|
2
2
|
%feed{:xmlns => 'http://www.w3.org/2005/Atom'}
|
3
|
-
%title=
|
3
|
+
%title= config.blog_title
|
4
4
|
%link{:href => url_for('/', :absolute => true)}
|
5
5
|
%id= base_url
|
6
6
|
- if @posts.any?
|
7
7
|
%updated= @posts.first.published_at
|
8
8
|
|
9
9
|
%author
|
10
|
-
%name=
|
10
|
+
%name= config.author_name
|
11
11
|
|
12
12
|
- @posts.each do |post|
|
13
13
|
%entry
|
@@ -17,7 +17,7 @@
|
|
17
17
|
%published= post.published_at
|
18
18
|
%updated= post.published_at
|
19
19
|
%author
|
20
|
-
%name=
|
20
|
+
%name= config.author_name
|
21
21
|
%content{:type => 'html'}
|
22
22
|
:cdata
|
23
23
|
#{post.to_html}
|
data/lib/views/index.haml
CHANGED
data/lib/views/layout.haml
CHANGED
@@ -1,28 +1,32 @@
|
|
1
1
|
!!! 5
|
2
2
|
%html
|
3
3
|
%head
|
4
|
-
%title= [@page_title,
|
4
|
+
%title= [@page_title, config.blog_title].compact.join(" | ")
|
5
5
|
%meta{ :"http-equiv" => "content-type", :content => "text/html; charset=UTF-8" }
|
6
6
|
%meta{ :name => "viewport", :content => "width=device-width, initial-scale=1.0" }
|
7
|
-
%link{ :href =>
|
8
|
-
%link{ :href =>
|
9
|
-
%script{ :type => 'text/javascript', :src => '//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js' }
|
10
|
-
%script{ :type => 'text/javascript', :src => '//browserid.org/include.js' }
|
11
|
-
%script{ :type => 'text/javascript', :src => '/js/schnitzelpress.js' }
|
7
|
+
%link{ :href => "/assets/schnitzelpress.#{ASSET_TIMESTAMP}.css", :media => "screen", :rel => "stylesheet", :type => "text/css" }
|
8
|
+
%link{ :href => config.blog_feed_url, :title => "Subscribe via Atom Feed", :rel => 'alternate', :type => 'application/atom+xml' }
|
12
9
|
%body
|
13
10
|
.container
|
14
11
|
%header
|
15
12
|
.site-title
|
16
|
-
%a{:href => '/'}=
|
13
|
+
%a{:href => '/'}= h config.blog_title
|
17
14
|
- if @show_description
|
18
|
-
~ markdown
|
15
|
+
~ markdown config.blog_description
|
16
|
+
|
17
|
+
#actions.admin_only
|
18
|
+
= yield_content :actions
|
19
|
+
%a{:href => '/admin/'} #{icon 'cog'} Go To Admin
|
20
|
+
%a{:href => '/logout'} #{icon 'signout'} Logout
|
19
21
|
|
20
22
|
= yield
|
21
23
|
|
22
24
|
%footer
|
23
|
-
~ markdown
|
25
|
+
~ markdown config.blog_footer
|
24
26
|
|
25
|
-
- if production? &&
|
27
|
+
- if production? && config.google_analytics_id.present?
|
26
28
|
= partial 'google_analytics'
|
27
|
-
- if production? &&
|
29
|
+
- if production? && config.gauges_id.present?
|
28
30
|
= partial 'gauges'
|
31
|
+
|
32
|
+
%script{ :type => 'text/javascript', :src => "/assets/schnitzelpress.#{ASSET_TIMESTAMP}.js" }
|
data/lib/views/login.haml
CHANGED
@@ -6,6 +6,10 @@
|
|
6
6
|
|
7
7
|
%p
|
8
8
|
%a.button#browser_id{:href => '/auth/browser_id'} Log in with BrowserID
|
9
|
+
- if Schnitzelpress.env.development?
|
10
|
+
%a.green.button{:href => '/auth/developer'} Developer Login
|
9
11
|
|
10
12
|
%form{:method => 'post', :action => '/auth/browser_id/callback', :noValidate => 'noValidate'}
|
11
13
|
%input{:type => 'hidden', :name => 'assertion'}
|
14
|
+
|
15
|
+
%script{ :type => 'text/javascript', :src => '//browserid.org/include.js' }
|
@@ -1,11 +1,11 @@
|
|
1
1
|
- if posts.any?
|
2
2
|
%h2= title
|
3
|
-
|
3
|
+
.admin-post-list
|
4
4
|
- posts.each do |post|
|
5
|
-
|
6
|
-
|
7
|
-
%a
|
8
|
-
|
9
|
-
%a
|
10
|
-
|
11
|
-
=
|
5
|
+
.row
|
6
|
+
.ten.columns
|
7
|
+
%a{:href => "/admin/edit/#{post.id}"}= h (post.title || ("%s..." % post.body.first(50)))
|
8
|
+
.two.columns.icons
|
9
|
+
%a{:href => url_for(post)}= icon 'eye-open'
|
10
|
+
%a{:href => "/admin/edit/#{post.id}"}= icon 'edit'
|
11
|
+
= link_to_delete_post icon('trash'), post
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
:javascript
|
4
4
|
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
|
5
|
-
var disqus_shortname = '#{
|
5
|
+
var disqus_shortname = '#{config.disqus_id}';
|
6
6
|
var disqus_developer = #{production? ? 0 : 1};
|
7
7
|
var disqus_identifier = '#{disqus_identifier}';
|
8
8
|
|
@@ -5,7 +5,7 @@
|
|
5
5
|
t.type = 'text/javascript';
|
6
6
|
t.async = true;
|
7
7
|
t.id = 'gauges-tracker';
|
8
|
-
t.setAttribute('data-site-id', '#{
|
8
|
+
t.setAttribute('data-site-id', '#{config.gauges_id}');
|
9
9
|
t.src = '//secure.gaug.es/track.js';
|
10
10
|
var s = document.getElementsByTagName('script')[0];
|
11
11
|
s.parentNode.insertBefore(t, s);
|
@@ -4,13 +4,13 @@
|
|
4
4
|
- show_body ||= complete || !show_summary
|
5
5
|
- show_read_more ||= !complete && post.summary.present?
|
6
6
|
- show_permalink ||= true
|
7
|
-
- show_twitter ||= complete && post.post? &&
|
7
|
+
- show_twitter ||= complete && post.post? && config.twitter_id.present?
|
8
8
|
|
9
9
|
%article.post{:class => [post.status, post.link_post? ? 'link' : 'article']}
|
10
10
|
%header
|
11
11
|
- if show_title
|
12
12
|
%h1
|
13
|
-
%a{:href => post.link || post.to_url}= h post.title
|
13
|
+
%a.instapaper_title{:href => post.link || post.to_url}= h post.title
|
14
14
|
- if post.link_post?
|
15
15
|
%span.link-arrow ➝
|
16
16
|
|
@@ -19,11 +19,12 @@
|
|
19
19
|
~ markdown post.summary
|
20
20
|
- if show_read_more
|
21
21
|
%p
|
22
|
-
%a{:href => url_for(post)}= post.read_more.presence ||
|
22
|
+
%a{:href => url_for(post)}= post.read_more.presence || "Read Complete Article"
|
23
23
|
→
|
24
24
|
|
25
25
|
- if show_body
|
26
|
-
|
26
|
+
.instapaper_body
|
27
|
+
~ post.to_html
|
27
28
|
|
28
29
|
%footer
|
29
30
|
- if show_permalink
|
@@ -33,6 +34,6 @@
|
|
33
34
|
- if show_twitter
|
34
35
|
.social_media_buttons
|
35
36
|
- if show_twitter
|
36
|
-
%a{:href => "https://twitter.com/share", :class => "twitter-share-button", :data => {:via =>
|
37
|
+
%a{:href => "https://twitter.com/share", :class => "twitter-share-button", :data => {:via => config.twitter_id}}
|
37
38
|
:javascript
|
38
39
|
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");
|
@@ -17,4 +17,6 @@
|
|
17
17
|
= form_field @post, :disqus
|
18
18
|
|
19
19
|
.buttons
|
20
|
-
%
|
20
|
+
%button.green{:type => 'submit'} #{icon 'ok'} #{@post.new_record? ? 'Create Post' : 'Update Post'}
|
21
|
+
or
|
22
|
+
= link_to_delete_post "delete this post", @post
|
data/lib/views/post.haml
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
- if @extra_posts
|
6
6
|
%section.extra_posts
|
7
7
|
%h1
|
8
|
-
%a{href
|
8
|
+
%a{:href => '/blog'}= @extra_posts.first
|
9
9
|
%ul
|
10
10
|
- for post in @extra_posts.second
|
11
11
|
%li
|
@@ -14,3 +14,6 @@
|
|
14
14
|
- if show_disqus? && @post.disqus?
|
15
15
|
%section.disqus
|
16
16
|
= partial 'disqus', :disqus_identifier => @post.disqus_identifier
|
17
|
+
|
18
|
+
- content_for :actions do
|
19
|
+
%a{:href => "/admin/edit/%s" % @post.id} #{icon 'edit'} Edit
|
@@ -8,6 +8,34 @@ body, .container {
|
|
8
8
|
background-image: url(/img/background.png);
|
9
9
|
}
|
10
10
|
|
11
|
+
.admin_only {
|
12
|
+
display: none;
|
13
|
+
body.show_admin & { display: block; }
|
14
|
+
}
|
15
|
+
|
16
|
+
/* action panel */
|
17
|
+
#actions {
|
18
|
+
@include small-type;
|
19
|
+
margin: 5px;
|
20
|
+
|
21
|
+
a {
|
22
|
+
display: inline-block;
|
23
|
+
padding: 3px 6px;
|
24
|
+
background-color: $color-text;
|
25
|
+
color: $color-background;
|
26
|
+
font-weight: bold;
|
27
|
+
text-decoration: none;
|
28
|
+
border-radius: 3px;
|
29
|
+
@include appear-on-hover;
|
30
|
+
}
|
31
|
+
|
32
|
+
@media only screen and (min-width: 641px) {
|
33
|
+
position: fixed;
|
34
|
+
top: 0px;
|
35
|
+
right: 0px;
|
36
|
+
}
|
37
|
+
}
|
38
|
+
|
11
39
|
/* posts */
|
12
40
|
article.post {
|
13
41
|
header {
|
@@ -31,8 +59,7 @@ article.post {
|
|
31
59
|
@include animated;
|
32
60
|
|
33
61
|
margin: 2em 0;
|
34
|
-
|
35
|
-
&:hover { opacity: 1 }
|
62
|
+
@include appear-on-hover;
|
36
63
|
}
|
37
64
|
}
|
38
65
|
}
|
@@ -52,12 +79,35 @@ ul.admin {
|
|
52
79
|
}
|
53
80
|
}
|
54
81
|
|
55
|
-
|
82
|
+
div.admin-post-list {
|
56
83
|
padding: 5px 0;
|
84
|
+
margin: 1em 0;
|
57
85
|
max-height: 300px;
|
58
86
|
overflow: auto;
|
59
87
|
border-bottom: 1px dotted rgba($color-text, 0.5);
|
60
88
|
border-top: 1px dotted rgba($color-text, 0.5);
|
89
|
+
|
90
|
+
.icons {
|
91
|
+
display: none;
|
92
|
+
text-align: right;
|
93
|
+
a {
|
94
|
+
color: $color-footer;
|
95
|
+
&:hover { color: $color-text };
|
96
|
+
}
|
97
|
+
}
|
98
|
+
.row {
|
99
|
+
padding: 3px;
|
100
|
+
margin-bottom: 0;
|
101
|
+
&:hover {
|
102
|
+
background-color: rgba($color-text, 0.05);
|
103
|
+
.icons {
|
104
|
+
display: block;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
}
|
108
|
+
a {
|
109
|
+
border: none;
|
110
|
+
}
|
61
111
|
}
|
62
112
|
|
63
113
|
// forms
|
@@ -87,3 +137,17 @@ section.posts #welcome {
|
|
87
137
|
@include clearfix;
|
88
138
|
}
|
89
139
|
}
|
140
|
+
|
141
|
+
// font-awesome
|
142
|
+
@font-face {
|
143
|
+
font-family: 'FontAwesome';
|
144
|
+
src: url('/font/fontawesome-webfont.eot');
|
145
|
+
src: url('/font/fontawesome-webfont.eot?#iefix') format('embedded-opentype'), url('/font/fontawesome-webfont.woff') format('woff'), url('/font/fontawesome-webfont.ttf') format('truetype'), url('/font/fontawesome-webfont.svgz#FontAwesomeRegular') format('svg'), url('/font/fontawesome-webfont.svg#FontAwesomeRegular') format('svg');
|
146
|
+
font-weight: normal;
|
147
|
+
font-style: normal;
|
148
|
+
}
|
149
|
+
.font-awesome {
|
150
|
+
font-family: FontAwesome;
|
151
|
+
font-weight: normal;
|
152
|
+
font-style: normal;
|
153
|
+
}
|
data/schnitzelpress.gemspec
CHANGED
@@ -13,12 +13,14 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
14
|
gem.name = "schnitzelpress"
|
15
15
|
gem.require_paths = ["lib"]
|
16
|
-
gem.version =
|
16
|
+
gem.version = Schnitzelpress::VERSION
|
17
17
|
|
18
18
|
# base dependencies
|
19
19
|
gem.add_dependency 'rack', '~> 1.4.1'
|
20
20
|
gem.add_dependency 'rack-contrib', '~> 1.1.0'
|
21
|
+
gem.add_dependency 'rack-cache', '~> 1.1.0'
|
21
22
|
gem.add_dependency 'sinatra', '~> 1.3.2'
|
23
|
+
gem.add_dependency 'sinatra-contrib', '~> 1.3.1'
|
22
24
|
gem.add_dependency 'activesupport', '~> 3.2.0'
|
23
25
|
|
24
26
|
# database related
|
@@ -35,10 +37,11 @@ Gem::Specification.new do |gem|
|
|
35
37
|
gem.add_dependency 'sass', '~> 3.1.15'
|
36
38
|
gem.add_dependency 'redcarpet', '~> 2.1.0'
|
37
39
|
gem.add_dependency 'coderay', '~> 1.0.5'
|
38
|
-
gem.add_dependency 'schnitzelstyle', '~> 0.1.
|
40
|
+
gem.add_dependency 'schnitzelstyle', '~> 0.1.1'
|
39
41
|
gem.add_dependency 'i18n', '~> 0.6.0'
|
40
42
|
gem.add_dependency 'tilt', '~> 1.3.0'
|
41
43
|
gem.add_dependency 'ruby-oembed', '~> 0.8.5'
|
44
|
+
gem.add_dependency 'packr', '~> 3.1.1'
|
42
45
|
|
43
46
|
# CLI related
|
44
47
|
gem.add_dependency 'thor', '~> 0.14.6'
|
data/spec/app_spec.rb
CHANGED
@@ -1,16 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
configure do
|
5
|
-
set :blog_title, "A Test Blog"
|
6
|
-
end
|
7
|
-
end
|
8
|
-
|
9
|
-
describe SchnitzelPress::App do
|
3
|
+
describe Schnitzelpress::App do
|
10
4
|
include Rack::Test::Methods
|
11
5
|
|
12
6
|
def app
|
13
|
-
|
7
|
+
Schnitzelpress::App
|
14
8
|
end
|
15
9
|
|
16
10
|
describe 'the home page' do
|
@@ -23,7 +17,7 @@ describe SchnitzelPress::App do
|
|
23
17
|
subject { last_response }
|
24
18
|
|
25
19
|
it { should be_ok }
|
26
|
-
its(:body) { should have_tag 'title', :text =>
|
20
|
+
its(:body) { should have_tag 'title', :text => Schnitzelpress::Config.instance.blog_title }
|
27
21
|
its(:body) { should have_tag 'section.posts > article.post.published', :count => 5 }
|
28
22
|
its(:body) { should_not have_tag 'section.posts > article.post.draft' }
|
29
23
|
end
|
@@ -36,14 +30,14 @@ describe SchnitzelPress::App do
|
|
36
30
|
|
37
31
|
describe 'the public feed url' do
|
38
32
|
before do
|
39
|
-
|
33
|
+
Schnitzelpress::Config.instance.blog_feed_url = 'http://feeds.feedburner.com/example_org'
|
40
34
|
get '/feed'
|
41
35
|
end
|
42
36
|
|
43
37
|
subject { last_response }
|
44
38
|
it { should be_redirect }
|
45
39
|
its(:status) { should == 307 }
|
46
|
-
specify { subject["Location"].should == 'http://
|
40
|
+
specify { subject["Location"].should == 'http://example.org/blog.atom' }
|
47
41
|
end
|
48
42
|
|
49
43
|
describe 'viewing a single post' do
|
data/spec/assets_spec.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Schnitzelpress::Actions::Assets' do
|
4
|
+
include Rack::Test::Methods
|
5
|
+
|
6
|
+
def app
|
7
|
+
Schnitzelpress::App
|
8
|
+
end
|
9
|
+
|
10
|
+
describe '/assets/schnitzelpress.*.js' do
|
11
|
+
before do
|
12
|
+
Schnitzelpress::JavascriptPacker.should_receive(:pack_javascripts!).and_return('{123}')
|
13
|
+
get '/assets/schnitzelpress.123.js'
|
14
|
+
end
|
15
|
+
subject { last_response }
|
16
|
+
it { should be_ok }
|
17
|
+
its(:body) { should == '{123}' }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '/assets/schnitzelpress.*.css' do
|
21
|
+
before { get '/assets/schnitzelpress.123.css' }
|
22
|
+
subject { last_response }
|
23
|
+
it { should be_ok }
|
24
|
+
its(:content_type) { should == 'text/css;charset=utf-8' }
|
25
|
+
end
|
26
|
+
end
|
data/spec/factories.rb
CHANGED
data/spec/post_spec.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
3
|
+
describe Schnitzelpress::Post do
|
4
4
|
subject do
|
5
5
|
Factory.build(:post)
|
6
6
|
end
|
@@ -81,7 +81,7 @@ describe SchnitzelPress::Post do
|
|
81
81
|
it 'should return the latest published posts' do
|
82
82
|
2.times { Factory :draft_post }
|
83
83
|
5.times { Factory :published_post }
|
84
|
-
|
84
|
+
Schnitzelpress::Post.latest.size.should == 5
|
85
85
|
end
|
86
86
|
end
|
87
87
|
|
@@ -91,4 +91,11 @@ describe SchnitzelPress::Post do
|
|
91
91
|
its(:month) { should == 01 }
|
92
92
|
its(:day) { should == 02 }
|
93
93
|
end
|
94
|
+
|
95
|
+
context 'to_url' do
|
96
|
+
it 'should produce double-digit months and days' do
|
97
|
+
@post = Factory.build(:post, :published_at => '2012-1-1 12:00:00', :slug => 'test')
|
98
|
+
@post.to_url.should == '/2012/01/01/test/'
|
99
|
+
end
|
100
|
+
end
|
94
101
|
end
|