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.
- 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|
|