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,85 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Configuration
5
+ class Base
6
+ class InvalidConfigurationKey < StandardError; end
7
+
8
+ def self.settings
9
+ @settings ||= {}
10
+ end
11
+
12
+ def self.setting(key, type, default = nil)
13
+ settings[key] = OpenStruct.new(type: type, default: default)
14
+
15
+ define_method key do |*args|
16
+ if args.length > 0
17
+ set(key, *args)
18
+ else
19
+ get(key)
20
+ end
21
+ end
22
+
23
+ define_method "#{key}=" do |value|
24
+ set(key, value)
25
+ end
26
+
27
+ define_method "#{key}?" do
28
+ get(key) ? true : false
29
+ end
30
+ end
31
+
32
+ def get(key)
33
+ fail InvalidConfigurationKey unless setting?(key)
34
+ if configuration.key?(key)
35
+ configuration[key]
36
+ else
37
+ self.class.settings[key].default
38
+ end
39
+ end
40
+
41
+ def set(key, value)
42
+ fail InvalidConfigurationKey unless setting?(key)
43
+ value = parse_value(key, value)
44
+ unless valid_type?(key, value)
45
+ fail(
46
+ ArgumentError,
47
+ "expected #{self.class.settings[key].type}, got #{value.class}"
48
+ )
49
+ end
50
+ configuration[key] = value
51
+ end
52
+
53
+ protected
54
+
55
+ def configuration
56
+ @configuration ||= {}
57
+ end
58
+
59
+ def setting?(key)
60
+ self.class.settings.key?(key)
61
+ end
62
+
63
+ def type_for(key)
64
+ self.class.settings[key].type
65
+ end
66
+
67
+ def valid_type?(key, value)
68
+ return true if value.nil?
69
+ if type_for(key) == :boolean
70
+ value.is_a?(TrueClass) || value.is_a?(FalseClass)
71
+ else
72
+ value.is_a?(type_for(key).to_s.camelize.constantize)
73
+ end
74
+ end
75
+
76
+ def parse_value(key, value)
77
+ if type_for(key) == :boolean
78
+ value = true if value == :enabled
79
+ value = false if value == :disabled
80
+ end
81
+ value
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Configuration
5
+ class Pages < Base
6
+ setting :site_name, :string, "Pages Site"
7
+ setting :default_sender, :string
8
+ setting :localizations, :boolean, false
9
+ setting :locales, :hash
10
+ setting :text_filter, :symbol, :textile
11
+ setting :page_cache, :boolean, true
12
+ setting :domain_based_cache, :boolean, false
13
+ setting :rss_fulltext, :boolean, true
14
+ setting :image_fallback_url, :string
15
+ setting :default_author, :string
16
+ setting :comment_notifications, :array, []
17
+ setting :close_comments_after, :integer
18
+ setting :comment_honeypot, :boolean, false
19
+ setting :recaptcha, :boolean, false
20
+ setting :pages_path_scope, :string
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,9 @@
1
+ # encoding: utf-8
2
+
3
+ load "pages_core/configuration/base.rb"
4
+ load "pages_core/configuration/pages.rb"
5
+
6
+ module PagesCore
7
+ module Configuration
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ class Engine < Rails::Engine
5
+ initializer :active_job do |_config|
6
+ ActiveJob::Base.queue_adapter = :delayed_job
7
+ end
8
+
9
+ initializer :append_migrations do |app|
10
+ unless app.root.to_s.match root.to_s
11
+ config.paths["db/migrate"].expanded.each do |expanded_path|
12
+ app.config.paths["db/migrate"] << expanded_path
13
+ end
14
+ end
15
+ end
16
+
17
+ # Enable asset precompilation
18
+ initializer :assets do |_config|
19
+ Rails.application.config.assets.precompile += %w(
20
+ pages/admin.js
21
+ pages/admin.css
22
+ pages/admin/print.css
23
+ pages/errors.css
24
+ )
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Extensions
5
+ module HashExtensions
6
+ def deep_merge(hash)
7
+ target = dup
8
+
9
+ hash.keys.each do |key|
10
+ if hash[key].is_a?(Hash) && self[key].is_a?(Hash)
11
+ target[key] = target[key].deep_merge(hash[key])
12
+ next
13
+ end
14
+
15
+ target[key] = hash[key]
16
+ end
17
+
18
+ target
19
+ end
20
+ end
21
+ end
22
+ end
23
+ Hash.send(:include, PagesCore::Extensions::HashExtensions)
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Extensions
5
+ module StringExtensions
6
+ def to_html_with(append, options = {})
7
+ to_html(options.merge(append: append))
8
+ end
9
+
10
+ def to_html(options = {})
11
+ PagesCore::HtmlFormatter.to_html(self, options)
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ String.send(:include, PagesCore::Extensions::StringExtensions)
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+
3
+ load "pages_core/extensions/hash_extensions.rb"
4
+ load "pages_core/extensions/string_extensions.rb"
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Localizable
5
+ # = Localizable::ActiveRecordExtension
6
+ #
7
+ # Extends ActiveRecord::Base with the localizable setup method.
8
+ #
9
+ module ActiveRecordExtension
10
+ # Extends the model with Localizable features.
11
+ # It takes an optional block as argument, which yields an instance of
12
+ # Localizable::Configuration.
13
+ #
14
+ # Example:
15
+ #
16
+ # class Page < ActiveRecord::Base
17
+ # localizable do
18
+ # attribute :name
19
+ # attribute :body
20
+ # end
21
+ # end
22
+ #
23
+ def localizable(&block)
24
+ unless self.is_a?(Localizable::ClassMethods)
25
+ send :extend, Localizable::ClassMethods
26
+ send :include, Localizable::InstanceMethods
27
+ has_many(
28
+ :localizations,
29
+ as: :localizable,
30
+ dependent: :destroy,
31
+ autosave: true
32
+ )
33
+ before_save :cleanup_localizations!
34
+ end
35
+ localizable_configuration.instance_eval(&block) if block_given?
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ ActiveRecord::Base.send(:extend, PagesCore::Localizable::ActiveRecordExtension)
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Localizable
5
+ # = Localizable::ClassMethods
6
+ #
7
+ # Class methods for all Localizable models.
8
+ #
9
+ module ClassMethods
10
+ # Returns a scope where all records will be set to the given locale.
11
+ #
12
+ def in_locale(locale)
13
+ all
14
+ .extending(Localizable::ScopeExtension)
15
+ .localize(locale)
16
+ .includes(:localizations)
17
+ end
18
+
19
+ # Returns a scope with only records matching the given locale.
20
+ #
21
+ # Page.localized('en').first.locale # => 'en'
22
+ #
23
+ def localized(locale)
24
+ in_locale(locale)
25
+ .where("localizations.locale = ?", locale)
26
+ .references(:localizations)
27
+ end
28
+
29
+ def localized_attributes
30
+ localizable_configuration.attributes.keys
31
+ end
32
+
33
+ # Accessor for the configuration.
34
+ def localizable_configuration
35
+ @localizable_configuration ||= inherited_localizable_configuration
36
+ end
37
+
38
+ private
39
+
40
+ def inherited_localizable_configuration
41
+ if superclass.respond_to?(:localizable_configuration)
42
+ Localizable::Configuration.new(
43
+ superclass.localizable_configuration.attributes.dup
44
+ )
45
+ else
46
+ Localizable::Configuration.new
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Localizable
5
+ class Configuration
6
+ def initialize(attributes = nil)
7
+ @attributes = attributes
8
+ end
9
+
10
+ def attribute(attribute_name, options = {})
11
+ attribute_table[attribute_name.to_sym] = options
12
+ end
13
+
14
+ def attributes
15
+ attribute_table.merge(dictionary_attributes)
16
+ end
17
+
18
+ def dictionary(dict)
19
+ dictionaries << dict
20
+ end
21
+
22
+ def attribute?(attribute)
23
+ attributes.keys.include?(attribute)
24
+ end
25
+
26
+ private
27
+
28
+ def dictionaries
29
+ @dictionaries ||= []
30
+ end
31
+
32
+ def dictionary_attributes
33
+ dictionaries.map(&:call).inject({}) do |attrs, list|
34
+ attrs.merge(hashify(list))
35
+ end
36
+ end
37
+
38
+ def hashify(list)
39
+ return list if list.is_a?(Hash)
40
+ list.each_with_object({}) do |e, a|
41
+ a[e] = {}
42
+ end
43
+ end
44
+
45
+ def attribute_table
46
+ @attributes ||= {}
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,130 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Localizable
5
+ # = Localizable::InstanceMethods
6
+ #
7
+ # This is the public API for all localizable models.
8
+ # See Localizable for usage examples.
9
+ #
10
+ module InstanceMethods
11
+ # Returns all locales saved for this page.
12
+ #
13
+ def locales
14
+ localizer.locales
15
+ end
16
+
17
+ # Getter for locale
18
+ #
19
+ # page.locale # => 'en'
20
+ #
21
+ def locale
22
+ localizer.locale
23
+ end
24
+
25
+ # Setter for locale
26
+ #
27
+ # page.locale = 'no' # => 'no'
28
+ #
29
+ def locale=(locale)
30
+ @localizer = Localizer.new(self)
31
+ localizer.locale = locale
32
+ end
33
+
34
+ # Returns true if this page has a locale set
35
+ #
36
+ def locale?
37
+ localizer.locale?
38
+ end
39
+
40
+ # Returns a copy of the model with a different locale.
41
+ #
42
+ # localized = page.localize('en')
43
+ #
44
+ # localize also takes a block as an argument, which returns the
45
+ # result of the block.
46
+ #
47
+ # page.localize('nb') do |p|
48
+ # p.locale # => 'nb'
49
+ # end
50
+ # page.locale # => 'en'
51
+ #
52
+ def localize(locale)
53
+ clone = self.clone.localize!(locale)
54
+ (block_given?) ? (yield clone) : clone
55
+ end
56
+
57
+ # In-place variant of #localize.
58
+ #
59
+ # page.localize!('en')
60
+ #
61
+ # This is functionally equivalent to setting locale=,
62
+ # but returns the model instead of the locale and is chainable.
63
+ #
64
+ def localize!(locale)
65
+ @localizer = Localizer.new(self)
66
+ localizer.locale = locale
67
+ self
68
+ end
69
+
70
+ # assign_attributes from ActiveRecord is overridden to catch locale before
71
+ # any other attributes are written. This enables the following construct:
72
+ #
73
+ # Page.create(name: 'My Page', locale: 'en')
74
+ #
75
+ def assign_attributes(new_attributes)
76
+ if new_attributes.is_a?(Hash)
77
+ attributes = new_attributes.stringify_keys
78
+ self.locale = attributes["language"] if attributes.key?("language")
79
+ self.locale = attributes["locale"] if attributes.key?("locale")
80
+ end
81
+ super
82
+ end
83
+
84
+ # A localized model responds to :foo, :foo= and :foo?
85
+ #
86
+ def respond_to?(method_name, *args)
87
+ requested_attribute, _ = method_name.to_s.match(/(.*?)([\?=]?)$/)[1..2]
88
+ localizer.attribute?(requested_attribute.to_sym) ? true : super
89
+ end
90
+
91
+ alias_method :translate, :localize
92
+ alias_method :translate!, :localize!
93
+ alias_method :working_language, :locale
94
+ alias_method :working_language=, :locale=
95
+
96
+ protected
97
+
98
+ # Getter for the model's Localizer.
99
+ #
100
+ def localizer
101
+ @localizer ||= Localizer.new(self)
102
+ end
103
+
104
+ # Callback for cleaning up empty localizations.
105
+ # This is performed automatically when the model is saved.
106
+ #
107
+ def cleanup_localizations!
108
+ localizer.cleanup_localizations!
109
+ end
110
+
111
+ def method_missing(method_name, *args)
112
+ attr = method_to_attr(method_name)
113
+ super unless localizer.attribute?(attr)
114
+
115
+ case method_name.to_s
116
+ when /\?$/
117
+ localizer.value_for?(attr)
118
+ when /=$/
119
+ localizer.set(attr, args.first)
120
+ else
121
+ localizer.get(attr).to_s
122
+ end
123
+ end
124
+
125
+ def method_to_attr(method_name)
126
+ method_name.to_s.match(/(.*?)([\?=]?)$/)[1].to_sym
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,72 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Localizable
5
+ class Localizer
6
+ attr_accessor :locale
7
+ def initialize(model)
8
+ @model = model
9
+ @configuration = model.class.localizable_configuration
10
+ end
11
+
12
+ def attribute?(attribute)
13
+ @configuration.attribute?(attribute)
14
+ end
15
+
16
+ def locales
17
+ @model.localizations.map(&:locale).uniq
18
+ end
19
+
20
+ def locale?
21
+ locale ? true : false
22
+ end
23
+
24
+ def get(attribute, options = {})
25
+ get_options = { locale: locale }.merge(options)
26
+
27
+ find_localizations(
28
+ attribute.to_s,
29
+ get_options[:locale].to_s
30
+ ).try(&:first) ||
31
+ @model.localizations.new(
32
+ locale: get_options[:locale].to_s,
33
+ name: attribute.to_s
34
+ )
35
+ end
36
+
37
+ def set(attribute, value, options = {})
38
+ set_options = { locale: locale }.merge(options)
39
+ if value.is_a?(Hash)
40
+ value.each do |loc, val|
41
+ set(attribute, val, locale: loc)
42
+ end
43
+ else
44
+ unless set_options[:locale]
45
+ fail(
46
+ ArgumentError,
47
+ "Tried to set :#{attribute}, but no locale has been set"
48
+ )
49
+ end
50
+ get(attribute, locale: set_options[:locale]).value = value
51
+ end
52
+ value
53
+ end
54
+
55
+ def value_for?(attribute)
56
+ get(attribute).value?
57
+ end
58
+
59
+ def cleanup_localizations!
60
+ @model.localizations = @model.localizations.select(&:value?)
61
+ end
62
+
63
+ private
64
+
65
+ def find_localizations(name, locale)
66
+ @model.localizations.select do |l|
67
+ l.name == name && l.locale == locale
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ module Localizable
5
+ # = Localizable::ScopeExtension
6
+ #
7
+ # Injected into the Relation when Model.localized is called.
8
+ #
9
+ module ScopeExtension
10
+ attr_accessor :locale
11
+
12
+ def localize(locale)
13
+ @locale = locale
14
+ self
15
+ end
16
+
17
+ def to_a
18
+ super.map { |record| record.localize(@locale) }
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ load "pages_core/localizable/active_record_extension.rb"
4
+ load "pages_core/localizable/class_methods.rb"
5
+ load "pages_core/localizable/configuration.rb"
6
+ load "pages_core/localizable/instance_methods.rb"
7
+ load "pages_core/localizable/localizer.rb"
8
+ load "pages_core/localizable/scope_extension.rb"
9
+
10
+ module PagesCore
11
+ # = Localizable
12
+ #
13
+ # Localizable allows any model to have localized attributes.
14
+ #
15
+ # == Configuring the model
16
+ #
17
+ # class Page < ActiveRecord::Base
18
+ # localizable do
19
+ # attribute :name
20
+ # attribute :body
21
+ # end
22
+ # end
23
+ #
24
+ # == Usage
25
+ #
26
+ # page = Page.create(name: 'Hello', locale: 'en')
27
+ # page.name? # => true
28
+ # page.name.to_s # => 'Hello'
29
+ #
30
+ # The localized attributes always return an instance of Localization.
31
+ #
32
+ # To get a localized version of a page, call .localize on it:
33
+ #
34
+ # page = Page.first.localize('en')
35
+ #
36
+ # .localize also takes a block argument:
37
+ #
38
+ # page.localize('nb') do |p|
39
+ # p.locale # => 'nb'
40
+ # end
41
+ # page.locale # => 'en'
42
+ #
43
+ # Multiple locales can be updated at the same time:
44
+ #
45
+ # page.name = {'en' => 'Hello', 'nb' => 'Hallo'}
46
+ #
47
+ module Localizable
48
+ end
49
+ end
@@ -0,0 +1,14 @@
1
+ # encoding: utf-8
2
+
3
+ module PagesCore
4
+ class PagesPlugin < Plugin
5
+ paths["db/migrate"] = "db/migrate"
6
+
7
+ admin_menu_item "News", proc { news_admin_pages_path(@locale) }, :pages,
8
+ if: proc { Page.news_pages.any? },
9
+ current: proc { @page && @page.parent.try(&:news_page?) }
10
+
11
+ admin_menu_item "Pages", proc { admin_pages_path(@locale) }, :pages
12
+ admin_menu_item "Users", proc { admin_users_path }, :account
13
+ end
14
+ end