cartoonist-blog 0.0.3.5 → 0.0.4

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.
@@ -0,0 +1,102 @@
1
+ class BlogAdminController < ApplicationController
2
+ helper :blog
3
+ before_filter :preview!, :only => [:preview]
4
+ before_filter :ensure_ssl!
5
+ before_filter :check_admin!
6
+
7
+ def preview
8
+ if params[:id].present?
9
+ begin
10
+ @post = BlogPost.preview_from_url_title params[:id]
11
+ rescue
12
+ redirect_to "/blog_admin/preview"
13
+ end
14
+
15
+ if @post.posted_at
16
+ @disabled_next = @post.newest_preview?
17
+ else
18
+ @disabled_next = true
19
+ end
20
+ else
21
+ @post = BlogPost.preview_current
22
+ @title = "Blog for #{Setting[:site_name]}"
23
+ @disabled_next = true
24
+ end
25
+
26
+ @disabled_prev = true if @post.oldest?
27
+ render "blog/show", :layout => "blog"
28
+ end
29
+
30
+ def preview_content
31
+ render :text => Markdown.render(params[:content]), :layout => false
32
+ end
33
+
34
+ def index
35
+ @unposted = BlogPost.unposted.chronological
36
+ @posted = BlogPost.posted.reversed
37
+ end
38
+
39
+ def create
40
+ url_title = BlogPost.url_titlize params[:title]
41
+ post = BlogPost.create :title => params[:title], :url_title => url_title, :content => params[:content], :author => session[:user], :tweet => tweet_message(url_title), :locked => true
42
+ redirect_to "/blog_admin/#{post.id}/edit"
43
+ end
44
+
45
+ def edit
46
+ @post = BlogPost.find params[:id].to_i
47
+ rescue ActiveRecord::RecordNotFound
48
+ redirect_to "/blog_admin/new"
49
+ end
50
+
51
+ def update
52
+ post = BlogPost.find params[:id].to_i
53
+ raise "Cannot update locked post!" if post.locked
54
+ original_tweet = post.tweet
55
+ original_url_title = post.url_title
56
+ post.title = params[:title]
57
+ post.url_title = BlogPost.url_titlize params[:title]
58
+ post.author = params[:author]
59
+ post.tweet = params[:tweet]
60
+ post.content = params[:content]
61
+ post.locked = true
62
+
63
+ if original_tweet == post.tweet && original_url_title != post.url_title && !post.tweeted?
64
+ post.tweet = tweet_message post.url_title
65
+ end
66
+
67
+ if params[:posted] && params[:posted_at_date].present?
68
+ time = "#{params[:posted_at_date]} #{params[:posted_at_hour]}:#{params[:posted_at_minute]} #{params[:posted_at_meridiem]}"
69
+ time = DateTime.parse time
70
+ time = Time.local time.year, time.month, time.day, time.hour, time.min
71
+ post.posted_at = time
72
+ elsif params[:posted]
73
+ post.posted_at = 1.hour.from_now
74
+ else
75
+ post.posted_at = nil
76
+ end
77
+
78
+ post.save!
79
+ redirect_to "/blog_admin/#{post.id}/edit"
80
+ end
81
+
82
+ def lock
83
+ post = BlogPost.find params[:id].to_i
84
+ post.locked = true
85
+ post.save!
86
+ redirect_to "/blog_admin/#{post.id}/edit"
87
+ end
88
+
89
+ def unlock
90
+ post = BlogPost.find params[:id].to_i
91
+ post.locked = false
92
+ post.save!
93
+ redirect_to "/blog_admin/#{post.id}/edit"
94
+ end
95
+
96
+ private
97
+ def tweet_message(url_title)
98
+ tweet = "New blog post: http://#{Setting[:domain]}/blog/#{url_title}"
99
+ tweet = "New blog post: http://#{Setting[:domain]}/blog" if tweet.length > 140
100
+ tweet
101
+ end
102
+ end
@@ -0,0 +1,58 @@
1
+ class BlogController < ApplicationController
2
+ def archives
3
+ @posts = BlogPost.archives
4
+ render :layout => "page"
5
+ cache_page_as "blog/archives.#{cache_type}.tmp.html"
6
+ end
7
+
8
+ def show
9
+ @post = BlogPost.from_url_title params[:id]
10
+ @disabled_prev = @post.oldest?
11
+ @disabled_next = @post.newest?
12
+ render
13
+ cache_show_page
14
+ rescue
15
+ redirect_to "/blog"
16
+ end
17
+
18
+ def index
19
+ @post = BlogPost.current
20
+ @disabled_prev = true if @post.oldest?
21
+ @disabled_next = true
22
+ @title = "Blog for #{Setting[:site_name]}"
23
+ render :show
24
+ cache_page_as "blog.#{cache_type}.tmp.html"
25
+ end
26
+
27
+ def feed
28
+ respond_to do |format|
29
+ format.html { redirect_to "/blog/feed" }
30
+
31
+ format.rss do
32
+ @feed = feed_content
33
+ render :content_type => "application/xml"
34
+ end
35
+ end
36
+ end
37
+
38
+ private
39
+ def feed_content
40
+ result = blog_cache.read "blog-feed"
41
+ return result if result
42
+ result = BlogFeed.new BlogPost.feed
43
+ blog_cache.write "blog-feed", result
44
+ result
45
+ end
46
+
47
+ def blog_cache
48
+ @@blog_cache ||= ActiveSupport::Cache::MemoryStore.new(:expires_in => 2.hours)
49
+ end
50
+
51
+ def cache_show_page
52
+ if @disabled_next
53
+ cache_page_as "blog/#{@post.url_title}.#{cache_type}.tmp.html"
54
+ else
55
+ cache_page_as "blog/#{@post.url_title}.#{cache_type}.html"
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,21 @@
1
+ module BlogAdminHelper
2
+ def lock_toggle_target
3
+ if @post.locked
4
+ "unlock"
5
+ else
6
+ "lock"
7
+ end
8
+ end
9
+
10
+ def lock_disabled
11
+ if @post.locked
12
+ 'disabled="disabled"'.html_safe
13
+ end
14
+ end
15
+
16
+ def format_posted_at(fmt)
17
+ if @post && @post.posted_at
18
+ @post.posted_at.localtime.strftime fmt
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+ module BlogHelper
2
+ def blog_current_url
3
+ if preview?
4
+ "/blog_admin/preview"
5
+ else
6
+ "/blog"
7
+ end
8
+ end
9
+
10
+ def blog_post_url(url_title)
11
+ if preview?
12
+ "/blog_admin/#{url_title}/preview"
13
+ else
14
+ "/blog/#{url_title}"
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ class BlogFeed
2
+ attr_reader :pub_date, :items
3
+
4
+ def initialize(feed)
5
+ @pub_date = feed.first.posted_at.localtime.strftime "%a, %d %b %Y %H:%M:00 %z"
6
+ @items = feed.map do |item|
7
+ BlogFeed::Item.new item
8
+ end
9
+ end
10
+
11
+ class Item
12
+ attr_reader :title, :content, :url_title, :pub_date
13
+
14
+ def initialize(post)
15
+ @title = post.title
16
+ @content = Markdown.render post.content, false
17
+ @url_title = post.url_title
18
+ @pub_date = post.posted_at.localtime.strftime "%a, %d %b %Y %H:%M:00 %z"
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,187 @@
1
+ class BlogPost < ActiveRecord::Base
2
+ include Tweetable
3
+ attr_accessor :for_preview
4
+
5
+ def expected_tweet_time
6
+ posted_at
7
+ end
8
+
9
+ def formatted_posted_at(default_msg = "not yet posted")
10
+ if posted_at
11
+ posted_at.localtime.strftime "%-m/%-d/%Y at %-l:%M %P"
12
+ else
13
+ default_msg
14
+ end
15
+ end
16
+
17
+ def first_post
18
+ return @first_post if @first_post_retrieved
19
+ @first_post_retrieved = true
20
+ @first_post ||= BlogPost.first_post
21
+ end
22
+
23
+ def first_url_title
24
+ first_post.url_title if first_post
25
+ end
26
+
27
+ def newest_post
28
+ return @newest_post if @newest_post_retrieved
29
+ @newest_post_retrieved = true
30
+ @newest_post ||= BlogPost.newest_post
31
+ end
32
+
33
+ def newest_preview_post
34
+ return @newest_preview_post if @newest_preview_post_retrieved
35
+ @newest_preview_post_retrieved = true
36
+ @newest_preview_post ||= BlogPost.newest_preview_post
37
+ end
38
+
39
+ def newest_id
40
+ newest_post.id if newest_post
41
+ end
42
+
43
+ def newest_preview_id
44
+ newest_preview_post.id if newest_preview_post
45
+ end
46
+
47
+ def oldest?
48
+ url_title == first_url_title
49
+ end
50
+
51
+ def newest?
52
+ id == newest_id
53
+ end
54
+
55
+ def newest_preview?
56
+ id == newest_preview_id
57
+ end
58
+
59
+ def previous_post
60
+ return @previous_post if @previous_post_retrieved
61
+
62
+ if posted_at
63
+ @previous_post_retrieved = true
64
+ @previous_post ||= BlogPost.previous_post(self)
65
+ elsif for_preview
66
+ @previous_post_retrieved = true
67
+ @previous_post ||= BlogPost.preview_current
68
+ end
69
+ end
70
+
71
+ def next_post
72
+ return @next_post if @next_post_retrieved
73
+
74
+ if posted_at
75
+ @next_post_retrieved = true
76
+ @next_post ||= BlogPost.next_post(self)
77
+ end
78
+ end
79
+
80
+ def prev_url_title
81
+ previous_post.url_title if previous_post
82
+ end
83
+
84
+ def next_url_title
85
+ next_post.url_title if next_post
86
+ end
87
+
88
+ def real?
89
+ url_title
90
+ end
91
+
92
+ def absolute_url
93
+ "http://#{Setting[:domain]}/blog/#{url_title}"
94
+ end
95
+
96
+ class << self
97
+ def url_titlize(title)
98
+ title.downcase.gsub(" ", "-").gsub(/[^-_a-z0-9]/, "")
99
+ end
100
+
101
+ def newest_preview_post
102
+ reversed.first || new(:title => "No Posts Yet", :content => "There are no blog posts yet.")
103
+ end
104
+
105
+ def newest_post
106
+ posted.reversed.first || new(:title => "No Posts Yet", :content => "There are no blog posts yet.")
107
+ end
108
+
109
+ def first_post
110
+ posted.chronological.first || new(:title => "No Posts Yet", :content => "There are no blog posts yet.")
111
+ end
112
+
113
+ def posted
114
+ where "blog_posts.posted_at IS NOT NULL AND blog_posts.posted_at <= ?", Time.now
115
+ end
116
+
117
+ def unposted
118
+ where "blog_posts.posted_at IS NULL OR blog_posts.posted_at > ?", Time.now
119
+ end
120
+
121
+ def chronological
122
+ order "blog_posts.posted_at ASC"
123
+ end
124
+
125
+ def reversed
126
+ order "blog_posts.posted_at DESC"
127
+ end
128
+
129
+ def all_columns
130
+ select "blog_posts.*"
131
+ end
132
+
133
+ def current
134
+ post = posted.reversed.first
135
+ post = new :title => "No Posts Yet", :content => "There are no blog posts yet." unless post
136
+ post
137
+ end
138
+
139
+ def preview_current
140
+ post = reversed.first
141
+ post = new :title => "No Posts Yet", :content => "There are no blog posts yet." unless post
142
+ post.for_preview = true
143
+ post
144
+ end
145
+
146
+ def previous_post(post)
147
+ context = BlogPost
148
+ context = posted unless post.for_preview
149
+ context.where("blog_posts.posted_at < ?", post.posted_at).reversed.first
150
+ end
151
+
152
+ def next_post(post)
153
+ context = BlogPost
154
+ context = posted unless post.for_preview
155
+ context.where("blog_posts.posted_at > ?", post.posted_at).chronological.first
156
+ end
157
+
158
+ def from_url_title(url_title)
159
+ post = posted.where(:url_title => url_title).first
160
+ raise ActiveRecord::RecordNotFound.new("No records found!") unless post
161
+ post
162
+ end
163
+
164
+ def preview_from_url_title(url_title)
165
+ post = where(:url_title => url_title).first
166
+ raise ActiveRecord::RecordNotFound.new("No records found!") unless post
167
+ post.for_preview = true
168
+ post
169
+ end
170
+
171
+ def archives
172
+ posted.reversed.select([:url_title, :title, :posted_at]).all
173
+ end
174
+
175
+ def untweeted
176
+ posted.where(:tweeted_at => nil).all
177
+ end
178
+
179
+ def feed
180
+ posted.reversed.take 10
181
+ end
182
+
183
+ def sitemap
184
+ posted.reversed.all
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,10 @@
1
+ <% content_for(:title, "Blog Archives for #{Setting[:site_name]}") %>
2
+
3
+ <ul>
4
+ <% @posts.each do |post| %>
5
+ <li>
6
+ <%= post.posted_at.localtime.strftime "%m/%d/%Y" %>:
7
+ <a href="/blog/<%= post.url_title %>"><%= post.title %></a>
8
+ </li>
9
+ <% end %>
10
+ </ul>
@@ -0,0 +1,15 @@
1
+ <% content_for :rss_title, "#{Setting[:site_name]} Blog" %>
2
+ <% content_for :pub_date, @feed.pub_date %>
3
+
4
+ <% @feed.items.each do |item| %>
5
+ <item>
6
+ <title><%= item.title %></title>
7
+ <description>
8
+ <%= "<h1>#{h item.title}</h1>" %>
9
+ <%= item.content %>
10
+ </description>
11
+ <link>http://<%= Setting[:domain] %>/blog/<%= item.url_title %></link>
12
+ <guid>http://<%= Setting[:domain] %>/blog/<%= item.url_title %></guid>
13
+ <pubDate><%= item.pub_date %></pubDate>
14
+ </item>
15
+ <% end %>
@@ -0,0 +1,16 @@
1
+ <% content_for(:title, @title || @post.title) %>
2
+ <% content_for :post_date, @post.formatted_posted_at %>
3
+ <% content_for :first, @post.first_url_title %>
4
+ <% content_for :prev, @post.prev_url_title %>
5
+ <% content_for :next, @post.next_url_title %>
6
+ <% enable_disqus! :path => "blog/#{@post.url_title}", :title => "#{@post.title}", :category => Setting[:disqus_blog_post_category] %>
7
+
8
+ <div class="blog-post">
9
+ <h1 class="title"><a href="/blog/<%= @post.url_title %>"><%= @post.title %></a></h1>
10
+ <h2 class="posted-date">Posted on <%= @post.formatted_posted_at %></h2>
11
+ <h2 class="byline">by <%= @post.author %></h2>
12
+
13
+ <div class="blog-post-content">
14
+ <%= markdown @post.content %>
15
+ </div>
16
+ </div>
@@ -0,0 +1,103 @@
1
+ <p>
2
+ <a href="/blog_admin/<%= @post.url_title %>/preview">Preview this post</a>
3
+ </p>
4
+
5
+ <p>
6
+ <%= form_tag "/blog_admin/#{@post.id}/#{lock_toggle_target}", :method => :post do %>
7
+ <input type="submit" value="<%= lock_toggle_target %>" />
8
+ <% end %>
9
+ </p>
10
+
11
+ <%= form_tag "/blog_admin/#{@post.id}", :method => :put do %>
12
+ <p>
13
+ <label><input type="checkbox" name="posted" value="true" <%= checked="checked".html_safe if @post.posted_at %> <%= lock_disabled %> />Posted at</label>
14
+ <input type="text" name="posted_at_date" value="<%= format_posted_at "%Y-%m-%d" %>" <%= lock_disabled %> />
15
+ <select name="posted_at_hour" <%= lock_disabled %>>
16
+ <% 1.upto 12 do |h| %>
17
+ <option value="<%= h %>" <%= selected h, format_posted_at("%-l").to_i %>><%= h %></option>
18
+ <% end %>
19
+ </select>
20
+ <select name="posted_at_minute" <%= lock_disabled %>>
21
+ <% 0.upto 60 do |m| %>
22
+ <option value="<%= m %>" <%= selected m, format_posted_at("%-M").to_i %>><%= m %></option>
23
+ <% end %>
24
+ </select>
25
+ <select name="posted_at_meridiem" <%= lock_disabled %>>
26
+ <option value="am" <%= selected "am", format_posted_at("%P") %>>am</option>
27
+ <option value="pm" <%= selected "pm", format_posted_at("%P") %>>pm</option>
28
+ </select>
29
+ </p>
30
+
31
+ <p>
32
+ URL Title: <%= @post.url_title %>
33
+ </p>
34
+
35
+ <p>
36
+ Title:
37
+ <input type="text" name="title" size="100" value="<%= @post.title %>" <%= lock_disabled %> />
38
+ </p>
39
+
40
+ <p>
41
+ Author:
42
+ <input type="text" name="author" size="20" value="<%= @post.author %>" <%= lock_disabled %> />
43
+ </p>
44
+
45
+ <p>
46
+ Tweet:
47
+ <% if @post.tweeted_at %>
48
+ <em>(sent <%= @post.tweeted_at.strftime "%-m/%-d/%Y %-l:%M %P" %>)</em>
49
+ <% end %>
50
+ <br />
51
+ <textarea name="tweet" rows="2" cols="100" tabindex="5" <%= lock_disabled %>><%= @post.tweet %></textarea>
52
+ </p>
53
+
54
+ <p>
55
+ <input type="submit" value="Save" <%= lock_disabled %> />
56
+ <input type="button" value="Preview" class="preview-content" />
57
+ </p>
58
+
59
+ <p>
60
+ Content:<br />
61
+ <textarea name="content" rows="20" cols="100" <%= lock_disabled %>><%= @post.content %></textarea><br />
62
+ </p>
63
+
64
+ <p>
65
+ <input type="submit" value="Save" <%= lock_disabled %> />
66
+ <input type="button" value="Preview" class="preview-content" />
67
+ </p>
68
+ <% end %>
69
+
70
+ <hr />
71
+
72
+ <div class="preview-content">
73
+ </div>
74
+
75
+ <%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" %>
76
+ <%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.18/jquery-ui.min.js" %>
77
+ <%= stylesheet_link_tag "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.17/themes/base/jquery-ui.css" %>
78
+ <%= javascript_tag do %>
79
+ $(function() {
80
+ $("input[name='posted_at_date']").datepicker({ dateFormat: "yy-mm-dd" });
81
+ $(".preview-content").click(function() {
82
+ var $this = $(this).attr("disabled", "disabled");
83
+ $.ajax({
84
+ url: "/blog_admin/preview_content",
85
+ type: "post",
86
+ data: {
87
+ authenticity_token: $("form input[name='authenticity_token']").val(),
88
+ content: $("textarea[name='content']").val()
89
+ },
90
+ dataType: "text",
91
+ success: function(text) {
92
+ $(".preview-content").html(text);
93
+ $this.removeAttr("disabled");
94
+ },
95
+ error: function() {
96
+ $(".preview-content").html('<div style="color: red;">There was an error.</div>');
97
+ $this.removeAttr("disabled");
98
+ }
99
+ });
100
+ return false;
101
+ });
102
+ });
103
+ <% end %>
@@ -0,0 +1,23 @@
1
+ <h2><%= t "admin.blog.index.not_posted" %></h2>
2
+
3
+ <ul>
4
+ <% @unposted.each do |post| %>
5
+ <li>
6
+ <%= post.formatted_posted_at "" %>
7
+ <a href="/blog_admin/<%= post.id %>/edit"><%= post.title %></a>
8
+ (<a href="/blog_admin/<%= post.url_title %>/preview"><%= t "admin.blog.index.preview" %></a>)
9
+ </li>
10
+ <% end %>
11
+ </ul>
12
+
13
+ <h2><%= t "admin.blog.index.posted" %></h2>
14
+
15
+ <ul>
16
+ <% @posted.each do |post| %>
17
+ <li>
18
+ <%= post.formatted_posted_at "" %>
19
+ <a href="/blog_admin/<%= post.id %>/edit"><%= post.title %></a>
20
+ (<a href="/blog_admin/<%= post.url_title %>/preview"><%= t "admin.blog.index.preview" %></a>)
21
+ </li>
22
+ <% end %>
23
+ </ul>
@@ -0,0 +1,47 @@
1
+ <%= form_tag "/blog_admin", :method => :post do %>
2
+ <p>
3
+ Title: <input type="text" name="title" autofocus="autofocus" size="100" /><br />
4
+ </p>
5
+
6
+ <p>
7
+ Content:<br />
8
+ <textarea name="content" rows="20" cols="100"></textarea><br />
9
+ </p>
10
+
11
+ <p>
12
+ <input type="submit" value="Save" />
13
+ <input type="button" value="Preview" class="preview-content" />
14
+ </p>
15
+ <% end %>
16
+
17
+ <hr />
18
+
19
+ <div class="preview-content">
20
+ </div>
21
+
22
+ <%= javascript_include_tag "https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" %>
23
+ <%= javascript_tag do %>
24
+ $(function() {
25
+ $(".preview-content").click(function() {
26
+ var $this = $(this).attr("disabled", "disabled");
27
+ $.ajax({
28
+ url: "/blog_admin/preview_content",
29
+ type: "post",
30
+ data: {
31
+ authenticity_token: $("form input[name='authenticity_token']").val(),
32
+ content: $("textarea[name='content']").val()
33
+ },
34
+ dataType: "text",
35
+ success: function(text) {
36
+ $(".preview-content").html(text);
37
+ $this.removeAttr("disabled");
38
+ },
39
+ error: function() {
40
+ $(".preview-content").html('<div style="color: red;">There was an error.</div>');
41
+ $this.removeAttr("disabled");
42
+ }
43
+ });
44
+ return false;
45
+ });
46
+ });
47
+ <% end %>
@@ -0,0 +1,70 @@
1
+ <% content_for :content_class, "blog-content" %>
2
+ <% licensed! %>
3
+ <% rss! "/blog/feed", t("blog.layout.rss_title", :site_name => Setting[:site_name]) %>
4
+
5
+ <% content_for :small_buttons do %>
6
+ <% if @post.real? %>
7
+ <a class="facebook" href="https://www.facebook.com/sharer.php?u=<%= u @post.absolute_url %>&t=<%= u t("blog.layout.facebook_text_message", :title => @post.title) %>" title="<%= t "blog.layout.facebook_title" %>"><%= t "blog.layout.facebook" %></a>
8
+ <a class="twitter" href="https://twitter.com/intent/tweet?source=<%= u Setting[:domain] %>&text=<%= u t("blog.layout.twitter_text_message", :url => @post.absolute_url) %>" title="<%= t "blog.layout.twitter_title" %>"><%= t "blog.layout.twitter" %></a>
9
+ <a class="google-plus" href="https://plus.google.com/share?url=<%= u @post.absolute_url %>" title="<%= t "blog.layout.google_plus_title" %>"><%= t "blog.layout.google_plus" %></a>
10
+ <a class="rss" href="<%= rss_path %>" title="<%= rss_title %>"><%= t "blog.layout.rss" %></a>
11
+ <% end %>
12
+ <% end %>
13
+
14
+ <% content_for :content do %>
15
+ <div class="blog-page">
16
+ <div class="nav-container">
17
+ <div class="nav">
18
+ <% if @disabled_prev %>
19
+ <a class="first-disabled">first</a>
20
+ <a class="prev-disabled">prev</a>
21
+ <% else %>
22
+ <a class="first" href="<%= blog_post_url yield(:first) %>">first</a>
23
+ <a class="prev" href="<%= blog_post_url yield(:prev) %>">prev</a>
24
+ <% end %>
25
+ <a class="archives" href="/blog/archives">archives</a>
26
+ <% if @disabled_next %>
27
+ <a class="next-disabled">next</a>
28
+ <a class="last-disabled">last</a>
29
+ <% else %>
30
+ <a class="next" href="<%= blog_post_url yield(:next) %>">next</a>
31
+ <a class="last" href="<%= blog_current_url %>">last</a>
32
+ <% end %>
33
+ </div>
34
+ </div>
35
+
36
+ <%= yield %>
37
+
38
+ <div class="nav-container">
39
+ <div class="nav">
40
+ <% if @disabled_prev %>
41
+ <a class="first-disabled">first</a>
42
+ <a class="prev-disabled">prev</a>
43
+ <% else %>
44
+ <a class="first" href="<%= blog_post_url yield(:first) %>">first</a>
45
+ <a class="prev" href="<%= blog_post_url yield(:prev) %>">prev</a>
46
+ <% end %>
47
+ <a class="archives" href="/blog/archives">archives</a>
48
+ <% if @disabled_next %>
49
+ <a class="next-disabled">next</a>
50
+ <a class="last-disabled">last</a>
51
+ <% else %>
52
+ <a class="next" href="<%= blog_post_url yield(:next) %>">next</a>
53
+ <a class="last" href="<%= blog_current_url %>">last</a>
54
+ <% end %>
55
+ </div>
56
+ </div>
57
+ </div>
58
+ <% end %>
59
+
60
+ <% content_for :post_date_content do %>
61
+ <p class="posted-date">Posted on <%= yield :post_date %></p>
62
+ <% end %>
63
+
64
+ <% content_for :admin_content do %>
65
+ <% if preview? %>
66
+ <p><a href="/admin/main">admin</a></p>
67
+ <% end %>
68
+ <% end %>
69
+
70
+ <%= render :template => "layouts/application" %>
@@ -0,0 +1,10 @@
1
+ <% content_for :subtabs do %>
2
+ <a class="subtab" href="/blog"><%= t "admin.blog.layout.latest" %></a>
3
+ <a class="subtab" href="/blog_admin"><%= t "admin.blog.layout.list" %></a>
4
+ <a class="subtab" href="/blog_admin/new"><%= t "admin.blog.layout.new" %></a>
5
+ <a class="subtab" href="/blog_admin/preview"><%= t "admin.blog.layout.preview" %></a>
6
+ <% end %>
7
+
8
+ <% content_for :page_title, t("admin.blog.layout.section") %>
9
+ <% content_for(:content) { yield } %>
10
+ <%= render :template => "layouts/admin" %>
@@ -1,7 +1,8 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "cartoonist-blog"
3
- s.version = "0.0.3.5"
4
- s.date = "2012-04-12"
3
+ raise "Cannot find version file!" unless File.exists?(File.join(File.dirname(__FILE__), "../CARTOONIST_VERSION"))
4
+ s.version = File.read File.join(File.dirname(__FILE__), "../CARTOONIST_VERSION")
5
+ s.date = Time.now.strftime "%Y-%m-%d"
5
6
  s.summary = "Cartoonist Blog"
