pages_core 3.4.3 → 3.5.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.
- checksums.yaml +4 -4
- data/README.md +81 -15
- data/Rakefile +1 -1
- data/app/assets/javascripts/pages/admin.es6.jsx +19 -0
- data/app/assets/javascripts/pages/admin/components.es6.jsx +1 -0
- data/app/assets/javascripts/pages/admin/components/page_tree.es6.jsx +330 -0
- data/app/assets/javascripts/pages/admin/components/page_tree_actions.es6.jsx +8 -0
- data/app/assets/javascripts/pages/admin/components/page_tree_node.es6.jsx +374 -0
- data/app/assets/javascripts/pages/admin/components/page_tree_store.es6.jsx +161 -0
- data/app/assets/javascripts/pages/admin/features/content_tabs.es6.jsx +63 -0
- data/app/assets/javascripts/pages/admin/features/edit_page.es6.jsx +141 -0
- data/app/assets/javascripts/pages/admin/features/editable_image.es6.jsx +145 -0
- data/app/assets/javascripts/pages/admin/features/modal.es6.jsx +90 -0
- data/app/assets/javascripts/pages/admin/features/page_images.es6.jsx +338 -0
- data/app/assets/javascripts/pages/admin/features/rich_text.es6.jsx +124 -0
- data/app/assets/javascripts/pages/admin/features/tag_editor.es6.jsx +160 -0
- data/app/assets/javascripts/pages/admin/lib/ajax_extensions.es6.jsx +21 -0
- data/app/assets/javascripts/pages/admin/lib/center_on_screen.es6.jsx +22 -0
- data/app/assets/javascripts/pages/admin/lib/tree.es6.jsx +294 -0
- data/app/assets/javascripts/pages/login_form.es6.jsx +21 -0
- data/app/assets/stylesheets/pages/admin.scss +148 -0
- data/app/assets/stylesheets/pages/admin/components/buttons.scss +5 -0
- data/app/assets/stylesheets/pages/admin/{editable_image.css.erb → components/editable_image.scss} +7 -8
- data/app/assets/stylesheets/pages/admin/components/forms.scss +71 -0
- data/app/assets/stylesheets/pages/admin/components/header.scss +169 -0
- data/app/assets/stylesheets/pages/admin/{images.css.scss.erb → components/images.scss} +6 -11
- data/app/assets/stylesheets/pages/admin/components/layout.scss +44 -0
- data/app/assets/stylesheets/pages/admin/components/links.scss +43 -0
- data/app/assets/stylesheets/pages/admin/components/list_table.scss +58 -0
- data/app/assets/stylesheets/pages/admin/{login.css.scss.erb → components/login.scss} +1 -1
- data/app/assets/stylesheets/pages/admin/{modal.css.erb → components/modal.scss} +3 -2
- data/app/assets/stylesheets/pages/admin/components/page_tree.scss +173 -0
- data/app/assets/stylesheets/pages/admin/{pagination.css.scss → components/pagination.scss} +13 -4
- data/app/assets/stylesheets/pages/admin/components/sidebar.scss +25 -0
- data/app/assets/stylesheets/pages/admin/{tag_editor.css.scss.erb → components/tag_editor.scss} +6 -0
- data/app/assets/stylesheets/pages/admin/components/textarea.scss +76 -0
- data/app/assets/stylesheets/pages/admin/controllers/pages.scss +196 -0
- data/app/assets/stylesheets/pages/admin/controllers/{users.css.erb → users.scss} +0 -0
- data/app/assets/stylesheets/pages/admin/mixins/breakpoints.scss +21 -0
- data/app/assets/stylesheets/pages/admin/mixins/clearfix.scss +7 -0
- data/app/assets/stylesheets/pages/admin/mixins/gradients.scss +7 -0
- data/app/assets/stylesheets/pages/admin/{print.css.erb → print.scss} +0 -0
- data/app/assets/stylesheets/pages/admin/vars.scss +8 -0
- data/app/controllers/admin/invites_controller.rb +10 -6
- data/app/controllers/admin/page_files_controller.rb +6 -8
- data/app/controllers/admin/page_images_controller.rb +14 -19
- data/app/controllers/admin/pages_controller.rb +44 -97
- data/app/controllers/admin/password_resets_controller.rb +7 -2
- data/app/controllers/concerns/pages_core/add_comments_controller.rb +67 -0
- data/app/controllers/concerns/pages_core/admin/news_page_controller.rb +58 -0
- data/app/controllers/concerns/pages_core/authentication.rb +1 -1
- data/app/controllers/concerns/pages_core/exception_handler.rb +44 -21
- data/app/controllers/concerns/pages_core/policies_helper.rb +10 -6
- data/app/controllers/concerns/pages_core/preview_pages_controller.rb +43 -0
- data/app/controllers/concerns/pages_core/process_titler.rb +2 -2
- data/app/controllers/concerns/pages_core/rss_controller.rb +25 -0
- data/app/controllers/concerns/pages_core/search_pages_controller.rb +40 -0
- data/app/controllers/errors_controller.rb +14 -2
- data/app/controllers/pages_core/admin_controller.rb +7 -5
- data/app/controllers/pages_core/frontend/page_files_controller.rb +5 -7
- data/app/controllers/pages_core/frontend/pages_controller.rb +41 -219
- data/app/controllers/pages_core/frontend_controller.rb +8 -2
- data/app/controllers/pages_core/sitemaps_controller.rb +5 -4
- data/app/formatters/pages_core/html_formatter.rb +33 -23
- data/app/helpers/admin/menu_helper.rb +12 -9
- data/app/helpers/admin/pages_helper.rb +40 -28
- data/app/helpers/pages_core/admin/admin_helper.rb +58 -56
- data/app/helpers/pages_core/admin/labelled_field_helper.rb +6 -7
- data/app/helpers/pages_core/admin/tag_editor_helper.rb +11 -9
- data/app/helpers/pages_core/application_helper.rb +13 -26
- data/app/helpers/pages_core/form_builder.rb +71 -134
- data/app/helpers/pages_core/head_tags_helper.rb +26 -168
- data/app/helpers/pages_core/images_helper.rb +3 -3
- data/app/helpers/pages_core/meta_tags_helper.rb +96 -0
- data/app/helpers/pages_core/open_graph_tags_helper.rb +51 -0
- data/app/helpers/pages_core/page_path_helper.rb +40 -0
- data/app/mailers/admin_mailer.rb +14 -14
- data/app/models/autopublisher.rb +2 -2
- data/app/models/category.rb +8 -8
- data/app/models/concerns/pages_core/has_roles.rb +2 -2
- data/app/models/concerns/pages_core/humanizable_param.rb +5 -5
- data/app/models/concerns/pages_core/page_model/autopublishable.rb +25 -0
- data/app/models/concerns/pages_core/page_model/commentable.rb +29 -0
- data/app/models/concerns/pages_core/page_model/images.rb +50 -0
- data/app/models/concerns/pages_core/page_model/localizable.rb +29 -0
- data/app/models/concerns/pages_core/page_model/pathable.rb +115 -0
- data/app/models/concerns/pages_core/page_model/redirectable.rb +36 -0
- data/app/models/concerns/pages_core/page_model/searchable.rb +41 -0
- data/app/models/concerns/pages_core/page_model/sortable.rb +54 -0
- data/app/models/concerns/pages_core/page_model/status.rb +50 -0
- data/app/models/concerns/pages_core/page_model/templateable.rb +82 -0
- data/app/models/concerns/pages_core/page_model/tree.rb +108 -0
- data/app/models/page.rb +30 -212
- data/app/models/page_builder.rb +4 -6
- data/app/models/page_category.rb +7 -0
- data/app/models/page_comment.rb +1 -1
- data/app/models/page_file.rb +4 -6
- data/app/models/page_image.rb +6 -7
- data/app/models/page_path.rb +46 -0
- data/app/models/password_reset_token.rb +5 -5
- data/app/models/role.rb +1 -1
- data/app/models/tag.rb +14 -16
- data/app/models/tagging.rb +2 -1
- data/app/models/user.rb +6 -7
- data/app/policies/page_policy.rb +8 -4
- data/app/policies/user_policy.rb +1 -1
- data/app/serializers/page_tree_serializer.rb +15 -0
- data/app/views/admin/invites/new.html.erb +2 -1
- data/app/views/admin/invites/show.html.erb +3 -4
- data/app/views/admin/pages/_edit_comments.html.erb +22 -6
- data/app/views/admin/pages/_edit_content.html.erb +4 -2
- data/app/views/admin/pages/_edit_images.html.erb +86 -75
- data/app/views/admin/pages/_edit_metadata.html.erb +22 -0
- data/app/views/admin/pages/_edit_options.html.erb +23 -15
- data/app/views/admin/pages/_pagelisting.html.erb +6 -6
- data/app/views/admin/pages/edit.html.erb +11 -6
- data/app/views/admin/pages/index.html.erb +12 -53
- data/app/views/admin/pages/new.html.erb +3 -3
- data/app/views/admin/pages/news.html.erb +1 -1
- data/app/views/admin_mailer/invite.text.erb +1 -1
- data/app/views/admin_mailer/password_reset.text.erb +1 -1
- data/app/views/errors/422.html.erb +7 -0
- data/app/views/errors/500_critical.html.erb +1 -1
- data/app/views/layouts/admin.html.erb +36 -32
- data/app/views/layouts/admin/_header.html.erb +2 -2
- data/config/locales/en.yml +38 -1
- data/config/routes.rb +40 -23
- data/db/migrate/20111219033112_create_pages_tables.rb +25 -29
- data/db/migrate/20121010055412_drop_removed_tables.rb +3 -3
- data/db/migrate/20130823133208_update_page_redirect_to.rb +0 -13
- data/db/migrate/20140203183900_create_roles.rb +5 -2
- data/db/migrate/20140920231700_convert_images_to_dis.rb +4 -2
- data/db/migrate/20150401131300_localize_images.rb +7 -8
- data/db/migrate/20151002174800_create_page_paths.rb +10 -0
- data/db/migrate/20151021103400_drop_binaries_table.rb +7 -0
- data/db/migrate/20151204151000_remove_page_content_order.rb +5 -0
- data/db/migrate/20160330220900_rename_pages_categories.rb +6 -0
- data/db/migrate/20160405202700_change_localization_limit.rb +9 -0
- data/lib/pages_core.rb +22 -27
- data/lib/pages_core/admin_menu_item.rb +16 -3
- data/lib/pages_core/archive_finder.rb +40 -13
- data/lib/pages_core/cache_sweeper.rb +72 -45
- data/lib/pages_core/configuration.rb +2 -2
- data/lib/pages_core/configuration/base.rb +4 -8
- data/lib/pages_core/configuration/pages.rb +6 -3
- data/lib/pages_core/engine.rb +23 -1
- data/lib/pages_core/extensions.rb +2 -2
- data/lib/pages_core/file_embedder.rb +40 -0
- data/lib/pages_core/page_path_constraint.rb +23 -0
- data/lib/pages_core/pages_plugin.rb +11 -0
- data/lib/pages_core/paginates.rb +3 -3
- data/lib/pages_core/plugin.rb +14 -8
- data/lib/pages_core/templates.rb +6 -6
- data/lib/pages_core/templates/block_configuration.rb +1 -1
- data/lib/pages_core/templates/configuration.rb +23 -24
- data/lib/pages_core/templates/configuration_handler.rb +1 -1
- data/lib/pages_core/templates/configuration_proxy.rb +7 -11
- data/lib/pages_core/templates/template_configuration.rb +55 -61
- data/lib/pages_core/version.rb +1 -1
- data/lib/rails/generators/pages_core/install/install_generator.rb +22 -48
- data/lib/rails/generators/pages_core/install/templates/page_templates_initializer.rb +1 -1
- data/lib/rails/generators/pages_core/install/templates/pages_initializer.rb +6 -3
- data/lib/rails/generators/pages_core/rspec/rspec_generator.rb +4 -1
- data/lib/rails/generators/pages_core/rspec/templates/factories.rb +1 -1
- data/lib/tasks/pages.rake +4 -4
- data/lib/tasks/pages/page_paths.rake +12 -0
- data/template.rb +2 -2
- data/vendor/assets/javascripts/reflux.min.js +1 -0
- metadata +173 -85
- data/app/assets/images/pages/admin/description-bg.gif +0 -0
- data/app/assets/images/pages/admin/drag-handle.gif +0 -0
- data/app/assets/images/pages/admin/flash-error-bg.gif +0 -0
- data/app/assets/images/pages/admin/formelement-bg.gif +0 -0
- data/app/assets/images/pages/admin/header-tab-current-bg.gif +0 -0
- data/app/assets/images/pages/admin/list-table-td-bg.gif +0 -0
- data/app/assets/images/pages/admin/sidebar-bg.gif +0 -0
- data/app/assets/images/pages/admin/textarea_controls.gif +0 -0
- data/app/assets/javascripts/pages/admin.js.coffee +0 -54
- data/app/assets/javascripts/pages/admin/controllers/base.js.coffee +0 -4
- data/app/assets/javascripts/pages/admin/controllers/pages_controller.js.coffee +0 -139
- data/app/assets/javascripts/pages/admin/controllers/users_controller.js.coffee +0 -9
- data/app/assets/javascripts/pages/admin/features/content_tabs.js.coffee +0 -47
- data/app/assets/javascripts/pages/admin/features/editable_image.js.coffee.erb +0 -122
- data/app/assets/javascripts/pages/admin/features/modal.js.coffee +0 -66
- data/app/assets/javascripts/pages/admin/features/page_images.js +0 -329
- data/app/assets/javascripts/pages/admin/features/rich_text.js.coffee +0 -40
- data/app/assets/javascripts/pages/admin/features/tag_editor.js +0 -159
- data/app/assets/javascripts/pages/admin/lib/ajax_extensions.js.coffee +0 -17
- data/app/assets/javascripts/pages/admin/lib/center_on_screen.js.coffee +0 -21
- data/app/assets/javascripts/pages/admin/lib/jrichtextarea.js +0 -57
- data/app/assets/javascripts/pages/login_form.js.coffee +0 -17
- data/app/assets/stylesheets/pages/admin.css.erb +0 -404
- data/app/assets/stylesheets/pages/admin/buttons.css.erb +0 -5
- data/app/assets/stylesheets/pages/admin/controllers/artists.css.erb +0 -94
- data/app/assets/stylesheets/pages/admin/controllers/files.css.erb +0 -58
- data/app/assets/stylesheets/pages/admin/controllers/pages.css.scss.erb +0 -178
- data/app/assets/stylesheets/pages/admin/forms.css.scss.erb +0 -73
- data/app/assets/stylesheets/pages/admin/header.css.erb +0 -129
- data/app/assets/stylesheets/pages/admin/links.css.erb +0 -34
- data/app/assets/stylesheets/pages/admin/list_table.css.erb +0 -56
- data/app/assets/stylesheets/pages/admin/sidebar.css.erb +0 -39
- data/app/assets/stylesheets/pages/admin/sortable_images.css.erb +0 -18
- data/app/assets/stylesheets/pages/admin/textarea.css.erb +0 -55
- data/app/models/concerns/pages_core/page_tree.rb +0 -85
- data/app/models/concerns/pages_core/searchable_page.rb +0 -33
- data/app/models/concerns/pages_core/templateable.rb +0 -85
- data/app/models/localization.rb +0 -27
- data/db/migrate/20140515130100_remove_sphinx_deltas.rb +0 -15
- data/lib/pages_core/localizable.rb +0 -49
- data/lib/pages_core/localizable/active_record_extension.rb +0 -41
- data/lib/pages_core/localizable/class_methods.rb +0 -51
- data/lib/pages_core/localizable/configuration.rb +0 -50
- data/lib/pages_core/localizable/instance_methods.rb +0 -130
- data/lib/pages_core/localizable/localizer.rb +0 -72
- data/lib/pages_core/localizable/scope_extension.rb +0 -22
|
@@ -8,10 +8,7 @@ module PagesCore
|
|
|
8
8
|
|
|
9
9
|
module ClassMethods
|
|
10
10
|
def require_authorization(collection, member, options = {})
|
|
11
|
-
options =
|
|
12
|
-
collection: [:index, :new, :create],
|
|
13
|
-
member: [:show, :edit, :update, :destroy]
|
|
14
|
-
}.merge(options)
|
|
11
|
+
options = default_options.merge(options)
|
|
15
12
|
before_action do |controller|
|
|
16
13
|
action = params[:action].to_sym
|
|
17
14
|
if options[:collection].include?(action)
|
|
@@ -21,6 +18,13 @@ module PagesCore
|
|
|
21
18
|
end
|
|
22
19
|
end
|
|
23
20
|
end
|
|
21
|
+
|
|
22
|
+
def default_options
|
|
23
|
+
{
|
|
24
|
+
collection: [:index, :new, :create],
|
|
25
|
+
member: [:show, :edit, :update, :destroy]
|
|
26
|
+
}
|
|
27
|
+
end
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
def policy(object)
|
|
@@ -33,8 +37,8 @@ module PagesCore
|
|
|
33
37
|
end
|
|
34
38
|
|
|
35
39
|
def verify_policy(record)
|
|
36
|
-
return true if policy(record).public_send(
|
|
37
|
-
|
|
40
|
+
return true if policy(record).public_send(action_name + "?")
|
|
41
|
+
raise PagesCore::NotAuthorized
|
|
38
42
|
end
|
|
39
43
|
end
|
|
40
44
|
end
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module PagesCore
|
|
4
|
+
module PreviewPagesController
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
included do
|
|
8
|
+
before_action :disable_xss_protection, only: [:preview]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def preview
|
|
12
|
+
redirect_to(page_url(@locale, @page)) && return unless logged_in?
|
|
13
|
+
@page.attributes = page_params.merge(
|
|
14
|
+
status: 2,
|
|
15
|
+
published_at: Time.zone.now,
|
|
16
|
+
locale: @locale,
|
|
17
|
+
redirect_to: nil
|
|
18
|
+
)
|
|
19
|
+
render_page
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def disable_xss_protection
|
|
25
|
+
# Disabling this is probably not a good idea,
|
|
26
|
+
# but the header causes Chrome to choke when being
|
|
27
|
+
# redirected back after a submit and the page contains an iframe.
|
|
28
|
+
response.headers["X-XSS-Protection"] = "0"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def permitted_page_attributes
|
|
32
|
+
[:template, :user_id, :status, :feed_enabled, :published_at,
|
|
33
|
+
:redirect_to, :comments_allowed, :image_link, :news_page,
|
|
34
|
+
:unique_name, :pinned, :parent_page_id]
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def page_params
|
|
38
|
+
params.require(:page).permit(
|
|
39
|
+
Page.localized_attributes + permitted_page_attributes
|
|
40
|
+
)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -32,13 +32,13 @@ module PagesCore
|
|
|
32
32
|
def set_process_title
|
|
33
33
|
PagesCore::ProcessTitler.inc_number_of_requests do |i|
|
|
34
34
|
$0 = PagesCore::ProcessTitler.original_title +
|
|
35
|
-
|
|
35
|
+
": Handling #{request.path} (#{i} reqs)"
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def unset_process_title
|
|
40
40
|
$0 = PagesCore::ProcessTitler.original_title +
|
|
41
|
-
|
|
41
|
+
": Idle (#{PagesCore::ProcessTitler.number_of_requests} reqs)"
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module PagesCore
|
|
4
|
+
module RssController
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
private
|
|
8
|
+
|
|
9
|
+
def all_feed_items
|
|
10
|
+
feeds = Page.enabled_feeds(locale, include_hidden: true)
|
|
11
|
+
Page.where(parent_page_id: feeds)
|
|
12
|
+
.order("published_at DESC")
|
|
13
|
+
.published
|
|
14
|
+
.limit(20)
|
|
15
|
+
.localized(locale)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def render_rss(items, title: nil)
|
|
19
|
+
@title = PagesCore.config.site_name
|
|
20
|
+
@title += ": #{title}" if title
|
|
21
|
+
@items = items
|
|
22
|
+
render template: "feeds/pages", layout: false
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
module PagesCore
|
|
4
|
+
module SearchPagesController
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
def search
|
|
8
|
+
@search_query = params[:q] || params[:query] || ""
|
|
9
|
+
@search_category_id = params[:category_id]
|
|
10
|
+
|
|
11
|
+
@pages = Page.search(
|
|
12
|
+
normalize_search_query(@search_query),
|
|
13
|
+
search_options(category_id: @search_category_id)
|
|
14
|
+
)
|
|
15
|
+
@pages.each { |p| p.localize!(locale) }
|
|
16
|
+
@pages
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def normalize_search_query(str)
|
|
22
|
+
str.split(/\s+/)
|
|
23
|
+
.map { |p| "#{p}*" }
|
|
24
|
+
.join(" ")
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def search_options(category_id: nil)
|
|
28
|
+
options = {
|
|
29
|
+
page: (params[:page] || 1).to_i,
|
|
30
|
+
per_page: 20,
|
|
31
|
+
include: [:localizations, :categories, :image, :author],
|
|
32
|
+
order: :published_at,
|
|
33
|
+
sort_mode: :desc,
|
|
34
|
+
with: { status: 2, autopublish: 0 }
|
|
35
|
+
}
|
|
36
|
+
options[:with][:category_ids] = category_id unless category_id.blank?
|
|
37
|
+
options
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -19,6 +19,18 @@ class ErrorsController < ::ApplicationController
|
|
|
19
19
|
render_error params[:id].to_i
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
def not_found
|
|
23
|
+
render_error 404
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def unacceptable
|
|
27
|
+
render_error 422
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def internal_error
|
|
31
|
+
render_error 500
|
|
32
|
+
end
|
|
33
|
+
|
|
22
34
|
private
|
|
23
35
|
|
|
24
36
|
def deliver_error_report(report, from, description)
|
|
@@ -39,7 +51,7 @@ class ErrorsController < ::ApplicationController
|
|
|
39
51
|
|
|
40
52
|
def error_report_path
|
|
41
53
|
Rails.root
|
|
42
|
-
|
|
43
|
-
|
|
54
|
+
.join("log", "error_reports")
|
|
55
|
+
.join("#{session[:error_report]}.yml")
|
|
44
56
|
end
|
|
45
57
|
end
|
|
@@ -11,6 +11,13 @@ module PagesCore
|
|
|
11
11
|
|
|
12
12
|
layout "admin"
|
|
13
13
|
|
|
14
|
+
class << self
|
|
15
|
+
# Get name of class with in lowercase, with underscores.
|
|
16
|
+
def underscore
|
|
17
|
+
ActiveSupport::Inflector.underscore(to_s).split("/").last
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
14
21
|
def redirect
|
|
15
22
|
if Page.news_pages.any?
|
|
16
23
|
redirect_to news_admin_pages_url(@locale)
|
|
@@ -65,11 +72,6 @@ module PagesCore
|
|
|
65
72
|
|
|
66
73
|
# --- HELPERS ---
|
|
67
74
|
|
|
68
|
-
# Get name of class with in lowercase, with underscores.
|
|
69
|
-
def self.underscore
|
|
70
|
-
ActiveSupport::Inflector.underscore(to_s).split(/\//).last
|
|
71
|
-
end
|
|
72
|
-
|
|
73
75
|
# Add a stylesheet
|
|
74
76
|
def add_stylesheet(css_file)
|
|
75
77
|
@admin_stylesheets ||= []
|
|
@@ -6,7 +6,7 @@ module PagesCore
|
|
|
6
6
|
before_action :find_page_file, only: [:show, :edit, :update, :destroy]
|
|
7
7
|
|
|
8
8
|
def show
|
|
9
|
-
|
|
9
|
+
unless modified?(@page_file)
|
|
10
10
|
render(text: "304 Not Modified", status: 304) && return
|
|
11
11
|
end
|
|
12
12
|
|
|
@@ -14,12 +14,10 @@ module PagesCore
|
|
|
14
14
|
response.headers["Last-Modified"] = @page_file.updated_at.httpdate
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
send_data(
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
disposition: "attachment"
|
|
22
|
-
)
|
|
17
|
+
send_data(@page_file.data,
|
|
18
|
+
filename: @page_file.filename,
|
|
19
|
+
type: @page_file.content_type,
|
|
20
|
+
disposition: "attachment")
|
|
23
21
|
end
|
|
24
22
|
|
|
25
23
|
private
|
|
@@ -7,113 +7,37 @@ module PagesCore
|
|
|
7
7
|
include PagesCore::Templates::ControllerActions
|
|
8
8
|
include PagesCore::HeadTagsHelper
|
|
9
9
|
|
|
10
|
+
include PagesCore::AddCommentsController
|
|
11
|
+
include PagesCore::PreviewPagesController
|
|
12
|
+
include PagesCore::RssController
|
|
13
|
+
include PagesCore::SearchPagesController
|
|
14
|
+
|
|
10
15
|
caches_page :index if PagesCore.config(:page_cache)
|
|
11
16
|
|
|
12
|
-
before_action :disable_xss_protection, only: [:preview]
|
|
13
17
|
before_action :load_root_pages
|
|
18
|
+
before_action :find_page_by_path, only: [:show]
|
|
14
19
|
before_action :find_page, only: [:show, :preview, :add_comment]
|
|
20
|
+
before_action :require_page, only: [:show, :preview, :add_comment]
|
|
15
21
|
before_action :canonicalize_url, only: [:show]
|
|
16
22
|
after_action :cache_page_request, only: [:show]
|
|
17
23
|
|
|
18
24
|
def index
|
|
19
25
|
respond_to do |format|
|
|
20
|
-
format.html
|
|
21
|
-
|
|
22
|
-
no_page_given
|
|
23
|
-
elsif root_pages.any?
|
|
24
|
-
@page = root_pages.first
|
|
25
|
-
render_page
|
|
26
|
-
else
|
|
27
|
-
render_error 404
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
format.rss do
|
|
31
|
-
render_rss(all_feed_items)
|
|
32
|
-
end
|
|
26
|
+
format.html { render_published_page(root_pages.try(&:first)) }
|
|
27
|
+
format.rss { render_rss(all_feed_items) }
|
|
33
28
|
end
|
|
34
29
|
end
|
|
35
30
|
|
|
36
31
|
def show
|
|
37
32
|
respond_to do |format|
|
|
38
|
-
format.html
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
else
|
|
42
|
-
render_error 404
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
format.rss do
|
|
46
|
-
render_rss(
|
|
47
|
-
@page.pages.limit(20),
|
|
48
|
-
title: "#{PagesCore.config(:side_name)}: #{@page.name}"
|
|
49
|
-
)
|
|
50
|
-
end
|
|
51
|
-
format.json do
|
|
52
|
-
render json: @page
|
|
53
|
-
end
|
|
33
|
+
format.html { render_published_page(@page) }
|
|
34
|
+
format.rss { render_rss(@page.pages.limit(20), title: @page.name) }
|
|
35
|
+
format.json { render json: @page }
|
|
54
36
|
end
|
|
55
37
|
end
|
|
56
38
|
|
|
57
|
-
# Add a comment to a page. Recaptcha is performed if
|
|
58
|
-
# PagesCore.config(:recaptcha) is set.
|
|
59
|
-
def add_comment
|
|
60
|
-
@comment = new_comment(@page)
|
|
61
|
-
|
|
62
|
-
unless captcha_verified?
|
|
63
|
-
@comment.invalid_captcha = true
|
|
64
|
-
render_page
|
|
65
|
-
return
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
if @page.comments_allowed? && !honeypot_triggered?
|
|
69
|
-
@comment.save
|
|
70
|
-
if PagesCore.config(:comment_notifications)
|
|
71
|
-
deliver_comment_notifications(@page, @comment)
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
redirect_to(page_url(@locale, @page))
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
# Search pages
|
|
79
|
-
def search
|
|
80
|
-
@search_query = params[:q] || params[:query] || ""
|
|
81
|
-
@search_category_id = params[:category_id]
|
|
82
|
-
|
|
83
|
-
@pages = Page.search(
|
|
84
|
-
normalize_search_query(@search_query),
|
|
85
|
-
search_options(category_id: @search_category_id)
|
|
86
|
-
)
|
|
87
|
-
@pages.each { |p| p.localize!(locale) }
|
|
88
|
-
@pages
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def preview
|
|
92
|
-
redirect_to(page_url(@locale, @page)) && return unless logged_in?
|
|
93
|
-
|
|
94
|
-
@page.attributes = page_params.merge(
|
|
95
|
-
status: 2,
|
|
96
|
-
published_at: Time.now,
|
|
97
|
-
locale: @locale,
|
|
98
|
-
redirect_to: nil
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
render_page
|
|
102
|
-
end
|
|
103
|
-
|
|
104
39
|
private
|
|
105
40
|
|
|
106
|
-
def all_feed_items
|
|
107
|
-
Page
|
|
108
|
-
.where(
|
|
109
|
-
parent_page_id: Page.enabled_feeds(locale, include_hidden: true)
|
|
110
|
-
)
|
|
111
|
-
.order("published_at DESC")
|
|
112
|
-
.published
|
|
113
|
-
.limit(20)
|
|
114
|
-
.localized(locale)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
41
|
def canonical_path(page)
|
|
118
42
|
if page.redirects?
|
|
119
43
|
page.redirect_path(locale: page.locale)
|
|
@@ -123,22 +47,11 @@ module PagesCore
|
|
|
123
47
|
end
|
|
124
48
|
|
|
125
49
|
def canonicalize_url
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def disable_xss_protection
|
|
134
|
-
# Disabling this is probably not a good idea,
|
|
135
|
-
# but the header causes Chrome to choke when being
|
|
136
|
-
# redirected back after a submit and the page contains an iframe.
|
|
137
|
-
response.headers['X-XSS-Protection'] = "0"
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def preview?
|
|
141
|
-
@page.new_record?
|
|
50
|
+
return if @page.redirects?
|
|
51
|
+
return if request.path == canonical_path(@page)
|
|
52
|
+
# Don't canonicalize if any unknown params are present
|
|
53
|
+
return if (params.keys - %w(controller action path locale id)).any?
|
|
54
|
+
redirect_to(canonical_path(@page), status: :moved_permanently)
|
|
142
55
|
end
|
|
143
56
|
|
|
144
57
|
def render(*args)
|
|
@@ -151,10 +64,6 @@ module PagesCore
|
|
|
151
64
|
super
|
|
152
65
|
end
|
|
153
66
|
|
|
154
|
-
def rendered?
|
|
155
|
-
@already_rendered ? true : false
|
|
156
|
-
end
|
|
157
|
-
|
|
158
67
|
def page_template(page)
|
|
159
68
|
if PagesCore::Templates.names.include?(page.template)
|
|
160
69
|
page.template
|
|
@@ -164,144 +73,57 @@ module PagesCore
|
|
|
164
73
|
end
|
|
165
74
|
|
|
166
75
|
def render_page
|
|
167
|
-
if @page
|
|
168
|
-
redirect_to(@page.redirect_path(locale: @locale))
|
|
169
|
-
return
|
|
170
|
-
end
|
|
76
|
+
return if redirect_page(@page)
|
|
171
77
|
|
|
172
78
|
unless document_title?
|
|
173
|
-
|
|
174
|
-
document_title(@page.meta_title)
|
|
175
|
-
else
|
|
176
|
-
document_title(@page.name)
|
|
177
|
-
end
|
|
79
|
+
document_title(@page.meta_title? ? @page.meta_title : @page.name)
|
|
178
80
|
end
|
|
179
81
|
|
|
180
|
-
# Call template method
|
|
181
82
|
template = page_template(@page)
|
|
182
|
-
|
|
183
83
|
run_template_actions_for(template, @page)
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
return if rendered?
|
|
188
|
-
|
|
189
|
-
if instance_variables.include?("@page_template_layout")
|
|
190
|
-
render(
|
|
191
|
-
template: "pages/templates/#{template}",
|
|
192
|
-
layout: @page_template_layout
|
|
193
|
-
)
|
|
194
|
-
else
|
|
195
|
-
render template: "pages/templates/#{template}"
|
|
196
|
-
end
|
|
84
|
+
return if @already_rendered
|
|
85
|
+
render template: "pages/templates/#{template}"
|
|
197
86
|
end
|
|
198
87
|
|
|
199
88
|
# Cache pages by hand. This is dirty, but it works.
|
|
200
89
|
def cache_page_request
|
|
201
90
|
status_code = response.status.try(&:to_i)
|
|
202
91
|
unless status_code == 200 &&
|
|
203
|
-
|
|
204
|
-
|
|
92
|
+
PagesCore.config(:page_cache) &&
|
|
93
|
+
@page && @locale
|
|
205
94
|
return
|
|
206
95
|
end
|
|
207
96
|
|
|
208
97
|
self.class.cache_page response.body, request.path
|
|
209
98
|
end
|
|
210
99
|
|
|
211
|
-
def
|
|
212
|
-
[
|
|
213
|
-
|
|
214
|
-
:feed_enabled, :published_at, :redirect_to, :comments_allowed,
|
|
215
|
-
:image_link, :news_page, :unique_name, :pinned,
|
|
216
|
-
:parent_page_id
|
|
217
|
-
]
|
|
218
|
-
end
|
|
219
|
-
|
|
220
|
-
def page_params
|
|
221
|
-
params.require(:page).permit(
|
|
222
|
-
Page.localized_attributes + permitted_page_attributes
|
|
223
|
-
)
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
def captcha_verified?
|
|
227
|
-
!PagesCore.config(:recaptcha) || verify_recaptcha
|
|
228
|
-
end
|
|
229
|
-
|
|
230
|
-
def honeypot_triggered?
|
|
231
|
-
PagesCore.config(:comment_honeypot) && !params[:email].to_s.empty?
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
def remote_ip
|
|
235
|
-
request.env["REMOTE_ADDR"]
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
def new_comment(page)
|
|
239
|
-
PageComment.new(
|
|
240
|
-
page_comment_params.merge(remote_ip: remote_ip, page_id: page.id)
|
|
241
|
-
)
|
|
242
|
-
end
|
|
243
|
-
|
|
244
|
-
def comment_recipients(page)
|
|
245
|
-
PagesCore.config(:comment_notifications)
|
|
246
|
-
.map { |r| r == :author ? page.author.name_and_email : r }
|
|
247
|
-
.uniq
|
|
248
|
-
end
|
|
249
|
-
|
|
250
|
-
def deliver_comment_notifications(page, comment)
|
|
251
|
-
comment_recipients(page).each do |r|
|
|
252
|
-
AdminMailer.comment_notification(
|
|
253
|
-
r,
|
|
254
|
-
page,
|
|
255
|
-
comment,
|
|
256
|
-
page_url(locale, page)
|
|
257
|
-
).deliver_now
|
|
258
|
-
end
|
|
100
|
+
def find_page_by_path
|
|
101
|
+
return unless params[:path]
|
|
102
|
+
@page ||= PagePath.get(locale, params[:path]).try(&:page)
|
|
259
103
|
end
|
|
260
104
|
|
|
261
105
|
def find_page
|
|
262
|
-
@page ||=
|
|
263
|
-
@page.locale = @locale || I18n.default_locale.to_s
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
def find_page_by_id(id)
|
|
267
|
-
Page.find(id)
|
|
268
|
-
rescue
|
|
269
|
-
nil
|
|
270
|
-
end
|
|
271
|
-
|
|
272
|
-
def page_comment_params
|
|
273
|
-
params.require(:page_comment).permit(:name, :email, :url, :body)
|
|
106
|
+
@page ||= Page.find_by(id: params[:id]) || unique_page(params[:id])
|
|
107
|
+
@page.locale = @locale || I18n.default_locale.to_s if @page
|
|
274
108
|
end
|
|
275
109
|
|
|
276
|
-
def
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
110
|
+
def render_published_page(page)
|
|
111
|
+
if page && page.published?
|
|
112
|
+
@page = page
|
|
113
|
+
render_page
|
|
114
|
+
else
|
|
115
|
+
render_error 404
|
|
116
|
+
end
|
|
281
117
|
end
|
|
282
118
|
|
|
283
|
-
def
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
render template: "feeds/pages", layout: false
|
|
119
|
+
def redirect_page(page)
|
|
120
|
+
return false unless page.redirects?
|
|
121
|
+
redirect_to(page.redirect_path(locale: locale))
|
|
287
122
|
end
|
|
288
123
|
|
|
289
|
-
def
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
per_page: 20,
|
|
293
|
-
include: [:localizations, :categories, :image, :author],
|
|
294
|
-
order: :published_at,
|
|
295
|
-
sort_mode: :desc,
|
|
296
|
-
with: {
|
|
297
|
-
status: 2,
|
|
298
|
-
autopublish: 0
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
unless category_id.blank?
|
|
302
|
-
options[:with][:category_ids] = category_id
|
|
303
|
-
end
|
|
304
|
-
options
|
|
124
|
+
def require_page
|
|
125
|
+
return if @page
|
|
126
|
+
render_error 404
|
|
305
127
|
end
|
|
306
128
|
end
|
|
307
129
|
end
|