sunrise-comments 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,21 @@
1
+ = Sunrise Comments
2
+
3
+ == Install
4
+
5
+ rails generate sunrise:comments:install
6
+
7
+ In generated migration add "comments_count" column for counter cache:
8
+
9
+ add_column :posts, :comments_count, :integer, :default => 0
10
+
11
+ rake db:migrate
12
+
13
+ == Usage
14
+
15
+ class Post < ActiveRecord::Base
16
+ include Sunrise::Comments::Base
17
+ end
18
+
19
+ class User < ActiveRecord::Base
20
+ include Sunrise::Comments::Author
21
+ end
data/Rakefile ADDED
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+ require 'rake/rdoctask'
5
+ require File.join(File.dirname(__FILE__), 'lib', 'sunrise', 'comments', 'version')
6
+
7
+ desc 'Default: run unit tests.'
8
+ task :default => :test
9
+
10
+ desc 'Test the sunrise plugin.'
11
+ Rake::TestTask.new(:test) do |t|
12
+ t.libs << 'lib'
13
+ t.libs << 'test'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = true
16
+ end
17
+
18
+ desc 'Generate documentation for the sunrise plugin.'
19
+ Rake::RDocTask.new(:rdoc) do |rdoc|
20
+ rdoc.rdoc_dir = 'rdoc'
21
+ rdoc.title = 'Sunrise Comments'
22
+ rdoc.options << '--line-numbers' << '--inline-source'
23
+ rdoc.rdoc_files.include('README')
24
+ rdoc.rdoc_files.include('lib/**/*.rb')
25
+ end
26
+
27
+ begin
28
+ require 'jeweler'
29
+ Jeweler::Tasks.new do |s|
30
+ s.name = "sunrise-comments"
31
+ s.version = Sunrise::Comments::VERSION.dup
32
+ s.summary = "Rails CMS"
33
+ s.description = "Sunrise is a Aimbulance CMS"
34
+ s.email = "galeta.igor@gmail.com"
35
+ s.homepage = "https://github.com/galetahub/sunrise-comments"
36
+ s.authors = ["Igor Galeta", "Pavlo Galeta"]
37
+ s.files = FileList["[A-Z]*", "{app,config,lib}/**/*"]
38
+ s.extra_rdoc_files = FileList["[A-Z]*"] - %w(Gemfile Rakefile)
39
+
40
+ s.add_dependency('sunrise', "~> #{s.version}")
41
+ end
42
+
43
+ Jeweler::GemcutterTasks.new
44
+ rescue LoadError
45
+ puts "Jeweler not available. Install it with: gem install jeweler"
46
+ end
@@ -0,0 +1,62 @@
1
+ class CommentsController < ApplicationController
2
+ before_filter :find_author
3
+ before_filter :find_comment, :only => [:edit, :update, :destroy]
4
+
5
+ authorize_resource
6
+
7
+ respond_to :js, :only => [:create, :edit, :update, :destroy]
8
+
9
+ cache_sweeper :comment_sweeper, :only => [:create, :update, :destroy]
10
+
11
+ def new
12
+ @comment = Comment.new
13
+ @comment.author = @author
14
+ respond_with(@comment)
15
+ end
16
+
17
+ def create
18
+ @comment = Comment.new(params[:comment])
19
+ @comment.author = @author
20
+ @comment.save
21
+
22
+ respond_with(@comment, respond_options)
23
+ end
24
+
25
+ def edit
26
+ respond_with(@comment)
27
+ end
28
+
29
+ def update
30
+ @comment.update_attributes(params[:comment])
31
+ respond_with(@comment, respond_options)
32
+ end
33
+
34
+ def destroy
35
+ @comment.destroy
36
+ respond_with(@comment, respond_options)
37
+ end
38
+
39
+ protected
40
+
41
+ def find_author
42
+ @author = current_user
43
+ end
44
+
45
+ def find_comment
46
+ @comment = Comment.find(params[:id])
47
+ end
48
+
49
+ def respond_options(options = {})
50
+ options = { :location => root_path }.merge(options)
51
+
52
+ if @comment.commentable
53
+ options[:location] = polymorphic_path(@comment.commentable)
54
+ end
55
+
56
+ options
57
+ end
58
+
59
+ def current_ability
60
+ @current_ability ||= ::Ability.new(@author)
61
+ end
62
+ end
@@ -0,0 +1,22 @@
1
+ class CommentSweeper < ActionController::Caching::Sweeper
2
+ observe Comment
3
+
4
+ def after_create(item)
5
+ expire(item)
6
+ end
7
+
8
+ def after_update(item)
9
+ expire(item)
10
+ end
11
+
12
+ def after_destroy(item)
13
+ expire(item)
14
+ end
15
+
16
+ private
17
+
18
+ def expire(item=nil)
19
+ expire_fragment(%r{/comments})
20
+ StructureSweeper.sweep!
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ <%= content_tag(:div, :id => dom_id(model, :block), :class => "comment-block") do %>
2
+ <h3><img src="/images/coment_title.png" alt="коментарi" /></h3>
3
+ <div class="comment-container">
4
+ <%= render :partial => 'comments/form', :locals => { :comment => model.comments.new, :model => model } %>
5
+
6
+ <%= content_tag(:div, :id => dom_id(model, :comments)) do %>
7
+ <%= render :partial => 'comments/comment', :collection => model.comments %>
8
+ <% end %>
9
+ </div>
10
+ <% end %>
@@ -0,0 +1,18 @@
1
+ <%= content_tag(:div, :id => dom_id(comment), :class => "block") do %>
2
+ <%= record_asset_tag(comment.author, :avatar, "avatar_default.jpg", :type => :preview, :class => "autor-pic") %>
3
+ <span class="cover"></span>
4
+
5
+ <div class="coment-area">
6
+ <div class="comment-cont">
7
+ <strong class="autor"><%= comment.author.name %></strong>
8
+ <div class="txt">
9
+ <%=raw comment.content_html %>
10
+ </div>
11
+
12
+ <% if can? :delete, comment %>
13
+ <%= link_to 'видалити', comment_path(comment), :remote => true,
14
+ :method => :delete, :class => 'destroy', :confirm => t('sunrise.comments.destroy_confirm') %>
15
+ <% end %>
16
+ </div>
17
+ </div>
18
+ <% end %>
@@ -0,0 +1,33 @@
1
+ <%= content_tag(:div, :id => dom_id(model, :form), :class => "block") do %>
2
+ <% if user_signed_in? %>
3
+ <%= record_asset_tag(current_user, :avatar, "avatar_default.jpg", :type => :preview, :class => "autor-pic") %>
4
+
5
+ <span class="cover"></span>
6
+ <div class="coment-area">
7
+ <div class="comment-cont">
8
+ <strong class="autor"><%= current_user.name %></strong>
9
+
10
+ <div class="txtarea">
11
+ <noscript><p><%= t('sunrise.comments.noscript') %></p></noscript>
12
+ <%= form_for comment, :as => :comment, :remote => true do |f| %>
13
+ <%= f.hidden_field :commentable_type %>
14
+ <%= f.hidden_field :commentable_id %>
15
+
16
+ <%= f.text_area :content, :title => t('sunrise.comments.tooltip'),
17
+ :"data-disable-with" => t('sunrise.comments.loading') %>
18
+
19
+ <div class="ok">
20
+ <%= f.submit t('sunrise.comments.create'), :type => "image", :src => "/images/but_public.png",
21
+ :"data-disable-with" => t('sunrise.comments.loading'), :class => "but" %>
22
+ </div>
23
+ <% end %>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ <% else %>
28
+ <div class="comments-notice">
29
+ <%= t('sunrise.comments.notice') %>, <%= link_to 'войдите', new_user_session_path(:ref => request.path) %>
30
+ или <%= link_to 'зарегистрируйтесь', new_user_path(:ref => request.path) %>.
31
+ </div>
32
+ <% end %>
33
+ <% end %>
@@ -0,0 +1,8 @@
1
+ <% model = @comment.commentable %>
2
+ <% if @comment.errors.empty? %>
3
+ //$('#<%= dom_id(model, :block) %>').replaceWith("<%= escape_javascript(render(:partial => "block", :locals => { :model => model })) %>");
4
+ $('#<%= dom_id(model, :comments) %>').prepend("<%= escape_javascript(render(:partial => 'comment', :object => @comment)) %>");
5
+ $('#<%= dom_id(model, :form) %>').replaceWith("<%= escape_javascript(render(:partial=>"form", :locals=>{ :comment => model.comments.new, :model => model })) %>");
6
+ <% else %>
7
+ $('#<%= dom_id(model, :form) %>').replaceWith("<%= escape_javascript(render(:partial=>"form", :locals=>{ :comment => @comment, :model => model })) %>");
8
+ <% end %>
@@ -0,0 +1,2 @@
1
+ $('#<%= dom_id(@comment)%>').slideUp('slow');
2
+ //$('#comments_count').html(<%= @comment.comments_count %>);
@@ -0,0 +1,15 @@
1
+ ru:
2
+ sunrise:
3
+ comments:
4
+ title: "Комментарии"
5
+ noscript: "Вам необходимо включить поддержку Javascript, чтобы добавить комментарий"
6
+ tooltip: "Оставьте свой ​​комментарий ..."
7
+ create: "Отправить"
8
+ loading: "Загрузка ..."
9
+ notice: "Комментарии могут оставлять только зарегистрированные пользователи"
10
+ destroy_confirm: "Удалить комментарий?"
11
+ expand:
12
+ one: "Показать %{count} ответ"
13
+ few: "Показать %{count} ответa"
14
+ many: "Показать %{count} ответов"
15
+ other: "Показать %{count} ответов"
@@ -0,0 +1,15 @@
1
+ uk:
2
+ sunrise:
3
+ comments:
4
+ title: "Коментарі"
5
+ noscript: "Вам необхідно включити підтримку Javascript, щоб додати коментар"
6
+ tooltip: "Залиште свiй коментар ..."
7
+ create: "Опублікувати"
8
+ loading: "Завантаження ..."
9
+ notice: "Коментарі можуть залишати тільки зареєстровані користувачі"
10
+ destroy_confirm: "Видалити коментар?"
11
+ expand:
12
+ one: "Показати %{count} відповідь"
13
+ few: "Показати %{count} відповіді"
14
+ many: "Показати %{count} відповідей"
15
+ other: "Показати %{count} відповідей"
data/config/routes.rb ADDED
@@ -0,0 +1,7 @@
1
+ Rails.application.routes.draw do
2
+ resources :comments, :only => [:new, :create, :edit, :update, :destroy]
3
+
4
+ namespace :manage do
5
+ resources :comments
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ Usage:
2
+ rails generate sunrise:comments:install [options]
3
+
4
+ Options:
5
+ [--migrations] # Indicates when to generate migrations
6
+ # Default: true
7
+
8
+ Example:
9
+ rails g sunrise:comments:install
10
+
11
+ rails g sunrise:comments:install --skip-migrations
@@ -0,0 +1,34 @@
1
+ require 'rails/generators'
2
+ require 'rails/generators/migration'
3
+
4
+ module Sunrise
5
+ module Comments
6
+ class InstallGenerator < Rails::Generators::Base
7
+ include Rails::Generators::Migration
8
+
9
+ source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
10
+ class_option :migrations, :type => :boolean, :default => true, :description => "Generate migrations files"
11
+
12
+ desc "Generates comment migration and model"
13
+
14
+ def self.current_time
15
+ @current_time ||= Time.now
16
+ @current_time += 1.minute
17
+ end
18
+
19
+ def self.next_migration_number(dirname)
20
+ current_time.strftime("%Y%m%d%H%M%S")
21
+ end
22
+
23
+ def create_model
24
+ copy_file('comment.rb', 'app/models/comment.rb')
25
+ end
26
+
27
+ def create_migration
28
+ if options.migrations
29
+ migration_template "create_comments.rb", File.join('db/migrate', "sunrise_create_comments.rb")
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,29 @@
1
+ class Comment < ActiveRecord::Base
2
+ include Sunrise::Models::Comment
3
+
4
+ attr_accessible :user_name, :user_email, :content, :is_follow
5
+
6
+ # Validations
7
+ validates :content, :presence => true, :length => { :maximum => 500 }
8
+ validates :commentable_type, :presence => true, :inclusion => { :in => %w( Post ) }
9
+ validates :author_type, :inclusion => { :in => %w( User ) }, :allow_blank => true
10
+
11
+ with_options :if => :anonymous? do |anonymous|
12
+ anonymous.validates :user_name, :length => { :maximum => 100 }, :presence => true,
13
+ :format => { :with => /\A[^[:cntrl:]\\<>\/&]*\z/ }
14
+ anonymous.validates :user_email, :length => { :within => 6..100 }, :presence => true,
15
+ :format => { :with => /^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i }
16
+ end
17
+
18
+ # Format comment content
19
+ auto_html_for :content do
20
+ html_escape
21
+ big_words :length => 80, :tag => "span"
22
+ image
23
+ youtube :width => 500, :height => 300
24
+ vimeo :width => 500, :height => 300
25
+ link :target => "_blank", :rel => "nofollow"
26
+ simple_format
27
+ sanitize
28
+ end
29
+ end
@@ -0,0 +1,25 @@
1
+ class SunriseCreateComments < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :comments do |t|
4
+ t.string :user_name, :limit => 50
5
+ t.string :user_email, :limit => 50
6
+ t.text :content, :null => false
7
+ t.text :content_html
8
+ t.integer :commentable_id, :default => 0, :null => false
9
+ t.string :commentable_type, :limit => 15, :default => "", :null => false
10
+ t.boolean :is_follow, :default => false
11
+
12
+ t.integer :author_id
13
+ t.string :author_type, :limit => 25
14
+
15
+ t.timestamps
16
+ end
17
+
18
+ add_index :comments, [:author_type, :author_id]
19
+ add_index :comments, [:commentable_type, :commentable_id]
20
+ end
21
+
22
+ def self.down
23
+ drop_table :comments
24
+ end
25
+ end
@@ -0,0 +1,2 @@
1
+ # encoding: utf-8
2
+ require 'sunrise/comments'
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ module Sunrise
3
+ module Comments
4
+ autoload :Base, 'sunrise/comments/base'
5
+ autoload :Author, 'sunrise/comments/author'
6
+
7
+ # Default way to setup Sunrise.
8
+ def self.setup
9
+ yield self
10
+ end
11
+ end
12
+ end
13
+
14
+ require 'sunrise/comments/version'
15
+ require 'sunrise/comments/engine'
@@ -0,0 +1,21 @@
1
+ module Sunrise
2
+ module Comments
3
+ module Author
4
+ def self.included(base)
5
+ base.send :include, InstanceMethods
6
+ base.send :extend, ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def self.extended(base)
11
+ base.class_eval do
12
+ has_many :comments, :as => :author, :dependent => :delete_all
13
+ end
14
+ end
15
+ end
16
+
17
+ module InstanceMethods
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ module Sunrise
2
+ module Comments
3
+ module Base
4
+ def self.included(base)
5
+ base.send :include, InstanceMethods
6
+ base.send :extend, ClassMethods
7
+ end
8
+
9
+ module ClassMethods
10
+ def self.extended(base)
11
+ base.class_eval do
12
+ has_many :comments, :as => :commentable, :dependent => :delete_all
13
+ end
14
+ end
15
+ end
16
+
17
+ module InstanceMethods
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ require 'rails'
2
+ require 'sunrise-comments'
3
+
4
+ module Sunrise
5
+ module Comments
6
+ class Engine < ::Rails::Engine
7
+ config.before_initialize do
8
+ Sunrise::Plugin.register :comments do |plugin|
9
+ plugin.model = 'sunrise/models/comment'
10
+ plugin.menu = false
11
+ plugin.version = Sunrise::Comments::VERSION.dup
12
+ end
13
+
14
+ Sunrise::Plugins.activate(:comments)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ module Sunrise
2
+ module Comments
3
+ VERSION = "0.1.0".freeze
4
+ end
5
+ end
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+ module Sunrise
3
+ module Models
4
+ module Comment
5
+ def self.included(base)
6
+ base.send :include, InstanceMethods
7
+ base.send :extend, ClassMethods
8
+ end
9
+
10
+ module ClassMethods
11
+ def self.extended(base)
12
+ base.class_eval do
13
+ belongs_to :commentable, :polymorphic => true, :counter_cache => true
14
+ belongs_to :author, :polymorphic => true
15
+
16
+ before_validation :make_author
17
+
18
+ default_scope order("#{quoted_table_name}.id DESC")
19
+ scope :recently, order("#{quoted_table_name}.created_at DESC")
20
+ scope :siblings_for, lambda { |item| where(["commentable_type = ? AND commentable_id = ?", item.commentable_type, item.commentable_id]) }
21
+ scope :follows, where(:is_follow => true)
22
+ end
23
+ end
24
+ end
25
+
26
+ module InstanceMethods
27
+
28
+ def comments_count
29
+ @comments_count ||= siblings.count
30
+ end
31
+
32
+ def siblings
33
+ self.class.siblings_for(self)
34
+ end
35
+
36
+ def anonymous?
37
+ author.nil?
38
+ end
39
+
40
+ protected
41
+
42
+ def make_author
43
+ unless author.nil?
44
+ self.user_email = author.email if author.respond_to?(:email)
45
+ self.user_name = author.name if author.respond_to?(:name)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sunrise-comments
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Igor Galeta
14
+ - Pavlo Galeta
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2011-05-18 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: sunrise
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 27
30
+ segments:
31
+ - 0
32
+ - 1
33
+ - 0
34
+ version: 0.1.0
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ description: Sunrise is a Aimbulance CMS
38
+ email: galeta.igor@gmail.com
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - README.rdoc
45
+ files:
46
+ - README.rdoc
47
+ - Rakefile
48
+ - app/controllers/comments_controller.rb
49
+ - app/sweepers/comment_sweeper.rb
50
+ - app/views/comments/_block.html.erb
51
+ - app/views/comments/_comment.html.erb
52
+ - app/views/comments/_form.html.erb
53
+ - app/views/comments/create.js.erb
54
+ - app/views/comments/destroy.js.erb
55
+ - config/locales/ru.yml
56
+ - config/locales/uk.yml
57
+ - config/routes.rb
58
+ - lib/generators/sunrise/comments/USAGE
59
+ - lib/generators/sunrise/comments/install_generator.rb
60
+ - lib/generators/sunrise/comments/templates/comment.rb
61
+ - lib/generators/sunrise/comments/templates/create_comments.rb
62
+ - lib/sunrise-comments.rb
63
+ - lib/sunrise/comments.rb
64
+ - lib/sunrise/comments/author.rb
65
+ - lib/sunrise/comments/base.rb
66
+ - lib/sunrise/comments/engine.rb
67
+ - lib/sunrise/comments/version.rb
68
+ - lib/sunrise/models/comment.rb
69
+ homepage: https://github.com/galetahub/sunrise-comments
70
+ licenses: []
71
+
72
+ post_install_message:
73
+ rdoc_options: []
74
+
75
+ require_paths:
76
+ - lib
77
+ required_ruby_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ hash: 3
83
+ segments:
84
+ - 0
85
+ version: "0"
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ hash: 3
92
+ segments:
93
+ - 0
94
+ version: "0"
95
+ requirements: []
96
+
97
+ rubyforge_project:
98
+ rubygems_version: 1.8.2
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: Rails CMS
102
+ test_files: []
103
+