ack_rocket_cms 0.7.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +45 -45
  3. data/README.md +64 -5
  4. data/app/assets/javascripts/{rocket_cms.js.coffee → rocket_cms.coffee} +0 -3
  5. data/app/controllers/concerns/rs_errors.rb +8 -4
  6. data/app/controllers/concerns/rs_localizeable.rb +26 -0
  7. data/app/controllers/concerns/rs_menu.rb +9 -2
  8. data/app/controllers/concerns/rs_pages.rb +14 -3
  9. data/app/helpers/gzip_helper.rb +27 -0
  10. data/app/models/concerns/seoable.rb +19 -30
  11. data/app/models/seo.rb +16 -0
  12. data/app/views/devise/registrations/edit.html.slim +21 -0
  13. data/app/views/devise/registrations/new.html.slim +21 -0
  14. data/app/views/devise/sessions/new.html.slim +18 -19
  15. data/app/views/devise/shared/_links.html.slim +4 -18
  16. data/app/views/news/show.html.slim +1 -1
  17. data/config/locales/en.rs.yml +1 -1
  18. data/config/locales/ru.rs.yml +11 -1
  19. data/lib/generators/rocket_cms/migration_generator.rb +1 -1
  20. data/lib/generators/rocket_cms/templates/admin.erb +8 -0
  21. data/lib/generators/rocket_cms/templates/migration_news.rb +10 -5
  22. data/lib/generators/rocket_cms/templates/migration_pages.rb +14 -5
  23. data/lib/generators/rocket_cms/templates/migration_seos.rb +14 -0
  24. data/lib/rocket_cms.rb +4 -0
  25. data/lib/rocket_cms/admin.rb +35 -8
  26. data/lib/rocket_cms/configuration.rb +7 -1
  27. data/lib/rocket_cms/controllers/contacts.rb +2 -2
  28. data/lib/rocket_cms/controllers/news.rb +1 -1
  29. data/lib/rocket_cms/controllers/search.rb +17 -0
  30. data/lib/rocket_cms/engine.rb +3 -3
  31. data/lib/rocket_cms/migration.rb +14 -11
  32. data/lib/rocket_cms/models/active_record/menu.rb +3 -0
  33. data/lib/rocket_cms/models/active_record/news.rb +6 -3
  34. data/lib/rocket_cms/models/active_record/page.rb +3 -0
  35. data/lib/rocket_cms/models/active_record/seo.rb +17 -0
  36. data/lib/rocket_cms/models/contact_message.rb +1 -1
  37. data/lib/rocket_cms/models/embedded_gallery_image.rb +4 -0
  38. data/lib/rocket_cms/models/gallery.rb +2 -0
  39. data/lib/rocket_cms/models/gallery_image.rb +2 -0
  40. data/lib/rocket_cms/models/mongoid/contact_message.rb +5 -5
  41. data/lib/rocket_cms/models/mongoid/embedded_gallery_image.rb +0 -1
  42. data/lib/rocket_cms/models/mongoid/gallery.rb +0 -1
  43. data/lib/rocket_cms/models/mongoid/gallery_image.rb +0 -1
  44. data/lib/rocket_cms/models/mongoid/news.rb +3 -4
  45. data/lib/rocket_cms/models/mongoid/page.rb +3 -2
  46. data/lib/rocket_cms/models/mongoid/seo.rb +23 -0
  47. data/lib/rocket_cms/models/news.rb +13 -5
  48. data/lib/rocket_cms/models/page.rb +7 -3
  49. data/lib/rocket_cms/models/seo.rb +17 -0
  50. data/lib/rocket_cms/seo_helpers.rb +13 -0
  51. data/lib/rocket_cms/version.rb +1 -1
  52. data/template.rb +4 -7
  53. metadata +13 -3
@@ -1,35 +1,29 @@
1
1
  module Seoable
2
2
  extend ActiveSupport::Concern
3
- if RocketCMS.mongoid?
4
- include ::Mongoid::Paperclip
5
- end
6
-
7
- included do
8
- if RocketCMS.mongoid?
9
- field :name, type: String, localize: RocketCMS.configuration.localize
10
- field :h1, type: String, localize: RocketCMS.configuration.localize
11
-
12
- field :title, type: String, localize: RocketCMS.configuration.localize
13
- field :keywords, type: String, localize: RocketCMS.configuration.localize
14
- field :description, type: String, localize: RocketCMS.configuration.localize
15
- field :robots, type: String, localize: RocketCMS.configuration.localize
3
+ LOCALIZED_FIELDS = [:h1, :title, :keywords, :description, :og_title]
4
+ FIELDS = LOCALIZED_FIELDS + [:og_image, :robots]
16
5
 
