pages_core 3.4.2

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 (271) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +29 -0
  3. data/Rakefile +10 -0
  4. data/app/assets/images/pages/admin/description-bg.gif +0 -0
  5. data/app/assets/images/pages/admin/drag-handle.gif +0 -0
  6. data/app/assets/images/pages/admin/drag-icon.png +0 -0
  7. data/app/assets/images/pages/admin/flash-error-bg.gif +0 -0
  8. data/app/assets/images/pages/admin/formelement-bg.gif +0 -0
  9. data/app/assets/images/pages/admin/header-tab-current-bg.gif +0 -0
  10. data/app/assets/images/pages/admin/icon.png +0 -0
  11. data/app/assets/images/pages/admin/image-editor-bg.png +0 -0
  12. data/app/assets/images/pages/admin/list-table-pin-blue.gif +0 -0
  13. data/app/assets/images/pages/admin/list-table-pin-disabled.gif +0 -0
  14. data/app/assets/images/pages/admin/list-table-pin-green.gif +0 -0
  15. data/app/assets/images/pages/admin/list-table-pin-red.gif +0 -0
  16. data/app/assets/images/pages/admin/list-table-pin-yellow.gif +0 -0
  17. data/app/assets/images/pages/admin/list-table-td-bg.gif +0 -0
  18. data/app/assets/images/pages/admin/loading-modal.gif +0 -0
  19. data/app/assets/images/pages/admin/sidebar-bg.gif +0 -0
  20. data/app/assets/images/pages/admin/textarea_controls.gif +0 -0
  21. data/app/assets/images/pages/admin/warning-icon.gif +0 -0
  22. data/app/assets/images/pages/favicon.gif +0 -0
  23. data/app/assets/images/pages/feed-icon-14x14.png +0 -0
  24. data/app/assets/javascripts/pages/admin/controllers/base.js.coffee +4 -0
  25. data/app/assets/javascripts/pages/admin/controllers/pages_controller.js.coffee +139 -0
  26. data/app/assets/javascripts/pages/admin/controllers/users_controller.js.coffee +9 -0
  27. data/app/assets/javascripts/pages/admin/features/content_tabs.js.coffee +47 -0
  28. data/app/assets/javascripts/pages/admin/features/editable_image.js.coffee.erb +122 -0
  29. data/app/assets/javascripts/pages/admin/features/modal.js.coffee +66 -0
  30. data/app/assets/javascripts/pages/admin/features/page_images.js +329 -0
  31. data/app/assets/javascripts/pages/admin/features/rich_text.js.coffee +40 -0
  32. data/app/assets/javascripts/pages/admin/features/tag_editor.js +159 -0
  33. data/app/assets/javascripts/pages/admin/lib/ajax_extensions.js.coffee +17 -0
  34. data/app/assets/javascripts/pages/admin/lib/center_on_screen.js.coffee +21 -0
  35. data/app/assets/javascripts/pages/admin/lib/jrichtextarea.js +57 -0
  36. data/app/assets/javascripts/pages/admin.js.coffee +54 -0
  37. data/app/assets/javascripts/pages/login_form.js.coffee +17 -0
  38. data/app/assets/stylesheets/pages/admin/buttons.css.erb +5 -0
  39. data/app/assets/stylesheets/pages/admin/controllers/artists.css.erb +94 -0
  40. data/app/assets/stylesheets/pages/admin/controllers/files.css.erb +58 -0
  41. data/app/assets/stylesheets/pages/admin/controllers/pages.css.scss.erb +178 -0
  42. data/app/assets/stylesheets/pages/admin/controllers/users.css.erb +3 -0
  43. data/app/assets/stylesheets/pages/admin/editable_image.css.erb +19 -0
  44. data/app/assets/stylesheets/pages/admin/forms.css.scss.erb +73 -0
  45. data/app/assets/stylesheets/pages/admin/header.css.erb +129 -0
  46. data/app/assets/stylesheets/pages/admin/images.css.scss.erb +160 -0
  47. data/app/assets/stylesheets/pages/admin/links.css.erb +34 -0
  48. data/app/assets/stylesheets/pages/admin/list_table.css.erb +56 -0
  49. data/app/assets/stylesheets/pages/admin/login.css.scss.erb +32 -0
  50. data/app/assets/stylesheets/pages/admin/modal.css.erb +14 -0
  51. data/app/assets/stylesheets/pages/admin/pagination.css.scss +22 -0
  52. data/app/assets/stylesheets/pages/admin/print.css.erb +17 -0
  53. data/app/assets/stylesheets/pages/admin/sidebar.css.erb +39 -0
  54. data/app/assets/stylesheets/pages/admin/sortable_images.css.erb +18 -0
  55. data/app/assets/stylesheets/pages/admin/tag_editor.css.scss.erb +48 -0
  56. data/app/assets/stylesheets/pages/admin/textarea.css.erb +55 -0
  57. data/app/assets/stylesheets/pages/admin.css.erb +404 -0
  58. data/app/assets/stylesheets/pages/errors.css +126 -0
  59. data/app/controller_dummies/admin/admin_controller.rb +6 -0
  60. data/app/controller_dummies/application_controller.rb +6 -0
  61. data/app/controller_dummies/frontend_controller.rb +4 -0
  62. data/app/controller_dummies/images_controller.rb +4 -0
  63. data/app/controller_dummies/page_files_controller.rb +4 -0
  64. data/app/controller_dummies/pages_controller.rb +4 -0
  65. data/app/controller_dummies/sitemaps_controller.rb +4 -0
  66. data/app/controllers/admin/categories_controller.rb +57 -0
  67. data/app/controllers/admin/images_controller.rb +48 -0
  68. data/app/controllers/admin/invites_controller.rb +79 -0
  69. data/app/controllers/admin/page_comments_controller.rb +61 -0
  70. data/app/controllers/admin/page_files_controller.rb +81 -0
  71. data/app/controllers/admin/page_images_controller.rb +116 -0
  72. data/app/controllers/admin/pages_controller.rb +179 -0
  73. data/app/controllers/admin/password_resets_controller.rb +83 -0
  74. data/app/controllers/admin/users_controller.rb +102 -0
  75. data/app/controllers/concerns/pages_core/authentication.rb +48 -0
  76. data/app/controllers/concerns/pages_core/domain_based_cache.rb +28 -0
  77. data/app/controllers/concerns/pages_core/exception_handler.rb +114 -0
  78. data/app/controllers/concerns/pages_core/policies_helper.rb +40 -0
  79. data/app/controllers/concerns/pages_core/process_titler.rb +44 -0
  80. data/app/controllers/errors_controller.rb +45 -0
  81. data/app/controllers/pages_core/admin_controller.rb +109 -0
  82. data/app/controllers/pages_core/application_controller.rb +31 -0
  83. data/app/controllers/pages_core/frontend/page_files_controller.rb +42 -0
  84. data/app/controllers/pages_core/frontend/pages_controller.rb +308 -0
  85. data/app/controllers/pages_core/frontend_controller.rb +34 -0
  86. data/app/controllers/pages_core/images_controller.rb +15 -0
  87. data/app/controllers/pages_core/sitemaps_controller.rb +73 -0
  88. data/app/controllers/sessions_controller.rb +38 -0
  89. data/app/formatters/pages_core/html_formatter.rb +86 -0
  90. data/app/helpers/admin/admin_helper.rb +7 -0
  91. data/app/helpers/admin/menu_helper.rb +65 -0
  92. data/app/helpers/admin/pages_helper.rb +74 -0
  93. data/app/helpers/application_helper.rb +5 -0
  94. data/app/helpers/frontend_helper.rb +5 -0
  95. data/app/helpers/pages_core/admin/admin_helper.rb +108 -0
  96. data/app/helpers/pages_core/admin/labelled_field_helper.rb +73 -0
  97. data/app/helpers/pages_core/admin/tag_editor_helper.rb +46 -0
  98. data/app/helpers/pages_core/application_helper.rb +65 -0
  99. data/app/helpers/pages_core/form_builder.rb +187 -0
  100. data/app/helpers/pages_core/frontend_helper.rb +21 -0
  101. data/app/helpers/pages_core/head_tags_helper.rb +270 -0
  102. data/app/helpers/pages_core/images_helper.rb +36 -0
  103. data/app/helpers/pages_core/login_helper.rb +14 -0
  104. data/app/indices/page_file_index.rb +9 -0
  105. data/app/indices/page_index.rb +29 -0
  106. data/app/indices/user_index.rb +11 -0
  107. data/app/jobs/pages_core/autopublish_job.rb +11 -0
  108. data/app/jobs/pages_core/sweep_cache_job.rb +11 -0
  109. data/app/mailers/admin_mailer.rb +46 -0
  110. data/app/models/autopublisher.rb +33 -0
  111. data/app/models/category.rb +23 -0
  112. data/app/models/concerns/pages_core/has_roles.rb +25 -0
  113. data/app/models/concerns/pages_core/humanizable_param.rb +17 -0
  114. data/app/models/concerns/pages_core/page_tree.rb +85 -0
  115. data/app/models/concerns/pages_core/searchable_page.rb +33 -0
  116. data/app/models/concerns/pages_core/sweepable.rb +23 -0
  117. data/app/models/concerns/pages_core/taggable.rb +46 -0
  118. data/app/models/concerns/pages_core/templateable.rb +85 -0
  119. data/app/models/image.rb +23 -0
  120. data/app/models/invite.rb +33 -0
  121. data/app/models/invite_role.rb +11 -0
  122. data/app/models/localization.rb +27 -0
  123. data/app/models/page.rb +281 -0
  124. data/app/models/page_builder.rb +61 -0
  125. data/app/models/page_comment.rb +18 -0
  126. data/app/models/page_file.rb +74 -0
  127. data/app/models/page_image.rb +62 -0
  128. data/app/models/password_reset_token.rb +38 -0
  129. data/app/models/role.rb +51 -0
  130. data/app/models/tag.rb +64 -0
  131. data/app/models/tagging.rb +22 -0
  132. data/app/models/user.rb +131 -0
  133. data/app/policies/invite_policy.rb +29 -0
  134. data/app/policies/page_file_policy.rb +25 -0
  135. data/app/policies/page_image_policy.rb +25 -0
  136. data/app/policies/page_policy.rb +33 -0
  137. data/app/policies/policy.rb +64 -0
  138. data/app/policies/user_policy.rb +49 -0
  139. data/app/serializers/admin/image_serializer.rb +10 -0
  140. data/app/serializers/admin/page_image_serializer.rb +6 -0
  141. data/app/serializers/page_image_serializer.rb +38 -0
  142. data/app/serializers/page_serializer.rb +21 -0
  143. data/app/views/admin/invites/new.html.erb +16 -0
  144. data/app/views/admin/invites/show.html.erb +25 -0
  145. data/app/views/admin/pages/_edit_comments.html.erb +21 -0
  146. data/app/views/admin/pages/_edit_content.html.erb +10 -0
  147. data/app/views/admin/pages/_edit_images.html.erb +84 -0
  148. data/app/views/admin/pages/_edit_metadata.html.erb +24 -0
  149. data/app/views/admin/pages/_edit_options.html.erb +72 -0
  150. data/app/views/admin/pages/_pagelisting.html.erb +63 -0
  151. data/app/views/admin/pages/edit.html.erb +161 -0
  152. data/app/views/admin/pages/index.html.erb +67 -0
  153. data/app/views/admin/pages/new.html.erb +48 -0
  154. data/app/views/admin/pages/news.html.erb +69 -0
  155. data/app/views/admin/password_resets/show.html.erb +24 -0
  156. data/app/views/admin/users/_access_control.html.erb +14 -0
  157. data/app/views/admin/users/_list.html.erb +62 -0
  158. data/app/views/admin/users/_login_form.html.erb +47 -0
  159. data/app/views/admin/users/deactivated.html.erb +12 -0
  160. data/app/views/admin/users/edit.html.erb +54 -0
  161. data/app/views/admin/users/index.html.erb +27 -0
  162. data/app/views/admin/users/login.html.erb +15 -0
  163. data/app/views/admin/users/new.html.erb +23 -0
  164. data/app/views/admin/users/new_password.html.erb +19 -0
  165. data/app/views/admin/users/show.html.erb +64 -0
  166. data/app/views/admin_mailer/comment_notification.text.erb +7 -0
  167. data/app/views/admin_mailer/error_report.html.erb +70 -0
  168. data/app/views/admin_mailer/invite.text.erb +9 -0
  169. data/app/views/admin_mailer/password_reset.text.erb +13 -0
  170. data/app/views/errors/403.html.erb +6 -0
  171. data/app/views/errors/404.html.erb +11 -0
  172. data/app/views/errors/405.html.erb +4 -0
  173. data/app/views/errors/500.html.erb +19 -0
  174. data/app/views/errors/500_critical.html.erb +7 -0
  175. data/app/views/errors/_generic_help.html.erb +21 -0
  176. data/app/views/errors/report.html.erb +4 -0
  177. data/app/views/feeds/pages.rss.builder +39 -0
  178. data/app/views/layouts/admin/_analytics.html.erb +18 -0
  179. data/app/views/layouts/admin/_header.html.erb +37 -0
  180. data/app/views/layouts/admin.html.erb +79 -0
  181. data/app/views/layouts/errors.html.erb +23 -0
  182. data/app/views/sitemaps/show.xml.builder +9 -0
  183. data/config/locales/en.yml +6 -0
  184. data/config/removed_migrations.yml +60 -0
  185. data/config/routes.rb +127 -0
  186. data/db/migrate/20111219033112_create_pages_tables.rb +281 -0
  187. data/db/migrate/20120627033112_rename_textbits.rb +19 -0
  188. data/db/migrate/20121010055412_drop_removed_tables.rb +83 -0
  189. data/db/migrate/20130130053932_add_queue_to_delayed_jobs.rb +11 -0
  190. data/db/migrate/20130303053932_remove_filter_from_localizations.rb +11 -0
  191. data/db/migrate/20130303160632_remove_imagesets.rb +24 -0
  192. data/db/migrate/20130303161732_remove_sms_subscribers.rb +16 -0
  193. data/db/migrate/20130823133208_update_page_redirect_to.rb +25 -0
  194. data/db/migrate/20140203183900_create_roles.rb +63 -0
  195. data/db/migrate/20140414150500_change_locale_names.rb +13 -0
  196. data/db/migrate/20140515130100_remove_sphinx_deltas.rb +15 -0
  197. data/db/migrate/20140604142100_remove_openid_url.rb +9 -0
  198. data/db/migrate/20140920231700_convert_images_to_dis.rb +79 -0
  199. data/db/migrate/20140922124600_convert_page_files_to_dis.rb +50 -0
  200. data/db/migrate/20141004003100_create_password_reset_tokens.rb +10 -0
  201. data/db/migrate/20141006181300_remove_user_cruft.rb +11 -0
  202. data/db/migrate/20141007173000_create_invites.rb +16 -0
  203. data/db/migrate/20150204130800_update_delayed_job_table.rb +9 -0
  204. data/db/migrate/20150401131300_localize_images.rb +39 -0
  205. data/db/migrate/20150520174300_add_meta_image_to_page.rb +5 -0
  206. data/db/migrate/20150904164200_add_pinned_to_tags.rb +5 -0
  207. data/lib/pages_core/admin_menu_item.rb +22 -0
  208. data/lib/pages_core/archive_finder.rb +75 -0
  209. data/lib/pages_core/cache_sweeper.rb +112 -0
  210. data/lib/pages_core/configuration/base.rb +85 -0
  211. data/lib/pages_core/configuration/pages.rb +23 -0
  212. data/lib/pages_core/configuration.rb +9 -0
  213. data/lib/pages_core/engine.rb +27 -0
  214. data/lib/pages_core/extensions/hash_extensions.rb +23 -0
  215. data/lib/pages_core/extensions/string_extensions.rb +17 -0
  216. data/lib/pages_core/extensions.rb +4 -0
  217. data/lib/pages_core/localizable/active_record_extension.rb +41 -0
  218. data/lib/pages_core/localizable/class_methods.rb +51 -0
  219. data/lib/pages_core/localizable/configuration.rb +50 -0
  220. data/lib/pages_core/localizable/instance_methods.rb +130 -0
  221. data/lib/pages_core/localizable/localizer.rb +72 -0
  222. data/lib/pages_core/localizable/scope_extension.rb +22 -0
  223. data/lib/pages_core/localizable.rb +49 -0
  224. data/lib/pages_core/pages_plugin.rb +14 -0
  225. data/lib/pages_core/paginates.rb +102 -0
  226. data/lib/pages_core/plugin.rb +118 -0
  227. data/lib/pages_core/templates/block_configuration.rb +17 -0
  228. data/lib/pages_core/templates/configuration.rb +81 -0
  229. data/lib/pages_core/templates/configuration_handler.rb +62 -0
  230. data/lib/pages_core/templates/configuration_proxy.rb +28 -0
  231. data/lib/pages_core/templates/controller_actions.rb +32 -0
  232. data/lib/pages_core/templates/template_configuration.rb +198 -0
  233. data/lib/pages_core/templates.rb +53 -0
  234. data/lib/pages_core/version.rb +5 -0
  235. data/lib/pages_core.rb +89 -0
  236. data/lib/rails/generators/pages_core/frontend/frontend_generator.rb +68 -0
  237. data/lib/rails/generators/pages_core/frontend/templates/application.css.scss.erb +3 -0
  238. data/lib/rails/generators/pages_core/frontend/templates/application.js.erb +16 -0
  239. data/lib/rails/generators/pages_core/frontend/templates/base.css.scss.erb +3 -0
  240. data/lib/rails/generators/pages_core/frontend/templates/breakpoints.css.scss.erb +24 -0
  241. data/lib/rails/generators/pages_core/frontend/templates/hidpi.css.scss.erb +8 -0
  242. data/lib/rails/generators/pages_core/frontend/templates/layout.html.erb +15 -0
  243. data/lib/rails/generators/pages_core/frontend/templates/normalize.css.erb +425 -0
  244. data/lib/rails/generators/pages_core/install/install_generator.rb +135 -0
  245. data/lib/rails/generators/pages_core/install/templates/active_job_initializer.rb +1 -0
  246. data/lib/rails/generators/pages_core/install/templates/application_controller.rb +11 -0
  247. data/lib/rails/generators/pages_core/install/templates/application_helper.rb +5 -0
  248. data/lib/rails/generators/pages_core/install/templates/cache_sweeper_initializer.rb +11 -0
  249. data/lib/rails/generators/pages_core/install/templates/default_page_template.html.erb +5 -0
  250. data/lib/rails/generators/pages_core/install/templates/delayed_job +7 -0
  251. data/lib/rails/generators/pages_core/install/templates/delayed_job_initializer.rb +3 -0
  252. data/lib/rails/generators/pages_core/install/templates/frontend_controller.rb +6 -0
  253. data/lib/rails/generators/pages_core/install/templates/frontend_helper.rb +5 -0
  254. data/lib/rails/generators/pages_core/install/templates/gitignore.erb +25 -0
  255. data/lib/rails/generators/pages_core/install/templates/page_templates_initializer.rb +67 -0
  256. data/lib/rails/generators/pages_core/install/templates/pages_controller.rb +4 -0
  257. data/lib/rails/generators/pages_core/install/templates/pages_initializer.rb +45 -0
  258. data/lib/rails/generators/pages_core/install/templates/thinking_sphinx.yml +12 -0
  259. data/lib/rails/generators/pages_core/rspec/rspec_generator.rb +34 -0
  260. data/lib/rails/generators/pages_core/rspec/templates/factories.rb +9 -0
  261. data/lib/rails/generators/pages_core/rspec/templates/mailer_macros.rb +9 -0
  262. data/lib/rails/generators/pages_core/rspec/templates/spec_helper.rb +51 -0
  263. data/lib/tasks/db.rake +96 -0
  264. data/lib/tasks/pages/assets.rake +65 -0
  265. data/lib/tasks/pages/cache.rake +16 -0
  266. data/lib/tasks/pages/update.rake +19 -0
  267. data/lib/tasks/pages.rake +76 -0
  268. data/template.rb +19 -0
  269. data/vendor/assets/javascripts/jquery.dimscreen.js +77 -0
  270. data/vendor/assets/javascripts/jquery.fieldselection.js +59 -0
  271. metadata +690 -0
