ack_rocket_cms 0.7.7.1 → 0.8.0
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 +4 -4
- data/Gemfile.lock +45 -45
- data/README.md +64 -5
- data/app/assets/javascripts/{rocket_cms.js.coffee → rocket_cms.coffee} +0 -3
- data/app/controllers/concerns/rs_errors.rb +8 -4
- data/app/controllers/concerns/rs_localizeable.rb +26 -0
- data/app/controllers/concerns/rs_menu.rb +9 -2
- data/app/controllers/concerns/rs_pages.rb +14 -3
- data/app/helpers/gzip_helper.rb +27 -0
- data/app/models/concerns/seoable.rb +19 -30
- data/app/models/seo.rb +16 -0
- data/app/views/devise/registrations/edit.html.slim +21 -0
- data/app/views/devise/registrations/new.html.slim +21 -0
- data/app/views/devise/sessions/new.html.slim +18 -19
- data/app/views/devise/shared/_links.html.slim +4 -18
- data/app/views/news/show.html.slim +1 -1
- data/config/locales/en.rs.yml +1 -1
- data/config/locales/ru.rs.yml +11 -1
- data/lib/generators/rocket_cms/migration_generator.rb +1 -1
- data/lib/generators/rocket_cms/templates/admin.erb +8 -0
- data/lib/generators/rocket_cms/templates/migration_news.rb +10 -5
- data/lib/generators/rocket_cms/templates/migration_pages.rb +14 -5
- data/lib/generators/rocket_cms/templates/migration_seos.rb +14 -0
- data/lib/rocket_cms.rb +4 -0
- data/lib/rocket_cms/admin.rb +35 -8
- data/lib/rocket_cms/configuration.rb +7 -1
- data/lib/rocket_cms/controllers/contacts.rb +2 -2
- data/lib/rocket_cms/controllers/news.rb +1 -1
- data/lib/rocket_cms/controllers/search.rb +17 -0
- data/lib/rocket_cms/engine.rb +3 -3
- data/lib/rocket_cms/migration.rb +14 -11
- data/lib/rocket_cms/models/active_record/menu.rb +3 -0
- data/lib/rocket_cms/models/active_record/news.rb +6 -3
- data/lib/rocket_cms/models/active_record/page.rb +3 -0
- data/lib/rocket_cms/models/active_record/seo.rb +17 -0
- data/lib/rocket_cms/models/contact_message.rb +1 -1
- data/lib/rocket_cms/models/embedded_gallery_image.rb +4 -0
- data/lib/rocket_cms/models/gallery.rb +2 -0
- data/lib/rocket_cms/models/gallery_image.rb +2 -0
- data/lib/rocket_cms/models/mongoid/contact_message.rb +5 -5
- data/lib/rocket_cms/models/mongoid/embedded_gallery_image.rb +0 -1
- data/lib/rocket_cms/models/mongoid/gallery.rb +0 -1
- data/lib/rocket_cms/models/mongoid/gallery_image.rb +0 -1
- data/lib/rocket_cms/models/mongoid/news.rb +3 -4
- data/lib/rocket_cms/models/mongoid/page.rb +3 -2
- data/lib/rocket_cms/models/mongoid/seo.rb +23 -0
- data/lib/rocket_cms/models/news.rb +13 -5
- data/lib/rocket_cms/models/page.rb +7 -3
- data/lib/rocket_cms/models/seo.rb +17 -0
- data/lib/rocket_cms/seo_helpers.rb +13 -0
- data/lib/rocket_cms/version.rb +1 -1
- data/template.rb +4 -7
- metadata +13 -3
@@ -1,35 +1,29 @@
|
|
1
1
|
module Seoable
|
2
2
|
extend ActiveSupport::Concern
|
3
|
-
|
4
|
-
|
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
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
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
|
-
|
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
|
|
data/app/models/seo.rb
ADDED
@@ -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
|
-
|
2
|
-
|
3
|
-
|
4
|
-
.
|
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
|
-
.
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
18
|
+
.actions
|
19
|
+
= f.submit I18n.t("shared.enter")
|
20
|
+
br
|
22
21
|
|
23
|
-
|
22
|
+
= render "devise/shared/links"
|
@@ -1,25 +1,11 @@
|
|
1
1
|
- if controller_name != 'sessions'
|
2
|
-
= link_to "
|
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 "
|
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 "
|
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.
|
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
|
data/config/locales/en.rs.yml
CHANGED
@@ -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'
|
data/config/locales/ru.rs.yml
CHANGED
@@ -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
|
-
|
7
|
-
|
8
|
-
|
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
|
-
|
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
|
-
|
18
|
-
|
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
|
+
|
data/lib/rocket_cms.rb
CHANGED
@@ -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'
|
data/lib/rocket_cms/admin.rb
CHANGED
@@ -20,10 +20,20 @@ module RocketCMS
|
|
20
20
|
}
|
21
21
|
end
|
22
22
|
|
23
|
-
def seo_config(is_active =
|
23
|
+
def seo_config(is_active = true)
|
24
24
|
Proc.new {
|
25
|
-
active
|
26
|
-
|
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
|
-
|
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.
|
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.
|
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|
|