rocket_cms 0.1.13

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.
Files changed (99) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +2 -0
  6. data/.travis.yml +19 -0
  7. data/Gemfile +4 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +36 -0
  10. data/Rakefile +1 -0
  11. data/app/assets/javascripts/head.load.js +707 -0
  12. data/app/assets/javascripts/jquery.placeholder.js +157 -0
  13. data/app/assets/javascripts/rocket_cms.js.coffee +10 -0
  14. data/app/assets/javascripts/rocket_cms/flash.js.coffee +3 -0
  15. data/app/assets/javascripts/rocket_cms/map.js.coffee +22 -0
  16. data/app/assets/stylesheets/rocket_cms.css.sass +2 -0
  17. data/app/assets/stylesheets/rocket_cms/flash.css.sass +66 -0
  18. data/app/assets/stylesheets/rocket_cms/normalize.css.scss +406 -0
  19. data/app/controllers/concerns/no_cache.rb +12 -0
  20. data/app/controllers/concerns/rs_errors.rb +58 -0
  21. data/app/controllers/concerns/rs_menu.rb +45 -0
  22. data/app/controllers/concerns/rs_pages.rb +41 -0
  23. data/app/controllers/contacts_controller.rb +29 -0
  24. data/app/controllers/news_controller.rb +22 -0
  25. data/app/controllers/pages_controller.rb +12 -0
  26. data/app/controllers/search_controller.rb +25 -0
  27. data/app/mailers/contact_mailer.rb +15 -0
  28. data/app/models/ckeditor/asset.rb +5 -0
  29. data/app/models/ckeditor/attachment_file.rb +15 -0
  30. data/app/models/ckeditor/picture.rb +16 -0
  31. data/app/models/concerns/boolean_field.rb +9 -0
  32. data/app/models/concerns/enableable.rb +8 -0
  33. data/app/models/concerns/geocodeable.rb +4 -0
  34. data/app/models/concerns/manual_slug.rb +38 -0
  35. data/app/models/concerns/mappable.rb +77 -0
  36. data/app/models/concerns/seoable.rb +35 -0
  37. data/app/models/concerns/sort_field.rb +12 -0
  38. data/app/models/concerns/sortable.rb +8 -0
  39. data/app/models/concerns/trackable.rb +8 -0
  40. data/app/models/contact_message.rb +6 -0
  41. data/app/models/menu.rb +6 -0
  42. data/app/models/news.rb +5 -0
  43. data/app/models/page.rb +6 -0
  44. data/app/views/contact_mailer/new_message_email.html.haml +15 -0
  45. data/app/views/contacts/new.html.haml +10 -0
  46. data/app/views/contacts/sent.html.haml +4 -0
  47. data/app/views/errors/_base.html.haml +3 -0
  48. data/app/views/errors/error_403.html.haml +1 -0
  49. data/app/views/errors/error_404.html.haml +1 -0
  50. data/app/views/errors/error_500.html.haml +1 -0
  51. data/app/views/news/index.html.haml +8 -0
  52. data/app/views/news/show.html.haml +8 -0
  53. data/app/views/pages/show.html.haml +1 -0
  54. data/app/views/rails_admin/main/_check_boxes.html.haml +27 -0
  55. data/app/views/rails_admin/main/_form_raw.html.haml +1 -0
  56. data/app/views/search/index.html.haml +19 -0
  57. data/app/views/shared/_admin_link.html.haml +3 -0
  58. data/app/views/shared/_messages.html.haml +7 -0
  59. data/app/views/shared/_meta.html.haml +6 -0
  60. data/app/views/shared/_obj.html.haml +14 -0
  61. data/app/views/shared/_og.html.haml +4 -0
  62. data/config/locales/en.rocket_admin.yml +6 -0
  63. data/config/locales/en.rs.yml +17 -0
  64. data/config/locales/ru.cancan.yml +4 -0
  65. data/config/locales/ru.devise.yml +65 -0
  66. data/config/locales/ru.kaminari.yml +17 -0
  67. data/config/locales/ru.models.yml +78 -0
  68. data/config/locales/ru.mongoid.yml +450 -0
  69. data/config/locales/ru.rails_admin.yml +147 -0
  70. data/config/locales/ru.rocket_admin.yml +6 -0
  71. data/config/locales/ru.rs.yml +17 -0
  72. data/config/locales/ru.simple_captcha.yml +3 -0
  73. data/config/locales/ru.simple_form.yml +9 -0
  74. data/lib/filename_to_slug.rb +32 -0
  75. data/lib/generators/rocket_cms/admin_generator.rb +20 -0
  76. data/lib/generators/rocket_cms/templates/ability.erb +17 -0
  77. data/lib/generators/rocket_cms/templates/admin.erb +71 -0
  78. data/lib/generators/rocket_cms/utils.rb +22 -0
  79. data/lib/history_tracker.rb +4 -0
  80. data/lib/rails_admin/custom_show_in_app.rb +39 -0
  81. data/lib/rocket_cms.rb +57 -0
  82. data/lib/rocket_cms/admin.rb +128 -0
  83. data/lib/rocket_cms/configuration.rb +54 -0
  84. data/lib/rocket_cms/controller.rb +24 -0
  85. data/lib/rocket_cms/elastic_search.rb +32 -0
  86. data/lib/rocket_cms/engine.rb +4 -0
  87. data/lib/rocket_cms/model.rb +16 -0
  88. data/lib/rocket_cms/models/contact_message.rb +37 -0
  89. data/lib/rocket_cms/models/menu.rb +16 -0
  90. data/lib/rocket_cms/models/news.rb +61 -0
  91. data/lib/rocket_cms/models/page.rb +86 -0
  92. data/lib/rocket_cms/patch.rb +58 -0
  93. data/lib/rocket_cms/rails_admin_menu.rb +137 -0
  94. data/lib/rocket_cms/railtie.rb +39 -0
  95. data/lib/rocket_cms/tasks.rb +14 -0
  96. data/lib/rocket_cms/version.rb +3 -0
  97. data/lib/smart_excerpt.rb +98 -0
  98. data/rocket_cms.gemspec +50 -0
  99. metadata +533 -0
