cartoonist-blog 0.0.3.5 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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