17
- field :og_title, type: String, localize: RocketCMS.configuration.localize
18
- has_mongoid_attached_file :og_image, styles: {thumb: "800x600>"}
19
- elsif RocketCMS.active_record?
20
- has_attached_file :og_image, styles: {thumb: "800x600>"}
6
+ if Seo.separate_table?
7
+ included do
8
+ has_one :seo, as: :seoable, autosave: true
9
+ accepts_nested_attributes_for :seo
10
+ delegate *FIELDS, to: :seo
11
+ delegate *(FIELDS.map {|f| "#{f}=".to_sym }), to: :seo
12
+ alias seo_without_build seo
13
+ def seo
14
+ seo_without_build || build_seo
15
+ end
16
+ if RocketCMS.config.localize
17
+ delegate *(LOCALIZED_FIELDS.map {|f| "#{f}_translations".to_sym }), to: :seo
18
+ delegate *(LOCALIZED_FIELDS.map {|f| "#{f}_translations=".to_sym }), to: :seo
19
+ end
21
20
  end
22
- validates_attachment_content_type :og_image, content_type: %w(image/gif image/jpeg image/jpg image/png), if: :og_image?
21
+ include RocketCMS::SeoHelpers
22
+ else
23
+ include RocketCMS::Models::Seo
23
24
  end
24
25
 
25
- def page_title
26
- title.blank? ? name : title
27
- end
28
26
 
29
- def get_og_title
30
- og_title.blank? ? name : og_title
31
- end
32
-
33
27
  def self.admin
34
28
  RocketCMS.seo_config
35
29
  end
@@ -37,10 +31,5 @@ module Seoable
37
31
  def og_image_jcrop_options
38
32
  {aspectRation: 800.0/600.0}
39
33
  end
40
-
41
- # deprecated
42
- def self.seo_config
43
- RocketCMS.seo_config
44
- end
45
34
  end
46
35
 
