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.
Files changed (215) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +81 -15
  3. data/Rakefile +1 -1
  4. data/app/assets/javascripts/pages/admin.es6.jsx +19 -0
  5. data/app/assets/javascripts/pages/admin/components.es6.jsx +1 -0
  6. data/app/assets/javascripts/pages/admin/components/page_tree.es6.jsx +330 -0
  7. data/app/assets/javascripts/pages/admin/components/page_tree_actions.es6.jsx +8 -0
  8. data/app/assets/javascripts/pages/admin/components/page_tree_node.es6.jsx +374 -0
  9. data/app/assets/javascripts/pages/admin/components/page_tree_store.es6.jsx +161 -0
  10. data/app/assets/javascripts/pages/admin/features/content_tabs.es6.jsx +63 -0
  11. data/app/assets/javascripts/pages/admin/features/edit_page.es6.jsx +141 -0
  12. data/app/assets/javascripts/pages/admin/features/editable_image.es6.jsx +145 -0
  13. data/app/assets/javascripts/pages/admin/features/modal.es6.jsx +90 -0
  14. data/app/assets/javascripts/pages/admin/features/page_images.es6.jsx +338 -0
  15. data/app/assets/javascripts/pages/admin/features/rich_text.es6.jsx +124 -0
  16. data/app/assets/javascripts/pages/admin/features/tag_editor.es6.jsx +160 -0
  17. data/app/assets/javascripts/pages/admin/lib/ajax_extensions.es6.jsx +21 -0
  18. data/app/assets/javascripts/pages/admin/lib/center_on_screen.es6.jsx +22 -0
  19. data/app/assets/javascripts/pages/admin/lib/tree.es6.jsx +294 -0
  20. data/app/assets/javascripts/pages/login_form.es6.jsx +21 -0
  21. data/app/assets/stylesheets/pages/admin.scss +148 -0
  22. data/app/assets/stylesheets/pages/admin/components/buttons.scss +5 -0
  23. data/app/assets/stylesheets/pages/admin/{editable_image.css.erb → components/editable_image.scss} +7 -8
  24. data/app/assets/stylesheets/pages/admin/components/forms.scss +71 -0
  25. data/app/assets/stylesheets/pages/admin/components/header.scss +169 -0
  26. data/app/assets/stylesheets/pages/admin/{images.css.scss.erb → components/images.scss} +6 -11
  27. data/app/assets/stylesheets/pages/admin/components/layout.scss +44 -0
  28. data/app/assets/stylesheets/pages/admin/components/links.scss +43 -0
  29. data/app/assets/stylesheets/pages/admin/components/list_table.scss +58 -0
  30. data/app/assets/stylesheets/pages/admin/{login.css.scss.erb → components/login.scss} +1 -1
  31. data/app/assets/stylesheets/pages/admin/{modal.css.erb → components/modal.scss} +3 -2
  32. data/app/assets/stylesheets/pages/admin/components/page_tree.scss +173 -0
  33. data/app/assets/stylesheets/pages/admin/{pagination.css.scss → components/pagination.scss} +13 -4
  34. data/app/assets/stylesheets/pages/admin/components/sidebar.scss +25 -0
  35. data/app/assets/stylesheets/pages/admin/{tag_editor.css.scss.erb → components/tag_editor.scss} +6 -0
  36. data/app/assets/stylesheets/pages/admin/components/textarea.scss +76 -0
  37. data/app/assets/stylesheets/pages/admin/controllers/pages.scss +196 -0
  38. data/app/assets/stylesheets/pages/admin/controllers/{users.css.erb → users.scss} +0 -0
  39. data/app/assets/stylesheets/pages/admin/mixins/breakpoints.scss +21 -0
  40. data/app/assets/stylesheets/pages/admin/mixins/clearfix.scss +7 -0
  41. data/app/assets/stylesheets/pages/admin/mixins/gradients.scss +7 -0
  42. data/app/assets/stylesheets/pages/admin/{print.css.erb → print.scss} +0 -0
  43. data/app/assets/stylesheets/pages/admin/vars.scss +8 -0
  44. data/app/controllers/admin/invites_controller.rb +10 -6
  45. data/app/controllers/admin/page_files_controller.rb +6 -8
  46. data/app/controllers/admin/page_images_controller.rb +14 -19
  47. data/app/controllers/admin/pages_controller.rb +44 -97
  48. data/app/controllers/admin/password_resets_controller.rb +7 -2
  49. data/app/controllers/concerns/pages_core/add_comments_controller.rb +67 -0
  50. data/app/controllers/concerns/pages_core/admin/news_page_controller.rb +58 -0
  51. data/app/controllers/concerns/pages_core/authentication.rb +1 -1
  52. data/app/controllers/concerns/pages_core/exception_handler.rb +44 -21
  53. data/app/controllers/concerns/pages_core/policies_helper.rb +10 -6
  54. data/app/controllers/concerns/pages_core/preview_pages_controller.rb +43 -0
  55. data/app/controllers/concerns/pages_core/process_titler.rb +2 -2
  56. data/app/controllers/concerns/pages_core/rss_controller.rb +25 -0
  57. data/app/controllers/concerns/pages_core/search_pages_controller.rb +40 -0
  58. data/app/controllers/errors_controller.rb +14 -2
  59. data/app/controllers/pages_core/admin_controller.rb +7 -5
  60. data/app/controllers/pages_core/frontend/page_files_controller.rb +5 -7
  61. data/app/controllers/pages_core/frontend/pages_controller.rb +41 -219
  62. data/app/controllers/pages_core/frontend_controller.rb +8 -2
  63. data/app/controllers/pages_core/sitemaps_controller.rb +5 -4
  64. data/app/formatters/pages_core/html_formatter.rb +33 -23
  65. data/app/helpers/admin/menu_helper.rb +12 -9
  66. data/app/helpers/admin/pages_helper.rb +40 -28
  67. data/app/helpers/pages_core/admin/admin_helper.rb +58 -56
  68. data/app/helpers/pages_core/admin/labelled_field_helper.rb +6 -7
  69. data/app/helpers/pages_core/admin/tag_editor_helper.rb +11 -9
  70. data/app/helpers/pages_core/application_helper.rb +13 -26
  71. data/app/helpers/pages_core/form_builder.rb +71 -134
  72. data/app/helpers/pages_core/head_tags_helper.rb +26 -168
  73. data/app/helpers/pages_core/images_helper.rb +3 -3
  74. data/app/helpers/pages_core/meta_tags_helper.rb +96 -0
  75. data/app/helpers/pages_core/open_graph_tags_helper.rb +51 -0
  76. data/app/helpers/pages_core/page_path_helper.rb +40 -0
  77. data/app/mailers/admin_mailer.rb +14 -14
  78. data/app/models/autopublisher.rb +2 -2
  79. data/app/models/category.rb +8 -8
  80. data/app/models/concerns/pages_core/has_roles.rb +2 -2
  81. data/app/models/concerns/pages_core/humanizable_param.rb +5 -5
  82. data/app/models/concerns/pages_core/page_model/autopublishable.rb +25 -0
  83. data/app/models/concerns/pages_core/page_model/commentable.rb +29 -0
  84. data/app/models/concerns/pages_core/page_model/images.rb +50 -0
  85. data/app/models/concerns/pages_core/page_model/localizable.rb +29 -0
  86. data/app/models/concerns/pages_core/page_model/pathable.rb +115 -0
  87. data/app/models/concerns/pages_core/page_model/redirectable.rb +36 -0
  88. data/app/models/concerns/pages_core/page_model/searchable.rb +41 -0
  89. data/app/models/concerns/pages_core/page_model/sortable.rb +54 -0
  90. data/app/models/concerns/pages_core/page_model/status.rb +50 -0
  91. data/app/models/concerns/pages_core/page_model/templateable.rb +82 -0
  92. data/app/models/concerns/pages_core/page_model/tree.rb +108 -0
  93. data/app/models/page.rb +30 -212
  94. data/app/models/page_builder.rb +4 -6
  95. data/app/models/page_category.rb +7 -0
  96. data/app/models/page_comment.rb +1 -1
  97. data/app/models/page_file.rb +4 -6
  98. data/app/models/page_image.rb +6 -7
  99. data/app/models/page_path.rb +46 -0
  100. data/app/models/password_reset_token.rb +5 -5
  101. data/app/models/role.rb +1 -1
  102. data/app/models/tag.rb +14 -16
  103. data/app/models/tagging.rb +2 -1
  104. data/app/models/user.rb +6 -7
  105. data/app/policies/page_policy.rb +8 -4
  106. data/app/policies/user_policy.rb +1 -1
  107. data/app/serializers/page_tree_serializer.rb +15 -0
  108. data/app/views/admin/invites/new.html.erb +2 -1
  109. data/app/views/admin/invites/show.html.erb +3 -4
  110. data/app/views/admin/pages/_edit_comments.html.erb +22 -6
  111. data/app/views/admin/pages/_edit_content.html.erb +4 -2
  112. data/app/views/admin/pages/_edit_images.html.erb +86 -75
  113. data/app/views/admin/pages/_edit_metadata.html.erb +22 -0
  114. data/app/views/admin/pages/_edit_options.html.erb +23 -15
  115. data/app/views/admin/pages/_pagelisting.html.erb +6 -6
  116. data/app/views/admin/pages/edit.html.erb +11 -6
  117. data/app/views/admin/pages/index.html.erb +12 -53
  118. data/app/views/admin/pages/new.html.erb +3 -3
  119. data/app/views/admin/pages/news.html.erb +1 -1
  120. data/app/views/admin_mailer/invite.text.erb +1 -1
  121. data/app/views/admin_mailer/password_reset.text.erb +1 -1
  122. data/app/views/errors/422.html.erb +7 -0
  123. data/app/views/errors/500_critical.html.erb +1 -1
  124. data/app/views/layouts/admin.html.erb +36 -32
  125. data/app/views/layouts/admin/_header.html.erb +2 -2
  126. data/config/locales/en.yml +38 -1
  127. data/config/routes.rb +40 -23
  128. data/db/migrate/20111219033112_create_pages_tables.rb +25 -29
  129. data/db/migrate/20121010055412_drop_removed_tables.rb +3 -3
  130. data/db/migrate/20130823133208_update_page_redirect_to.rb +0 -13
  131. data/db/migrate/20140203183900_create_roles.rb +5 -2
  132. data/db/migrate/20140920231700_convert_images_to_dis.rb +4 -2
  133. data/db/migrate/20150401131300_localize_images.rb +7 -8
  134. data/db/migrate/20151002174800_create_page_paths.rb +10 -0
  135. data/db/migrate/20151021103400_drop_binaries_table.rb +7 -0
  136. data/db/migrate/20151204151000_remove_page_content_order.rb +5 -0
  137. data/db/migrate/20160330220900_rename_pages_categories.rb +6 -0
  138. data/db/migrate/20160405202700_change_localization_limit.rb +9 -0
  139. data/lib/pages_core.rb +22 -27
  140. data/lib/pages_core/admin_menu_item.rb +16 -3
  141. data/lib/pages_core/archive_finder.rb +40 -13
  142. data/lib/pages_core/cache_sweeper.rb +72 -45
  143. data/lib/pages_core/configuration.rb +2 -2
  144. data/lib/pages_core/configuration/base.rb +4 -8
  145. data/lib/pages_core/configuration/pages.rb +6 -3
  146. data/lib/pages_core/engine.rb +23 -1
  147. data/lib/pages_core/extensions.rb +2 -2
  148. data/lib/pages_core/file_embedder.rb +40 -0
  149. data/lib/pages_core/page_path_constraint.rb +23 -0
  150. data/lib/pages_core/pages_plugin.rb +11 -0
  151. data/lib/pages_core/paginates.rb +3 -3
  152. data/lib/pages_core/plugin.rb +14 -8
  153. data/lib/pages_core/templates.rb +6 -6
  154. data/lib/pages_core/templates/block_configuration.rb +1 -1
  155. data/lib/pages_core/templates/configuration.rb +23 -24
  156. data/lib/pages_core/templates/configuration_handler.rb +1 -1
  157. data/lib/pages_core/templates/configuration_proxy.rb +7 -11
  158. data/lib/pages_core/templates/template_configuration.rb +55 -61
  159. data/lib/pages_core/version.rb +1 -1
  160. data/lib/rails/generators/pages_core/install/install_generator.rb +22 -48
  161. data/lib/rails/generators/pages_core/install/templates/page_templates_initializer.rb +1 -1
  162. data/lib/rails/generators/pages_core/install/templates/pages_initializer.rb +6 -3
  163. data/lib/rails/generators/pages_core/rspec/rspec_generator.rb +4 -1
  164. data/lib/rails/generators/pages_core/rspec/templates/factories.rb +1 -1
  165. data/lib/tasks/pages.rake +4 -4
  166. data/lib/tasks/pages/page_paths.rake +12 -0
  167. data/template.rb +2 -2
  168. data/vendor/assets/javascripts/reflux.min.js +1 -0
  169. metadata +173 -85
  170. data/app/assets/images/pages/admin/description-bg.gif +0 -0
  171. data/app/assets/images/pages/admin/drag-handle.gif +0 -0
  172. data/app/assets/images/pages/admin/flash-error-bg.gif +0 -0
  173. data/app/assets/images/pages/admin/formelement-bg.gif +0 -0
  174. data/app/assets/images/pages/admin/header-tab-current-bg.gif +0 -0
  175. data/app/assets/images/pages/admin/list-table-td-bg.gif +0 -0
  176. data/app/assets/images/pages/admin/sidebar-bg.gif +0 -0
  177. data/app/assets/images/pages/admin/textarea_controls.gif +0 -0
  178. data/app/assets/javascripts/pages/admin.js.coffee +0 -54
  179. data/app/assets/javascripts/pages/admin/controllers/base.js.coffee +0 -4
  180. data/app/assets/javascripts/pages/admin/controllers/pages_controller.js.coffee +0 -139
  181. data/app/assets/javascripts/pages/admin/controllers/users_controller.js.coffee +0 -9
  182. data/app/assets/javascripts/pages/admin/features/content_tabs.js.coffee +0 -47
  183. data/app/assets/javascripts/pages/admin/features/editable_image.js.coffee.erb +0 -122
  184. data/app/assets/javascripts/pages/admin/features/modal.js.coffee +0 -66
  185. data/app/assets/javascripts/pages/admin/features/page_images.js +0 -329
  186. data/app/assets/javascripts/pages/admin/features/rich_text.js.coffee +0 -40
  187. data/app/assets/javascripts/pages/admin/features/tag_editor.js +0 -159
  188. data/app/assets/javascripts/pages/admin/lib/ajax_extensions.js.coffee +0 -17
  189. data/app/assets/javascripts/pages/admin/lib/center_on_screen.js.coffee +0 -21
  190. data/app/assets/javascripts/pages/admin/lib/jrichtextarea.js +0 -57
  191. data/app/assets/javascripts/pages/login_form.js.coffee +0 -17
  192. data/app/assets/stylesheets/pages/admin.css.erb +0 -404
  193. data/app/assets/stylesheets/pages/admin/buttons.css.erb +0 -5
  194. data/app/assets/stylesheets/pages/admin/controllers/artists.css.erb +0 -94
  195. data/app/assets/stylesheets/pages/admin/controllers/files.css.erb +0 -58
  196. data/app/assets/stylesheets/pages/admin/controllers/pages.css.scss.erb +0 -178
  197. data/app/assets/stylesheets/pages/admin/forms.css.scss.erb +0 -73
  198. data/app/assets/stylesheets/pages/admin/header.css.erb +0 -129
  199. data/app/assets/stylesheets/pages/admin/links.css.erb +0 -34
  200. data/app/assets/stylesheets/pages/admin/list_table.css.erb +0 -56
  201. data/app/assets/stylesheets/pages/admin/sidebar.css.erb +0 -39
  202. data/app/assets/stylesheets/pages/admin/sortable_images.css.erb +0 -18
  203. data/app/assets/stylesheets/pages/admin/textarea.css.erb +0 -55
  204. data/app/models/concerns/pages_core/page_tree.rb +0 -85
  205. data/app/models/concerns/pages_core/searchable_page.rb +0 -33
  206. data/app/models/concerns/pages_core/templateable.rb +0 -85
  207. data/app/models/localization.rb +0 -27
  208. data/db/migrate/20140515130100_remove_sphinx_deltas.rb +0 -15
  209. data/lib/pages_core/localizable.rb +0 -49
  210. data/lib/pages_core/localizable/active_record_extension.rb +0 -41
  211. data/lib/pages_core/localizable/class_methods.rb +0 -51
  212. data/lib/pages_core/localizable/configuration.rb +0 -50
  213. data/lib/pages_core/localizable/instance_methods.rb +0 -130
  214. data/lib/pages_core/localizable/localizer.rb +0 -72
  215. 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(params[:action] + "?")
