ack_rocket_cms 0.7.2.1

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 (132) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +1 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +19 -0
  7. data/Gemfile +5 -0
  8. data/Gemfile.lock +244 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +74 -0
  11. data/Rakefile +1 -0
  12. data/app/assets/javascripts/head.load.js +707 -0
  13. data/app/assets/javascripts/jquery.placeholder.js +157 -0
  14. data/app/assets/javascripts/rocket_cms.js.coffee +10 -0
  15. data/app/assets/javascripts/rocket_cms/flash.js.coffee +3 -0
  16. data/app/assets/javascripts/rocket_cms/map.js.coffee +22 -0
  17. data/app/assets/stylesheets/rocket_cms.css.sass +6 -0
  18. data/app/assets/stylesheets/rocket_cms/flash.css.sass +66 -0
  19. data/app/assets/stylesheets/rocket_cms/normalize.css.scss +406 -0
  20. data/app/controllers/concerns/no_cache.rb +12 -0
  21. data/app/controllers/concerns/rs_errors.rb +63 -0
  22. data/app/controllers/concerns/rs_menu.rb +45 -0
  23. data/app/controllers/concerns/rs_pages.rb +41 -0
  24. data/app/controllers/contacts_controller.rb +3 -0
  25. data/app/controllers/home_controller.rb +5 -0
  26. data/app/controllers/news_controller.rb +3 -0
  27. data/app/controllers/pages_controller.rb +4 -0
  28. data/app/controllers/search_controller.rb +4 -0
  29. data/app/mailers/contact_mailer.rb +15 -0
  30. data/app/models/concerns/boolean_field.rb +17 -0
  31. data/app/models/concerns/enableable.rb +8 -0
  32. data/app/models/concerns/geocodeable.rb +4 -0
  33. data/app/models/concerns/mappable.rb +95 -0
  34. data/app/models/concerns/seoable.rb +42 -0
  35. data/app/models/concerns/sitemap_data.rb +20 -0
  36. data/app/models/concerns/sort_field.rb +17 -0
  37. data/app/models/concerns/sortable.rb +8 -0
  38. data/app/models/contact_message.rb +11 -0
  39. data/app/models/menu.rb +11 -0
  40. data/app/models/news.rb +10 -0
  41. data/app/models/page.rb +11 -0
  42. data/app/views/blocks/_footer.html.haml +1 -0
  43. data/app/views/contact_mailer/new_message_email.html.haml +16 -0
  44. data/app/views/contacts/index.html.haml +10 -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/home/index.html.haml +1 -0
  52. data/app/views/layouts/application.html.haml +23 -0
  53. data/app/views/layouts/application.html.slim +24 -0
  54. data/app/views/news/index.html.haml +9 -0
  55. data/app/views/news/show.html.haml +8 -0
  56. data/app/views/pages/show.html.haml +1 -0
  57. data/app/views/rails_admin/main/_check_boxes.html.haml +27 -0
  58. data/app/views/rails_admin/main/_enum_check_boxes.html.haml +5 -0
  59. data/app/views/rails_admin/main/_enum_radio_buttons.html.haml +5 -0
  60. data/app/views/rails_admin/main/_form_raw.html.haml +1 -0
  61. data/app/views/search/index.html.haml +19 -0
  62. data/app/views/shared/_admin_link.html.haml +3 -0
  63. data/app/views/shared/_messages.html.haml +7 -0
  64. data/app/views/shared/_meta.html.haml +6 -0
  65. data/app/views/shared/_obj.html.haml +20 -0
  66. data/app/views/shared/_og.html.haml +4 -0
  67. data/config/locales/en.rocket_admin.yml +6 -0
  68. data/config/locales/en.rs.yml +20 -0
  69. data/config/locales/ru.cancan.yml +4 -0
  70. data/config/locales/ru.devise.yml +65 -0
  71. data/config/locales/ru.kaminari.yml +17 -0
  72. data/config/locales/ru.models.yml +92 -0
  73. data/config/locales/ru.mongoid.yml +450 -0
  74. data/config/locales/ru.rails_admin.yml +148 -0
  75. data/config/locales/ru.rocket_admin.yml +6 -0
  76. data/config/locales/ru.rs.yml +20 -0
  77. data/config/locales/ru.simple_captcha.yml +3 -0
  78. data/config/locales/ru.simple_form.yml +9 -0
  79. data/lib/filename_to_slug.rb +34 -0
  80. data/lib/generators/rocket_cms/ability_generator.rb +15 -0
  81. data/lib/generators/rocket_cms/admin_generator.rb +21 -0
  82. data/lib/generators/rocket_cms/capify_generator.rb +40 -0
  83. data/lib/generators/rocket_cms/layout_generator.rb +15 -0
  84. data/lib/generators/rocket_cms/migration_generator.rb +19 -0
  85. data/lib/generators/rocket_cms/templates/Capfile +17 -0
  86. data/lib/generators/rocket_cms/templates/ability.erb +28 -0
  87. data/lib/generators/rocket_cms/templates/admin.erb +81 -0
  88. data/lib/generators/rocket_cms/templates/deploy.erb +47 -0
  89. data/lib/generators/rocket_cms/templates/dl.erb +30 -0
  90. data/lib/generators/rocket_cms/templates/migration_contact_messages.rb +15 -0
  91. data/lib/generators/rocket_cms/templates/migration_news.rb +21 -0
  92. data/lib/generators/rocket_cms/templates/migration_pages.rb +36 -0
  93. data/lib/generators/rocket_cms/templates/production.erb +8 -0
  94. data/lib/generators/rocket_cms/templates/unicorn.erb +66 -0
  95. data/lib/generators/rocket_cms/utils.rb +22 -0
  96. data/lib/manual_slug.rb +11 -0
  97. data/lib/manual_slug/active_record.rb +32 -0
  98. data/lib/manual_slug/mongoid.rb +36 -0
  99. data/lib/rails_admin/custom_show_in_app.rb +39 -0
  100. data/lib/rocket_cms.rb +88 -0
  101. data/lib/rocket_cms/admin.rb +152 -0
  102. data/lib/rocket_cms/configuration.rb +67 -0
  103. data/lib/rocket_cms/controller.rb +24 -0
  104. data/lib/rocket_cms/controllers/contacts.rb +70 -0
  105. data/lib/rocket_cms/controllers/news.rb +31 -0
  106. data/lib/rocket_cms/controllers/pages.rb +19 -0
  107. data/lib/rocket_cms/controllers/search.rb +45 -0
  108. data/lib/rocket_cms/elastic_search.rb +31 -0
  109. data/lib/rocket_cms/engine.rb +39 -0
  110. data/lib/rocket_cms/migration.rb +31 -0
  111. data/lib/rocket_cms/model.rb +25 -0
  112. data/lib/rocket_cms/models/active_record/contact_message.rb +14 -0
  113. data/lib/rocket_cms/models/active_record/menu.rb +14 -0
  114. data/lib/rocket_cms/models/active_record/news.rb +23 -0
  115. data/lib/rocket_cms/models/active_record/page.rb +17 -0
  116. data/lib/rocket_cms/models/contact_message.rb +27 -0
  117. data/lib/rocket_cms/models/menu.rb +29 -0
  118. data/lib/rocket_cms/models/mongoid/contact_message.rb +20 -0
  119. data/lib/rocket_cms/models/mongoid/menu.rb +12 -0
  120. data/lib/rocket_cms/models/mongoid/news.rb +27 -0
  121. data/lib/rocket_cms/models/mongoid/page.rb +26 -0
  122. data/lib/rocket_cms/models/news.rb +50 -0
  123. data/lib/rocket_cms/models/page.rb +76 -0
  124. data/lib/rocket_cms/patch.rb +58 -0
  125. data/lib/rocket_cms/rails_admin_menu.rb +145 -0
  126. data/lib/rocket_cms/simple_form_patch.rb +12 -0
  127. data/lib/rocket_cms/tasks.rb +13 -0
  128. data/lib/rocket_cms/version.rb +3 -0
  129. data/release.sh +13 -0
  130. data/rocket_cms.gemspec +54 -0
  131. data/template.rb +557 -0
  132. metadata +533 -0