@@ -0,0 +1,16 @@
1
+ if RocketCMS.active_record?
2
+ class Seo < ActiveRecord::Base
3
+ end
4
+ end
5
+
6
+ class Seo
7
+ include RocketCMS::Models::Seo
8
+ RocketCMS.apply_patches self
9
+ rails_admin &RocketCMS.seo_config
10
+ belongs_to :seoable, polymorphic: true
11
+
12
+ def self.separate_table?
13
+ (RocketCMS.mongoid? && RocketCMS.config.separate_seo_table) || (RocketCMS.active_record? && Seo.table_exists?)
14
+ end
15
+ end
16
+
@@ -0,0 +1,21 @@
1
+ h2 Редактирование профиля
2
+ = simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
3
+ /= devise_error_messages!
4
+ .field
5
+ = f.label :email, I18n.t("shared.email")
6
+ br
7
+ = f.email_field :email, autofocus: true
8
+ .field
9
+ = f.label :password
10
+ - if @minimum_password_length
11
+ em
12
+ (Минимум символов: #{@minimum_password_length})
13
+ br
14
+ = f.password_field :password, I18n.t("shared.password"), autocomplete: "off"
15
+ .field
16
+ = f.label :password_confirmation
17
+ br
18
+ = f.password_field :password_confirmation, I18n.t("shared.password_confirmation"), autocomplete: "off"
19
+ .actions
20
+ = f.submit "Зарегистрироваться"
21
+ = render "devise/shared/links"
@@ -0,0 +1,21 @@
1
+ h2 Регистрация
2
+ = simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
3
+ = devise_error_messages!
4
+ .field
5
+ = f.label :email, label: I18n.t("shared.email")
6
+ br
7
+ = f.email_field :email, autofocus: true
8
+ .field
9
+ = f.label :password
10
+ - if @minimum_password_length
11
+ em= " (Минимум символов: #{@minimum_password_length})"
12
+ br
13
+ = f.password_field :password, label: I18n.t("shared.password"), autocomplete: "off"
14
+ .field
15
+ = f.label :password_confirmation
16
+ br
17
+ = f.password_field :password_confirmation, label: I18n.t("shared.password_confirmation"), autocomplete: "off"
18
+ .actions
19
+ = f.submit "Зарегистрироваться"
20
+ br
21
+ = render "devise/shared/links"
@@ -1,23 +1,22 @@
1
- main
2
- h2 Вход на сайт
3
- = form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
4
- .field
5
- = f.label :email, "E-mail"
6
- br
7
- = f.email_field :email, autofocus: true, title: "E-mail"
1
+ h2= I18n.t("shared.enter_site")
2
+ = form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
3
+ .field
4
+ = f.label :email, I18n.t("shared.email")
8
5
  br
9
- .field
10
- = f.label :password, "Пароль"
11
- br
12
- = f.password_field :password, autocomplete: "off", title: "Пароль"
6
+ = f.email_field :email, autofocus: true, title: I18n.t("shared.email")
7
+ br
8
+ .field
9
+ = f.label :password, title: I18n.t("shared.password")
13
10
  br
14
- - if devise_mapping.rememberable?
15
- .field
16
- = f.check_box :remember_me, title: "Запомнить меня"
17
- = f.label :remember_me, "Запомнить меня"
11
+ = f.password_field :password, autocomplete: "off", title: I18n.t("shared.password")
12
+ br
13
+ - if devise_mapping.rememberable?
14
+ .field
15
+ = f.check_box :remember_me, title: I18n.t("shared.remember_me")
16
+ = f.label :remember_me, I18n.t("shared.remember_me")
18
17
 
19
- .actions
20
- = f.submit "Войти"
21
- br
18
+ .actions
19
+ = f.submit I18n.t("shared.enter")
20
+ br
22
21
 
23
- = render "devise/shared/links"
22
+ = render "devise/shared/links"
@@ -1,25 +1,11 @@
1
1
  - if controller_name != 'sessions'
2
- = link_to "Войти на сайт", new_session_path(resource_name)
2
+ = link_to I18n.t("shared.enter_site"), new_session_path(resource_name)
3
3
  br
4
4
 
5
5
  - if devise_mapping.registerable? && controller_name != 'registrations'
6
- = link_to "Зарегистрироваться", new_registration_path(resource_name)
6
+ = link_to I18n.t("shared.registration"), new_registration_path(resource_name)
7
7
  br
8
8
 
9
9
  - if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations'
10
- = link_to "Забыли пароль?", new_password_path(resource_name)
11
- br
12
-
13
-
14
- - if devise_mapping.confirmable? && controller_name != 'confirmations'
15
- = link_to "Не пришли инструкции по подтверждению аккаунта?", new_confirmation_path(resource_name)
16
- br
17
-
18
- /- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks'
19
- / = link_to "Не пришли инстуркции по разблокировке аккаунта?", new_unlock_path(resource_name)
20
- / br
21
-
22
- - if devise_mapping.omniauthable?
23
- - resource_class.omniauth_providers.each do |provider|
24
- = link_to "Войти через #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider)
25
- br
10
+ = link_to I18n.t("shared.forget_password"), new_password_path(resource_name)
11
+ br
@@ -2,7 +2,7 @@
2
2
  h1.rs-news-title= @news.name
3
3
  .rs-news-date= l(@news.time.to_date)
4
4
  .rs-news-text= @news.excerpt
5
- - if !RocketCMS.configuration.news_image_styles.nil? && @news.image?
5
+ - if !RocketCMS.config.news_image_styles.nil? && @news.image?
6
6
  .rs-news-image= image_tag @news.image.url(:main)
7
7
  .rs-news-content
8
8
  = render 'shared/obj', obj: @news
@@ -23,6 +23,6 @@ en:
23
23
  errors:
24
24
  title: "Error %{code}"
25
25
  form_expired: "Token expired"
26
- internal_error: "Internal error"
26
+ internal_error: "Internal error: %{klass} %{message}"
27
27
  access_denied: "Access denied"
28
28
  not_found: 'The requested page was not found on this server'
@@ -23,6 +23,16 @@ ru:
23
23
  errors:
24
24
  title: "Ошибка %{code}"
25
25
  form_expired: "Истекло время на заполение формы"
26
- internal_error: "Внутренняя ошибка"
26
+ internal_error: "Внутренняя ошибка: %{klass} %{message}"
27
27
  access_denied: "Доступ запрещен"
28
28
  not_found: 'Запрашиваемая страница была удалена, или введён некорректный адрес'
29
+
30
+
31
+ shared:
32
+ enter_site: Войти на сайт
33
+ email: E-mail
34
+ password: Пароль
35
+ remember_me: Запомнить меня
36
+ enter: Войти
37
+ registration: Зарегистрироваться
38
+ forget_password: Забыли пароль?
@@ -9,7 +9,7 @@ module RocketCms
9
9
  desc 'RocketCMS migration generator'
10
10
  def install
11
11
  if RocketCMS.active_record?
12
- %w(contact_messages news pages).each do |table_name|
12
+ %w(contact_messages news pages seos).each do |table_name|
13
13
  migration_template "migration_#{table_name}.rb", "db/migrate/rocket_cms_create_#{table_name}.rb"
14
14
  end
15
15
  end
@@ -54,8 +54,16 @@ RailsAdmin.config do |config|
54
54
  end
55
55
 
56
56
  toggle
57
+ <<<<<<< HEAD
57
58
  toggle_menu
58
59
  sitemap
60
+ =======
61
+ toggle_menu do
62
+ visible do
63
+ ['Page'].include? bindings[:abstract_model].model_name
64
+ end
65
+ end
66
+ >>>>>>> upstream/master
59
67
  end
60
68
 
61
69
  config.main_app_name = ['<%= Rails.application.class.name.split('::')[0] %>', 'Админка']
@@ -3,14 +3,19 @@ class RocketCmsCreateNews < ActiveRecord::Migration
3
3
  create_table :news do |t|
4
4
  t.boolean :enabled, default: true, null: false
5
5
  t.timestamp :time, null: false
6
- t.string :name, null: false
7
- t.text :excerpt
8
- t.text :content
6
+
7
+ if RocketCMS.config.localize
8
+ t.column :name_translations, 'hstore', default: {}
9
+ t.column :excerpt_translations, 'hstore', default: {}
10
+ t.column :content_translations, 'hstore', default: {}
11
+ else
12
+ t.string :name, null: false
13
+ t.text :excerpt
14
+ t.text :content
15
+ end
9
16
 
10
17
  t.string :slug, null: false
11
18
  t.attachment :image
12
- RocketCMS::Migration.seo_fields(t)
13
-
14
19
  t.timestamps
15
20
  end
16
21
 
@@ -1,7 +1,12 @@
1
1
  class RocketCmsCreatePages < ActiveRecord::Migration
2
2
  def change
3
3
  create_table :menus do |t|
4
- t.string :name, null: false
4
+
5
+ if RocketCMS.config.localize
6
+ t.column :name_translations, 'hstore'
7
+ else
8
+ t.string :name, null: false
9
+ end
5
10
  t.string :slug, null: false
6
11
  t.timestamps
7
12
  end
@@ -14,14 +19,18 @@ class RocketCmsCreatePages < ActiveRecord::Migration
14
19
  t.integer :rgt
15
20
  t.integer :depth
16
21
 
17
- t.string :slug, null: false
18
- t.attachment :image
22
+ if RocketCMS.config.localize
23
+ t.column :name_translations, 'hstore', default: {}
24
+ t.column :content_translations, 'hstore', default: {}
25
+ else
26
+ t.string :name, null: false
27
+ t.text :content
28
+ end
19
29
 
30
+ t.string :slug, null: false
20
31
  t.string :regexp
21
32
  t.string :redirect
22
- t.text :content
23
33
  t.string :fullpath, null: false
24
- RocketCMS::Migration.seo_fields(t)
25
34
  t.timestamps
26
35
  end
27
36
  add_index :pages, :slug, unique: true
@@ -0,0 +1,14 @@
1
+ class RocketCmsCreateSeos < ActiveRecord::Migration
2
+ def change
3
+ create_table :seos do |t|
4
+ t.boolean :enabled, default: true, null: false
5
+ t.integer :seoable_id
6
+ t.string :seoable_type
7
+ RocketCMS::Migration.seo_fields(t)
8
+ t.timestamps
9
+ end
10
+
11
+ add_index :seos, [:seoable_id, :seoable_type], unique: true
12
+ end
13
+ end
14
+
@@ -29,6 +29,7 @@ require 'turbolinks'
29
29
  require 'simple-navigation'
30
30
  require 'ack_rails_admin_jcrop'
31
31
 
32
+ require 'rocket_cms/seo_helpers'
32
33
  require 'rocket_cms/configuration'
33
34
  require 'rocket_cms/patch'
34
35
  require 'rocket_cms/admin'
@@ -57,6 +58,7 @@ module RocketCMS
57
58
  autoload :Migration, 'rocket_cms/migration'
58
59
 
59
60
  module Models
61
+ autoload :Seo, 'rocket_cms/models/seo'
60
62
  autoload :Menu, 'rocket_cms/models/menu'
61
63
  autoload :Page, 'rocket_cms/models/page'
62
64
  autoload :News, 'rocket_cms/models/news'
@@ -69,6 +71,7 @@ module RocketCMS
69
71
  autoload :Gallery, 'rocket_cms/models/gallery'
70
72
 
71
73
  module Mongoid
74
+ autoload :Seo, 'rocket_cms/models/mongoid/seo'
72
75
  autoload :Menu, 'rocket_cms/models/mongoid/menu'
73
76
  autoload :Page, 'rocket_cms/models/mongoid/page'
74
77
  autoload :News, 'rocket_cms/models/mongoid/news'
@@ -82,6 +85,7 @@ module RocketCMS
82
85
  end
83
86
 
84
87
  module ActiveRecord
88
+ autoload :Seo, 'rocket_cms/models/active_record/seo'
85
89
  autoload :Menu, 'rocket_cms/models/active_record/menu'
86
90
  autoload :Page, 'rocket_cms/models/active_record/page'
87
91
  autoload :News, 'rocket_cms/models/active_record/news'
@@ -20,10 +20,20 @@ module RocketCMS
20
20
  }
