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,46 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Taggable
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ has_many :taggings, as: :taggable, dependent: :destroy
9
+ has_many :tags, through: :taggings
10
+ end
11
+
12
+ module ClassMethods
13
+ def tagged_with(*tags)
14
+ all
15
+ .includes(:tags)
16
+ .where("tags.name IN (?)", Tag.parse(tags))
17
+ .references(:tags)
18
+ end
19
+ end
20
+
21
+ def serialized_tags
22
+ tags.order("name ASC").map(&:name).to_json
23
+ end
24
+
25
+ def serialized_tags=(json)
26
+ tag_with(ActiveSupport::JSON.decode(json))
27
+ end
28
+
29
+ def tag_with(*list)
30
+ Tag.transaction do
31
+ taggings.destroy_all
32
+ Tag.parse(list).each do |name|
33
+ Tag.find_or_create_by(name: name).on(self)
34
+ end
35
+ end
36
+ end
37
+
38
+ def tag_list=(tag_list)
39
+ tag_with(tag_list)
40
+ end
41
+
42
+ def tag_list
43
+ tags.order("name ASC").map(&:name).join(", ")
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Templateable
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ before_validation :ensure_template
9
+ end
10
+
11
+ def template_config
12
+ PagesCore::Templates::TemplateConfiguration.new(template)
13
+ end
14
+
15
+ def template
16
+ !self[:template].blank? ? self[:template] : inherited_or_default_template
17
+ end
18
+
19
+ def default_subtemplate
20
+ template_config.value(:sub_template) ||
21
+ default_template ||
22
+ subtemplate_with_postfix ||
23
+ singularized_subtemplate ||
24
+ template
25
+ end
26
+
27
+ private
28
+
29
+ def singularized_subtemplate
30
+ singularized = ActiveSupport::Inflector.singularize(base_template)
31
+ return if base_template == singularized
32
+ find_template_by_expression(
33
+ Regexp.new("^" + Regexp.quote(singularized))
34
+ )
35
+ end
36
+
37
+ def subtemplate_with_postfix
38
+ find_template_by_expression(
39
+ Regexp.new(
40
+ "^" + Regexp.quote(base_template) + "_?(post|page|subpage|item)"
41
+ )
42
+ )
43
+ end
44
+
45
+ def base_template
46
+ template
47
+ .split(/_/)
48
+ .reject { |w| %w(index list archive liste arkiv).include?(w) }
49
+ .join(" ")
50
+ end
51
+
52
+ def default_template
53
+ configured = PagesCore::Templates.configuration.get(
54
+ :default, :template, :value
55
+ )
56
+ configured if configured != :autodetect
57
+ end
58
+
59
+ def find_template_by_expression(expr)
60
+ PagesCore::Templates
61
+ .names
62
+ .select { |t| t.match(expr) }
63
+ .try(&:first)
64
+ end
65
+
66
+ def inherited_or_default_template
67
+ default_options = PagesCore::Templates.configuration.get(
68
+ :default, :template, :options
69
+ )
70
+ if parent
71
+ t = parent.default_subtemplate
72
+ elsif default_options && default_options[:root]
73
+ t = default_options[:root]
74
+ elsif default_template
75
+ t = default_template
76
+ end
77
+ t ||= :index
78
+ t.to_s
79
+ end
80
+
81
+ def ensure_template
82
+ self[:template] ||= inherited_or_default_template
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,23 @@
1
+ class Image < ActiveRecord::Base
2
+ include DynamicImage::Model
3
+
4
+ localizable do
5
+ attribute :alternative
6
+ attribute :caption
7
+ end
8
+
9
+ def byline
10
+ ActiveSupport::Deprecation.warn "Image#byline is deprecated, use #caption"
11
+ caption
12
+ end
13
+
14
+ def byline?
15
+ ActiveSupport::Deprecation.warn "Image#byline? is deprecated, use #caption?"
16
+ caption?
17
+ end
18
+
19
+ def byline=(new_caption)
20
+ ActiveSupport::Deprecation.warn "Image#byline= is deprecated, use #caption="
21
+ self.caption = new_caption
22
+ end
23
+ end
@@ -0,0 +1,33 @@
1
+ class Invite < ActiveRecord::Base
2
+ include PagesCore::HasRoles
3
+
4
+ belongs_to :user
5
+ has_many :roles, class_name: "InviteRole", dependent: :destroy
6
+
7
+ before_validation :ensure_token
8
+
9
+ validates :user_id, presence: true
10
+
11
+ validates :email,
12
+ presence: true,
13
+ format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i },
14
+ uniqueness: { case_sensitive: false }
15
+
16
+ validates :token, presence: true
17
+
18
+ def create_user(attributes)
19
+ user = User.create(attributes.merge(
20
+ role_names: role_names,
21
+ creator: self.user,
22
+ activated: true
23
+ ))
24
+ destroy if user.valid?
25
+ user
26
+ end
27
+
28
+ private
29
+
30
+ def ensure_token
31
+ self.token ||= SecureRandom.hex(32)
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ class InviteRole < ActiveRecord::Base
2
+ belongs_to :invite
3
+ validates :name,
4
+ presence: true,
5
+ uniqueness: { scope: :invite_id },
6
+ inclusion: { in: proc { Role.roles.map(&:name) } }
7
+
8
+ def to_s
9
+ name.humanize
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ class Localization < ActiveRecord::Base
4
+ belongs_to :localizable, polymorphic: true
5
+
6
+ class << self
7
+ def locales
8
+ select("DISTINCT locale").map(&:locale)
9
+ end
10
+
11
+ def names
12
+ select("DISTINCT name").map(&:name)
13
+ end
14
+ end
15
+
16
+ def to_s
17
+ value || ""
18
+ end
19
+
20
+ def empty?
21
+ to_s.empty?
22
+ end
23
+
24
+ def translate(locale)
25
+ localizable.localizations.where(name: name, locale: locale).first
26
+ end
27
+ end
@@ -0,0 +1,281 @@
1
+ # encoding: utf-8
2
+
3
+ class Page < ActiveRecord::Base
4
+ include PagesCore::HumanizableParam
5
+ include PagesCore::PageTree
6
+ include PagesCore::SearchablePage
7
+ include PagesCore::Sweepable
8
+ include PagesCore::Taggable
9
+ include PagesCore::Templateable
10
+
11
+ belongs_to :author, class_name: "User", foreign_key: :user_id
12
+
13
+ has_and_belongs_to_many :categories, join_table: "pages_categories"
14
+
15
+ belongs_to_image :image
16
+ belongs_to_image :meta_image, class_name: "Image"
17
+
18
+ has_many :page_images, -> { order("position") }
19
+
20
+ has_many :images,
21
+ -> { where("`page_images`.`primary` = ?", false).order("position") },
22
+ through: :page_images
23
+
24
+ has_many :comments,
25
+ class_name: "PageComment",
26
+ dependent: :destroy
27
+
28
+ has_many :page_files,
29
+ -> { order("position ASC") },
30
+ class_name: "PageFile",
31
+ dependent: :destroy
32
+
33
+ acts_as_list scope: :parent_page
34
+
35
+ localizable do
36
+ attribute :name
37
+ attribute :body
38
+ attribute :excerpt
39
+ attribute :headline
40
+ attribute :boxout
41
+
42
+ attribute :meta_description
43
+ attribute :open_graph_title
44
+ attribute :open_graph_description
45
+
46
+ dictionary -> { PagesCore::Templates::TemplateConfiguration.all_blocks }
47
+ end
48
+
49
+ validates_format_of :redirect_to,
50
+ with: %r{\A(/|https?://)},
51
+ allow_nil: true,
52
+ allow_blank: true
53
+
54
+ validates_format_of :unique_name,
55
+ with: /\A[\w\d_\-]+\z/,
56
+ allow_nil: true,
57
+ allow_blank: true
58
+
59
+ validates_uniqueness_of :unique_name, allow_nil: true, allow_blank: true
60
+
61
+ validates :template, presence: true
62
+ validates :content_order, presence: true
63
+ validates :published_at, presence: true
64
+
65
+ before_validation :published_at
66
+ before_validation :set_autopublish
67
+ before_validation :set_content_order
68
+ after_save :ensure_page_images_contains_primary_image
69
+ after_save :queue_autopublisher
70
+ after_save ThinkingSphinx::RealTime.callback_for(:page)
71
+
72
+ scope :by_date, -> { order("published_at DESC") }
73
+ scope :published, -> { where(status: 2, autopublish: false) }
74
+ scope :visible, -> { where("status < 4") }
75
+ scope :news_pages, -> { visible.where(news_page: true) }
76
+ scope :pinned, -> { where(pinned: true) }
77
+
78
+ class << self
79
+ def archive_finder
80
+ PagesCore::ArchiveFinder.new(all, timestamp: :published_at)
81
+ end
82
+
83
+ # Find all published and feed enabled pages
84
+ def enabled_feeds(locale, options = {})
85
+ conditions = (options[:include_hidden]) ? "status IN (2,3)" : "status = 2"
86
+ Page.where(feed_enabled: true).where(conditions).localized(locale)
87
+ end
88
+
89
+ def status_labels
90
+ {
91
+ 0 => "Draft",
92
+ 1 => "Reviewed",
93
+ 2 => "Published",
94
+ 3 => "Hidden",
95
+ 4 => "Deleted"
96
+ }
97
+ end
98
+
99
+ def order_by_tags(tags)
100
+ joins(
101
+ "LEFT JOIN taggings ON taggings.taggable_id = pages.id AND " \
102
+ "taggable_type = \"Page\"",
103
+ "LEFT JOIN tags ON tags.id = taggings.tag_id AND tags.id IN (" +
104
+ tags.map(&:id).join(",") +
105
+ ")"
106
+ )
107
+ .group("pages.id, localizations.id")
108
+ .reorder("COUNT(tags.id) DESC, position ASC")
109
+ end
110
+ end
111
+
112
+ def comments_closed_after_time?
113
+ if PagesCore.config.close_comments_after.nil?
114
+ false
115
+ else
116
+ (Time.now - published_at) > PagesCore.config.close_comments_after
117
+ end
118
+ end
119
+
120
+ def comments_allowed?
121
+ if self.comments_closed_after_time?
122
+ false
123
+ else
124
+ self[:comments_allowed]
125
+ end
126
+ end
127
+
128
+ def extended?
129
+ excerpt? && body?
130
+ end
131
+
132
+ def empty?
133
+ !body? && !excerpt?
134
+ end
135
+ alias_method :blank?, :empty?
136
+
137
+ def excerpt_or_body
138
+ excerpt? ? excerpt : body
139
+ end
140
+
141
+ def image
142
+ super.try { |i| i.localize(locale) }
143
+ end
144
+
145
+ def images
146
+ super.in_locale(locale)
147
+ end
148
+
149
+ def page_images
150
+ super.in_locale(locale)
151
+ end
152
+
153
+ def files
154
+ page_files.in_locale(locale)
155
+ end
156
+
157
+ def headline_or_name
158
+ headline? ? headline : name
159
+ end
160
+
161
+ # Does this page have an image?
162
+ def image?
163
+ self.image_id?
164
+ end
165
+
166
+ # Get subpages
167
+ def pages(_options = nil)
168
+ if self.locale?
169
+ subpages.published.localized(locale)
170
+ else
171
+ subpages.published
172
+ end
173
+ end
174
+
175
+ def subpages
176
+ children.order(pinned_content_order)
177
+ end
178
+
179
+ # Return the status of the page as a string
180
+ def status_label
181
+ self.class.status_labels[status]
182
+ end
183
+
184
+ def flag_as_deleted!
185
+ update(status: 4)
186
+ end
187
+
188
+ # Get publication date, which defaults to the creation date
189
+ def published_at
190
+ if self.created_at?
191
+ self[:published_at] ||= created_at
192
+ else
193
+ self[:published_at] ||= Time.now
194
+ end
195
+ end
196
+
197
+ # Returns boolean true if page has a valid redirect
198
+ def redirects?
199
+ self.redirect_to?
200
+ end
201
+
202
+ def redirect_path(params = {})
203
+ path = redirect_to.dup
204
+ if path.start_with? "/"
205
+ params.each do |key, value|
206
+ unless value.is_a?(String) || value.is_a?(Symbol)
207
+ fail "redirect_url param must be a string or a symbol"
208
+ end
209
+ path.gsub!("/:#{key}", "/#{value}")
210
+ end
211
+ end
212
+ path
213
+ end
214
+
215
+ # Returns true if this page's children is reorderable
216
+ def reorderable_children?
217
+ !self.content_order? || content_order =~ /position/
218
+ end
219
+
220
+ # Returns true if this page is reorderable
221
+ def reorderable?
222
+ !parent || !parent.content_order? || parent.content_order =~ /position/
223
+ end
224
+
225
+ def draft?
226
+ status == 0
227
+ end
228
+
229
+ def reviewed?
230
+ status == 1
231
+ end
232
+
233
+ def published?
234
+ status == 2 && !autopublish?
235
+ end
236
+
237
+ def hidden?
238
+ status == 3
239
+ end
240
+
241
+ def deleted?
242
+ status == 4
243
+ end
244
+
245
+ def to_param
246
+ humanized_param(name)
247
+ end
248
+
249
+ def content_order
250
+ self[:content_order] || "position"
251
+ end
252
+
253
+ private
254
+
255
+ def ensure_page_images_contains_primary_image
256
+ return if !image_id? || !image_id_changed?
257
+ page_image = page_images.where(image_id: image_id).first
258
+ if page_image
259
+ page_image.update(primary: true)
260
+ else
261
+ page_images.create(image_id: image_id, primary: true)
262
+ end
263
+ end
264
+
265
+ def pinned_content_order
266
+ self.news_page? ? "pages.pinned DESC, #{content_order}" : content_order
267
+ end
268
+
269
+ def set_autopublish
270
+ self.autopublish = published_at? && published_at > Time.now
271
+ true
272
+ end
273
+
274
+ def set_content_order
275
+ self[:content_order] ||= "position"
276
+ end
277
+
278
+ def queue_autopublisher
279
+ Autopublisher.queue! if self.autopublish?
280
+ end
281
+ end
@@ -0,0 +1,61 @@
1
+ # encoding: utf-8
2
+
3
+ # # PageBuilder
4
+ #
5
+ # PageBuilder is a simple DSL for building pages, for use in ie. seeds.rb
6
+ #
7
+ # Example:
8
+ #
9
+ # PageBuilder.build(User.first) do
10
+ # page "Home", template: "home"
11
+ # page "Products" do
12
+ # page "Product 1"
13
+ # page "Product 2"
14
+ # end
15
+ # page "Contact", unique_name: "contact"
16
+ # end
17
+ class PageBuilder
18
+ attr_reader :user, :locale, :parent
19
+
20
+ class << self
21
+ def build(user, locale: nil, parent: nil, &block)
22
+ new(user, locale: locale, parent: parent)
23
+ .run(&block)
24
+ end
25
+ end
26
+
27
+ def initialize(user, locale: nil, parent: nil)
28
+ @user = user
29
+ @locale = locale || I18n.default_locale
30
+ @parent = parent
31
+ end
32
+
33
+ def page(name, options={}, &block)
34
+ page = Page.create(
35
+ { name: name }
36
+ .merge(default_options)
37
+ .merge(options)
38
+ )
39
+ if block_given?
40
+ self.class
41
+ .new(user, locale: locale, parent: page)
42
+ .run(&block)
43
+ end
44
+ page
45
+ end
46
+
47
+ def run(&block)
48
+ instance_eval(&block)
49
+ end
50
+
51
+ private
52
+
53
+ def default_options
54
+ {
55
+ author: user,
56
+ parent: parent,
57
+ status: 2,
58
+ locale: locale
59
+ }
60
+ end
61
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ class PageComment < ActiveRecord::Base
4
+ include PagesCore::Sweepable
5
+
6
+ belongs_to :page, counter_cache: :comments_count
7
+ attr_accessor :invalid_captcha
8
+
9
+ def valid_captcha?
10
+ (invalid_captcha) ? false : true
11
+ end
12
+
13
+ after_create do |page_comment|
14
+ if page_comment.page && page_comment.valid?
15
+ page_comment.page.update(last_comment_at: page_comment.created_at)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+
3
+ class PageFile < ActiveRecord::Base
4
+ include Dis::Model
5
+
6
+ belongs_to :page
7
+
8
+ validates_data_presence
9
+ validates :content_type, presence: true
10
+ validates :filename, presence: true
11
+ validates :content_length, presence: true
12
+
13
+ acts_as_list scope: :page
14
+
15
+ localizable do
16
+ attribute :description
17
+ end
18
+
19
+ before_validation :set_name_from_filename
20
+
21
+ after_save ThinkingSphinx::RealTime.callback_for(:page_file)
22
+
23
+ class << self
24
+ def formats
25
+ {
26
+ "audio/mpeg" => :mp3,
27
+ "image/gif" => :gif,
28
+ "image/jpeg" => :jpg,
29
+ "image/jpg" => :jpg,
30
+ "image/pjpeg" => :jpg,
31
+ "image/png" => :png,
32
+ "application/pdf" => :pdf
33
+ }
34
+ end
35
+ end
36
+
37
+ def format?
38
+ content_type && self.class.formats.keys.include?(content_type)
39
+ end
40
+
41
+ def format
42
+ self.class.formats[content_type]
43
+ end
44
+
45
+ def filename_extension
46
+ if filename_extension?
47
+ filename.match(/\.([^\.]+)$/)[1]
48
+ else
49
+ ""
50
+ end
51
+ end
52
+
53
+ def filename_extension?
54
+ filename =~ /\./
55
+ end
56
+
57
+ def to_param
58
+ if filename_extension?
59
+ "#{id}.#{filename_extension}"
60
+ else
61
+ "#{id}"
62
+ end
63
+ end
64
+
65
+ def published
66
+ page.published
67
+ end
68
+
69
+ private
70
+
71
+ def set_name_from_filename
72
+ self.name = File.basename(filename, ".*") if self.filename? && !self.name?
73
+ end
74
+ end