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.
- checksums.yaml +7 -0
- data/README.md +29 -0
- data/Rakefile +10 -0
- data/app/assets/images/pages/admin/description-bg.gif +0 -0
- data/app/assets/images/pages/admin/drag-handle.gif +0 -0
- data/app/assets/images/pages/admin/drag-icon.png +0 -0
- data/app/assets/images/pages/admin/flash-error-bg.gif +0 -0
- data/app/assets/images/pages/admin/formelement-bg.gif +0 -0
- data/app/assets/images/pages/admin/header-tab-current-bg.gif +0 -0
- data/app/assets/images/pages/admin/icon.png +0 -0
- data/app/assets/images/pages/admin/image-editor-bg.png +0 -0
- data/app/assets/images/pages/admin/list-table-pin-blue.gif +0 -0
- data/app/assets/images/pages/admin/list-table-pin-disabled.gif +0 -0
- data/app/assets/images/pages/admin/list-table-pin-green.gif +0 -0
- data/app/assets/images/pages/admin/list-table-pin-red.gif +0 -0
- data/app/assets/images/pages/admin/list-table-pin-yellow.gif +0 -0
- data/app/assets/images/pages/admin/list-table-td-bg.gif +0 -0
- data/app/assets/images/pages/admin/loading-modal.gif +0 -0
- data/app/assets/images/pages/admin/sidebar-bg.gif +0 -0
- data/app/assets/images/pages/admin/textarea_controls.gif +0 -0
- data/app/assets/images/pages/admin/warning-icon.gif +0 -0
- data/app/assets/images/pages/favicon.gif +0 -0
- data/app/assets/images/pages/feed-icon-14x14.png +0 -0
- data/app/assets/javascripts/pages/admin/controllers/base.js.coffee +4 -0
- data/app/assets/javascripts/pages/admin/controllers/pages_controller.js.coffee +139 -0
- data/app/assets/javascripts/pages/admin/controllers/users_controller.js.coffee +9 -0
- data/app/assets/javascripts/pages/admin/features/content_tabs.js.coffee +47 -0
- data/app/assets/javascripts/pages/admin/features/editable_image.js.coffee.erb +122 -0
- data/app/assets/javascripts/pages/admin/features/modal.js.coffee +66 -0
- data/app/assets/javascripts/pages/admin/features/page_images.js +329 -0
- data/app/assets/javascripts/pages/admin/features/rich_text.js.coffee +40 -0
- data/app/assets/javascripts/pages/admin/features/tag_editor.js +159 -0
- data/app/assets/javascripts/pages/admin/lib/ajax_extensions.js.coffee +17 -0
- data/app/assets/javascripts/pages/admin/lib/center_on_screen.js.coffee +21 -0
- data/app/assets/javascripts/pages/admin/lib/jrichtextarea.js +57 -0
- data/app/assets/javascripts/pages/admin.js.coffee +54 -0
- data/app/assets/javascripts/pages/login_form.js.coffee +17 -0
- data/app/assets/stylesheets/pages/admin/buttons.css.erb +5 -0
- data/app/assets/stylesheets/pages/admin/controllers/artists.css.erb +94 -0
- data/app/assets/stylesheets/pages/admin/controllers/files.css.erb +58 -0
- data/app/assets/stylesheets/pages/admin/controllers/pages.css.scss.erb +178 -0
- data/app/assets/stylesheets/pages/admin/controllers/users.css.erb +3 -0
- data/app/assets/stylesheets/pages/admin/editable_image.css.erb +19 -0
- data/app/assets/stylesheets/pages/admin/forms.css.scss.erb +73 -0
- data/app/assets/stylesheets/pages/admin/header.css.erb +129 -0
- data/app/assets/stylesheets/pages/admin/images.css.scss.erb +160 -0
- data/app/assets/stylesheets/pages/admin/links.css.erb +34 -0
- data/app/assets/stylesheets/pages/admin/list_table.css.erb +56 -0
- data/app/assets/stylesheets/pages/admin/login.css.scss.erb +32 -0
- data/app/assets/stylesheets/pages/admin/modal.css.erb +14 -0
- data/app/assets/stylesheets/pages/admin/pagination.css.scss +22 -0
- data/app/assets/stylesheets/pages/admin/print.css.erb +17 -0
- data/app/assets/stylesheets/pages/admin/sidebar.css.erb +39 -0
- data/app/assets/stylesheets/pages/admin/sortable_images.css.erb +18 -0
- data/app/assets/stylesheets/pages/admin/tag_editor.css.scss.erb +48 -0
- data/app/assets/stylesheets/pages/admin/textarea.css.erb +55 -0
- data/app/assets/stylesheets/pages/admin.css.erb +404 -0
- data/app/assets/stylesheets/pages/errors.css +126 -0
- data/app/controller_dummies/admin/admin_controller.rb +6 -0
- data/app/controller_dummies/application_controller.rb +6 -0
- data/app/controller_dummies/frontend_controller.rb +4 -0
- data/app/controller_dummies/images_controller.rb +4 -0
- data/app/controller_dummies/page_files_controller.rb +4 -0
- data/app/controller_dummies/pages_controller.rb +4 -0
- data/app/controller_dummies/sitemaps_controller.rb +4 -0
- data/app/controllers/admin/categories_controller.rb +57 -0
- data/app/controllers/admin/images_controller.rb +48 -0
- data/app/controllers/admin/invites_controller.rb +79 -0
- data/app/controllers/admin/page_comments_controller.rb +61 -0
- data/app/controllers/admin/page_files_controller.rb +81 -0
- data/app/controllers/admin/page_images_controller.rb +116 -0
- data/app/controllers/admin/pages_controller.rb +179 -0
- data/app/controllers/admin/password_resets_controller.rb +83 -0
- data/app/controllers/admin/users_controller.rb +102 -0
- data/app/controllers/concerns/pages_core/authentication.rb +48 -0
- data/app/controllers/concerns/pages_core/domain_based_cache.rb +28 -0
- data/app/controllers/concerns/pages_core/exception_handler.rb +114 -0
- data/app/controllers/concerns/pages_core/policies_helper.rb +40 -0
- data/app/controllers/concerns/pages_core/process_titler.rb +44 -0
- data/app/controllers/errors_controller.rb +45 -0
- data/app/controllers/pages_core/admin_controller.rb +109 -0
- data/app/controllers/pages_core/application_controller.rb +31 -0
- data/app/controllers/pages_core/frontend/page_files_controller.rb +42 -0
- data/app/controllers/pages_core/frontend/pages_controller.rb +308 -0
- data/app/controllers/pages_core/frontend_controller.rb +34 -0
- data/app/controllers/pages_core/images_controller.rb +15 -0
- data/app/controllers/pages_core/sitemaps_controller.rb +73 -0
- data/app/controllers/sessions_controller.rb +38 -0
- data/app/formatters/pages_core/html_formatter.rb +86 -0
- data/app/helpers/admin/admin_helper.rb +7 -0
- data/app/helpers/admin/menu_helper.rb +65 -0
- data/app/helpers/admin/pages_helper.rb +74 -0
- data/app/helpers/application_helper.rb +5 -0
- data/app/helpers/frontend_helper.rb +5 -0
- data/app/helpers/pages_core/admin/admin_helper.rb +108 -0
- data/app/helpers/pages_core/admin/labelled_field_helper.rb +73 -0
- data/app/helpers/pages_core/admin/tag_editor_helper.rb +46 -0
- data/app/helpers/pages_core/application_helper.rb +65 -0
- data/app/helpers/pages_core/form_builder.rb +187 -0
- data/app/helpers/pages_core/frontend_helper.rb +21 -0
- data/app/helpers/pages_core/head_tags_helper.rb +270 -0
- data/app/helpers/pages_core/images_helper.rb +36 -0
- data/app/helpers/pages_core/login_helper.rb +14 -0
- data/app/indices/page_file_index.rb +9 -0
- data/app/indices/page_index.rb +29 -0
- data/app/indices/user_index.rb +11 -0
- data/app/jobs/pages_core/autopublish_job.rb +11 -0
- data/app/jobs/pages_core/sweep_cache_job.rb +11 -0
- data/app/mailers/admin_mailer.rb +46 -0
- data/app/models/autopublisher.rb +33 -0
- data/app/models/category.rb +23 -0
- data/app/models/concerns/pages_core/has_roles.rb +25 -0
- data/app/models/concerns/pages_core/humanizable_param.rb +17 -0
- data/app/models/concerns/pages_core/page_tree.rb +85 -0
- data/app/models/concerns/pages_core/searchable_page.rb +33 -0
- data/app/models/concerns/pages_core/sweepable.rb +23 -0
- data/app/models/concerns/pages_core/taggable.rb +46 -0
- data/app/models/concerns/pages_core/templateable.rb +85 -0
- data/app/models/image.rb +23 -0
- data/app/models/invite.rb +33 -0
- data/app/models/invite_role.rb +11 -0
- data/app/models/localization.rb +27 -0
- data/app/models/page.rb +281 -0
- data/app/models/page_builder.rb +61 -0
- data/app/models/page_comment.rb +18 -0
- data/app/models/page_file.rb +74 -0
- data/app/models/page_image.rb +62 -0
- data/app/models/password_reset_token.rb +38 -0
- data/app/models/role.rb +51 -0
- data/app/models/tag.rb +64 -0
- data/app/models/tagging.rb +22 -0
- data/app/models/user.rb +131 -0
- data/app/policies/invite_policy.rb +29 -0
- data/app/policies/page_file_policy.rb +25 -0
- data/app/policies/page_image_policy.rb +25 -0
- data/app/policies/page_policy.rb +33 -0
- data/app/policies/policy.rb +64 -0
- data/app/policies/user_policy.rb +49 -0
- data/app/serializers/admin/image_serializer.rb +10 -0
- data/app/serializers/admin/page_image_serializer.rb +6 -0
- data/app/serializers/page_image_serializer.rb +38 -0
- data/app/serializers/page_serializer.rb +21 -0
- data/app/views/admin/invites/new.html.erb +16 -0
- data/app/views/admin/invites/show.html.erb +25 -0
- data/app/views/admin/pages/_edit_comments.html.erb +21 -0
- data/app/views/admin/pages/_edit_content.html.erb +10 -0
- data/app/views/admin/pages/_edit_images.html.erb +84 -0
- data/app/views/admin/pages/_edit_metadata.html.erb +24 -0
- data/app/views/admin/pages/_edit_options.html.erb +72 -0
- data/app/views/admin/pages/_pagelisting.html.erb +63 -0
- data/app/views/admin/pages/edit.html.erb +161 -0
- data/app/views/admin/pages/index.html.erb +67 -0
- data/app/views/admin/pages/new.html.erb +48 -0
- data/app/views/admin/pages/news.html.erb +69 -0
- data/app/views/admin/password_resets/show.html.erb +24 -0
- data/app/views/admin/users/_access_control.html.erb +14 -0
- data/app/views/admin/users/_list.html.erb +62 -0
- data/app/views/admin/users/_login_form.html.erb +47 -0
- data/app/views/admin/users/deactivated.html.erb +12 -0
- data/app/views/admin/users/edit.html.erb +54 -0
- data/app/views/admin/users/index.html.erb +27 -0
- data/app/views/admin/users/login.html.erb +15 -0
- data/app/views/admin/users/new.html.erb +23 -0
- data/app/views/admin/users/new_password.html.erb +19 -0
- data/app/views/admin/users/show.html.erb +64 -0
- data/app/views/admin_mailer/comment_notification.text.erb +7 -0
- data/app/views/admin_mailer/error_report.html.erb +70 -0
- data/app/views/admin_mailer/invite.text.erb +9 -0
- data/app/views/admin_mailer/password_reset.text.erb +13 -0
- data/app/views/errors/403.html.erb +6 -0
- data/app/views/errors/404.html.erb +11 -0
- data/app/views/errors/405.html.erb +4 -0
- data/app/views/errors/500.html.erb +19 -0
- data/app/views/errors/500_critical.html.erb +7 -0
- data/app/views/errors/_generic_help.html.erb +21 -0
- data/app/views/errors/report.html.erb +4 -0
- data/app/views/feeds/pages.rss.builder +39 -0
- data/app/views/layouts/admin/_analytics.html.erb +18 -0
- data/app/views/layouts/admin/_header.html.erb +37 -0
- data/app/views/layouts/admin.html.erb +79 -0
- data/app/views/layouts/errors.html.erb +23 -0
- data/app/views/sitemaps/show.xml.builder +9 -0
- data/config/locales/en.yml +6 -0
- data/config/removed_migrations.yml +60 -0
- data/config/routes.rb +127 -0
- data/db/migrate/20111219033112_create_pages_tables.rb +281 -0
- data/db/migrate/20120627033112_rename_textbits.rb +19 -0
- data/db/migrate/20121010055412_drop_removed_tables.rb +83 -0
- data/db/migrate/20130130053932_add_queue_to_delayed_jobs.rb +11 -0
- data/db/migrate/20130303053932_remove_filter_from_localizations.rb +11 -0
- data/db/migrate/20130303160632_remove_imagesets.rb +24 -0
- data/db/migrate/20130303161732_remove_sms_subscribers.rb +16 -0
- data/db/migrate/20130823133208_update_page_redirect_to.rb +25 -0
- data/db/migrate/20140203183900_create_roles.rb +63 -0
- data/db/migrate/20140414150500_change_locale_names.rb +13 -0
- data/db/migrate/20140515130100_remove_sphinx_deltas.rb +15 -0
- data/db/migrate/20140604142100_remove_openid_url.rb +9 -0
- data/db/migrate/20140920231700_convert_images_to_dis.rb +79 -0
- data/db/migrate/20140922124600_convert_page_files_to_dis.rb +50 -0
- data/db/migrate/20141004003100_create_password_reset_tokens.rb +10 -0
- data/db/migrate/20141006181300_remove_user_cruft.rb +11 -0
- data/db/migrate/20141007173000_create_invites.rb +16 -0
- data/db/migrate/20150204130800_update_delayed_job_table.rb +9 -0
- data/db/migrate/20150401131300_localize_images.rb +39 -0
- data/db/migrate/20150520174300_add_meta_image_to_page.rb +5 -0
- data/db/migrate/20150904164200_add_pinned_to_tags.rb +5 -0
- data/lib/pages_core/admin_menu_item.rb +22 -0
- data/lib/pages_core/archive_finder.rb +75 -0
- data/lib/pages_core/cache_sweeper.rb +112 -0
- data/lib/pages_core/configuration/base.rb +85 -0
- data/lib/pages_core/configuration/pages.rb +23 -0
- data/lib/pages_core/configuration.rb +9 -0
- data/lib/pages_core/engine.rb +27 -0
- data/lib/pages_core/extensions/hash_extensions.rb +23 -0
- data/lib/pages_core/extensions/string_extensions.rb +17 -0
- data/lib/pages_core/extensions.rb +4 -0
- data/lib/pages_core/localizable/active_record_extension.rb +41 -0
- data/lib/pages_core/localizable/class_methods.rb +51 -0
- data/lib/pages_core/localizable/configuration.rb +50 -0
- data/lib/pages_core/localizable/instance_methods.rb +130 -0
- data/lib/pages_core/localizable/localizer.rb +72 -0
- data/lib/pages_core/localizable/scope_extension.rb +22 -0
- data/lib/pages_core/localizable.rb +49 -0
- data/lib/pages_core/pages_plugin.rb +14 -0
- data/lib/pages_core/paginates.rb +102 -0
- data/lib/pages_core/plugin.rb +118 -0
- data/lib/pages_core/templates/block_configuration.rb +17 -0
- data/lib/pages_core/templates/configuration.rb +81 -0
- data/lib/pages_core/templates/configuration_handler.rb +62 -0
- data/lib/pages_core/templates/configuration_proxy.rb +28 -0
- data/lib/pages_core/templates/controller_actions.rb +32 -0
- data/lib/pages_core/templates/template_configuration.rb +198 -0
- data/lib/pages_core/templates.rb +53 -0
- data/lib/pages_core/version.rb +5 -0
- data/lib/pages_core.rb +89 -0
- data/lib/rails/generators/pages_core/frontend/frontend_generator.rb +68 -0
- data/lib/rails/generators/pages_core/frontend/templates/application.css.scss.erb +3 -0
- data/lib/rails/generators/pages_core/frontend/templates/application.js.erb +16 -0
- data/lib/rails/generators/pages_core/frontend/templates/base.css.scss.erb +3 -0
- data/lib/rails/generators/pages_core/frontend/templates/breakpoints.css.scss.erb +24 -0
- data/lib/rails/generators/pages_core/frontend/templates/hidpi.css.scss.erb +8 -0
- data/lib/rails/generators/pages_core/frontend/templates/layout.html.erb +15 -0
- data/lib/rails/generators/pages_core/frontend/templates/normalize.css.erb +425 -0
- data/lib/rails/generators/pages_core/install/install_generator.rb +135 -0
- data/lib/rails/generators/pages_core/install/templates/active_job_initializer.rb +1 -0
- data/lib/rails/generators/pages_core/install/templates/application_controller.rb +11 -0
- data/lib/rails/generators/pages_core/install/templates/application_helper.rb +5 -0
- data/lib/rails/generators/pages_core/install/templates/cache_sweeper_initializer.rb +11 -0
- data/lib/rails/generators/pages_core/install/templates/default_page_template.html.erb +5 -0
- data/lib/rails/generators/pages_core/install/templates/delayed_job +7 -0
- data/lib/rails/generators/pages_core/install/templates/delayed_job_initializer.rb +3 -0
- data/lib/rails/generators/pages_core/install/templates/frontend_controller.rb +6 -0
- data/lib/rails/generators/pages_core/install/templates/frontend_helper.rb +5 -0
- data/lib/rails/generators/pages_core/install/templates/gitignore.erb +25 -0
- data/lib/rails/generators/pages_core/install/templates/page_templates_initializer.rb +67 -0
- data/lib/rails/generators/pages_core/install/templates/pages_controller.rb +4 -0
- data/lib/rails/generators/pages_core/install/templates/pages_initializer.rb +45 -0
- data/lib/rails/generators/pages_core/install/templates/thinking_sphinx.yml +12 -0
- data/lib/rails/generators/pages_core/rspec/rspec_generator.rb +34 -0
- data/lib/rails/generators/pages_core/rspec/templates/factories.rb +9 -0
- data/lib/rails/generators/pages_core/rspec/templates/mailer_macros.rb +9 -0
- data/lib/rails/generators/pages_core/rspec/templates/spec_helper.rb +51 -0
- data/lib/tasks/db.rake +96 -0
- data/lib/tasks/pages/assets.rake +65 -0
- data/lib/tasks/pages/cache.rake +16 -0
- data/lib/tasks/pages/update.rake +19 -0
- data/lib/tasks/pages.rake +76 -0
- data/template.rb +19 -0
- data/vendor/assets/javascripts/jquery.dimscreen.js +77 -0
- data/vendor/assets/javascripts/jquery.fieldselection.js +59 -0
- 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,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,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
|