6
7
  s.description = "This core plugin for Cartoonist adds a simple blog."
7
8
  s.authors = ["Mike Virata-Stone"]
@@ -0,0 +1,32 @@
1
+ en:
2
+ admin:
3
+ blog:
4
+ index:
5
+ not_posted: Not yet posted
6
+ posted: Posted
7
+ preview: preview
8
+ layout:
9
+ latest: View Latest
10
+ list: List
11
+ new: New Post
12
+ preview: Preview
13
+ section: Blog
14
+ layout:
15
+ tab:
16
+ blog: Blog
17
+ application:
18
+ layout:
19
+ navigation:
20
+ blog: Blog
21
+ blog:
22
+ layout:
23
+ facebook: Facebook
24
+ facebook_text_message: "Check this out: %{title}"
25
+ facebook_title: Share this on Facebook
26
+ google_plus: Google Plus
27
+ google_plus_title: Post this to Google Plus
28
+ rss: RSS
29
+ rss_title: RSS Feed for the %{site_name} blog
30
+ twitter: Twitter
31
+ twitter_text_message: "Check this out: %{url}"
32
+ twitter_title: Tweet about this
@@ -0,0 +1,19 @@
1
+ class CreateBlogPosts < ActiveRecord::Migration
2
+ def change
3
+ create_table :blog_posts do |t|
4
+ t.string :title, :null => false
5
+ t.string :url_title, :null => false
6
+ t.string :author, :null => false
7
+ t.datetime :posted_at
8
+ t.text :content, :null => false
9
+ t.string :tweet, :null => false, :length => 140
10
+ t.datetime :tweeted_at
11
+ t.boolean :locked, :null => false, :default => false
12
+ t.timestamps
13
+ end
14
+
15
+ add_index :blog_posts, :title, :unique => true
16
+ add_index :blog_posts, :url_title, :unique => true
17
+ add_index :blog_posts, :posted_at
18
+ end
19
+ end
@@ -1,4 +1,48 @@
1
1
  module CartoonistBlog
