the_comments_ruby 2.3.3
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.
- checksums.yaml +7 -0
- data/.gitignore +30 -0
- data/.ruby-gemset.example +1 -0
- data/.ruby-version.example +1 -0
- data/.rvmrc.example +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +338 -0
- data/Rakefile +1 -0
- data/app/assets/javascripts/the_comments.js.coffee +108 -0
- data/app/assets/javascripts/the_comments_manage.js.coffee +27 -0
- data/app/assets/stylesheets/the_comments.css.scss +248 -0
- data/app/controllers/_templates_/comments_controller.rb +44 -0
- data/app/controllers/concerns/the_comments/controller.rb +197 -0
- data/app/controllers/concerns/the_comments/view_token.rb +20 -0
- data/app/helpers/render_comments_tree_helper.rb +111 -0
- data/app/models/_templates_/comment.rb +38 -0
- data/app/models/concerns/the_comments/comment.rb +116 -0
- data/app/models/concerns/the_comments/comment_states.rb +80 -0
- data/app/models/concerns/the_comments/commentable.rb +69 -0
- data/app/models/concerns/the_comments/user.rb +56 -0
- data/app/views/the_comments/_tree.html.erb +3 -0
- data/app/views/the_comments/haml/_additional_info.html.haml +13 -0
- data/app/views/the_comments/haml/_comment.html.haml +1 -0
- data/app/views/the_comments/haml/_comment_body.html.haml +25 -0
- data/app/views/the_comments/haml/_comment_edit.html.haml +26 -0
- data/app/views/the_comments/haml/_form.html.haml +8 -0
- data/app/views/the_comments/haml/_guest_form.html.haml +22 -0
- data/app/views/the_comments/haml/_logined_form.html.haml +18 -0
- data/app/views/the_comments/haml/_manage_controls.html.haml +30 -0
- data/app/views/the_comments/haml/_sidebar.html.haml +9 -0
- data/app/views/the_comments/haml/_sidebar_admin.html.haml +12 -0
- data/app/views/the_comments/haml/_sidebar_backlink.html.haml +3 -0
- data/app/views/the_comments/haml/_sidebar_user.html.haml +29 -0
- data/app/views/the_comments/haml/_tree.html.haml +16 -0
- data/app/views/the_comments/haml/manage.html.haml +26 -0
- data/app/views/the_comments/slim/_additional_info.html.slim +13 -0
- data/app/views/the_comments/slim/_comment.html.slim +1 -0
- data/app/views/the_comments/slim/_comment_body.html.slim +24 -0
- data/app/views/the_comments/slim/_comment_edit.html.slim +26 -0
- data/app/views/the_comments/slim/_form.html.slim +8 -0
- data/app/views/the_comments/slim/_guest_form.html.slim +22 -0
- data/app/views/the_comments/slim/_logined_form.html.slim +18 -0
- data/app/views/the_comments/slim/_manage_controls.html.slim +30 -0
- data/app/views/the_comments/slim/_sidebar.html.slim +9 -0
- data/app/views/the_comments/slim/_sidebar_admin.html.slim +12 -0
- data/app/views/the_comments/slim/_sidebar_backlink.html.slim +3 -0
- data/app/views/the_comments/slim/_sidebar_user.html.slim +29 -0
- data/app/views/the_comments/slim/_tree.html.slim +16 -0
- data/app/views/the_comments/slim/index.html.slim +18 -0
- data/app/views/the_comments/slim/manage.html.slim +26 -0
- data/app/views/the_comments/slim/my_comments.html.slim +28 -0
- data/config/initializers/the_comments.rb +14 -0
- data/config/locales/en.yml +68 -0
- data/config/locales/ru.yml +71 -0
- data/config/routes.rb +38 -0
- data/db/migrate/20130101010101_the_comments_change_user.rb +18 -0
- data/db/migrate/20130101010102_the_comments_create_comments.rb +50 -0
- data/db/migrate/20130101010103_the_comments_change_commentable.rb +13 -0
- data/docs/admin_ui_installation.md +145 -0
- data/docs/advanced_installation.md +185 -0
- data/docs/comment_api.md +58 -0
- data/docs/commentable_api.md +59 -0
- data/docs/config_file.md +27 -0
- data/docs/content_preprocessors.md +73 -0
- data/docs/customazation_of_views.md +30 -0
- data/docs/denormalization_and_recent_comments.md +40 -0
- data/docs/documentation.md +29 -0
- data/docs/generators.md +74 -0
- data/docs/pagination.md +123 -0
- data/docs/routes.md +77 -0
- data/docs/screencast.jpg +0 -0
- data/docs/the_comments.jpg +0 -0
- data/docs/the_comments_view_1.gif +0 -0
- data/docs/the_comments_view_2.gif +0 -0
- data/docs/the_comments_view_3.gif +0 -0
- data/docs/the_comments_view_4.gif +0 -0
- data/docs/the_comments_view_5.gif +0 -0
- data/docs/user_api.md +75 -0
- data/docs/what_is_comcoms.md +63 -0
- data/docs/whats_wrong_with_other_gems.md +28 -0
- data/docs/where_is_example_application.md +37 -0
- data/gem_version.rb +3 -0
- data/lib/generators/the_comments/USAGE +44 -0
- data/lib/generators/the_comments/the_comments_generator.rb +56 -0
- data/lib/generators/the_comments/views_generator.rb +79 -0
- data/lib/the_comments/config.rb +37 -0
- data/lib/the_comments/version.rb +1 -0
- data/lib/the_comments.rb +28 -0
- data/spec/dummy_app/.gitignore +18 -0
- data/spec/dummy_app/.rspec +1 -0
- data/spec/dummy_app/Gemfile +43 -0
- data/spec/dummy_app/README.md +33 -0
- data/spec/dummy_app/Rakefile +6 -0
- data/spec/dummy_app/app/assets/images/.keep +0 -0
- data/spec/dummy_app/app/assets/javascripts/admin_panel.js +5 -0
- data/spec/dummy_app/app/assets/javascripts/application.js +16 -0
- data/spec/dummy_app/app/assets/stylesheets/admin_panel.css +3 -0
- data/spec/dummy_app/app/assets/stylesheets/app.css.scss +4 -0
- data/spec/dummy_app/app/assets/stylesheets/application.css +16 -0
- data/spec/dummy_app/app/controllers/application_controller.rb +7 -0
- data/spec/dummy_app/app/controllers/comments_controller.rb +28 -0
- data/spec/dummy_app/app/controllers/concerns/.keep +0 -0
- data/spec/dummy_app/app/controllers/posts_controller.rb +13 -0
- data/spec/dummy_app/app/controllers/users_controller.rb +7 -0
- data/spec/dummy_app/app/helpers/application_helper.rb +2 -0
- data/spec/dummy_app/app/mailers/.keep +0 -0
- data/spec/dummy_app/app/models/.keep +0 -0
- data/spec/dummy_app/app/models/comment.rb +32 -0
- data/spec/dummy_app/app/models/concerns/.keep +0 -0
- data/spec/dummy_app/app/models/post.rb +17 -0
- data/spec/dummy_app/app/models/user.rb +21 -0
- data/spec/dummy_app/app/views/layouts/admin.html.haml +25 -0
- data/spec/dummy_app/app/views/layouts/application.html.haml +20 -0
- data/spec/dummy_app/app/views/posts/index.html.haml +22 -0
- data/spec/dummy_app/app/views/posts/show.html.haml +7 -0
- data/spec/dummy_app/bin/bundle +3 -0
- data/spec/dummy_app/bin/rails +4 -0
- data/spec/dummy_app/bin/rake +4 -0
- data/spec/dummy_app/config/application.rb +23 -0
- data/spec/dummy_app/config/boot.rb +4 -0
- data/spec/dummy_app/config/database.yml +11 -0
- data/spec/dummy_app/config/environment.rb +5 -0
- data/spec/dummy_app/config/environments/development.rb +29 -0
- data/spec/dummy_app/config/environments/production.rb +80 -0
- data/spec/dummy_app/config/environments/test.rb +36 -0
- data/spec/dummy_app/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy_app/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy_app/config/initializers/inflections.rb +16 -0
- data/spec/dummy_app/config/initializers/mime_types.rb +5 -0
- data/spec/dummy_app/config/initializers/secret_token.rb +12 -0
- data/spec/dummy_app/config/initializers/session_store.rb +3 -0
- data/spec/dummy_app/config/initializers/sorcery.rb +437 -0
- data/spec/dummy_app/config/initializers/the_comments.rb +14 -0
- data/spec/dummy_app/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy_app/config/locales/en.yml +23 -0
- data/spec/dummy_app/config/routes.rb +19 -0
- data/spec/dummy_app/config.ru +4 -0
- data/spec/dummy_app/db/migrate/20130712061503_sorcery_core.rb +16 -0
- data/spec/dummy_app/db/migrate/20130712065951_create_posts.rb +11 -0
- data/spec/dummy_app/db/migrate/20131027185332_change_user.the_comments_engine.rb +19 -0
- data/spec/dummy_app/db/migrate/20131027185333_create_comments.the_comments_engine.rb +51 -0
- data/spec/dummy_app/db/migrate/20131027185334_change_commentable.the_comments_engine.rb +14 -0
- data/spec/dummy_app/db/schema.rb +74 -0
- data/spec/dummy_app/db/seeds.rb +42 -0
- data/spec/dummy_app/lib/assets/.keep +0 -0
- data/spec/dummy_app/lib/tasks/.keep +0 -0
- data/spec/dummy_app/lib/tasks/app_bootstrap.rake +15 -0
- data/spec/dummy_app/log/.keep +0 -0
- data/spec/dummy_app/public/404.html +58 -0
- data/spec/dummy_app/public/422.html +58 -0
- data/spec/dummy_app/public/500.html +57 -0
- data/spec/dummy_app/public/favicon.ico +0 -0
- data/spec/dummy_app/public/robots.txt +5 -0
- data/spec/dummy_app/spec/factories/post.rb +6 -0
- data/spec/dummy_app/spec/factories/user.rb +6 -0
- data/spec/dummy_app/spec/models/user_counters_spec.rb +339 -0
- data/spec/dummy_app/spec/spec_helper.rb +29 -0
- data/spec/dummy_app/test/controllers/.keep +0 -0
- data/spec/dummy_app/test/fixtures/.keep +0 -0
- data/spec/dummy_app/test/helpers/.keep +0 -0
- data/spec/dummy_app/test/integration/.keep +0 -0
- data/spec/dummy_app/test/mailers/.keep +0 -0
- data/spec/dummy_app/test/models/.keep +0 -0
- data/spec/dummy_app/test/test_helper.rb +15 -0
- data/spec/dummy_app/vendor/assets/javascripts/.keep +0 -0
- data/spec/dummy_app/vendor/assets/stylesheets/.keep +0 -0
- data/the_comments.gemspec +25 -0
- data/the_comments.yml.teamocil.example +11 -0
- data/views_converter.rb +16 -0
- metadata +333 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
module TheComments
|
|
2
|
+
module Comment
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
scope :active, -> { with_state [:draft, :published] }
|
|
7
|
+
scope :with_users, -> { includes(:user) }
|
|
8
|
+
|
|
9
|
+
# Nested Set
|
|
10
|
+
acts_as_nested_set scope: [:commentable_type, :commentable_id]
|
|
11
|
+
|
|
12
|
+
# simple sort scopes
|
|
13
|
+
include ::TheSimpleSort::Base
|
|
14
|
+
|
|
15
|
+
# TheSortableTree
|
|
16
|
+
include ::TheSortableTree::Scopes
|
|
17
|
+
|
|
18
|
+
# Comments State Machine
|
|
19
|
+
include TheComments::CommentStates
|
|
20
|
+
|
|
21
|
+
validates :raw_content, presence: true
|
|
22
|
+
|
|
23
|
+
# relations
|
|
24
|
+
belongs_to :user
|
|
25
|
+
belongs_to :holder, class_name: :User
|
|
26
|
+
belongs_to :commentable, polymorphic: true
|
|
27
|
+
|
|
28
|
+
# callbacks
|
|
29
|
+
before_create :define_holder, :define_default_state, :define_anchor, :denormalize_commentable
|
|
30
|
+
after_create :update_cache_counters
|
|
31
|
+
before_save :prepare_content
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def header_title
|
|
35
|
+
title.present? ? title : I18n.t('the_comments.guest_name')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def user_name
|
|
39
|
+
user.try(:username) || user.try(:login) || header_title
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def avatar_url
|
|
43
|
+
src = id.to_s
|
|
44
|
+
src = title unless title.blank?
|
|
45
|
+
src = contacts if !contacts.blank? && /@/ =~ contacts
|
|
46
|
+
hash = Digest::MD5.hexdigest(src)
|
|
47
|
+
"https://2.gravatar.com/avatar/#{hash}?s=42&d=https://identicons.github.com/#{hash}.png"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def mark_as_spam
|
|
51
|
+
count = self_and_descendants.update_all({spam: true})
|
|
52
|
+
update_spam_counter
|
|
53
|
+
count
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def mark_as_not_spam
|
|
57
|
+
count = self_and_descendants.update_all({spam: false})
|
|
58
|
+
update_spam_counter
|
|
59
|
+
count
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def to_spam
|
|
63
|
+
mark_as_spam
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def update_spam_counter
|
|
69
|
+
holder.try :update_comcoms_spam_counter
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def define_anchor
|
|
73
|
+
self.anchor = SecureRandom.hex[0..5]
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def define_holder
|
|
77
|
+
c = self.commentable
|
|
78
|
+
self.holder = c.is_a?(User) ? c : c.try(:user)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def define_default_state
|
|
82
|
+
self.state = TheComments.config.default_owner_state if user && user == holder
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def denormalize_commentable
|
|
86
|
+
self.commentable_title = commentable.try :commentable_title
|
|
87
|
+
self.commentable_state = commentable.try :commentable_state
|
|
88
|
+
self.commentable_url = commentable.try :commentable_url
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def prepare_content
|
|
92
|
+
self.content = self.raw_content
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# Warn: increment! doesn't call validation =>
|
|
96
|
+
# before_validation filters doesn't work =>
|
|
97
|
+
# We have few unuseful requests
|
|
98
|
+
# I impressed that I found it and reduce DB requests
|
|
99
|
+
# Awesome logic pazzl! I'm really pedant :D
|
|
100
|
+
def update_cache_counters
|
|
101
|
+
user.try :recalculate_my_comments_counter!
|
|
102
|
+
|
|
103
|
+
if holder
|
|
104
|
+
holder.send :try, :define_denormalize_flags
|
|
105
|
+
holder.increment! "#{ state }_comcoms_count"
|
|
106
|
+
# holder.class.increment_counter("#{ state }_comcoms_count", holder.id)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
if commentable
|
|
110
|
+
commentable.send :define_denormalize_flags
|
|
111
|
+
commentable.increment! "#{ state }_comments_count"
|
|
112
|
+
# holder.class.increment_counter("#{ state }_comments_count", holder.id)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
module TheComments
|
|
2
|
+
module CommentStates
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
# :draft | :published | :deleted
|
|
7
|
+
state_machine :state, :initial => TheComments.config.default_state do
|
|
8
|
+
|
|
9
|
+
# events
|
|
10
|
+
event :to_draft do
|
|
11
|
+
transition all - :draft => :draft
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
event :to_published do
|
|
15
|
+
transition all - :published => :published
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
event :to_deleted do
|
|
19
|
+
transition any - :deleted => :deleted
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# transition callbacks
|
|
23
|
+
after_transition any => any do |comment|
|
|
24
|
+
@comment = comment
|
|
25
|
+
@owner = comment.user
|
|
26
|
+
@holder = comment.holder
|
|
27
|
+
@commentable = comment.commentable
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# between draft and published
|
|
31
|
+
after_transition [:draft, :published] => [:draft, :published] do |comment, transition|
|
|
32
|
+
from = transition.from_name
|
|
33
|
+
to = transition.to_name
|
|
34
|
+
|
|
35
|
+
if @holder
|
|
36
|
+
@holder.send :try, :define_denormalize_flags
|
|
37
|
+
@holder.increment! "#{to}_comcoms_count"
|
|
38
|
+
@holder.decrement! "#{from}_comcoms_count"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if @commentable
|
|
42
|
+
@commentable.send :define_denormalize_flags
|
|
43
|
+
@commentable.increment! "#{to}_comments_count"
|
|
44
|
+
@commentable.decrement! "#{from}_comments_count"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# to deleted (cascade like query)
|
|
49
|
+
after_transition [:draft, :published] => :deleted do |comment|
|
|
50
|
+
ids = comment.self_and_descendants.map(&:id)
|
|
51
|
+
::Comment.where(id: ids).update_all(state: :deleted)
|
|
52
|
+
|
|
53
|
+
@owner.try :recalculate_my_comments_counter!
|
|
54
|
+
@holder.try :recalculate_comcoms_counters!
|
|
55
|
+
@commentable.try :recalculate_comments_counters!
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# from deleted
|
|
59
|
+
after_transition :deleted => [:draft, :published] do |comment, transition|
|
|
60
|
+
to = transition.to_name
|
|
61
|
+
comment.mark_as_not_spam
|
|
62
|
+
|
|
63
|
+
@owner.try :recalculate_my_comments_counter!
|
|
64
|
+
|
|
65
|
+
if @holder
|
|
66
|
+
@holder.send :try, :define_denormalize_flags
|
|
67
|
+
@holder.decrement! :deleted_comcoms_count
|
|
68
|
+
@holder.increment! "#{to}_comcoms_count"
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if @commentable
|
|
72
|
+
@commentable.send :define_denormalize_flags
|
|
73
|
+
@commentable.decrement! :deleted_comments_count
|
|
74
|
+
@commentable.increment! "#{to}_comments_count"
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
module TheComments
|
|
2
|
+
module Commentable
|
|
3
|
+
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
has_many :comments, as: :commentable
|
|
8
|
+
|
|
9
|
+
# *define_denormalize_flags* - should be placed before title or url builder filters
|
|
10
|
+
before_validation :define_denormalize_flags
|
|
11
|
+
after_save :denormalize_for_comments, if: -> { !id_changed? }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Default Denormalization methods
|
|
15
|
+
# Overwrite it with your Application
|
|
16
|
+
def commentable_title
|
|
17
|
+
# My first blog post
|
|
18
|
+
try(:title) || TheComments.config.default_title
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def commentable_url
|
|
22
|
+
# /posts/1
|
|
23
|
+
['', self.class.to_s.tableize, self.to_param].join('/')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def commentable_state
|
|
27
|
+
# 'draft'
|
|
28
|
+
try(:state)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Helper methods
|
|
32
|
+
def comments_sum
|
|
33
|
+
published_comments_count + draft_comments_count
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def recalculate_comments_counters!
|
|
37
|
+
update_attributes!({
|
|
38
|
+
draft_comments_count: comments.with_state(:draft).count,
|
|
39
|
+
published_comments_count: comments.with_state(:published).count,
|
|
40
|
+
deleted_comments_count: comments.with_state(:deleted).count
|
|
41
|
+
})
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def define_denormalize_flags
|
|
47
|
+
@trackable_commentable_title = commentable_title
|
|
48
|
+
@trackable_commentable_state = commentable_state
|
|
49
|
+
@trackable_commentable_url = commentable_url
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def denormalization_fields_changed?
|
|
53
|
+
a = @trackable_commentable_title != commentable_title
|
|
54
|
+
b = @trackable_commentable_state != commentable_state
|
|
55
|
+
c = @trackable_commentable_url != commentable_url
|
|
56
|
+
a || b || c
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def denormalize_for_comments
|
|
60
|
+
if denormalization_fields_changed?
|
|
61
|
+
comments.update_all({
|
|
62
|
+
commentable_title: commentable_title,
|
|
63
|
+
commentable_state: commentable_state,
|
|
64
|
+
commentable_url: commentable_url
|
|
65
|
+
})
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
module TheComments
|
|
2
|
+
module User
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
has_many :comcoms, class_name: :Comment, foreign_key: :holder_id
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def my_comments; ::Comment.where(user: self); end
|
|
10
|
+
|
|
11
|
+
%w[draft published deleted].each do |state|
|
|
12
|
+
define_method "my_#{state}_comments" do
|
|
13
|
+
my_comments.with_state state
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
define_method "#{state}_comcoms" do
|
|
17
|
+
comcoms.with_state state
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def my_spam_comments
|
|
22
|
+
my_comments.where(spam: true)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# I think we shouldn't to have my_deleted_comments cache counter
|
|
26
|
+
def recalculate_my_comments_counter!
|
|
27
|
+
dcount = my_draft_comments.count
|
|
28
|
+
pcount = my_published_comments.count
|
|
29
|
+
update_attributes!({
|
|
30
|
+
my_draft_comments_count: dcount,
|
|
31
|
+
my_published_comments_count: pcount,
|
|
32
|
+
my_comments_count: dcount + pcount
|
|
33
|
+
})
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def recalculate_comcoms_counters!
|
|
37
|
+
update_attributes!({
|
|
38
|
+
draft_comcoms_count: draft_comcoms.count,
|
|
39
|
+
published_comcoms_count: published_comcoms.count,
|
|
40
|
+
deleted_comcoms_count: deleted_comcoms.count
|
|
41
|
+
})
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def update_comcoms_spam_counter
|
|
45
|
+
update!(spam_comcoms_count: comcoms.where(spam: true).count)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def comments_sum
|
|
49
|
+
published_comments_count + draft_comments_count
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def comcoms_sum
|
|
53
|
+
published_comcoms_count + draft_comcoms_count
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.additional_info{ style: "display:none" }
|
|
2
|
+
%br
|
|
3
|
+
%table.table.table-striped.table-hover
|
|
4
|
+
%tr
|
|
5
|
+
%th Tolerance time:
|
|
6
|
+
%th IP:
|
|
7
|
+
%th User Agent:
|
|
8
|
+
%th Referer:
|
|
9
|
+
%tr
|
|
10
|
+
%td= comment.tolerance_time || :none
|
|
11
|
+
%td= comment.ip
|
|
12
|
+
%td= comment.user_agent
|
|
13
|
+
%td= comment.referer
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
= build_server_tree(tree, render_module: RenderCommentsTreeHelper, controller: controller)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
%table.comment_body.table.table-striped.table-hover
|
|
2
|
+
%tr
|
|
3
|
+
%td{ style: "width: 120px;"}
|
|
4
|
+
%b= comment.commentable_type
|
|
5
|
+
→
|
|
6
|
+
%td
|
|
7
|
+
= link_to comment.commentable_title, comment.commentable_url
|
|
8
|
+
(#{comment.try(:commentable_state)})
|
|
9
|
+
%tr
|
|
10
|
+
%td
|
|
11
|
+
%b= t('the_comments.title')
|
|
12
|
+
%td
|
|
13
|
+
- if comment.try(:user)
|
|
14
|
+
= link_to comment.user_name, comment.user
|
|
15
|
+
- else
|
|
16
|
+
= comment.header_title
|
|
17
|
+
%tr
|
|
18
|
+
%td
|
|
19
|
+
%b= t('the_comments.contacts')
|
|
20
|
+
%td= comment.contacts
|
|
21
|
+
%tr.success
|
|
22
|
+
%td
|
|
23
|
+
%b= t('the_comments.content')
|
|
24
|
+
%td{ style: 'word-break: break-all;' }= raw comment.content
|
|
25
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
.edit_form{ style: "display:none" }
|
|
2
|
+
= form_for comment, remote: true, html:{ role: :form } do |f|
|
|
3
|
+
%table.table.table-striped.table-hover
|
|
4
|
+
%tr{ style: "width: 100px;"}
|
|
5
|
+
%td
|
|
6
|
+
%b= comment.commentable_type
|
|
7
|
+
→
|
|
8
|
+
%td
|
|
9
|
+
= link_to comment.commentable_title, comment.commentable_url
|
|
10
|
+
(#{comment.try(:commentable_state)})
|
|
11
|
+
%tr
|
|
12
|
+
%td
|
|
13
|
+
%b= t('the_comments.title')
|
|
14
|
+
%td= f.text_field :title, class: "form-control"
|
|
15
|
+
%tr
|
|
16
|
+
%td
|
|
17
|
+
%b= t('the_comments.contacts')
|
|
18
|
+
%td= f.text_field :contacts, class: "form-control"
|
|
19
|
+
%tr
|
|
20
|
+
%td
|
|
21
|
+
%b= t('the_comments.content')
|
|
22
|
+
%td= f.text_area :raw_content, class: "form-control", rows: 7
|
|
23
|
+
%tr
|
|
24
|
+
%td
|
|
25
|
+
%td= f.submit t('the_comments.update'), class: "btn btn-success"
|
|
26
|
+
%hr
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
%h3
|
|
2
|
+
= link_to t('the_comments.new'), '#', id: :new_root_comment
|
|
3
|
+
|
|
4
|
+
= form_for Comment.new, remote: true, authenticity_token: true do |f|
|
|
5
|
+
- if current_user
|
|
6
|
+
= render partial: 'the_comments/haml/logined_form', locals: { f: f, commentable: commentable }
|
|
7
|
+
- else
|
|
8
|
+
= render partial: 'the_comments/haml/guest_form', locals: { f: f, commentable: commentable }
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
%label= t('the_comments.form.title')
|
|
2
|
+
%p= f.text_field :title, class: 'form-control'
|
|
3
|
+
|
|
4
|
+
%label= t('the_comments.form.contacts')
|
|
5
|
+
%p= f.text_field :contacts, class: 'form-control'
|
|
6
|
+
|
|
7
|
+
%label= t('the_comments.form.content')
|
|
8
|
+
%p= f.text_area :raw_content, class: 'form-control'
|
|
9
|
+
|
|
10
|
+
%p.trap
|
|
11
|
+
- TheComments.config.empty_inputs.each do |name|
|
|
12
|
+
= text_field_tag name, nil, autocomplete: :off, tabindex: -1, id: nil
|
|
13
|
+
|
|
14
|
+
= hidden_field_tag :tolerance_time, 0, id: nil, class: :tolerance_time
|
|
15
|
+
|
|
16
|
+
= f.hidden_field :commentable_type, value: commentable.class
|
|
17
|
+
= f.hidden_field :commentable_id, value: commentable.id
|
|
18
|
+
= f.hidden_field :parent_id, class: :parent_id
|
|
19
|
+
|
|
20
|
+
%p
|
|
21
|
+
= f.submit t('the_comments.form.create'), class: :btn
|
|
22
|
+
= t('the_comments.form.thank_you')
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.logined_comment_form
|
|
2
|
+
.user_data
|
|
3
|
+
= link_to user_path(current_user), nopin: :nopin do
|
|
4
|
+
= image_tag current_user.try(:avatar).try(:url, :thumb)
|
|
5
|
+
.comment_data
|
|
6
|
+
= hidden_field_tag :tolerance_time, 0, id: nil, class: :tolerance_time
|
|
7
|
+
= f.hidden_field :commentable_type, value: commentable.class
|
|
8
|
+
= f.hidden_field :commentable_id, value: commentable.id
|
|
9
|
+
= f.hidden_field :parent_id, class: :parent_id
|
|
10
|
+
|
|
11
|
+
.user_name
|
|
12
|
+
%b= current_user.username.present? ? current_user.username : current_user.login
|
|
13
|
+
%label= t('the_comments.form.content')
|
|
14
|
+
%p= f.text_area :raw_content
|
|
15
|
+
|
|
16
|
+
%p
|
|
17
|
+
= f.submit t('the_comments.form.create'), class: :btn
|
|
18
|
+
= t('the_comments.form.thank_you')
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
- hidden = "display:none"
|
|
2
|
+
|
|
3
|
+
.row.controls
|
|
4
|
+
.col-md-9.action_btns
|
|
5
|
+
= link_to '#', class: "edit btn btn-success" do
|
|
6
|
+
= t('the_comments.edit')
|
|
7
|
+
|
|
8
|
+
= link_to '#', class: "btn btn-warning edit", style: "display:none" do
|
|
9
|
+
= t('the_comments.cancel')
|
|
10
|
+
|
|
11
|
+
- unless to_hide = comment.published? ? hidden : nil
|
|
12
|
+
- opts = { remote: true, style: to_hide, method: :post }
|
|
13
|
+
= link_to [:to_published, comment], opts.merge(class: "btn btn-primary to_published") do
|
|
14
|
+
= t('the_comments.to_published')
|
|
15
|
+
|
|
16
|
+
- unless to_hide = comment.draft? ? hidden : nil
|
|
17
|
+
- opts = { remote: true, style: to_hide, method: :post }
|
|
18
|
+
= link_to [:to_draft, comment], opts.merge(class: "btn btn-warning to_draft") do
|
|
19
|
+
= t('the_comments.to_draft')
|
|
20
|
+
|
|
21
|
+
- unless to_hide = comment.deleted? ? hidden : nil
|
|
22
|
+
- opts = { remote: true, style: to_hide, method: :delete, data: { confirm: t('the_comments.delete_confirm') } }
|
|
23
|
+
= link_to [:to_deleted, comment], opts.merge(class: "btn btn-danger to_deleted") do
|
|
24
|
+
= t('the_comments.to_deleted')
|
|
25
|
+
|
|
26
|
+
- opts = { remote: true, method: :post}
|
|
27
|
+
= link_to [:to_spam, comment], opts.merge(class: "btn btn-danger to_spam") do
|
|
28
|
+
= t('the_comments.to_spam')
|
|
29
|
+
.col-md-3.text-right
|
|
30
|
+
= link_to t('the_comments.additional_info'), "#", class: "additional_info btn btn-info"
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
.panel.panel-default
|
|
2
|
+
.panel-heading= t "the_comments.nav.header"
|
|
3
|
+
.panel-body
|
|
4
|
+
= render partial: 'the_comments/haml/sidebar_backlink'
|
|
5
|
+
|
|
6
|
+
- if current_user.comments_admin?
|
|
7
|
+
= render partial: 'the_comments/haml/sidebar_admin'
|
|
8
|
+
- else
|
|
9
|
+
= render partial: 'the_comments/haml/sidebar_user'
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
- cuser = current_user
|
|
2
|
+
|
|
3
|
+
= render partial: 'the_comments/haml/sidebar_user'
|
|
4
|
+
|
|
5
|
+
- if cuser.comments_admin?
|
|
6
|
+
%br
|
|
7
|
+
%h5= t 'the_comments.in_system', num: Comment.count
|
|
8
|
+
%p= link_to t("the_comments.published_comments", num: Comment.with_state(:published).count), [:total_published, :comments], class: 'btn btn-success btn-sm'
|
|
9
|
+
%p= link_to t("the_comments.draft_comments", num: Comment.with_state(:draft).count), [:total_draft, :comments], class: 'btn btn-info btn-sm'
|
|
10
|
+
%p
|
|
11
|
+
= link_to t("the_comments.deleted_comments", num: Comment.with_state(:deleted).count), [:total_deleted, :comments], class: 'btn btn-default btn-sm'
|
|
12
|
+
= link_to t("the_comments.spam_comments", num: Comment.where(spam: true).count), [:total_spam, :comments], class: 'btn btn-default btn-sm'
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
- cuser = current_user
|
|
2
|
+
|
|
3
|
+
%h5=t 'the_comments.written_by_me', num: cuser.my_comments.count
|
|
4
|
+
|
|
5
|
+
%p= link_to t("the_comments.published_comments", num: cuser.my_published_comments.count), [:my_published, :comments], class: 'btn btn-success btn-sm'
|
|
6
|
+
%p= link_to t("the_comments.draft_comments", num: cuser.my_draft_comments.count), [:my_draft, :comments], class: 'btn btn-info btn-sm'
|
|
7
|
+
|
|
8
|
+
%p
|
|
9
|
+
- if cuser.comments_admin?
|
|
10
|
+
= link_to t("the_comments.deleted_comments", num: cuser.my_deleted_comments.count), [:my_deleted, :comments], class: 'btn btn-default btn-sm'
|
|
11
|
+
= link_to t("the_comments.spam_comments", num: cuser.my_spam_comments.count), [:my_spam, :comments], class: 'btn btn-default btn-sm'
|
|
12
|
+
- else
|
|
13
|
+
%span.btn.btn-default.btn-sm= t("the_comments.deleted_comments", num: cuser.my_deleted_comments.count)
|
|
14
|
+
%span.btn.btn-default.btn-sm= t("the_comments.spam_comments", num: cuser.my_spam_comments.count)
|
|
15
|
+
|
|
16
|
+
%br
|
|
17
|
+
%h5= t 'the_comments.for_my_posts', num: cuser.comcoms.count
|
|
18
|
+
|
|
19
|
+
%p= link_to t("the_comments.published_comments", num: cuser.published_comcoms_count), [:published, :comments], class: 'btn btn-success btn-sm'
|
|
20
|
+
%p= link_to t("the_comments.draft_comments", num: cuser.draft_comcoms_count), [:draft, :comments], class: 'btn btn-info btn-sm'
|
|
21
|
+
%p
|
|
22
|
+
- if cuser.comments_admin?
|
|
23
|
+
= link_to t("the_comments.deleted_comments", num: cuser.deleted_comcoms_count), [:deleted, :comments], class: 'btn btn-default btn-sm'
|
|
24
|
+
= link_to t("the_comments.spam_comments", num: cuser.spam_comcoms_count), [:spam, :comments], class: 'btn btn-default btn-sm'
|
|
25
|
+
- else
|
|
26
|
+
%span.btn.btn-default.btn-sm= t("the_comments.deleted_comments", num: cuser.deleted_comcoms_count)
|
|
27
|
+
%span.btn.btn-default.btn-sm= t("the_comments.spam_comments", num: cuser.spam_comcoms_count)
|
|
28
|
+
|
|
29
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
- if commentable.try(:comments_on?) || true
|
|
2
|
+
%h4.comments_sum
|
|
3
|
+
- if commentable.comments_sum.zero?
|
|
4
|
+
Вы можете стать первым, кто оставит комментарий!
|
|
5
|
+
- else
|
|
6
|
+
Комментариев: #{ commentable.comments_sum }
|
|
7
|
+
|
|
8
|
+
- unless current_user
|
|
9
|
+
.comments_description
|
|
10
|
+
%p — Комментарий можно оставить <b>без регистрации</b>, для этого достаточно заполнить одно обязательное поле <b class='nobr'>Текст комментария</b>. Анонимные комментарии проходят модерацию и до момента одобрения видны только в браузере автора
|
|
11
|
+
%p — Комментарии зарегистрированных пользователей публикуются сразу после создания
|
|
12
|
+
|
|
13
|
+
.comments#comments
|
|
14
|
+
%ol.comments_tree{ data: { comments: { tolarance_time: TheComments.config.tolerance_time } } }
|
|
15
|
+
= render partial: 'the_comments/haml/comment', locals: { tree: comments_tree }
|
|
16
|
+
= render partial: 'the_comments/haml/form', locals: { commentable: commentable }
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
- content_for :title do
|
|
2
|
+
= t "the_comments.management"
|
|
3
|
+
|
|
4
|
+
- content_for :comments_sidebar do
|
|
5
|
+
= render partial: 'the_comments/haml/sidebar'
|
|
6
|
+
|
|
7
|
+
- content_for :comments_main do
|
|
8
|
+
= paginate @comments
|
|
9
|
+
|
|
10
|
+
- if @comments.blank?
|
|
11
|
+
.alert.alert-info= t 'the_comments.no_comments_here'
|
|
12
|
+
|
|
13
|
+
.comments
|
|
14
|
+
- @comments.each do |comment|
|
|
15
|
+
- klass = { published: :success, draft: :info, deleted: :danger }[comment.state.to_sym]
|
|
16
|
+
.panel{ class: "panel-#{klass}" }
|
|
17
|
+
.panel-heading= comment.header_title
|
|
18
|
+
.panel-body
|
|
19
|
+
= render partial: 'the_comments/haml/comment_body', locals: { comment: comment }
|
|
20
|
+
|
|
21
|
+
- if current_user.comments_admin?
|
|
22
|
+
= render partial: 'the_comments/haml/comment_edit', locals: { comment: comment }
|
|
23
|
+
= render partial: 'the_comments/haml/manage_controls', locals: { comment: comment }
|
|
24
|
+
= render partial: 'the_comments/haml/additional_info', locals: { comment: comment }
|
|
25
|
+
|
|
26
|
+
= paginate @comments
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.additional_info style: "display:none"
|
|
2
|
+
br
|
|
3
|
+
table.table.table-striped.table-hover
|
|
4
|
+
tr
|
|
5
|
+
th Tolerance time:
|
|
6
|
+
th IP:
|
|
7
|
+
th User Agent:
|
|
8
|
+
th Referer:
|
|
9
|
+
tr
|
|
10
|
+
td= comment.tolerance_time || :none
|
|
11
|
+
td= comment.ip
|
|
12
|
+
td= comment.user_agent
|
|
13
|
+
td= comment.referer
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
= build_server_tree(tree, render_module: RenderCommentsTreeHelper, controller: controller)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
table.comment_body.table.table-striped.table-hover
|
|
2
|
+
tr
|
|
3
|
+
td style: "width: 120px;"
|
|
4
|
+
b= comment.commentable_type
|
|
5
|
+
| →
|
|
6
|
+
td
|
|
7
|
+
= link_to comment.commentable_title, comment.commentable_url
|
|
8
|
+
| (#{comment.try(:commentable_state)})
|
|
9
|
+
tr
|
|
10
|
+
td
|
|
11
|
+
b= t('the_comments.title')
|
|
12
|
+
td
|
|
13
|
+
- if comment.try(:user)
|
|
14
|
+
= link_to comment.user_name, comment.user
|
|
15
|
+
- else
|
|
16
|
+
= comment.header_title
|
|
17
|
+
tr
|
|
18
|
+
td
|
|
19
|
+
b= t('the_comments.contacts')
|
|
20
|
+
td= comment.contacts
|
|
21
|
+
tr.success
|
|
22
|
+
td
|
|
23
|
+
b= t('the_comments.content')
|
|
24
|
+
td= comment.content
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
.edit_form style: "display:none"
|
|
2
|
+
= form_for comment, remote: true, html:{ role: :form } do |f|
|
|
3
|
+
table.table.table-striped.table-hover
|
|
4
|
+
tr style: "width: 100px;"
|
|
5
|
+
td
|
|
6
|
+
b= comment.commentable_type
|
|
7
|
+
| →
|
|
8
|
+
td
|
|
9
|
+
= link_to comment.commentable_title, comment.commentable_url
|
|
10
|
+
| (#{comment.try(:commentable_state)})
|
|
11
|
+
tr
|
|
12
|
+
td
|
|
13
|
+
b= t('the_comments.title')
|
|
14
|
+
td= f.text_field :title, class: "form-control"
|
|
15
|
+
tr
|
|
16
|
+
td
|
|
17
|
+
b= t('the_comments.contacts')
|
|
18
|
+
td= f.text_field :contacts, class: "form-control"
|
|
19
|
+
tr
|
|
20
|
+
td
|
|
21
|
+
b= t('the_comments.content')
|
|
22
|
+
td= f.text_area :raw_content, class: "form-control", rows: 7
|
|
23
|
+
tr
|
|
24
|
+
td
|
|
25
|
+
td= f.submit t('the_comments.update'), class: "btn btn-success"
|
|
26
|
+
hr
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
h3
|
|
2
|
+
= link_to t('the_comments.new'), '#', id: :new_root_comment
|
|
3
|
+
|
|
4
|
+
= form_for Comment.new, remote: true, authenticity_token: true do |f|
|
|
5
|
+
- if current_user
|
|
6
|
+
= render partial: 'the_comments/slim/logined_form', locals: { f: f, commentable: commentable }
|
|
7
|
+
- else
|
|
8
|
+
= render partial: 'the_comments/slim/guest_form', locals: { f: f, commentable: commentable }
|