refinerycms-blog 1.6.2 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +7 -0
- data/Gemfile.lock +293 -0
- data/app/controllers/admin/blog/categories_controller.rb +8 -4
- data/app/controllers/admin/blog/comments_controller.rb +34 -30
- data/app/controllers/admin/blog/posts_controller.rb +81 -70
- data/app/controllers/admin/blog/settings_controller.rb +46 -32
- data/app/controllers/blog/categories_controller.rb +11 -9
- data/app/controllers/blog/posts_controller.rb +84 -76
- data/app/helpers/blog_posts_helper.rb +8 -4
- data/app/mailers/blog/comment_mailer.rb +11 -9
- data/app/models/blog_category.rb +1 -1
- data/app/models/blog_post.rb +15 -4
- data/app/views/admin/blog/_submenu.html.erb +4 -0
- data/app/views/admin/blog/categories/_category.html.erb +1 -1
- data/app/views/admin/blog/categories/_form.html.erb +1 -1
- data/app/views/admin/blog/categories/index.html.erb +3 -3
- data/app/views/admin/blog/comments/index.html.erb +3 -3
- data/app/views/admin/blog/posts/_form.css.erb +7 -2
- data/app/views/admin/blog/posts/_form.html.erb +5 -5
- data/app/views/admin/blog/posts/_post.html.erb +5 -2
- data/app/views/admin/blog/posts/_teaser_part.html.erb +2 -2
- data/app/views/admin/blog/posts/index.html.erb +3 -3
- data/app/views/admin/blog/posts/uncategorized.html.erb +3 -3
- data/app/views/blog/comment_mailer/notification.html.erb +11 -11
- data/app/views/blog/posts/_comment.html.erb +2 -2
- data/app/views/blog/posts/_nav.html.erb +1 -1
- data/app/views/blog/posts/_post.html.erb +4 -3
- data/app/views/blog/posts/show.html.erb +1 -1
- data/app/views/blog/shared/_post.html.erb +11 -6
- data/changelog.md +17 -4
- data/config/locales/bg.yml +158 -0
- data/config/locales/en.yml +3 -1
- data/config/locales/es.yml +31 -0
- data/config/locales/it.yml +68 -17
- data/config/locales/ja.yml +159 -0
- data/config/locales/nl.yml +1 -0
- data/config/locales/sk.yml +8 -8
- data/config/routes.rb +3 -2
- data/db/migrate/8_add_primary_key_to_categorizations.rb +12 -0
- data/lib/refinery/blog/version.rb +3 -3
- data/lib/refinerycms-blog.rb +6 -16
- data/public/stylesheets/ui-lightness/jquery-ui-1.8.13.custom.css +1 -8
- data/readme.md +3 -2
- data/refinerycms-blog.gemspec +8 -2
- data/spec/models/blog_post_spec.rb +25 -1
- data/todo.md +5 -0
- metadata +62 -96
@@ -1,39 +1,53 @@
|
|
1
|
-
|
1
|
+
module Admin
|
2
|
+
module Blog
|
3
|
+
class SettingsController < Admin::BaseController
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
+
def notification_recipients
|
6
|
+
@recipients = BlogComment::Notification.recipients
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
if request.post?
|
9
|
+
BlogComment::Notification.recipients = params[:recipients]
|
10
|
+
flash[:notice] = t('updated', :scope => 'admin.blog.settings.notification_recipients',
|
11
|
+
:recipients => BlogComment::Notification.recipients)
|
12
|
+
unless request.xhr? or from_dialog?
|
13
|
+
redirect_back_or_default(admin_blog_posts_path)
|
14
|
+
else
|
15
|
+
render :text => "<script type='text/javascript'>parent.window.location = '#{admin_blog_posts_path}';</script>",
|
16
|
+
:layout => false
|
17
|
+
end
|
18
|
+
end
|
15
19
|
end
|
16
|
-
end
|
17
|
-
end
|
18
20
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
21
|
+
def moderation
|
22
|
+
enabled = BlogComment::Moderation.toggle!
|
23
|
+
unless request.xhr?
|
24
|
+
redirect_back_or_default(admin_blog_posts_path)
|
25
|
+
else
|
26
|
+
render :json => {:enabled => enabled},
|
27
|
+
:layout => false
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def comments
|
32
|
+
enabled = BlogComment.toggle!
|
33
|
+
unless request.xhr?
|
34
|
+
redirect_back_or_default(admin_blog_posts_path)
|
35
|
+
else
|
36
|
+
render :json => {:enabled => enabled},
|
37
|
+
:layout => false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def teasers
|
42
|
+
enabled = BlogPost.teaser_enabled_toggle!
|
43
|
+
unless request.xhr?
|
44
|
+
redirect_back_or_default(admin_blog_posts_path)
|
45
|
+
else
|
46
|
+
render :json => {:enabled => enabled},
|
47
|
+
:layout => false
|
48
|
+
end
|
49
|
+
end
|
28
50
|
|
29
|
-
def comments
|
30
|
-
enabled = BlogComment.toggle!
|
31
|
-
unless request.xhr?
|
32
|
-
redirect_back_or_default(admin_blog_posts_path)
|
33
|
-
else
|
34
|
-
render :json => {:enabled => enabled},
|
35
|
-
:layout => false
|
36
51
|
end
|
37
52
|
end
|
38
|
-
|
39
|
-
end
|
53
|
+
end
|
@@ -1,11 +1,13 @@
|
|
1
|
-
|
1
|
+
module Blog
|
2
|
+
class CategoriesController < BlogController
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
def show
|
5
|
+
@category = BlogCategory.find(params[:id])
|
6
|
+
@blog_posts = @category.posts.live.includes(:comments, :categories).paginate({
|
7
|
+
:page => params[:page],
|
8
|
+
:per_page => RefinerySetting.find_or_set(:blog_posts_per_page, 10)
|
9
|
+
})
|
10
|
+
end
|
10
11
|
|
11
|
-
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,101 +1,109 @@
|
|
1
|
-
|
1
|
+
module Blog
|
2
|
+
class PostsController < BlogController
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
4
|
+
before_filter :find_all_blog_posts, :except => [:archive]
|
5
|
+
before_filter :find_blog_post, :only => [:show, :comment, :update_nav]
|
6
|
+
before_filter :find_tags
|
6
7
|
|
7
|
-
|
8
|
+
respond_to :html, :js, :rss
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
format.
|
12
|
-
format
|
10
|
+
def index
|
11
|
+
# Rss feeders are greedy. Let's give them every blog post instead of paginating.
|
12
|
+
(@blog_posts = BlogPost.live.includes(:comments, :categories).all) if request.format.rss?
|
13
|
+
respond_with (@blog_posts) do |format|
|
14
|
+
format.html
|
15
|
+
format.rss
|
16
|
+
end
|
13
17
|
end
|
14
|
-
end
|
15
18
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
def show
|
20
|
+
@blog_comment = BlogComment.new
|
21
|
+
@canonical = url_for(:locale => ::Refinery::I18n.default_frontend_locale) if canonical?
|
22
|
+
|
23
|
+
respond_with (@blog_post) do |format|
|
24
|
+
format.html { present(@blog_post) }
|
25
|
+
format.js { render :partial => 'post', :layout => false }
|
26
|
+
end
|
22
27
|
end
|
23
|
-
end
|
24
28
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
def comment
|
30
|
+
if (@blog_comment = @blog_post.comments.create(params[:blog_comment])).valid?
|
31
|
+
if BlogComment::Moderation.enabled? or @blog_comment.ham?
|
32
|
+
begin
|
33
|
+
Blog::CommentMailer.notification(@blog_comment, request).deliver
|
34
|
+
rescue
|
35
|
+
logger.warn "There was an error delivering a blog comment notification.\n#{$!}\n"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
if BlogComment::Moderation.enabled?
|
40
|
+
flash[:notice] = t('thank_you_moderated', :scope => 'blog.posts.comments')
|
41
|
+
redirect_to blog_post_url(params[:id])
|
42
|
+
else
|
43
|
+
flash[:notice] = t('thank_you', :scope => 'blog.posts.comments')
|
44
|
+
redirect_to blog_post_url(params[:id],
|
45
|
+
:anchor => "comment-#{@blog_comment.to_param}")
|
32
46
|
end
|
47
|
+
else
|
48
|
+
render :action => 'show'
|
33
49
|
end
|
50
|
+
end
|
34
51
|
|
35
|
-
|
36
|
-
|
37
|
-
|
52
|
+
def archive
|
53
|
+
if params[:month].present?
|
54
|
+
date = "#{params[:month]}/#{params[:year]}"
|
55
|
+
@archive_date = Time.parse(date)
|
56
|
+
@date_title = @archive_date.strftime('%B %Y')
|
57
|
+
@blog_posts = BlogPost.live.by_archive(@archive_date).paginate({
|
58
|
+
:page => params[:page],
|
59
|
+
:per_page => RefinerySetting.find_or_set(:blog_posts_per_page, 10)
|
60
|
+
})
|
38
61
|
else
|
39
|
-
|
40
|
-
|
41
|
-
|
62
|
+
date = "01/#{params[:year]}"
|
63
|
+
@archive_date = Time.parse(date)
|
64
|
+
@date_title = @archive_date.strftime('%Y')
|
65
|
+
@blog_posts = BlogPost.live.by_year(@archive_date).paginate({
|
66
|
+
:page => params[:page],
|
67
|
+
:per_page => RefinerySetting.find_or_set(:blog_posts_per_page, 10)
|
68
|
+
})
|
42
69
|
end
|
43
|
-
|
44
|
-
render :action => 'show'
|
70
|
+
respond_with (@blog_posts)
|
45
71
|
end
|
46
|
-
end
|
47
72
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
@
|
52
|
-
@date_title = @archive_date.strftime('%B %Y')
|
53
|
-
@blog_posts = BlogPost.live.by_archive(@archive_date).paginate({
|
54
|
-
:page => params[:page],
|
55
|
-
:per_page => RefinerySetting.find_or_set(:blog_posts_per_page, 10)
|
56
|
-
})
|
57
|
-
else
|
58
|
-
date = "01/#{params[:year]}"
|
59
|
-
@archive_date = Time.parse(date)
|
60
|
-
@date_title = @archive_date.strftime('%Y')
|
61
|
-
@blog_posts = BlogPost.live.by_year(@archive_date).paginate({
|
73
|
+
def tagged
|
74
|
+
@tag = ActsAsTaggableOn::Tag.find(params[:tag_id])
|
75
|
+
@tag_name = @tag.name
|
76
|
+
@blog_posts = BlogPost.tagged_with(@tag_name).paginate({
|
62
77
|
:page => params[:page],
|
63
78
|
:per_page => RefinerySetting.find_or_set(:blog_posts_per_page, 10)
|
64
79
|
})
|
65
80
|
end
|
66
|
-
respond_with (@blog_posts)
|
67
|
-
end
|
68
81
|
|
69
|
-
|
70
|
-
@tag = ActsAsTaggableOn::Tag.find(params[:tag_id])
|
71
|
-
@tag_name = @tag.name
|
72
|
-
@blog_posts = BlogPost.tagged_with(@tag_name).paginate({
|
73
|
-
:page => params[:page],
|
74
|
-
:per_page => RefinerySetting.find_or_set(:blog_posts_per_page, 10)
|
75
|
-
})
|
76
|
-
end
|
77
|
-
|
78
|
-
protected
|
82
|
+
protected
|
79
83
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
84
|
+
def find_blog_post
|
85
|
+
unless (@blog_post = BlogPost.find(params[:id])).try(:live?)
|
86
|
+
if refinery_user? and current_user.authorized_plugins.include?("refinerycms_blog")
|
87
|
+
@blog_post = BlogPost.find(params[:id])
|
88
|
+
else
|
89
|
+
error_404
|
90
|
+
end
|
86
91
|
end
|
87
92
|
end
|
88
|
-
end
|
89
93
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
94
|
+
def find_all_blog_posts
|
95
|
+
@blog_posts = BlogPost.live.includes(:comments, :categories).paginate({
|
96
|
+
:page => params[:page],
|
97
|
+
:per_page => RefinerySetting.find_or_set(:blog_posts_per_page, 10)
|
98
|
+
})
|
99
|
+
end
|
96
100
|
|
97
|
-
|
98
|
-
|
101
|
+
def find_tags
|
102
|
+
@tags = BlogPost.tag_counts_on(:tags)
|
103
|
+
end
|
104
|
+
|
105
|
+
def canonical?
|
106
|
+
::Refinery.i18n_enabled? && ::Refinery::I18n.default_frontend_locale != ::Refinery::I18n.current_frontend_locale
|
107
|
+
end
|
99
108
|
end
|
100
|
-
|
101
|
-
end
|
109
|
+
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
module BlogPostsHelper
|
2
2
|
def blog_archive_list
|
3
|
-
posts = BlogPost.select('published_at').all_previous
|
3
|
+
posts = BlogPost.live.select('published_at').all_previous
|
4
4
|
return nil if posts.blank?
|
5
5
|
html = '<section id="blog_archive_list"><h2>'
|
6
|
-
html << t('blog.shared
|
6
|
+
html << t('archives', :scope => 'blog.shared')
|
7
7
|
html << '</h2><nav><ul>'
|
8
8
|
links = []
|
9
9
|
super_old_links = []
|
@@ -20,7 +20,7 @@ module BlogPostsHelper
|
|
20
20
|
links.each do |l|
|
21
21
|
year = l.split('/')[1]
|
22
22
|
month = l.split('/')[0]
|
23
|
-
count = BlogPost.by_archive(Time.parse(l)).size
|
23
|
+
count = BlogPost.live.by_archive(Time.parse(l)).size
|
24
24
|
text = t("date.month_names")[month.to_i] + " #{year} (#{count})"
|
25
25
|
html << "<li>"
|
26
26
|
html << link_to(text, archive_blog_posts_path(:year => year, :month => month))
|
@@ -28,7 +28,7 @@ module BlogPostsHelper
|
|
28
28
|
end
|
29
29
|
super_old_links.each do |l|
|
30
30
|
year = l.split('/')[1]
|
31
|
-
count = BlogPost.by_year(Time.parse(l)).size
|
31
|
+
count = BlogPost.live.by_year(Time.parse(l)).size
|
32
32
|
text = "#{year} (#{count})"
|
33
33
|
html << "<li>"
|
34
34
|
html << link_to(text, archive_blog_posts_path(:year => year))
|
@@ -42,6 +42,10 @@ module BlogPostsHelper
|
|
42
42
|
post.next.present? or post.prev.present?
|
43
43
|
end
|
44
44
|
|
45
|
+
def blog_post_teaser_enabled?
|
46
|
+
BlogPost.teasers_enabled?
|
47
|
+
end
|
48
|
+
|
45
49
|
def blog_post_teaser(post)
|
46
50
|
if post.respond_to?(:custom_teaser) && post.custom_teaser.present?
|
47
51
|
post.custom_teaser.html_safe
|
@@ -1,11 +1,13 @@
|
|
1
|
-
|
1
|
+
module Blog
|
2
|
+
class CommentMailer < ActionMailer::Base
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
def notification(comment, request)
|
5
|
+
subject BlogComment::Notification.subject
|
6
|
+
recipients BlogComment::Notification.recipients
|
7
|
+
from "\"#{RefinerySetting[:site_name]}\" <no-reply@#{request.domain(RefinerySetting.find_or_set(:tld_length, 1))}>"
|
8
|
+
sent_on Time.now
|
9
|
+
@comment = comment
|
10
|
+
end
|
10
11
|
|
11
|
-
end
|
12
|
+
end
|
13
|
+
end
|
data/app/models/blog_category.rb
CHANGED
data/app/models/blog_post.rb
CHANGED
@@ -8,12 +8,12 @@ class BlogPost < ActiveRecord::Base
|
|
8
8
|
default_scope :order => 'published_at DESC'
|
9
9
|
#.first & .last will be reversed -- consider a with_exclusive_scope on these?
|
10
10
|
|
11
|
-
belongs_to :author, :class_name => 'User', :foreign_key => :user_id
|
11
|
+
belongs_to :author, :class_name => 'User', :foreign_key => :user_id, :readonly => true
|
12
12
|
|
13
13
|
has_many :comments, :class_name => 'BlogComment', :dependent => :destroy
|
14
14
|
acts_as_taggable
|
15
15
|
|
16
|
-
has_many :categorizations
|
16
|
+
has_many :categorizations, :dependent => :destroy
|
17
17
|
has_many :categories, :through => :categorizations, :source => :blog_category
|
18
18
|
|
19
19
|
acts_as_indexed :fields => [:title, :body]
|
@@ -26,8 +26,6 @@ class BlogPost < ActiveRecord::Base
|
|
26
26
|
:approximate_ascii => RefinerySetting.find_or_set(:approximate_ascii, false, :scoping => 'blog'),
|
27
27
|
:strip_non_ascii => RefinerySetting.find_or_set(:strip_non_ascii, false, :scoping => 'blog')
|
28
28
|
|
29
|
-
attr_accessible :title, :body, :tag_list, :draft, :published_at, :browser_title, :meta_keywords, :meta_description, :user_id, :category_ids, :custom_url, :custom_teaser
|
30
|
-
|
31
29
|
scope :by_archive, lambda { |archive_date|
|
32
30
|
where(['published_at between ? and ?', archive_date.beginning_of_month, archive_date.end_of_month])
|
33
31
|
}
|
@@ -77,6 +75,19 @@ class BlogPost < ActiveRecord::Base
|
|
77
75
|
:scoping => 'blog'
|
78
76
|
})
|
79
77
|
end
|
78
|
+
|
79
|
+
def teasers_enabled?
|
80
|
+
RefinerySetting.find_or_set(:teasers_enabled, true, {
|
81
|
+
:scoping => 'blog'
|
82
|
+
})
|
83
|
+
end
|
84
|
+
|
85
|
+
def teaser_enabled_toggle!
|
86
|
+
currently = RefinerySetting.find_or_set(:teasers_enabled, true, {
|
87
|
+
:scoping => 'blog'
|
88
|
+
})
|
89
|
+
RefinerySetting.set(:teasers_enabled, {:value => !currently, :scoping => 'blog'})
|
90
|
+
end
|
80
91
|
|
81
92
|
def uncategorized
|
82
93
|
BlogPost.live.reject { |p| p.categories.any? }
|
@@ -85,6 +85,10 @@
|
|
85
85
|
notification_recipients_admin_blog_settings_url(:dialog => true, :height => 400),
|
86
86
|
:class => 'user_comment_icon' %>
|
87
87
|
</li>
|
88
|
+
<li>
|
89
|
+
<%= link_to t('.settings.teasers'),
|
90
|
+
teasers_admin_blog_settings_url, :class => "#{BlogPost.teasers_enabled? ? 'success' : 'failure'}_icon" %>
|
91
|
+
</li>
|
88
92
|
</ul>
|
89
93
|
|
90
94
|
</nav>
|
@@ -11,6 +11,6 @@
|
|
11
11
|
:class => "cancel confirm-delete",
|
12
12
|
:title => t('.delete'),
|
13
13
|
:method => :delete,
|
14
|
-
:confirm => t('shared.admin.delete
|
14
|
+
:confirm => t('message', :scope => 'shared.admin.delete', :title => category.title) %>
|
15
15
|
</span>
|
16
16
|
</li>
|
@@ -1,12 +1,12 @@
|
|
1
1
|
<%= render :partial => '/admin/blog/submenu' %>
|
2
2
|
<div id='records'>
|
3
3
|
<% if searching? %>
|
4
|
-
<h2><%= t('shared.admin.search
|
4
|
+
<h2><%= t('results_for', :scope => 'shared.admin.search', :query => params[:search]) %></h2>
|
5
5
|
<% if @blog_categories.any? %>
|
6
6
|
<%= render :partial => "blog_categories",
|
7
7
|
:collection => @blog_categories %>
|
8
8
|
<% else %>
|
9
|
-
<p><%= t('
|
9
|
+
<p><%= t('search_no_results', :scope => 'admin') %></p>
|
10
10
|
<% end %>
|
11
11
|
<% else %>
|
12
12
|
<% if @blog_categories.any? %>
|
@@ -18,7 +18,7 @@
|
|
18
18
|
<% else %>
|
19
19
|
<p>
|
20
20
|
<strong>
|
21
|
-
<%= t('.no_items_yet', :create => t('admin.blog.submenu.categories
|
21
|
+
<%= t('.no_items_yet', :create => t('new', :scope => 'admin.blog.submenu.categories')) %>
|
22
22
|
</strong>
|
23
23
|
</p>
|
24
24
|
<% end %>
|