@@ -0,0 +1,308 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Frontend
5
+ class PagesController < ::FrontendController
6
+ include PagesCore::FrontendHelper
7
+ include PagesCore::Templates::ControllerActions
8
+ include PagesCore::HeadTagsHelper
9
+
10
+ caches_page :index if PagesCore.config(:page_cache)
11
+
12
+ before_action :disable_xss_protection, only: [:preview]
13
+ before_action :load_root_pages
14
+ before_action :find_page, only: [:show, :preview, :add_comment]
15
+ before_action :canonicalize_url, only: [:show]
16
+ after_action :cache_page_request, only: [:show]
17
+
18
+ def index
19
+ 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
33
+ end
34
+ end
35
+
36
+ def show
37
+ 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
54
+ end
55
+ end
56
+
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
+ private
105
+
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
+ def canonical_path(page)
118
+ if page.redirects?
119
+ page.redirect_path(locale: page.locale)
120
+ else
121
+ page_path(page.locale, page)
122
+ end
123
+ end
124
+
125
+ 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?
142
+ end
143
+
144
+ def render(*args)
145
+ @already_rendered = true
146
+ super
147
+ end
148
+
149
+ def redirect_to(*args)
150
+ @already_rendered = true
151
+ super
152
+ end
153
+
154
+ def rendered?
155
+ @already_rendered ? true : false
156
+ end
157
+
158
+ def page_template(page)
159
+ if PagesCore::Templates.names.include?(page.template)
160
+ page.template
161
+ else
162
+ "index"
163
+ end
164
+ end
165
+
166
+ def render_page
167
+ if @page.redirects?
168
+ redirect_to(@page.redirect_path(locale: @locale))
169
+ return
170
+ end
171
+
172
+ unless document_title?
173
+ if @page.meta_title?
174
+ document_title(@page.meta_title)
175
+ else
176
+ document_title(@page.name)
177
+ end
178
+ end
179
+
180
+ # Call template method
181
+ template = page_template(@page)
182
+
183
+ 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
197
+ end
198
+
199
+ # Cache pages by hand. This is dirty, but it works.
200
+ def cache_page_request
201
+ status_code = response.status.try(&:to_i)
202
+ unless status_code == 200 &&
203
+ PagesCore.config(:page_cache) &&
204
+ @page && @locale
205
+ return
206
+ end
207
+
208
+ self.class.cache_page response.body, request.path
209
+ end
210
+
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
259
+ end
260
+
261
+ 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)
274
+ end
275
+
276
+ def normalize_search_query(str)
277
+ str
278
+ .split(/\s+/)
279
+ .map { |p| "#{p}*" }
280
+ .join(" ")
281
+ end
282
+
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
287
+ end
288
+
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
305
+ end
306
+ end
307
+ end
308
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+
3
+ # Abstract controller for all frontend controllers.
4
+ module PagesCore
5
+ class FrontendController < ApplicationController
6
+ include ApplicationHelper
7
+
8
+ before_action :set_i18n_locale
9
+
10
+ # Loads @root_pages and @rss_feeds. To automatically load these in your
11
+ # own controllers, add the following line to your controller definition:
12
+ #
13
+ # before_action :load_root_pages
14
+ #
15
+ def load_root_pages
16
+ @root_pages = Page.roots.localized(@locale).published
17
+ @rss_feeds = Page.where(feed_enabled: true).localized(@locale).published
18
+ end
19
+
20
+ private
21
+
22
+ def set_i18n_locale
23
+ legacy_locales = {
24
+ "nor" => "nb",
25
+ "eng" => "en"
26
+ }
27
+ locale_param = params[:locale] || I18n.default_locale
28
+ if legacy_locales[locale_param]
29
+ locale_param = legacy_locales[locale_param]
30
+ end
31
+ I18n.locale = locale_param
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ class ImagesController < ApplicationController
5
+ include DynamicImage::Controller
6
+
7
+ caches_page :show, :uncropped, :original
8
+
9
+ private
10
+
11
+ def model
12
+ Image
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ class SitemapsController < ApplicationController
5
+ caches_page :show
6
+
7
+ def show
8
+ @entries = formatted_entries
9
+ end
10
+
11
+ private
12
+
13
+ def format_time(timestamp)
14
+ if timestamp.kind_of?(Date)
15
+ timestamp.strftime("%Y-%m-%d")
16
+ else
17
+ timestamp.strftime("%Y-%m-%dT%H:%M:%S#{timestamp.formatted_offset}")
18
+ end
19
+ end
20
+
21
+ def format_record(record)
22
+ {
23
+ loc: record_url(record),
24
+ lastmod: format_time(record.updated_at)
25
+ }
26
+ end
27
+
28
+ def formatted_entries
29
+ records.map { |r| format_record(r) }
30
+ end
31
+
32
+ def locales
33
+ if PagesCore.config.locales
34
+ PagesCore.config.locales.keys
35
+ else
36
+ [I18n.default_locale]
37
+ end
38
+ end
39
+
40
+ def localized?(record)
41
+ record.is_a?(PagesCore::Localizable::InstanceMethods)
42
+ end
43
+
44
+ def pages
45
+ ([Page.root.localize(I18n.default_locale)] +
46
+ locales.flat_map do |locale|
47
+ Page.published.localized(locale)
48
+ end).uniq
49
+ end
50
+
51
+ def page_record_url(record)
52
+ if record == Page.root && record.locale == I18n.default_locale
53
+ root_url
54
+ else
55
+ page_url(record.locale, record)
56
+ end
57
+ end
58
+
59
+ def record_url(record)
60
+ if record.is_a?(Page)
61
+ page_record_url(record)
62
+ elsif localized?(record)
63
+ polymorphic_url(record, locale: record.locale)
64
+ else
65
+ polymorphic_url(record)
66
+ end
67
+ end
68
+
69
+ def records
70
+ pages
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ class SessionsController < ApplicationController
4
+ def create
5
+ user = find_user(params[:username], params[:password])
6
+ authenticate!(user) if user
7
+
8
+ if logged_in?
9
+ redirect_to success_url
10
+ else
11
+ flash[:notice] = "The provided email address and password combination " \
12
+ "was not valid"
13
+ redirect_to login_url
14
+ end
15
+ end
16
+
17
+ def destroy
18
+ flash[:notice] = "You have been logged out"
19
+ deauthenticate!
20
+ redirect_to login_url
21
+ end
22
+
23
+ protected
24
+
25
+ def find_user(username, password)
26
+ User.authenticate(username, password: password) if username && password
27
+ end
28
+
29
+ def success_url
30
+ # TODO: Validate URL
31
+ params[:success_url] || admin_default_url
32
+ end
33
+
34
+ def login_url
35
+ # TODO: Validate URL
36
+ params[:login_url] || login_admin_users_url
37
+ end
38
+ end
@@ -0,0 +1,86 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ class HtmlFormatter
5
+ include ActionView::Helpers::AssetTagHelper
6
+ include PagesCore::ImagesHelper
7
+ include Rails.application.routes.url_helpers
8
+
9
+ class << self
10
+ def to_html(string, options = {})
11
+ new(string, options).to_html
12
+ end
13
+ end
14
+
15
+ def initialize(string, options = {})
16
+ @string = string
17
+ @options = options
18
+ end
19
+
20
+ def to_html
21
+ string = parse_images(@string)
22
+ if @options[:shorten] && string.length > @options[:shorten]
23
+ string = string[0..@options[:shorten]] + "..."
24
+ end
25
+ string += " #{@options[:append]}" if @options[:append]
26
+ RedCloth.new(string).to_html.html_safe
27
+ end
28
+
29
+ private
30
+
31
+ def image_expression
32
+ /\[image:(\d+)([\s="\-\w]*)?\]/
33
+ end
34
+
35
+ def embed_image(id, size:, class_name:)
36
+ image = Image.find(id).localize(I18n.locale)
37
+ class_name = ["image", image_class_name(image), class_name].compact
38
+ content_tag(
39
+ :figure,
40
+ dynamic_image_tag(
41
+ image,
42
+ size: size,
43
+ crop: false,
44
+ upscale: false
45
+ ) + image_caption(image),
46
+ class: class_name
47
+ )
48
+ rescue ActiveRecord::RecordNotFound
49
+ nil
50
+ end
51
+
52
+ def parse_images(string)
53
+ string.gsub(image_expression).each do |str|
54
+ id = str.match(image_expression)[1]
55
+ options = str.match(image_expression)[2]
56
+
57
+ size = if options.match(/size="(\d*x\d*)"/)
58
+ Regexp.last_match(1)
59
+ else
60
+ "2000x2000"
61
+ end
62
+
63
+ class_name = if options.match(/class="([\s\-\w]+)"/)
64
+ Regexp.last_match(1)
65
+ end
66
+
67
+ embed_image(id, size: size, class_name: class_name)
68
+ end
69
+ end
70
+
71
+ def image_caption(image)
72
+ return unless image.caption?
73
+ content_tag(:figcaption, image.caption)
74
+ end
75
+
76
+ def image_class_name(image)
77
+ if image.size.x == image.size.y
78
+ "square"
79
+ elsif image.size.x > image.size.y
80
+ "landscape"
81
+ else
82
+ "portrait"
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ module Admin
4
+ module AdminHelper
5
+ include PagesCore::Admin::AdminHelper
6
+ end
7
+ end
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+
3
+ module Admin
4
+ module MenuHelper
5
+ def header_tabs(group)
6
+ content_tag :ul, class: group.to_s do
7
+ menu_items_for(group).map do |item|
8
+ content_tag :li do
9
+ path = instance_eval(&item.path)
10
+ link_to(
11
+ item.label,
12
+ path,
13
+ class: (current_menu_item?(item) ? "current" : "")
14
+ )
15
+ end
16
+ end.join.html_safe
17
+ end
18
+ end
19
+
20
+ protected
21
+
22
+ def menu_item_candidates
23
+ routes = Rails.application.routes
24
+ menu_items
25
+ .map { |item| [item, routes.recognize_path(instance_eval(&item.path))] }
26
+ .select { |_item, routing| routing[:controller] == params[:controller] }
27
+ end
28
+
29
+ def find_menu_candidate
30
+ menu_item_candidates
31
+ .select { |item, routing| yield(item, routing) }
32
+ .try(&:first)
33
+ .try(&:first)
34
+ end
35
+
36
+ def menu_candidate_by_current_proc
37
+ find_menu_candidate do |item, _|
38
+ item.options[:current] && instance_eval(&item.options[:current])
39
+ end
40
+ end
41
+
42
+ def current_menu_item
43
+ menu_candidate_by_current_proc ||
44
+ find_menu_candidate { |_, r| r[:action] == params[:action] } ||
45
+ find_menu_candidate { |_, r| r[:action] == "index" } ||
46
+ find_menu_candidate { |_, _| true }
47
+ end
48
+
49
+ def current_menu_item?(item)
50
+ item == current_menu_item
51
+ end
52
+
53
+ def menu_items
54
+ PagesCore::AdminMenuItem.items
55
+ end
56
+
57
+ def menu_items_for(group)
58
+ menu_items
59
+ .select { |item| item.group == group }
60
+ .reject do |item|
61
+ item.options[:if] && !instance_eval(&item.options[:if])
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+
3
+ module Admin
4
+ module PagesHelper
5
+ def page_block_field(form, block_name, block_options)
6
+ if block_options[:size] == :field
7
+ labelled_field(
8
+ form.text_field(
9
+ block_name,
10
+ class: ['text', block_options[:class]].join(" "),
11
+ placeholder: block_options[:placeholder]
12
+ ),
13
+ block_options[:title],
14
+ errors: form.object.errors[block_name],
15
+ description: block_options[:description]
16
+ )
17
+ else
18
+ labelled_field form.text_area(
19
+ block_name,
20
+ rows: (block_options[:size] == :large ? 15 : 5),
21
+ class: ['rich', block_options[:class]].join(" "),
22
+ placeholder: block_options[:placeholder]
23
+ ),
24
+ block_options[:title],
25
+ errors: form.object.errors[block_name],
26
+ description: block_options[:description]
27
+ end
28
+ end
29
+
30
+ def available_templates_for_select
31
+ PagesCore::Templates.names.collect do |template|
32
+ if template == "index"
33
+ ["[Default]", "index"]
34
+ else
35
+ [template.humanize, template]
36
+ end
37
+ end
38
+ end
39
+
40
+ def page_name(page, options = {})
41
+ page_names = if options[:include_parents]
42
+ [page.ancestors, page].flatten
43
+ else
44
+ [page]
45
+ end
46
+ safe_join(
47
+ page_names.map { |p| page_name_with_fallback(p) },
48
+ " &raquo; ".html_safe
49
+ )
50
+ end
51
+
52
+ def publish_time(time)
53
+ if time.year != Time.now.year
54
+ time.strftime("on %b %d %Y at %H:%M")
55
+ elsif time.to_date != Time.now.to_date
56
+ time.strftime("on %b %Y at %H:%M")
57
+ else
58
+ time.strftime("at %H:%M")
59
+ end
60
+ end
61
+
62
+ private
63
+
64
+ def page_name_with_fallback(page)
65
+ if page.name?
66
+ page.name.to_s
67
+ elsif page.localize(I18n.default_locale.to_s).name?
68
+ "(#{page.localize(I18n.default_locale.to_s).name})"
69
+ else
70
+ "(Untitled)"
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module ApplicationHelper #:nodoc:
4
+ include PagesCore::ApplicationHelper
5
+ end