2
2
  class Engine < ::Rails::Engine
3
+ Cartoonist::Admin::Tab.add :blog, :url => "/blog_admin", :order => 1
4
+ Cartoonist::Navigation::Link.add :url => "/blog", :preview_url => "/blog_admin/preview", :class => "blog", :label => "application.layout.navigation.blog", :order => 1
5
+ Cartoonist::Migration.add_for self
6
+
7
+ Cartoonist::Backup.for :blog_posts do
8
+ BlogPost.order(:id).all
9
+ end
10
+
11
+ Cartoonist::Sitemap.add do
12
+ posts = BlogPost.sitemap
13
+
14
+ result = posts.map do |post|
15
+ SitemapEntry.new "/blog/#{post.url_title}", post.posted_at, :never
16
+ end
17
+
18
+ unless result.empty?
19
+ first = posts.first
20
+ result << SitemapEntry.new("/blog", first.posted_at, :weekly, "0.9")
21
+ end
22
+
23
+ result
24
+ end
25
+
26
+ Cartoonist::Routes.add do
27
+ resources :blog do
28
+ collection do
29
+ get "archives"
30
+ get "feed", :defaults => { :format => "rss" }
31
+ end
32
+ end
33
+
34
+ resources :blog_admin do
35
+ member do
36
+ post "lock"
37
+ get "preview"
38
+ post "unlock"
39
+ end
40
+
41
+ collection do
42
+ get "preview"
43
+ post "preview_content"
44
+ end
45
+ end
46
+ end
3
47
  end