@@ -0,0 +1,12 @@
1
+ module NoCache
2
+ extend ActiveSupport::Concern
3
+ included do
4
+ before_filter :set_cache_buster
5
+ end
6
+
7
+ protected
8
+ def set_cache_buster
9
+ expires_now()
10
+ response.headers["Pragma"] = "no-cache"
11
+ end
12
+ end
@@ -0,0 +1,58 @@
1
+ module RsErrors
2
+ extend ActiveSupport::Concern
3
+ included do
4
+ if Rails.env.production? || Rails.env.staging?
5
+ rescue_from Exception, with: :render_500
6
+ rescue_from ActionController::RoutingError, with: :render_404
7
+ rescue_from ActionController::UnknownController, with: :render_404
8
+ rescue_from AbstractController::ActionNotFound, with: :render_404
9
+ rescue_from Mongoid::Errors::DocumentNotFound, with: :render_404
10
+ rescue_from Mongoid::Errors::InvalidFind, with: :render_404
11
+ end
12
+
13
+ if defined?(CanCan)
14
+ rescue_from CanCan::AccessDenied do |exception|
15
+ if !user_signed_in?
16
+ #scope = rails_admin? ? main_app : self
17
+ #redirect_to scope.new_user_session_path, alert: "Необходимо авторизоваться"
18
+ authenticate_user!
19
+ else
20
+ redirect_to '/', alert: "Доступ запрещен"
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ protected
27
+ def render_404(exception = nil)
28
+ Rails.logger.error "404: #{request.url}"
29
+ unless exception.nil?
30
+ Rails.logger.error exception.message
31
+ Rails.logger.error exception.backtrace.join("\n")
32
+ capture_exception(exception) if defined?(Raven)
33
+ end
34
+ render_error(404)
35
+ end
36
+
37
+ def render_500(exception)
38
+ Rails.logger.error "500: #{request.url}"
39
+ Rails.logger.error exception.message
40
+ Rails.logger.error exception.backtrace.join("\n")
41
+ capture_exception(exception) if defined?(Raven)
42
+ begin
43
+ if rails_admin_controller?
44
+ return render text: 'Внутренняя ошибка'
45
+ end
46
+ rescue
47
+ end
48
+ render_error(500)
49
+ end
50
+
51
+ def render_error(code = 500)
52
+ render template: "errors/error_#{code}", formats: [:html], handlers: [:haml, :slim], layout: RocketCMS.configuration.error_layout, status: code
53
+ end
54
+
55
+ def rails_admin?
56
+ self.is_a?(RailsAdmin::ApplicationController)
57
+ end
58
+ end
@@ -0,0 +1,45 @@
1
+ module RsMenu
2
+ extend ActiveSupport::Concern
3
+ included do
4
+ helper_method :navigation
5
+ end
6
+
7
+ def render_with_subs(items, primary, item)
8
+ subs = items.select { |i| i.parent_id == item.id && !i.name.blank? && i.enabled }
9
+ if subs.empty?
10
+ block = nil
11
+ else
12
+ block = Proc.new do |sub_nav|
13
+ subs.each { |sub| render_with_subs(items, sub_nav, sub) }
14
+ end
15
+ end
16
+ cr = item.clean_regexp
17
+ navigation_item(primary, item, block)
18
+ end
19
+
20
+ def navigation_item(primary, item, block=nil)
21
+ url = item.redirect.blank? ? item.fullpath : item.redirect
22
+ if block.nil?
23
+ primary.item(item.slug, item.name, url, item.nav_options)
24
+ else
25
+ primary.item(item.slug, item.name, url, item.nav_options, &block)
26
+ end
27
+ end
28
+
29
+ def navigation(type)
30
+ Proc.new do |primary|
31
+ SimpleNavigation.config.autogenerate_item_ids = false
32
+ begin
33
+ items = ::Menu.find(type.to_s).pages.asc(:lft).to_a
34
+ items.select { |i| i.parent_id.nil? && !i.name.blank? && i.enabled }.each do |item|
35
+ render_with_subs(items, primary, item)
36
+ end
37
+ rescue Exception => exception
38
+ Rails.logger.error exception.message
39
+ Rails.logger.error exception.backtrace.join("\n")
40
+ capture_exception(exception) if respond_to?(:capture_exception)
41
+ items
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,41 @@
1
+ module RsPages
2
+ extend ActiveSupport::Concern
3
+ included do
4
+ before_filter :find_page
5
+ end
6
+
7
+ private
8
+
9
+ def find_page
10
+ @seo_page = find_seo_page request.path
11
+ if !@seo_page.nil? && !@seo_page.redirect.blank?
12
+ redirect_to @seo_page.redirect
13
+ end
14
+ end
15
+
16
+ def find_seo_page(path)
17
+ do_redirect = false
18
+ if path[0] != '/'
19
+ path = '/' + path
20
+ end
21
+ if path.length > 1 && path[-1] == '/'
22
+ path = path[0..-2]
23
+ do_redirect = true
24
+ end
25
+
26
+ page = Page.enabled.where(fullpath: path).first
27
+ if page.nil?
28
+ do_redirect = true
29
+ spath = path.chomp(File.extname(path))
30
+ if spath != path
31
+ page = Page.enabled.where(fullpath: spath).first
32
+ end
33
+ end
34
+ if !page.nil? && do_redirect
35
+ redirect_to path
36
+ end
37
+
38
+ page
39
+ end
40
+
41
+ end
@@ -0,0 +1,29 @@
1
+ class ContactsController < ApplicationController
2
+ def new
3
+ @contact_message = ContactMessage.new
4
+ end
5
+
6
+ def create
7
+ @contact_message = ContactMessage.new(message_params)
8
+ if RocketCMS.configuration.contacts_captcha
9
+ meth = :save_with_captcha
10
+ else
11
+ meth = :save
12
+ end
13
+
14
+ if @contact_message.send(meth)
15
+ redirect_to :contacts_sent
16
+ else
17
+ flash.now[:alert] = @contact_message.errors.full_messages.join("\n")
18
+ render action: "new"
19
+ end
20
+ end
21
+
22
+ def sent
23
+ end
24
+
25
+ private
26
+ def message_params
27
+ params.require(:contact_message).permit(RocketCMS.configuration.contacts_fields.keys + [:name, :email, :phone, :content, :captcha, :captcha_key])
28
+ end
29
+ end
@@ -0,0 +1,22 @@
1
+ class NewsController < ApplicationController
2
+ def index
3
+ @news = News.enabled.after_now.by_date
4
+
5
+ unless RocketCMS.configuration.news_per_page.nil?
6
+ @news = @news.page(params[:page])
7
+ end
8
+ end
9
+
10
+ def show
11
+ @news = News.after_now.find(params[:id])
12
+ end
13
+
14
+ private
15
+ def page_title
16
+ if @news.class.name == 'News'
17
+ @news.page_title
18
+ else
19
+ super
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ class PagesController < ApplicationController
2
+ def show
3
+ if @seo_page.nil? || !@seo_page.persisted?
4
+ unless params[:id].blank?
5
+ @seo_page = Page.enabled.find(params[:id])
6
+ end
7
+ end
8
+ if @seo_page.nil?
9
+ render_404
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ class SearchController < ApplicationController
2
+ def index
3
+ if params[:query].blank?
4
+ @results = []
5
+ else
6
+ @results = Mongoid::Elasticsearch.search({
7
+ body: {
8
+ query: {
9
+ query_string: {
10
+ query: Mongoid::Elasticsearch::Utils.clean(params[:query])
11
+ }
12
+ },
13
+ highlight: {
14
+ fields: {
15
+ name: {},
16
+ content: {}
17
+ }
18
+ }
19
+ }},
20
+ page: params[:page],
21
+ per_page: RocketCMS.configuration.search_per_page,
22
+ )
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,15 @@
1
+ class ContactMailer < ActionMailer::Base
2
+ def new_message_email(message)
3
+ @message = message
4
+
5
+ #if message.attachment?
6
+ # attachments[message.attachment.identifier] = File.read(message.attachment.current_path)
7
+ #end
8
+
9
+ mail(
10
+ from: Settings.default_email_from(default: 'noreply@rscx.ru'),
11
+ to: Settings.form_email(default: 'glebtv@ya.ru'),
12
+ subject: "[#{Settings.email_topic(default: 'с сайта')}] #{message.name} #{message.email}"
13
+ )
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ class Ckeditor::Asset
2
+ include Ckeditor::Orm::Mongoid::AssetBase
3
+ include Mongoid::Paperclip
4
+ include Ckeditor::Backend::Paperclip
5
+ end
@@ -0,0 +1,15 @@
1
+ class Ckeditor::AttachmentFile < Ckeditor::Asset
2
+ has_mongoid_attached_file :data,
3
+ :url => "/ckeditor_assets/attachments/:id/:filename",
4
+ :path => ":rails_root/public/ckeditor_assets/attachments/:id/:filename"
5
+ if respond_to?(:do_not_validate_attachment_file_type)
6
+ do_not_validate_attachment_file_type :data, if: :data?
7
+ end
8
+
9
+ validates_attachment_size :data, :less_than => 100.megabytes
10
+ validates_attachment_presence :data
11
+
12
+ def url_thumb
13
+ @url_thumb ||= Ckeditor::Utils.filethumb(filename)
14
+ end
15
+ end
@@ -0,0 +1,16 @@
1
+ class Ckeditor::Picture < Ckeditor::Asset
2
+ has_mongoid_attached_file :data,
3
+ :url => "/ckeditor_assets/pictures/:id/:style_:basename.:extension",
4
+ :path => ":rails_root/public/ckeditor_assets/pictures/:id/:style_:basename.:extension",
5
+ :styles => { :content => '800>', :thumb => '118x100#' }
6
+ if respond_to?(:validates_attachment_content_type)
7
+ validates_attachment_content_type :data, :content_type => ['image/gif', 'image/jpeg', 'image/jpg', 'image/png'], if: :data?
8
+ end
9
+
10
+ validates_attachment_size :data, :less_than => 2.megabytes
11
+ validates_attachment_presence :data
12
+
13
+ def url_content
14
+ url(:content)
15
+ end
16
+ end
@@ -0,0 +1,9 @@
1
+ module BooleanField
2
+ extend ActiveSupport::Concern
3
+ module ClassMethods
4
+ def boolean_field(name, default = true)
5
+ field name, type: Mongoid::Boolean, default: default
6
+ scope name, -> { where(name => true) }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ module Enableable
2
+ extend ActiveSupport::Concern
3
+ include BooleanField
4
+
5
+ included do
6
+ boolean_field(:enabled)
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ module Geocodeable
2
+ extend ActiveSupport::Concern
3
+ include Mappable
4
+ end
@@ -0,0 +1,38 @@
1
+ module ManualSlug
2
+ extend ActiveSupport::Concern
3
+ include Mongoid::Slug
4
+
5
+ def text_slug
6
+ self._slugs.empty? ? '' : self._slugs.last
7
+ end
8
+ def text_slug=(slug)
9
+ if slug.blank?
10
+ self._slugs = []
11
+ else
12
+ self._slugs.delete(slug)
13
+ self._slugs << slug
14
+ end
15
+ end
16
+
17
+ module ClassMethods
18
+ def manual_slug(field, options = {}, callback = true)
19
+ options.merge!(permanent: true, history: true)
20
+ slug field, options
21
+
22
+ # we will create slugs manually when needed
23
+ skip_callback :create, :before, :build_slug
24
+
25
+ before_validation do
26
+ self._slugs = self._slugs.map{ |s| s.strip }.select {|s| !s.blank? }
27
+
28
+ if self._slugs.empty?
29
+ self.build_slug
30
+ end
31
+
32
+ true
33
+ end if callback
34
+ end
35
+ end
36
+
37
+ end
38
+
@@ -0,0 +1,77 @@
1
+ module Mappable
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ include Geocoder::Model::Mongoid
6
+
7
+ field :coordinates, type: Array
8
+ field :address, type: String
9
+
10
+ field :map_address, type: String
11
+ field :map_hint, type: String
12
+
13
+ field :lat, type: Float
14
+ field :lon, type: Float
15
+
16
+ geocoded_by :geo_address
17
+
18
+ after_validation do
19
+ if geo_address.blank?
20
+ self.coordinates = nil
21
+ else
22
+ if new_record? || address_changed? || coordinates.nil? || map_address_changed?
23
+ geocode
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def get_lat
30
+ if lat.blank?
31
+ if coordinates.nil?
32
+ nil
33
+ else
34
+ coordinates[1]
35
+ end
36
+ else
37
+ lat
38
+ end
39
+ end
40
+ def get_lon
41
+ if lon.blank?
42
+ if coordinates.nil?
43
+ nil
44
+ else
45
+ coordinates[0]
46
+ end
47
+ else
48
+ lon
49
+ end
50
+ end
51
+
52
+ def has_map?
53
+ (!lat.blank? && !lon.blank?) || !coordinates.nil?
54
+ end
55
+
56
+ def to_map
57
+ {
58
+ id: id.to_s,
59
+ hint: map_hint,
60
+ addr: address,
61
+ lat: get_lat,
62
+ lon: get_lon,
63
+ }
64
+ end
65
+
66
+ def geo_address
67
+ if map_address.blank?
68
+ address
69
+ else
70
+ map_address
71
+ end
72
+ end
73
+
74
+ def self.admin
75
+ RocketCMS.map_config
76
+ end
77
+ end