37
- fail PagesCore::NotAuthorized
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
- ": Handling #{request.path} (#{i} reqs)"
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
- ": Idle (#{PagesCore::ProcessTitler.number_of_requests} reqs)"
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
- .join("log", "error_reports")
43
- .join("#{session[:error_report]}.yml")
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
- if !modified?(@page_file)
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
- @page_file.data,
19
- filename: @page_file.filename,
20
- type: @page_file.content_type,
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 do
21
- if self.respond_to?(:no_page_given)
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 do
39
- if @page && @page.published?
40
- render_page
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
- unless @page.redirects?
127
- if request.path != canonical_path(@page)
128
- redirect_to canonical_path(@page)
129
- end
130
- end
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.redirects?
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
- if @page.meta_title?
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
- @page_template_layout = false if @disable_layout
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
- PagesCore.config(:page_cache) &&
204
- @page && @locale
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 permitted_page_attributes
212
- [
213
- :template, :user_id, :status, :content_order,
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 ||= find_page_by_id(params[:id]) || unique_page(params[:id])
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 normalize_search_query(str)
277
- str
278
- .split(/\s+/)
279
- .map { |p| "#{p}*" }
280
- .join(" ")
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 render_rss(items, title: nil)
284
- @items, @title = items, title
285
- response.headers["Content-Type"] = "application/rss+xml;charset=utf-8"
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 search_options(category_id: nil)
290
- options = {
291
- page: (params[:page] || 1).to_i,
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