@@ -0,0 +1,17 @@
1
+ module RocketCMS
2
+ module Models
3
+ module ActiveRecord
4
+ module Page
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ acts_as_nested_set
9
+ has_paper_trail
10
+ validates_lengths_from_database only: [:name, :title, :content, :excerpt, :h1, :keywords, :robots, :og_title, :regexp, :redirect, :fullpath]
11
+ scope :sorted, -> { order(lft: :asc) }
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,27 @@
1
+ module RocketCMS
2
+ module Models
3
+ module ContactMessage
4
+ extend ActiveSupport::Concern
5
+ include RocketCMS::Model
6
+ include RocketCMS.orm_specific('ContactMessage')
7
+
8
+ included do
9
+
10
+ apply_simple_captcha message: RocketCMS.configuration.contacts_captcha_error_message
11
+
12
+ validates_email_format_of :email, unless: 'email.blank?'
13
+ if RocketCMS.configuration.contacts_message_required
14
+ validates_presence_of :content
15
+ end
16
+ validate do
17
+ if email.blank? && phone.blank?
18
+ errors.add(:email, I18n.t('rs.no_contact_info'))
19
+ end
20
+ end
21
+ after_create do
22
+ ContactMailer.new_message_email(self).deliver
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,29 @@
1
+ module RocketCMS
2
+ module Models
3
+ module Menu
4
+ extend ActiveSupport::Concern
5
+ include RocketCMS::Model
6
+ include Enableable
7
+ include RocketCMS.orm_specific('Menu')
8
+ include ManualSlug
9
+
10
+ included do
11
+
12
+ field :name, type: String, localize: true
13
+ manual_slug :name
14
+
15
+ after_save do
16
+ Rails.cache.delete 'menus'
17
+ end
18
+ after_destroy do
19
+ Rails.cache.delete 'menus'
20
+ end
21
+
22
+ has_and_belongs_to_many :pages, inverse_of: :menus
23
+ alias_method :items, :pages
24
+ manual_slug :name
25
+ end
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,20 @@
1
+ module RocketCMS
2
+ module Models
3
+ module Mongoid
4
+ module ContactMessage
5
+ extend ActiveSupport::Concern
6
+ included do
7
+ field :name, type: String
8
+ field :email, type: String
9
+ field :phone, type: String
10
+ field :content, type: String
11
+ RocketCMS.configuration.contacts_fields.each_pair do |fn, ft|
12
+ next if ft.nil?
13
+ field fn, type: ft
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,12 @@
1
+ module RocketCMS
2
+ module Models
3
+ module Mongoid
4
+ module Menu
5
+ extend ActiveSupport::Concern
6
+ included do
7
+ field :name, type: String
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,27 @@
1
+ module RocketCMS
2
+ module Models
3
+ module Mongoid
4
+ module News
5
+ extend ActiveSupport::Concern
6
+ unless RocketCMS.configuration.news_image_styles.nil?
7
+ include ::Mongoid::Paperclip
8
+ end
9
+ included do
10
+ field :time, type: Time
11
+ index({enabled: 1, time: 1})
12
+ unless RocketCMS.configuration.news_image_styles.nil?
13
+ has_mongoid_attached_file :image, styles: RocketCMS.configuration.news_image_styles
14
+ validates_attachment_content_type :image, content_type: %w(image/gif image/jpeg image/jpg image/png), if: :image?
15
+ end
16
+
17
+ field :excerpt, type: String, localize: RocketCMS.configuration.localize
18
+ field :content, type: String, localize: RocketCMS.configuration.localize
19
+
20
+ scope :after_now, -> { where(:time.lt => Time.now) }
21
+ scope :by_date, -> { desc(:time) }
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
@@ -0,0 +1,26 @@
1
+ module RocketCMS
2
+ module Models
3
+ module Mongoid
4
+ module Page
5
+ extend ActiveSupport::Concern
6
+ included do
7
+ field :regexp, type: String
8
+ field :redirect, type: String
9
+ field :excerpt, type: String, localize: RocketCMS.configuration.localize
10
+ field :content, type: String, localize: RocketCMS.configuration.localize
11
+ field :fullpath, type: String
12
+ has_and_belongs_to_many :menus, inverse_of: :pages
13
+ acts_as_nested_set
14
+
15
+ manual_slug :name
16
+
17
+ scope :sorted, -> { order_by([:lft, :asc]) }
18
+ scope :menu, ->(menu_id) { enabled.sorted.where(menu_ids: menu_id) }
19
+
20
+ scope :in_sitemap, -> { where(sitemap_show: true) }
21
+ scope :sitemap_show, -> { in_sitemap }
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,50 @@
1
+ module RocketCMS
2
+ module Models
3
+ module News
4
+ extend ActiveSupport::Concern
5
+ include RocketCMS::Model
6
+ include Seoable
7
+ include Enableable
8
+ include RocketCMS.orm_specific('News')
9
+ include ManualSlug
10
+ include SitemapData
11
+
12
+ if RocketCMS.configuration.search_enabled
13
+ include RocketCMS::ElasticSearch
14
+ end
15
+
16
+ included do
17
+
18
+ validates_presence_of :name, :content
19
+ before_validation do
20
+ self.time = Time.now if self.time.blank?
21
+ end
22
+ scope :recent, ->(count = 5) { enabled.after_now.by_date.limit(count) }
23
+ unless RocketCMS.configuration.news_per_page.nil?
24
+ paginates_per RocketCMS.configuration.news_per_page
25
+ end
26
+ smart_excerpt :excerpt, :content, RocketCMS.configuration.news_excerpt
27
+ manual_slug :report_slug
28
+
29
+ RocketCMS.apply_patches self
30
+ end
31
+
32
+ def report_slug
33
+ if time.blank?
34
+ name
35
+ elsif name.blank?
36
+ time.strftime('%Y-%m-%d')
37
+ else
38
+ time.strftime('%Y-%m-%d') + '-' + name[0..20]
39
+ end
40
+ end
41
+ def html5_date
42
+ time.strftime('%Y-%m-%d')
43
+ end
44
+ def format_date
45
+ time.strftime('%d.%m.%Y')
46
+ end
47
+ end
48
+ end
49
+ end
50
+
@@ -0,0 +1,76 @@
1
+ module RocketCMS
2
+ module Models
3
+ module Page
4
+ extend ActiveSupport::Concern
5
+ include RocketCMS::Model
6
+ include Enableable
7
+ include Seoable
8
+ include ManualSlug
9
+ include SitemapData
10
+
11
+ include RocketCMS.orm_specific('Page')
12
+
13
+ if RocketCMS.configuration.search_enabled
14
+ include RocketCMS::ElasticSearch
15
+ end
16
+
17
+ included do
18
+
19
+ before_validation do
20
+ self.fullpath = "/pages/#{slug}" if self.fullpath.blank?
21
+ end
22
+ validates_uniqueness_of :fullpath
23
+ validates_presence_of :name
24
+ manual_slug :name
25
+ end
26
+
27
+ def get_fullpath
28
+ redirect.blank? ? fullpath : redirect
29
+ end
30
+
31
+ def has_content?
32
+ @content_used.nil? && !content.blank?
33
+ end
34
+
35
+ def page_content
36
+ if @content_used.nil?
37
+ @content_used = true
38
+ if content.nil?
39
+ ''
40
+ else
41
+ content.gsub(/\{\{(.*?)\}\}/) do
42
+ Settings ? Settings.get($1).val : "" #temp
43
+ end
44
+ end
45
+ else
46
+ ''
47
+ end
48
+ end
49
+
50
+ def is_current?(url)
51
+ if fullpath == '/'
52
+ url == '/'
53
+ else
54
+ url.match(clean_regexp)
55
+ end
56
+ end
57
+
58
+ def clean_regexp
59
+ if regexp.blank?
60
+ /^#{Regexp.escape(fullpath)}$/
61
+ else
62
+ begin
63
+ /#{regexp}/
64
+ rescue
65
+ # not a valid regexp - treat as literal search string
66
+ /#{Regexp.escape(regexp)}/
67
+ end
68
+ end
69
+ end
70
+
71
+ def nav_options
72
+ {highlights_on: clean_regexp}
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,58 @@
1
+ module RocketCMS
2
+ class PatchDSL
3
+ def self.call(&blk)
4
+ instance = new
5
+ instance.instance_eval(&blk)
6
+ instance.instance_variables.inject({}) { |result_hash, instance_variable|
7
+ result_hash[instance_variable[1..-1].to_sym] = instance.instance_variable_get(instance_variable)
8
+ result_hash
9
+ }
10
+ end
11
+
12
+ def initialize
13
+ @model = Proc.new {}
14
+ @admin = Proc.new {}
15
+ @list = Proc.new {}
16
+ @show = Proc.new {}
17
+ @edit = Proc.new {}
18
+ @export = Proc.new {}
19
+ end
20
+
21
+ def model(&blk); @model = blk; end
22
+ def admin(&blk); @admin = blk; end
23
+ def list(&blk); @list = blk; end
24
+ def show(&blk); @show = blk; end
25
+ def edit(&blk); @edit = blk; end
26
+ def export(&blk); @export = blk; end
27
+ end
28
+
29
+ @@patches = {}
30
+
31
+ def self.only_patches(s, sections)
32
+ s.instance_eval do
33
+ sections.each do |section|
34
+ send section do
35
+ RocketCMS.apply_patches self
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ def self.apply_patches(s)
42
+ if s.class.name.index('RailsAdmin::Config::Sections::').nil?
43
+ if s.class.name == 'RailsAdmin::Config::Model'
44
+ s.instance_eval(&@@patches[s.abstract_model.model_name][:admin]) unless @@patches[s.abstract_model.model_name].nil?
45
+ else
46
+ s.instance_eval(&@@patches[s.name][:model]) unless @@patches[s.name].nil?
47
+ end
48
+ else
49
+ model = s.abstract_model.model_name
50
+ action = s.class.name.split('::')[-1].downcase.to_sym
51
+ s.instance_eval(&@@patches[model][action]) unless @@patches[model].nil?
52
+ end
53
+ end
54
+
55
+ def self.patch(model, &blk)
56
+ @@patches[model] = PatchDSL.call(&blk)
57
+ end
58
+ end
@@ -0,0 +1,145 @@
1
+ module RailsAdmin
2
+ module Config
3
+ module Fields
4
+ module Types
5
+ class Menu < RailsAdmin::Config::Fields::Base
6
+ # Register field type for the type loader
7
+ RailsAdmin::Config::Fields::Types::register(self)
8
+ include RailsAdmin::Engine.routes.url_helpers
9
+
10
+ register_instance_option :pretty_value do
11
+ obj = bindings[:object]
12
+ ret = []
13
+ menus = Rails.cache.fetch 'menus', expires_in: 10.minutes do
14
+ if RocketCMS.mongoid?
15
+ ::Menu.all.map { |m| {id: m.id.to_s, name: m.name } }
16
+ else
17
+ ::Menu.all.map { |m| {id: m.id, name: m.name } }
18
+ end
19
+ end
20
+ menus.each do |m|
21
+ if RocketCMS.mongoid?
22
+ on = obj.menu_ids.include?(BSON::ObjectId.from_string(m[:id]))
23
+ else
24
+ on = obj.menu_ids.include?(m[:id].to_i)
25
+ end
26
+ ret << bindings[:view].link_to(
27
+ m[:name],
28
+ bindings[:view].toggle_menu_path(model_name: @abstract_model, id: obj.id, menu: m[:id], on: !on),
29
+ #method: :post,
30
+ title: m[:name],
31
+ class: "btn btn-mini #{on ? "btn-success" : "btn-danger"}",
32
+ style: 'margin-bottom: 5px;',
33
+ onclick: 'var $t = $(this); $.ajax({type: "POST", url: $t.attr("href"), data: {ajax:true}, success: function(r) { $t.attr("href", r.href); $t.attr("class", r.class); }, error: function(e) { alert(e.responseText); }}); return false;'
34
+ )
35
+ end
36
+ ('<div style="white-space: normal;">' + ret.join(' ') + '</div>').html_safe
37
+ end
38
+
39
+ register_instance_option :formatted_value do
40
+ pretty_value
41
+ end
42
+
43
+ register_instance_option :export_value do
44
+ nil
45
+ end
46
+
47
+ register_instance_option :partial do
48
+ :form_raw
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ module RailsAdmin
57
+ module Config
58
+ module Actions
59
+ class ToggleMenu < Base
60
+ RailsAdmin::Config::Actions.register(self)
61
+
62
+ # Is the action acting on the root level (Example: /admin/contact)
63
+ register_instance_option :root? do
64
+ false
65
+ end
66
+
67
+ register_instance_option :collection? do
68
+ false
69
+ end
70
+
71
+ # Is the action on an object scope (Example: /admin/team/1/edit)
72
+ register_instance_option :member? do
73
+ true
74
+ end
75
+
76
+ register_instance_option :controller do
77
+ proc do
78
+ ajax_link = Proc.new do |am, obj, menu, on|
79
+ render json: {
80
+ href: toggle_menu_path(model_name: am, id: obj.id, menu: menu.id, on: !on),
81
+ class: "btn btn-mini #{on ? "btn-success" : "btn-danger"}",
82
+ }
83
+ end
84
+ if params['id'].present?
85
+ begin
86
+ @object = @abstract_model.model.find(params['id'])
87
+ @menu = ::Menu.find(params[:menu])
88
+ if params[:on] == 'true'
89
+ @object.menus << @menu
90
+ else
91
+ @object.menus.delete(@menu)
92
+ end
93
+
94
+ if @object.save
95
+ if params['ajax'].present?
96
+ if params[:on] == 'true'
97
+ ajax_link.call(@abstract_model, @object, @menu, true)
98
+ else
99
+ ajax_link.call(@abstract_model, @object, @menu, false)
100
+ end
101
+ else
102
+ if params[:on] == 'true'
103
+ flash[:success] = I18n.t('rs.m.enabled', menu: @menu.name)
104
+ else
105
+ flash[:success] = I18n.t('rs.m.disabled', menu: @menu.name)
106
+ end
107
+ end
108
+ else
109
+ if params['ajax'].present?
110
+ render text: @object.errors.full_messages.join(', '), layout: false, status: 422
111
+ else
112
+ flash[:error] = @object.errors.full_messages.join(', ')
113
+ end
114
+ end
115
+ rescue Exception => e
116
+ if params['ajax'].present?
117
+ render text: I18n.t('rs.m.error', err: e.to_s), status: 422
118
+ else
119
+ flash[:error] = I18n.t('rs.m.error', err: e.to_s)
120
+ end
121
+ end
122
+ else
123
+ if params['ajax'].present?
124
+ render text: I18n.t('rs.m.no_id'), status: 422
125
+ else
126
+ flash[:error] = I18n.t('rs.m.no_id')
127
+ end
128
+
129
+ end
130
+
131
+ redirect_to :back unless params['ajax'].present?
132
+ end
133
+ end
134
+
135
+ register_instance_option :link_icon do
136
+ 'icon-move'
137
+ end
138
+
139
+ register_instance_option :http_methods do
140
+ [:post]
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end