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,270 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module HeadTagsHelper
5
+ # Sets a default image to use for meta tags. Supports
6
+ # both paths and Image objects.
7
+ #
8
+ # default_meta_image image_path("facebook-share.png")
9
+ # default_meta_image root_page.image
10
+ #
11
+ def default_meta_image(*args)
12
+ if args.any?
13
+ @default_meta_image = args.first
14
+ else
15
+ @default_meta_image
16
+ end
17
+ end
18
+
19
+ # Returns true if default meta image has been set.
20
+ def default_meta_image?
21
+ default_meta_image ? true : false
22
+ end
23
+
24
+ # Sets a document title.
25
+ #
26
+ # document_title "Dashboard"
27
+ #
28
+ def document_title(*args)
29
+ if args.any?
30
+ @document_title = args.first
31
+ else
32
+ safe_join(
33
+ [@document_title, PagesCore.config(:site_name)].compact.uniq,
34
+ " - "
35
+ )
36
+ end
37
+ end
38
+ alias_method :page_title, :document_title
39
+
40
+ # Returns true if document title has been set.
41
+ def document_title?
42
+ @document_title ? true : false
43
+ end
44
+
45
+ # Generates links for all RSS feeds. Specify
46
+ # :include_hidden to also include hidden pages.
47
+ #
48
+ # feed_tags
49
+ # feed_tags include_hidden: true
50
+ #
51
+ def feed_tags(options = {})
52
+ feeds = Page.enabled_feeds(@locale, options)
53
+ return unless feeds.any?
54
+ feed_tags = [
55
+ rss_link_tag(
56
+ PagesCore.config(:site_name),
57
+ pages_url(@locale, format: :rss)
58
+ )
59
+ ]
60
+ if feeds.count < 1
61
+ feed_tags += feeds.map do |page|
62
+ rss_link_tag(
63
+ "#{PagesCore.config(:site_name)}: #{page.name}",
64
+ page_url(@locale, page, format: :rss)
65
+ )
66
+ end
67
+ end
68
+ safe_join(feed_tags, "\n")
69
+ end
70
+
71
+ # Outputs Google Analytics tracking code.
72
+ #
73
+ # google_analytics_tags "UA-12345678-1"
74
+ #
75
+ def google_analytics_tags(account_id)
76
+ javascript_tag(
77
+ "var _gaq = _gaq || [];\n" \
78
+ "_gaq.push(['_setAccount', '#{account_id}']);\n" \
79
+ "_gaq.push(['_trackPageview']);\n" \
80
+ "(function() {\n" \
81
+ "var ga = document.createElement('script'); " \
82
+ "ga.type = 'text/javascript'; ga.async = true;\n" \
83
+ "ga.src = ('https:' == document.location.protocol ? 'https://ssl' " \
84
+ ": 'http://www') + '.google-analytics.com/ga.js';\n" \
85
+ "var s = document.getElementsByTagName('script')[0]; " \
86
+ "s.parentNode.insertBefore(ga, s);\n" \
87
+ "})();"
88
+ )
89
+ end
90
+
91
+ # Outputs a HTML5 doctype and head tags, with document title
92
+ # and relevant meta tags. Takes a block which will be placed
93
+ # inside <head>.
94
+ #
95
+ # <%= head_tag do %>
96
+ # <%= stylesheet_link_tag "application" %>
97
+ # <%= javascript_include_tag "application" %>
98
+ # <%= feed_tags %>
99
+ # <% end %>
100
+ #
101
+ def head_tag(&block)
102
+ # The block output must be captured first
103
+ block_output = block_given? ? capture(&block) : nil
104
+
105
+ "<!doctype html>\n<html lang=\"#{I18n.locale}\">".html_safe +
106
+ content_tag(:head) { safe_join(head_tag_contents(block_output), "\n") }
107
+ end
108
+
109
+ # Sets a description for meta tags.
110
+ #
111
+ # meta_description "This is an awesome site"
112
+ #
113
+ def meta_description(*args)
114
+ if args.any?
115
+ @meta_description = args.first
116
+ else
117
+ description = @meta_description
118
+ description ||= @page.meta_description if @page.try(&:meta_description?)
119
+ description ||= @page.excerpt if @page && !@page.excerpt.empty?
120
+ strip_tags(description)
121
+ end
122
+ end
123
+
124
+ # Returns true if meta description has been set.
125
+ def meta_description?
126
+ !meta_description.blank?
127
+ end
128
+
129
+ # Sets an image to use for meta tags. Supports
130
+ # both paths and Image objects.
131
+ #
132
+ # meta_image image_path("facebook-share.png")
133
+ # meta_image @page.image
134
+ #
135
+ def meta_image(*args)
136
+ if args.any?
137
+ @meta_image = args.first
138
+ else
139
+ image = @meta_image
140
+ image ||= @page.try(&:meta_image)
141
+ image ||= @page.try(&:image)
142
+ image ||= default_meta_image
143
+ if image.is_a?(Image)
144
+ dynamic_image_url(image, size: "1200x", only_path: false)
145
+ else
146
+ image
147
+ end
148
+ end
149
+ end
150
+
151
+ # Returns true if meta image has been set.
152
+ def meta_image?
153
+ !meta_image.blank? || default_meta_image?
154
+ end
155
+
156
+ # Sets keywords for meta tags.
157
+ #
158
+ # meta_keywords "cialis viagra"
159
+ #
160
+ def meta_keywords(*args)
161
+ if args.any?
162
+ @meta_keywords = Array(args.first).join(" ")
163
+ else
164
+ keywords = @meta_keywords
165
+ keywords ||= @page.tag_list if @page && @page.tags.any?
166
+ strip_tags(keywords)
167
+ end
168
+ end
169
+
170
+ # Returns true if meta keywords have been set.
171
+ def meta_keywords?
172
+ !meta_keywords.blank?
173
+ end
174
+
175
+ def open_graph_properties
176
+ @_open_graph_properties ||= {}
177
+ end
178
+
179
+ # Outputs Open Graph tags for Facebook.
180
+ def open_graph_tags
181
+ properties = default_open_graph_properties.merge(open_graph_properties)
182
+ safe_join(
183
+ properties
184
+ .delete_if { |_, content| content.nil? }
185
+ .map do |name, content|
186
+ tag(:meta, property: "og:#{name}", content: content)
187
+ end,
188
+ "\n"
189
+ )
190
+ end
191
+
192
+ # Generates a link to an RSS feed.
193
+ #
194
+ # rss_link_tag "My feed", "feed.rss"
195
+ #
196
+ def rss_link_tag(title, href)
197
+ tag(
198
+ :link,
199
+ rel: "alternate",
200
+ type: "application/rss+xml",
201
+ title: title,
202
+ href: href
203
+ )
204
+ end
205
+
206
+ # Outputs Typekit tags.
207
+ #
208
+ # typekit_tags "aadgrag"
209
+ #
210
+ def typekit_tags(kit_id)
211
+ safe_join([
212
+ javascript_include_tag("http://use.typekit.com/#{kit_id}.js"),
213
+ javascript_tag("try{Typekit.load();}catch(e){}")
214
+ ], "\n")
215
+ end
216
+
217
+ private
218
+
219
+ def default_open_graph_title
220
+ if @page.try(:open_graph_title?)
221
+ @page.open_graph_title
222
+ else
223
+ document_title
224
+ end
225
+ end
226
+
227
+ def default_open_graph_description
228
+ if @page.try(:open_graph_description?)
229
+ @page.open_graph_description
230
+ elsif meta_description?
231
+ meta_description
232
+ end
233
+ end
234
+
235
+ def default_open_graph_properties
236
+ {
237
+ type: "website",
238
+ site_name: PagesCore.config(:site_name),
239
+ title: default_open_graph_title,
240
+ image: (meta_image if meta_image?),
241
+ description: default_open_graph_description,
242
+ url: request.url
243
+ }
244
+ end
245
+
246
+ def meta_description_tag
247
+ return unless meta_description?
248
+ tag(:meta, name: "description", content: meta_description)
249
+ end
250
+
251
+ def meta_keywords_tag
252
+ return unless meta_keywords?
253
+ tag(:meta, name: "keywords", content: meta_keywords)
254
+ end
255
+
256
+ def head_tag_contents(block_output)
257
+ [
258
+ tag(:meta, charset: "utf-8"),
259
+ tag(:meta, "http-equiv" => "X-UA-Compatible", "content" => "IE=edge"),
260
+ content_tag(:title, document_title),
261
+ meta_description_tag,
262
+ meta_keywords_tag,
263
+ (tag(:link, rel: "image_src", href: meta_image) if meta_image?),
264
+ open_graph_tags,
265
+ csrf_meta_tags,
266
+ block_output
267
+ ]
268
+ end
269
+ end
270
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module ImagesHelper
5
+ include DynamicImage::Helper
6
+
7
+ def dynamic_image_tag(record_or_array, options={})
8
+ super(
9
+ record_or_array,
10
+ extract_alt_text(record_or_array).merge(options)
11
+ )
12
+ end
13
+
14
+ def original_dynamic_image_tag(record_or_array, options={})
15
+ super(
16
+ record_or_array,
17
+ extract_alt_text(record_or_array).merge(options)
18
+ )
19
+ end
20
+
21
+ def uncropped_dynamic_image_tag(record_or_array, options={})
22
+ super(
23
+ record_or_array,
24
+ extract_alt_text(record_or_array).merge(options)
25
+ )
26
+ end
27
+
28
+ private
29
+
30
+ def extract_alt_text(record_or_array)
31
+ record = extract_dynamic_image_record(record_or_array)
32
+ return {} unless record.alternative?
33
+ { alt: record.alternative }
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,14 @@
1
+ module PagesCore
2
+ module LoginHelper
3
+ def login_form(success_url:, login_url:)
4
+ render(
5
+ partial: "admin/users/login_form",
6
+ locals: { success_url: success_url, login_url: login_url }
7
+ )
8
+ end
9
+
10
+ def logout_link(name, login_url:)
11
+ link_to name, session_path(login_url: login_url), method: "delete"
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ ThinkingSphinx::Index.define :page_file, with: :real_time do
2
+ indexes name
3
+ indexes filename
4
+
5
+ has page_id, type: :integer
6
+ has created_at, type: :timestamp
7
+ has updated_at, type: :timestamp
8
+ has published, type: :boolean
9
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ ThinkingSphinx::Index.define :page, with: :real_time do
4
+ indexes localization_values
5
+ indexes category_names
6
+ indexes tag_list
7
+ indexes author.name, as: :author_name
8
+ indexes author.email, as: :author_email
9
+ indexes comment_names
10
+ indexes comment_bodies
11
+ indexes file_names
12
+ indexes file_filenames
13
+
14
+ has category_ids, type: :integer, multi: true
15
+ has tag_ids, type: :integer, multi: true
16
+
17
+ has published_at, type: :timestamp
18
+ has created_at, type: :timestamp
19
+ has updated_at, type: :timestamp
20
+ has user_id, type: :integer
21
+ has parent_page_id, type: :integer
22
+ has status, type: :integer
23
+ has template, type: :string
24
+ has autopublish, type: :boolean
25
+ has feed_enabled, type: :boolean
26
+ has published, type: :boolean
27
+
28
+ set_property group_concat_max_len: 16.megabytes
29
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ ThinkingSphinx::Index.define :user, with: :real_time do
4
+ indexes username
5
+ indexes name
6
+ indexes email
7
+
8
+ has last_login_at, type: :timestamp
9
+ has created_at, type: :timestamp
10
+ has activated, type: :boolean
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ class AutopublishJob < ActiveJob::Base
5
+ queue_as :pages_core
6
+
7
+ def perform
8
+ Autopublisher.run!
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ class SweepCacheJob < ActiveJob::Base
5
+ queue_as :pages_core
6
+
7
+ def perform
8
+ PagesCore::CacheSweeper.sweep!
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+
3
+ class AdminMailer < ActionMailer::Base
4
+ before_action :default_headers
5
+ default from: proc { "\"Pages\" <support@manualdesign.no>" }
6
+
7
+ def error_report(error_report, from, description)
8
+ @error_report, @from, @description = error_report, from, description
9
+ short_message = @error_report[:message].gsub(/[\s\n]+/, " ")[0..80]
10
+ mail(
11
+ to: "system+error@manualdesign.no",
12
+ from: "\"Error reports\" <system+error@manualdesign.no>",
13
+ subject: "[#{PagesCore.config(:site_name)}] Error: #{short_message}"
14
+ )
15
+ end
16
+
17
+ def password_reset(user, url)
18
+ @user, @url = user, url
19
+ mail(
20
+ to: @user.email,
21
+ subject: "Reset your password on #{PagesCore.config(:site_name)}"
22
+ )
23
+ end
24
+
25
+ def comment_notification(recipient, page, comment, url)
26
+ @recipient, @page, @comment, @url = recipient, page, comment, url
27
+ mail(
28
+ to: recipient,
29
+ subject: "[#{PagesCore.config(:site_name)}] New comment on #{@page.name}"
30
+ )
31
+ end
32
+
33
+ def invite(invite, url)
34
+ @invite, @url = invite, url
35
+ mail(
36
+ to: @invite.email,
37
+ subject: "#{PagesCore.config(:site_name)} has invited you to Pages"
38
+ )
39
+ end
40
+
41
+ private
42
+
43
+ def default_headers
44
+ headers("X-MC-Subaccount" => "pages")
45
+ end
46
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ class Autopublisher
4
+ class << self
5
+ def run!(_options = {})
6
+ if due_pages.any?
7
+ PagesCore::CacheSweeper.once do
8
+ due_pages.each do |p|
9
+ p.update(autopublish: false)
10
+ end
11
+ end
12
+ end
13
+ self.queue!
14
+ end
15
+
16
+ def queue!
17
+ return unless queued_pages.any?
18
+ PagesCore::AutopublishJob
19
+ .set(wait_until: queued_pages.first.published_at)
20
+ .perform_later
21
+ end
22
+
23
+ protected
24
+
25
+ def queued_pages
26
+ Page.where(autopublish: true).order("published_at ASC")
27
+ end
28
+
29
+ def due_pages
30
+ queued_pages.where("published_at < ?", (Time.now + 2.minutes))
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ class Category < ActiveRecord::Base
4
+ has_and_belongs_to_many :pages, join_table: "pages_categories"
5
+ validates_presence_of :name
6
+ acts_as_list
7
+
8
+ before_save :set_slug
9
+ after_save ThinkingSphinx::RealTime.callback_for(:pages, [:page])
10
+
11
+ scope :by_name, -> { order("name ASC") }
12
+
13
+ private
14
+
15
+ def set_slug
16
+ self.slug = name
17
+ .downcase
18
+ .gsub(/[^\w\s]/, "")
19
+ .split(/[^\w\d\-]+/)
20
+ .compact
21
+ .join("-")
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ module PagesCore
2
+ module HasRoles
3
+ extend ActiveSupport::Concern
4
+
5
+ def role?(role_name)
6
+ role_names.include?(role_name.to_s)
7
+ end
8
+ alias_method :has_role?, :role?
9
+
10
+ def role_names
11
+ roles.map(&:name)
12
+ end
13
+
14
+ def role_names=(names)
15
+ new_roles = names.map do |name|
16
+ if role?(name)
17
+ roles.where(name: name).first
18
+ else
19
+ roles.new(name: name)
20
+ end
21
+ end
22
+ self.roles = new_roles
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module HumanizableParam
5
+ extend ActiveSupport::Concern
6
+
7
+ def humanized_param(slug)
8
+ return id.to_s unless slug && !slug.blank?
9
+ "#{id}-" + slug
10
+ .gsub(/[\[\{]/, "(")
11
+ .gsub(/[\]\}]/, ")")
12
+ .gsub(/[^[[:alnum:]]()\-]+/, "-")
13
+ .gsub(/[\-]{2,}/, "-")
14
+ .gsub(/(^\-|\-$)/, "")
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,85 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module PageTree
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ belongs_to :parent,
9
+ class_name: "Page",
10
+ foreign_key: :parent_page_id,
11
+ inverse_of: :children
12
+
13
+ has_many :children,
14
+ class_name: "Page",
15
+ foreign_key: :parent_page_id,
16
+ inverse_of: :parent,
17
+ dependent: :destroy
18
+
19
+ # This must be included after the belongs_to call in order
20
+ # to override the .parent method.
21
+ include PagesCore::PageTree::InstanceMethods
22
+ end
23
+
24
+ module ClassMethods
25
+ # Returns all root pages
26
+ def roots
27
+ where(parent_page_id: nil).order("position ASC")
28
+ end
29
+
30
+ # Returns the first root page
31
+ def root
32
+ roots.first
33
+ end
34
+ end
35
+
36
+ module InstanceMethods
37
+ # Returns list of ancestors, starting from parent until root.
38
+ #
39
+ # subchild1.ancestors # => [child1, root]
40
+ def ancestors
41
+ node, nodes = self, []
42
+ nodes << node = node.parent while node.parent
43
+ nodes
44
+ end
45
+
46
+ # Finds the page's next sibling. Returns nil if there isn't one.
47
+ def next_sibling
48
+ return unless siblings.any?
49
+ siblings[(siblings.index(self) + 1)...siblings.length].try(&:first)
50
+ end
51
+
52
+ # Returns the pages parent
53
+ def parent
54
+ super.try { |node| node.localize(locale) }
55
+ end
56
+
57
+ # Finds the page's next sibling. Returns nil if there isn't one.
58
+ def previous_sibling
59
+ return unless siblings.any?
60
+ siblings[0...siblings.index(self)].try(&:last)
61
+ end
62
+
63
+ # Returns the root node of the tree.
64
+ def root
65
+ self_and_ancestors.last
66
+ end
67
+
68
+ # Returns ancestors and current node itself.
69
+ #
70
+ # subchild1.self_and_ancestors # => [subchild1, child1, root]
71
+ def self_and_ancestors
72
+ [self] + ancestors
73
+ end
74
+
75
+ # Returns all siblings, including self.
76
+ def siblings
77
+ if parent
78
+ parent.pages
79
+ else
80
+ self.class.roots.map { |node| node.localize(locale) }
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,33 @@
1
+ module PagesCore
2
+ module SearchablePage
3
+ extend ActiveSupport::Concern
4
+
5
+ def localization_values
6
+ localizations.map(&:value)
7
+ end
8
+
9
+ def category_names
10
+ categories.map(&:name)
11
+ end
12
+
13
+ def comment_names
14
+ comments.map(&:name)
15
+ end
16
+
17
+ def comment_bodies
18
+ comments.map(&:body)
19
+ end
20
+
21
+ def file_names
22
+ files.map(&:name)
23
+ end
24
+
25
+ def file_filenames
26
+ files.map(&:filename)
27
+ end
28
+
29
+ def published
30
+ published?
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Sweepable
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ after_save :sweep_cache!
9
+ after_destroy :sweep_cache!
10
+ end
11
+
12
+ attr_accessor :cache_swept
13
+
14
+ protected
15
+
16
+ def sweep_cache!
17
+ return unless PagesCore::CacheSweeper.enabled
18
+ return if cache_swept
19
+ PagesCore::SweepCacheJob.perform_later
20
+ self.cache_swept = true
21
+ end
22
+ end
23
+ end