4
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cartoonist-blog
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3.5
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-12 00:00:00.000000000 Z
12
+ date: 2012-04-16 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: This core plugin for Cartoonist adds a simple blog.
15
15
  email: reasonnumber@gmail.com
@@ -18,7 +18,23 @@ extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
20
  - .gitignore
21
+ - app/controllers/blog_admin_controller.rb
22
+ - app/controllers/blog_controller.rb
23
+ - app/helpers/blog_admin_helper.rb
24
+ - app/helpers/blog_helper.rb
25
+ - app/models/blog_feed.rb
26
+ - app/models/blog_post.rb
27
+ - app/views/blog/archives.html.erb
28
+ - app/views/blog/feed.rss.erb
29
+ - app/views/blog/show.html.erb
30
+ - app/views/blog_admin/edit.html.erb
31
+ - app/views/blog_admin/index.html.erb
32
+ - app/views/blog_admin/new.html.erb
33
+ - app/views/layouts/blog.html.erb
34
+ - app/views/layouts/blog_admin.html.erb
21
35
  - cartoonist-blog.gemspec
36
+ - config/locales/en.yml
37
+ - db/migrate/20120308064117_create_blog_posts.rb
22
38
  - lib/cartoonist-blog.rb
23
39
  - lib/cartoonist-blog/engine.rb
24
40
  homepage: http://reasonnumber.com/cartoonist