21
21
  end
22
22
 
23
- def seo_config(is_active = false)
23
+ def seo_config(is_active = true)
24
24
  Proc.new {
25
- active is_active
26
- label "SEO"
25
+ if respond_to?(:active)
26
+ active is_active
27
+ label "SEO"
28
+ else
29
+ visible false
30
+ end
31
+ RocketCMS.seo_fields(self)
32
+ }
33
+ end
34
+
35
+ def seo_fields(s)
36
+ s.instance_eval do
27
37
  field :h1, :string
28
38
  field :title, :string
29
39
  field :keywords, :text
@@ -31,6 +41,7 @@ module RocketCMS
31
41
  field :robots, :string
32
42
 
33
43
  field :og_title, :string
44
+
34
45
  field :og_image, :jcrop do
35
46
  jcrop_options :og_image_jcrop_options
36
47
  end
@@ -38,7 +49,7 @@ module RocketCMS
38
49
  if block_given?
39
50
  yield
40
51
  end
41
- }
52
+ end
42
53
  end
43
54
 
44
55
  def page_config(fields = {})
@@ -90,12 +101,21 @@ module RocketCMS
90
101
  end
91
102
  end
92
103
  end
93
- group :seo, &RocketCMS.seo_config
104
+ if Seo.separate_table?
105
+ group :seo do
106
+ active true
107
+ field :seo do
108
+ active true
109
+ end
110
+ end
111
+ else
112
+ group :seo, &RocketCMS.seo_config(true)
113
+ end
94
114
  group :sitemap_data, &RocketCMS.sitemap_data_config
95
115
  end
96
116
  RocketCMS.only_patches self, [:show, :export]
97
117
  nested_set({
98
- max_depth: RocketCMS.configuration.menu_max_depth,
118
+ max_depth: RocketCMS.config.menu_max_depth,
99
119
  scopes: []
100
120
  })
101
121
 
@@ -149,9 +169,11 @@ module RocketCMS
149
169
  end
150
170
 
151
171
  field :enabled, :toggle
152
- field :time
172
+ field :time do
173
+ sort_reverse true
174
+ end
153
175
  field :name
154
- unless RocketCMS.configuration.news_image_styles.nil?
176
+ unless RocketCMS.config.news_image_styles.nil?
155
177
  field :image, :jcrop do
156
178
  jcrop_options :image_jcrop_options
157
179
  end
@@ -172,6 +194,11 @@ module RocketCMS
172
194
 
173
195
  RocketCMS.apply_patches self
174
196
 
197
+ list do
198
+ RocketCMS.apply_patches self
199
+ sort_by :time
200
+ end
201
+
175
202
  edit do
176
203
  field :content, :ck_editor
177
204
  fields.each_pair do |name, type|