alchemy_cms 2.5.3.1 → 2.6.0.rc5
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.
- data/.gitignore +1 -1
- data/.travis.yml +5 -13
- data/Gemfile +6 -3
- data/README.md +3 -2
- data/alchemy_cms.gemspec +22 -22
- data/app/assets/fonts/alchemy-icons.eot +0 -0
- data/app/assets/fonts/alchemy-icons.svg +54 -0
- data/app/assets/fonts/alchemy-icons.ttf +0 -0
- data/app/assets/fonts/alchemy-icons.woff +0 -0
- data/app/assets/images/alchemy/icons.png +0 -0
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +151 -0
- data/app/assets/javascripts/alchemy/alchemy.buttons.js.coffee +3 -2
- data/app/assets/javascripts/alchemy/alchemy.datepicker.js.coffee +31 -0
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js +1 -1
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +98 -0
- data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +23 -24
- data/app/assets/javascripts/alchemy/alchemy.growler.js.coffee +27 -0
- data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +11 -8
- data/app/assets/javascripts/alchemy/alchemy.hotkeys.js.coffee +32 -0
- data/app/assets/javascripts/alchemy/alchemy.image_cropper.js.coffee +46 -0
- data/app/assets/javascripts/alchemy/alchemy.js +8 -2
- data/app/assets/javascripts/alchemy/alchemy.link_overlay.js.coffee +5 -4
- data/app/assets/javascripts/alchemy/alchemy.list_filter.js.coffee +49 -0
- data/app/assets/javascripts/alchemy/alchemy.onload.js.coffee +3 -0
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +71 -0
- data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +61 -0
- data/app/assets/javascripts/alchemy/alchemy.spinner.js.coffee +35 -0
- data/app/assets/javascripts/alchemy/alchemy.string_extension.js.coffee +11 -0
- data/app/assets/javascripts/alchemy/alchemy.windows.js.coffee +278 -0
- data/app/assets/stylesheets/alchemy/admin.css.scss +2 -0
- data/app/assets/stylesheets/alchemy/archive.scss +109 -65
- data/app/assets/stylesheets/alchemy/base.scss +16 -188
- data/app/assets/stylesheets/alchemy/dashboard.scss +2 -2
- data/app/assets/stylesheets/alchemy/defaults.scss +2 -1
- data/app/assets/stylesheets/alchemy/elements.scss +58 -94
- data/app/assets/stylesheets/alchemy/errors.scss +2 -2
- data/app/assets/stylesheets/alchemy/{mixins.scss → extends.scss} +104 -80
- data/app/assets/stylesheets/alchemy/flash.scss +4 -6
- data/app/assets/stylesheets/alchemy/fonts.scss +46 -0
- data/app/assets/stylesheets/alchemy/form_elements.scss +46 -45
- data/app/assets/stylesheets/alchemy/frame.scss +20 -15
- data/app/assets/stylesheets/alchemy/icons.scss +22 -9
- data/app/assets/stylesheets/alchemy/jquery-ui.scss +476 -399
- data/app/assets/stylesheets/alchemy/login.scss +1 -1
- data/app/assets/stylesheets/alchemy/menubar.css.scss +1 -1
- data/app/assets/stylesheets/alchemy/notices.scss +5 -5
- data/app/assets/stylesheets/alchemy/pagination.scss +25 -13
- data/app/assets/stylesheets/alchemy/search.scss +29 -17
- data/app/assets/stylesheets/alchemy/sitemap.scss +41 -36
- data/app/assets/stylesheets/alchemy/tables.scss +102 -50
- data/app/assets/stylesheets/alchemy/tinymce_dialog.css.scss +18 -16
- data/app/assets/stylesheets/alchemy/toolbar.scss +84 -24
- data/app/assets/stylesheets/alchemy/upload.scss +14 -9
- data/app/assets/stylesheets/alchemy/variables.scss +1 -0
- data/app/assets/stylesheets/tiny_mce/plugins/inlinepopups/skins/alchemy/window.css.scss +18 -21
- data/app/controllers/alchemy/admin/attachments_controller.rb +29 -39
- data/app/controllers/alchemy/admin/base_controller.rb +3 -9
- data/app/controllers/alchemy/admin/clipboard_controller.rb +1 -1
- data/app/controllers/alchemy/admin/contents_controller.rb +1 -1
- data/app/controllers/alchemy/admin/dashboard_controller.rb +1 -1
- data/app/controllers/alchemy/admin/elements_controller.rb +3 -3
- data/app/controllers/alchemy/admin/essence_files_controller.rb +1 -1
- data/app/controllers/alchemy/admin/essence_pictures_controller.rb +5 -5
- data/app/controllers/alchemy/admin/languages_controller.rb +1 -1
- data/app/controllers/alchemy/admin/pages_controller.rb +18 -16
- data/app/controllers/alchemy/admin/pictures_controller.rb +11 -10
- data/app/controllers/alchemy/admin/resources_controller.rb +87 -14
- data/app/controllers/alchemy/admin/tags_controller.rb +3 -3
- data/app/controllers/alchemy/admin/trash_controller.rb +3 -3
- data/app/controllers/alchemy/admin/users_controller.rb +6 -11
- data/app/controllers/alchemy/attachments_controller.rb +8 -9
- data/app/controllers/alchemy/base_controller.rb +17 -10
- data/app/controllers/alchemy/pages_controller.rb +7 -19
- data/app/controllers/alchemy/passwords_controller.rb +15 -3
- data/app/controllers/alchemy/user_sessions_controller.rb +5 -4
- data/app/controllers/alchemy/users_controller.rb +1 -1
- data/app/helpers/alchemy/admin/attachments_helper.rb +2 -2
- data/app/helpers/alchemy/admin/base_helper.rb +62 -90
- data/app/helpers/alchemy/admin/elements_helper.rb +13 -5
- data/app/helpers/alchemy/admin/essences_helper.rb +3 -5
- data/app/helpers/alchemy/admin/pages_helper.rb +6 -3
- data/app/helpers/alchemy/admin/tags_helper.rb +60 -0
- data/app/helpers/alchemy/base_helper.rb +16 -20
- data/app/helpers/alchemy/elements_helper.rb +7 -11
- data/app/helpers/alchemy/essences_helper.rb +2 -2
- data/app/helpers/alchemy/pages_helper.rb +31 -69
- data/app/helpers/alchemy/url_helper.rb +11 -3
- data/app/models/alchemy/attachment.rb +73 -45
- data/app/models/alchemy/cell.rb +1 -1
- data/app/models/alchemy/content.rb +20 -9
- data/app/models/alchemy/element.rb +9 -7
- data/app/models/alchemy/page.rb +15 -248
- data/app/models/alchemy/page/cells.rb +71 -0
- data/app/models/alchemy/page/elements.rb +147 -0
- data/app/models/alchemy/page/naming.rb +90 -0
- data/app/models/alchemy/picture.rb +18 -13
- data/app/models/alchemy/tag.rb +1 -1
- data/app/models/alchemy/user.rb +38 -6
- data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +14 -7
- data/app/views/alchemy/admin/attachments/_attachment.html.erb +17 -12
- data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +3 -8
- data/app/views/alchemy/admin/attachments/_files_list.html.erb +20 -12
- data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +11 -0
- data/app/views/alchemy/admin/attachments/_tag_list.html.erb +31 -0
- data/app/views/alchemy/admin/attachments/archive_overlay.js.erb +4 -0
- data/app/views/alchemy/admin/attachments/edit.html.erb +8 -7
- data/app/views/alchemy/admin/attachments/index.html.erb +19 -12
- data/app/views/alchemy/admin/attachments/new.html.erb +2 -2
- data/app/views/alchemy/admin/attachments/show.html.erb +3 -0
- data/app/views/alchemy/admin/contents/_missing.html.erb +4 -4
- data/app/views/alchemy/admin/contents/create.js.erb +1 -1
- data/app/views/alchemy/admin/contents/new.html.erb +6 -3
- data/app/views/alchemy/admin/dashboard/_locked_pages.html.erb +1 -1
- data/app/views/alchemy/admin/dashboard/_users.html.erb +1 -1
- data/app/views/alchemy/admin/dashboard/index.html.erb +3 -3
- data/app/views/alchemy/admin/dashboard/info.html.erb +16 -13
- data/app/views/alchemy/admin/elements/_add_picture.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_element_foot.html.erb +4 -4
- data/app/views/alchemy/admin/elements/_element_head.html.erb +1 -7
- data/app/views/alchemy/admin/elements/_elements_select.html.erb +2 -2
- data/app/views/alchemy/admin/elements/_new_element_form.html.erb +4 -4
- data/app/views/alchemy/admin/elements/_picture_gallery_editor.html.erb +1 -1
- data/app/views/alchemy/admin/elements/create.js.erb +2 -2
- data/app/views/alchemy/admin/elements/fold.js.erb +3 -6
- data/app/views/alchemy/admin/elements/new.html.erb +1 -1
- data/app/views/alchemy/admin/elements/order.js.erb +1 -1
- data/app/views/alchemy/admin/elements/trash.js.erb +1 -1
- data/app/views/alchemy/admin/elements/update.js.erb +2 -2
- data/app/views/alchemy/admin/essence_files/edit.html.erb +4 -4
- data/app/views/alchemy/admin/essence_pictures/crop.html.erb +17 -18
- data/app/views/alchemy/admin/essence_pictures/edit.html.erb +2 -2
- data/app/views/alchemy/admin/essence_pictures/update.js.erb +1 -0
- data/app/views/alchemy/admin/languages/_form.html.erb +12 -10
- data/app/views/alchemy/admin/languages/_language.html.erb +2 -1
- data/app/views/alchemy/admin/languages/_table.html.erb +3 -3
- data/app/views/alchemy/admin/languages/index.html.erb +15 -15
- data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +6 -6
- data/app/views/alchemy/admin/layoutpages/index.html.erb +41 -40
- data/app/views/alchemy/admin/pages/_contactform_links.html.erb +4 -4
- data/app/views/alchemy/admin/pages/_create_language_form.html.erb +6 -6
- data/app/views/alchemy/admin/pages/_external_link.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_file_link.html.erb +3 -3
- data/app/views/alchemy/admin/pages/_internal_link.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_page.html.erb +13 -13
- data/app/views/alchemy/admin/pages/_page_for_links.html.erb +2 -4
- data/app/views/alchemy/admin/pages/_sitemap.html.erb +5 -0
- data/app/views/alchemy/admin/pages/configure.html.erb +7 -7
- data/app/views/alchemy/admin/pages/configure_external.html.erb +4 -4
- data/app/views/alchemy/admin/pages/edit.html.erb +23 -30
- data/app/views/alchemy/admin/pages/index.html.erb +34 -23
- data/app/views/alchemy/admin/pages/new.html.erb +1 -1
- data/app/views/alchemy/admin/pages/sort.js.erb +1 -1
- data/app/views/alchemy/admin/partials/_flash_upload.html.erb +2 -3
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +2 -2
- data/app/views/alchemy/admin/partials/_search_form.html.erb +3 -3
- data/app/views/alchemy/admin/partials/_upload_form.html.erb +2 -2
- data/app/views/alchemy/admin/pictures/_archive.html.erb +7 -7
- data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +6 -6
- data/app/views/alchemy/admin/pictures/_filter_bar.html.erb +4 -4
- data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_picture.html.erb +3 -8
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +9 -14
- data/app/views/alchemy/admin/pictures/_tag_list.html.erb +27 -25
- data/app/views/alchemy/admin/pictures/archive_overlay.js.erb +3 -1
- data/app/views/alchemy/admin/pictures/index.html.erb +49 -42
- data/app/views/alchemy/admin/pictures/new.html.erb +2 -2
- data/app/views/alchemy/admin/pictures/show.html.erb +11 -0
- data/app/views/alchemy/admin/resources/_boolean.html.erb +2 -2
- data/app/views/alchemy/admin/resources/_datetime.html.erb +2 -2
- data/app/views/alchemy/admin/resources/_form.html.erb +9 -8
- data/app/views/alchemy/admin/resources/_resource.html.erb +15 -21
- data/app/views/alchemy/admin/resources/_string.html.erb +2 -2
- data/app/views/alchemy/admin/resources/_table.html.erb +11 -13
- data/app/views/alchemy/admin/resources/_text.html.erb +2 -2
- data/app/views/alchemy/admin/resources/index.csv.erb +13 -0
- data/app/views/alchemy/admin/resources/index.html.erb +24 -15
- data/app/views/alchemy/admin/sites/index.html.erb +23 -0
- data/app/views/alchemy/admin/tags/_radio_tag.html.erb +1 -1
- data/app/views/alchemy/admin/tags/_tag.html.erb +2 -1
- data/app/views/alchemy/admin/tags/edit.html.erb +1 -1
- data/app/views/alchemy/admin/tags/index.html.erb +16 -11
- data/app/views/alchemy/admin/tags/new.html.erb +3 -3
- data/app/views/alchemy/admin/trash/clear.js.coffee +1 -1
- data/app/views/alchemy/admin/users/_table.html.erb +12 -5
- data/app/views/alchemy/admin/users/_user.html.erb +16 -16
- data/app/views/alchemy/admin/users/index.html.erb +28 -16
- data/app/views/alchemy/breadcrumb/_page.html.erb +15 -0
- data/app/views/alchemy/breadcrumb/_spacer.html.erb +1 -0
- data/app/views/alchemy/elements/_editor_not_found.html.erb +1 -1
- data/app/views/alchemy/essences/_essence_file_editor.html.erb +16 -16
- data/app/views/alchemy/essences/_essence_file_view.html.erb +8 -9
- data/app/views/alchemy/essences/_essence_picture_editor.html.erb +3 -6
- data/app/views/alchemy/essences/_essence_picture_tools.html.erb +9 -8
- data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +0 -5
- data/app/views/alchemy/essences/_linkable_essence_tools.html.erb +2 -2
- data/app/views/alchemy/navigation/_link.html.erb +7 -7
- data/app/views/alchemy/navigation/_renderer.html.erb +29 -36
- data/app/views/alchemy/notifications/admin_user_created.de.text.erb +5 -1
- data/app/views/alchemy/notifications/admin_user_created.en.text.erb +5 -1
- data/app/views/alchemy/notifications/registered_user_created.de.text.erb +13 -0
- data/app/views/alchemy/notifications/registered_user_created.en.text.erb +13 -0
- data/app/views/alchemy/search/_result.html.erb +4 -6
- data/app/views/alchemy/search/_results.html.erb +4 -5
- data/app/views/alchemy/user_sessions/leave.html.erb +1 -1
- data/app/views/alchemy/user_sessions/new.html.erb +2 -2
- data/app/views/kaminari/_first_page.html.erb +11 -0
- data/app/views/kaminari/_gap.html.erb +1 -1
- data/app/views/kaminari/_last_page.html.erb +11 -0
- data/app/views/kaminari/_next_page.html.erb +2 -2
- data/app/views/kaminari/_page.html.erb +1 -1
- data/app/views/kaminari/_paginator.html.erb +2 -0
- data/app/views/kaminari/_prev_page.html.erb +2 -2
- data/app/views/layouts/alchemy/admin.html.erb +4 -5
- data/config/alchemy/config.yml +8 -12
- data/config/authorization_rules.rb +4 -3
- data/config/initializers/dragonfly.rb +20 -12
- data/config/locales/alchemy.de.yml +20 -15
- data/config/locales/alchemy.en.yml +15 -10
- data/config/locales/devise.de.yml +1 -0
- data/config/routes.rb +3 -3
- data/{spec/dummy/db/migrate/20121118000000_alchemy_two_point_four.rb → db/migrate/20130214233001_alchemy_two_point_five.rb} +50 -36
- data/db/migrate/20130221200514_migrate_attachments_to_dragonfly.rb +21 -0
- data/db/migrate/20130312205327_change_alchemy_users_role_to_roles.rb +11 -0
- data/lib/alchemy/capistrano.rb +10 -8
- data/lib/alchemy/errors.rb +7 -0
- data/lib/alchemy/filetypes.rb +33 -0
- data/lib/alchemy/i18n.rb +9 -1
- data/lib/alchemy/name_conversions.rb +28 -0
- data/lib/alchemy/page_layout.rb +5 -3
- data/lib/alchemy/resource.rb +132 -29
- data/lib/alchemy/resources_helper.rb +81 -12
- data/lib/alchemy/upgrader.rb +14 -276
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +17 -2
- data/lib/rails/generators/alchemy/deploy_script/templates/deploy.rb.tt +1 -1
- data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +1 -1
- data/lib/tasks/alchemy/convert.rake +39 -0
- data/lib/tasks/alchemy/install.rake +4 -6
- data/lib/tasks/alchemy/upgrade.rake +18 -1
- data/spec/controllers/admin/clipboard_controller_spec.rb +4 -4
- data/spec/controllers/admin/elements_controller_spec.rb +23 -23
- data/spec/controllers/admin/pages_controller_spec.rb +15 -0
- data/spec/controllers/admin/resources_controller_spec.rb +1 -11
- data/spec/controllers/admin/trash_controller_spec.rb +9 -9
- data/spec/controllers/attachments_controller_spec.rb +3 -3
- data/spec/controllers/elements_controller_spec.rb +2 -2
- data/spec/controllers/pages_controller_spec.rb +160 -129
- data/spec/controllers/pictures_controller_spec.rb +2 -2
- data/spec/controllers/user_sessions_controller_spec.rb +3 -3
- data/spec/controllers/users_controller_spec.rb +2 -2
- data/spec/dummy/app/models/event.rb +2 -2
- data/spec/dummy/app/models/location.rb +4 -0
- data/spec/dummy/app/views/layouts/application.html.erb +6 -42
- data/spec/dummy/config/routes.rb +1 -1
- data/spec/dummy/db/migrate/20121026104128_create_events.rb +0 -1
- data/{db/migrate/20121118000000_alchemy_two_point_four.rb → spec/dummy/db/migrate/20130214233001_alchemy_two_point_five.rb} +50 -36
- data/spec/dummy/db/migrate/20130221200514_migrate_attachments_to_dragonfly.rb +21 -0
- data/spec/dummy/db/migrate/20130312205327_change_alchemy_users_role_to_roles.rb +11 -0
- data/spec/dummy/db/migrate/20130328101418_create_locations.rb +9 -0
- data/spec/dummy/db/schema.rb +15 -6
- data/spec/factories.rb +4 -4
- data/spec/{integration → features}/admin/link_overlay_spec.rb +0 -0
- data/spec/{integration → features}/admin/modules_integration_spec.rb +1 -1
- data/spec/{integration → features}/admin/pages_controller_spec.rb +9 -4
- data/spec/{integration → features}/admin/picture_library_integration_spec.rb +5 -5
- data/spec/{integration → features}/admin/resources_integration_spec.rb +1 -1
- data/spec/{integration → features}/navigation_spec.rb +0 -0
- data/spec/{integration → features}/pages_controller_spec.rb +42 -112
- data/spec/{integration → features}/picture_security_spec.rb +2 -2
- data/spec/{integration → features}/security_spec.rb +7 -7
- data/spec/{integration → features}/translation_integration_spec.rb +0 -0
- data/spec/helpers/admin/base_helper_spec.rb +0 -50
- data/spec/helpers/admin/tags_helper_spec.rb +53 -0
- data/spec/helpers/base_helper_spec.rb +19 -3
- data/spec/helpers/pages_helper_spec.rb +92 -44
- data/spec/{url_helpers_spec.rb → helpers/picture_url_helpers_spec.rb} +7 -7
- data/spec/helpers/url_helper_spec.rb +92 -72
- data/spec/{config_spec.rb → libraries/config_spec.rb} +0 -0
- data/spec/libraries/resource_spec.rb +215 -76
- data/spec/libraries/resources_helper_spec.rb +70 -28
- data/spec/models/attachment_spec.rb +75 -9
- data/spec/models/clipboard_spec.rb +1 -1
- data/spec/models/element_spec.rb +7 -0
- data/spec/models/page_spec.rb +144 -25
- data/spec/models/picture_spec.rb +5 -5
- data/spec/models/resource_spec.rb +47 -10
- data/spec/models/user_spec.rb +115 -3
- data/spec/{routing_spec.rb → routing/routing_spec.rb} +8 -20
- data/spec/spec_helper.rb +5 -6
- data/spec/support/alchemy/specs_helpers.rb +1 -1
- data/spec/support/ci/install_phantomjs +1 -1
- data/spec/support/image with spaces.png +0 -0
- data/vendor/assets/javascripts/jquery_plugins/jquery.Jcrop.min.js +18 -18
- data/vendor/assets/javascripts/jquery_plugins/{jquery.dialogextend.1_0_1.js → jquery.dialogextend.js} +25 -17
- data/vendor/assets/javascripts/jquery_plugins/jquery.scrollTo.min.js +7 -0
- data/vendor/assets/javascripts/jquery_plugins/jquery.ui.tabspaging.js +7 -7
- data/vendor/assets/javascripts/keymage.min.js +6 -0
- data/vendor/assets/javascripts/spin.min.js +1 -0
- metadata +122 -124
- data/app/assets/images/alchemy/ajax_loader.gif +0 -0
- data/app/assets/images/alchemy/gui/toggle.png +0 -0
- data/app/assets/images/alchemy/image_loader.gif +0 -0
- data/app/assets/images/alchemy/shading.png +0 -0
- data/app/assets/images/alchemy/tabs.gif +0 -0
- data/app/assets/javascripts/alchemy/alchemy.base.js +0 -172
- data/app/assets/javascripts/alchemy/alchemy.datepicker.js +0 -47
- data/app/assets/javascripts/alchemy/alchemy.element_editor_selector.js +0 -91
- data/app/assets/javascripts/alchemy/alchemy.growler.js +0 -46
- data/app/assets/javascripts/alchemy/alchemy.image_cropper.js +0 -60
- data/app/assets/javascripts/alchemy/alchemy.js_extensions.js +0 -15
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js +0 -97
- data/app/assets/javascripts/alchemy/alchemy.windows.js +0 -321
- data/app/models/alchemy/clipboard_spec.rb +0 -0
- data/app/views/alchemy/admin/pictures/show_in_window.html.erb +0 -8
- data/app/views/alchemy/notifications/registered_user_created.text.erb +0 -11
- data/db/migrate/20121121162313_switch_from_fleximage_to_dragonfly.rb +0 -21
- data/db/migrate/20121205155004_create_alchemy_sites.rb +0 -14
- data/db/migrate/20121211163003_add_public_to_alchemy_sites.rb +0 -6
- data/db/migrate/20121220102223_add_aliases_to_site.rb +0 -6
- data/db/migrate/20130110212411_create_alchemy_legacy_page_urls.rb +0 -11
- data/db/migrate/20130121092645_migrate_to_devise.rb +0 -24
- data/spec/alchemy_spec.rb +0 -7
- data/spec/dummy/db/migrate/20121121162313_switch_from_fleximage_to_dragonfly.rb +0 -21
- data/spec/dummy/db/migrate/20121205155004_create_alchemy_sites.rb +0 -14
- data/spec/dummy/db/migrate/20121211163003_add_public_to_alchemy_sites.rb +0 -6
- data/spec/dummy/db/migrate/20121220102223_add_aliases_to_site.rb +0 -6
- data/spec/dummy/db/migrate/20130110212411_create_alchemy_legacy_page_urls.rb +0 -11
- data/spec/dummy/db/migrate/20130121092645_migrate_to_devise.rb +0 -24
- data/vendor/assets/javascripts/jquery_plugins/jquery.scrollTo-1.4.2-min.js +0 -11
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
module Alchemy
|
|
2
|
+
module Page::Cells
|
|
3
|
+
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
has_many :cells, :dependent => :destroy
|
|
8
|
+
after_create :create_cells, :if => :can_have_cells?, :unless => :systempage?
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
module ClassMethods
|
|
12
|
+
|
|
13
|
+
# Copy page cells
|
|
14
|
+
#
|
|
15
|
+
# @param source [Alchemy::Page]
|
|
16
|
+
# @param target [Alchemy::Page]
|
|
17
|
+
# @return [Array]
|
|
18
|
+
#
|
|
19
|
+
def copy_cells(source, target)
|
|
20
|
+
new_cells = []
|
|
21
|
+
source.cells.each do |cell|
|
|
22
|
+
new_cells << Cell.create(:name => cell.name, :page_id => target.id)
|
|
23
|
+
end
|
|
24
|
+
new_cells
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Returns true, if the page's page_layout defines cells.
|
|
30
|
+
def can_have_cells?
|
|
31
|
+
definition['cells'].present?
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Returns true, if the page has cells.
|
|
35
|
+
def has_cells?
|
|
36
|
+
cells.any?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Returns the cell definitions from page's page_layout defintion.
|
|
40
|
+
def cell_definitions
|
|
41
|
+
cell_names = self.layout_description['cells']
|
|
42
|
+
return [] if cell_names.blank?
|
|
43
|
+
Cell.all_definitions_for(cell_names)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Returns elements grouped by cell.
|
|
47
|
+
def elements_grouped_by_cells
|
|
48
|
+
elements.not_trashed.in_cell.group_by(&:cell)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Returns element names from cell definition.
|
|
52
|
+
def element_names_from_cells
|
|
53
|
+
cell_definitions.collect { |c| c['elements'] }.flatten.uniq
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Returns element names that are not defined in a cell.
|
|
57
|
+
def element_names_not_in_cell
|
|
58
|
+
layout_description['elements'].uniq - element_names_from_cells
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
# Creates cells that are defined in page's page_layout definition.
|
|
64
|
+
def create_cells
|
|
65
|
+
definition['cells'].each do |cellname|
|
|
66
|
+
cells.create!(:name => cellname)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
module Alchemy
|
|
2
|
+
module Page::Elements
|
|
3
|
+
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
attr_accessor :do_not_autogenerate
|
|
8
|
+
|
|
9
|
+
has_many :elements, :order => :position
|
|
10
|
+
has_many :contents, :through => :elements
|
|
11
|
+
has_and_belongs_to_many :to_be_sweeped_elements, :class_name => 'Alchemy::Element', :uniq => true, :join_table => 'alchemy_elements_alchemy_pages'
|
|
12
|
+
|
|
13
|
+
after_create :autogenerate_elements, :unless => proc { systempage? || do_not_autogenerate }
|
|
14
|
+
after_update :trash_not_allowed_elements, :if => :page_layout_changed?
|
|
15
|
+
after_update :autogenerate_elements, :if => :page_layout_changed?
|
|
16
|
+
after_destroy { elements.each { |el| el.destroy unless el.trashed? } }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
module ClassMethods
|
|
20
|
+
|
|
21
|
+
# Copy page elements
|
|
22
|
+
#
|
|
23
|
+
# @param source [Alchemy::Page]
|
|
24
|
+
# @param target [Alchemy::Page]
|
|
25
|
+
# @return [Array]
|
|
26
|
+
#
|
|
27
|
+
def copy_elements(source, target)
|
|
28
|
+
new_elements = []
|
|
29
|
+
source.elements.not_trashed.each do |element|
|
|
30
|
+
# detect cell for element
|
|
31
|
+
if element.cell
|
|
32
|
+
cell = target.cells.detect { |c| c.name == element.cell.name }
|
|
33
|
+
else
|
|
34
|
+
cell = nil
|
|
35
|
+
end
|
|
36
|
+
# if cell is nil also pass nil to element.cell_id
|
|
37
|
+
new_element = Element.copy(element, :page_id => target.id, :cell_id => (cell.blank? ? nil : cell.id))
|
|
38
|
+
# move element to bottom of the list
|
|
39
|
+
new_element.move_to_bottom
|
|
40
|
+
new_elements << new_element
|
|
41
|
+
end
|
|
42
|
+
new_elements
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Finds selected elements from page.
|
|
48
|
+
#
|
|
49
|
+
# Returns only public elements by default.
|
|
50
|
+
# Pass true as second argument to get all elements.
|
|
51
|
+
#
|
|
52
|
+
# === Options are:
|
|
53
|
+
#
|
|
54
|
+
# :only => Array of element names # Returns only elements with given names
|
|
55
|
+
# :except => Array of element names # Returns all elements except the ones with given names
|
|
56
|
+
# :count => Integer # Limit the count of returned elements
|
|
57
|
+
# :offset => Integer # Starts with an offset while returning elements
|
|
58
|
+
# :random => Boolean # Return elements randomly shuffled
|
|
59
|
+
# :from_cell => Cell or String # Return elements from given cell
|
|
60
|
+
#
|
|
61
|
+
def find_selected_elements(options = {}, show_non_public = false)
|
|
62
|
+
if options[:from_cell].class.name == 'Alchemy::Cell'
|
|
63
|
+
elements = options[:from_cell].elements
|
|
64
|
+
elsif !options[:from_cell].blank? && options[:from_cell].class.name == 'String'
|
|
65
|
+
cell = cells.find_by_name(options[:from_cell])
|
|
66
|
+
if cell
|
|
67
|
+
elements = cell.elements
|
|
68
|
+
else
|
|
69
|
+
warn("Cell with name `#{options[:from_cell]}` could not be found!")
|
|
70
|
+
# Returns an empty relation. Can be removed with the release of Rails 4
|
|
71
|
+
elements = self.elements.where('1 = 0')
|
|
72
|
+
end
|
|
73
|
+
else
|
|
74
|
+
elements = self.elements.not_in_cell
|
|
75
|
+
end
|
|
76
|
+
if !options[:only].blank?
|
|
77
|
+
elements = elements.named(options[:only])
|
|
78
|
+
elsif !options[:except].blank?
|
|
79
|
+
elements = elements.excluded(options[:except])
|
|
80
|
+
end
|
|
81
|
+
elements = elements.reverse_order if options[:reverse_sort] || options[:reverse]
|
|
82
|
+
elements = elements.offset(options[:offset]).limit(options[:count])
|
|
83
|
+
elements = elements.order("RAND()") if options[:random]
|
|
84
|
+
show_non_public ? elements : elements.published
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# What is this? A Kind of proxy method? Why not rendering the elements directly if you already have them????
|
|
88
|
+
def find_elements(options = {}, show_non_public = false)
|
|
89
|
+
if !options[:collection].blank? && options[:collection].is_a?(Array)
|
|
90
|
+
return options[:collection]
|
|
91
|
+
else
|
|
92
|
+
find_selected_elements(options, show_non_public)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Returns all elements that should be feeded via rss.
|
|
97
|
+
#
|
|
98
|
+
# Define feedable elements in your +page_layouts.yml+:
|
|
99
|
+
#
|
|
100
|
+
# - name: news
|
|
101
|
+
# feed: true
|
|
102
|
+
# feed_elements: [element_name, element_2_name]
|
|
103
|
+
#
|
|
104
|
+
def feed_elements
|
|
105
|
+
elements.named(definition['feed_elements'])
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
private
|
|
109
|
+
|
|
110
|
+
# Looks in the page_layout descripion, if there are elements to autogenerate.
|
|
111
|
+
#
|
|
112
|
+
# And if so, it generates them.
|
|
113
|
+
#
|
|
114
|
+
# If the page has cells, it looks if there are elements to generate.
|
|
115
|
+
#
|
|
116
|
+
def autogenerate_elements
|
|
117
|
+
elements_already_on_page = self.elements.available.collect(&:name)
|
|
118
|
+
elements = self.layout_description["autogenerate"]
|
|
119
|
+
if elements.present?
|
|
120
|
+
elements.each do |element|
|
|
121
|
+
next if elements_already_on_page.include?(element)
|
|
122
|
+
Element.create_from_scratch(attributes_for_element_name(element))
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Returns a hash of attributes for given element name
|
|
128
|
+
def attributes_for_element_name(element)
|
|
129
|
+
if self.has_cells? && (cell_definition = cell_definitions.detect { |c| c['elements'].include?(element) })
|
|
130
|
+
cell = self.cells.find_by_name(cell_definition['name'])
|
|
131
|
+
if cell
|
|
132
|
+
return {:page_id => self.id, :cell_id => cell.id, :name => element}
|
|
133
|
+
else
|
|
134
|
+
raise "Cell not found for page #{self.inspect}"
|
|
135
|
+
end
|
|
136
|
+
else
|
|
137
|
+
return {:page_id => self.id, :name => element}
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Trashes all elements that are not allowed for this page_layout.
|
|
142
|
+
def trash_not_allowed_elements
|
|
143
|
+
elements.select { |e| !definition['elements'].include?(e.name) }.map(&:trash)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
end
|
|
147
|
+
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module Alchemy
|
|
2
|
+
module Page::Naming
|
|
3
|
+
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
include NameConversions
|
|
6
|
+
RESERVED_URLNAMES = %w(admin messages new)
|
|
7
|
+
|
|
8
|
+
included do
|
|
9
|
+
before_validation :set_urlname, :if => :renamed?, :unless => proc { systempage? || redirects_to_external? }
|
|
10
|
+
|
|
11
|
+
validates_presence_of :name
|
|
12
|
+
validates_length_of :urlname, :minimum => 3, :if => 'urlname.present?'
|
|
13
|
+
validates_uniqueness_of(
|
|
14
|
+
:urlname,
|
|
15
|
+
:scope => [:language_id, :layoutpage],
|
|
16
|
+
:if => 'urlname.present?'
|
|
17
|
+
)
|
|
18
|
+
validates :urlname, :exclusion => {:in => RESERVED_URLNAMES}
|
|
19
|
+
|
|
20
|
+
before_save :set_title, :if => 'title.blank?', :unless => proc { systempage? || redirects_to_external? }
|
|
21
|
+
after_update(:if => proc { Config.get(:url_nesting) && (urlname_changed? || visible_changed?) }) do
|
|
22
|
+
self.reload
|
|
23
|
+
self.descendants.map(&:update_urlname!)
|
|
24
|
+
end
|
|
25
|
+
after_move :update_urlname!, :if => proc { Config.get(:url_nesting) }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Returns true if name or urlname has changed.
|
|
29
|
+
def renamed?
|
|
30
|
+
name_changed? || urlname_changed?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Makes a slug of all ancestors urlnames including mine and delimit them be slash.
|
|
34
|
+
# So the whole path is stored as urlname in tha database.
|
|
35
|
+
def update_urlname!
|
|
36
|
+
names = ancestors.visible.contentpages.where(language_root: nil).map(&:slug).compact
|
|
37
|
+
new_urlname = (names << slug).join('/')
|
|
38
|
+
# update without callbacks
|
|
39
|
+
if new_record?
|
|
40
|
+
write_attribute :urlname, new_urlname
|
|
41
|
+
else
|
|
42
|
+
if urlname != new_urlname
|
|
43
|
+
legacy_urls.create(:urlname => urlname)
|
|
44
|
+
end
|
|
45
|
+
update_column :urlname, new_urlname
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Returns always the last part of a urlname path
|
|
50
|
+
def slug
|
|
51
|
+
urlname.to_s.split('/').last
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
# Sets the urlname to a url friendly slug.
|
|
57
|
+
# Either from name, or if present, from urlname.
|
|
58
|
+
# If url_nesting is enabled the urlname contains the whole path.
|
|
59
|
+
def set_urlname
|
|
60
|
+
if Config.get(:url_nesting)
|
|
61
|
+
url_name = [
|
|
62
|
+
parent.nil? || parent.language_root? ? nil : parent.urlname,
|
|
63
|
+
convert_url_name((urlname.blank? ? name : slug))
|
|
64
|
+
].compact.join('/')
|
|
65
|
+
else
|
|
66
|
+
url_name = convert_url_name((urlname.blank? ? name : urlname))
|
|
67
|
+
end
|
|
68
|
+
write_attribute :urlname, url_name
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def set_title
|
|
72
|
+
write_attribute :title, name
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Converts the given name into an url friendly string.
|
|
76
|
+
#
|
|
77
|
+
# Names shorter than 3 will be filled up with dashes,
|
|
78
|
+
# so it does not collidate with the language code.
|
|
79
|
+
#
|
|
80
|
+
def convert_url_name(name)
|
|
81
|
+
url_name = convert_to_urlname(name)
|
|
82
|
+
if url_name.length < 3
|
|
83
|
+
('-' * (3 - url_name.length)) + url_name
|
|
84
|
+
else
|
|
85
|
+
url_name
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
module Alchemy
|
|
2
2
|
class Picture < ActiveRecord::Base
|
|
3
|
+
include NameConversions
|
|
3
4
|
|
|
4
5
|
has_many :essence_pictures, :class_name => 'Alchemy::EssencePicture', :foreign_key => 'picture_id'
|
|
5
6
|
has_many :contents, :through => :essence_pictures
|
|
@@ -22,7 +23,8 @@ module Alchemy
|
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
validates_presence_of :image_file
|
|
25
|
-
|
|
26
|
+
validates_size_of :image_file, :maximum => Config.get(:uploader)['file_size_limit'].megabytes
|
|
27
|
+
validates_property :format, :of => :image_file, :in => Config.get(:uploader)['allowed_filetypes']['pictures'], :case_sensitive => false, :message => I18n.t("not a valid image")
|
|
26
28
|
|
|
27
29
|
acts_as_taggable
|
|
28
30
|
|
|
@@ -38,21 +40,24 @@ module Alchemy
|
|
|
38
40
|
scope :recent, where("#{self.table_name}.created_at > ?", Time.now-24.hours).order(:created_at)
|
|
39
41
|
scope :deletable, where("alchemy_pictures.id NOT IN (SELECT picture_id FROM alchemy_essence_pictures)")
|
|
40
42
|
|
|
41
|
-
|
|
42
|
-
Picture.where("name LIKE ?", "%#{params[:query]}%").page(params[:page] || 1).per(per_page).order(:name)
|
|
43
|
-
end
|
|
43
|
+
# Class methods
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
class << self
|
|
46
|
+
|
|
47
|
+
def find_paginated(params, per_page)
|
|
48
|
+
Picture.where("name LIKE ?", "%#{params[:query]}%").page(params[:page] || 1).per(per_page).order(:name)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def last_upload
|
|
52
|
+
last_picture = Picture.last
|
|
53
|
+
return Picture.scoped unless last_picture
|
|
54
|
+
Picture.where(:upload_hash => last_picture.upload_hash)
|
|
55
|
+
end
|
|
50
56
|
|
|
51
|
-
# Returning the filepath relative to Rails.root public folder.
|
|
52
|
-
def public_file_path
|
|
53
|
-
self.file_path.gsub("#{::Rails.root}/public", '')
|
|
54
57
|
end
|
|
55
58
|
|
|
59
|
+
# Instance methods
|
|
60
|
+
|
|
56
61
|
def urlname
|
|
57
62
|
if self.name.blank?
|
|
58
63
|
"image_#{self.id}"
|
|
@@ -67,7 +72,7 @@ module Alchemy
|
|
|
67
72
|
|
|
68
73
|
def humanized_name
|
|
69
74
|
return "" if image_file_name.blank?
|
|
70
|
-
(image_file_name
|
|
75
|
+
convert_to_humanized_name(image_file_name, suffix)
|
|
71
76
|
end
|
|
72
77
|
|
|
73
78
|
# Returning true if picture's width is greater than it's height
|
data/app/models/alchemy/tag.rb
CHANGED
data/app/models/alchemy/user.rb
CHANGED
|
@@ -14,15 +14,17 @@ module Alchemy
|
|
|
14
14
|
:login,
|
|
15
15
|
:email,
|
|
16
16
|
:gender,
|
|
17
|
-
:role,
|
|
18
17
|
:language,
|
|
19
18
|
:password,
|
|
20
19
|
:password_confirmation,
|
|
20
|
+
:roles,
|
|
21
21
|
:tag_list
|
|
22
22
|
)
|
|
23
23
|
|
|
24
24
|
has_many :folded_pages
|
|
25
25
|
|
|
26
|
+
validates_presence_of :roles
|
|
27
|
+
|
|
26
28
|
# Unlock all locked pages before destroy and before the user gets logged out.
|
|
27
29
|
before_destroy :unlock_pages!
|
|
28
30
|
Warden::Manager.before_logout do |user, auth, opts|
|
|
@@ -31,7 +33,10 @@ module Alchemy
|
|
|
31
33
|
end
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
scope :admins, where(:
|
|
36
|
+
scope :admins, where(arel_table[:roles].matches("%admin%")) # not pleased with that approach
|
|
37
|
+
# mysql regexp word matching would be much nicer, but it's not included in SQLite functions per se.
|
|
38
|
+
# scope :admins, where("#{table_name}.roles REGEXP '[[:<:]]admin[[:>:]]'")
|
|
39
|
+
|
|
35
40
|
scope :logged_in, lambda { where("last_request_at > ?", logged_in_timeout.seconds.ago) }
|
|
36
41
|
scope :logged_out, lambda { where("last_request_at is NULL or last_request_at <= ?", logged_in_timeout.seconds.ago) }
|
|
37
42
|
|
|
@@ -55,15 +60,40 @@ module Alchemy
|
|
|
55
60
|
end
|
|
56
61
|
|
|
57
62
|
def role_symbols
|
|
58
|
-
|
|
63
|
+
roles.map(&:to_sym)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def role
|
|
67
|
+
roles.first
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def roles
|
|
71
|
+
read_attribute(:roles).split(' ')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def roles=(roles_string)
|
|
75
|
+
if roles_string.is_a? Array
|
|
76
|
+
write_attribute(:roles, roles_string.join(' '))
|
|
77
|
+
elsif roles_string.is_a? String
|
|
78
|
+
write_attribute(:roles, roles_string)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def add_role(role)
|
|
83
|
+
self.roles = self.roles.push(role.to_s).uniq
|
|
59
84
|
end
|
|
60
85
|
|
|
61
86
|
# Returns true if the user ahs admin role
|
|
62
87
|
def is_admin?
|
|
63
|
-
|
|
88
|
+
has_role? 'admin'
|
|
64
89
|
end
|
|
65
90
|
alias_method :admin?, :is_admin?
|
|
66
91
|
|
|
92
|
+
# Returns true if the user has the given role.
|
|
93
|
+
def has_role?(role)
|
|
94
|
+
roles.include? role.to_s
|
|
95
|
+
end
|
|
96
|
+
|
|
67
97
|
# Calls unlock on all locked pages
|
|
68
98
|
def unlock_pages!
|
|
69
99
|
pages_locked_by_me.map(&:unlock)
|
|
@@ -107,8 +137,10 @@ module Alchemy
|
|
|
107
137
|
!logged_in?
|
|
108
138
|
end
|
|
109
139
|
|
|
110
|
-
def
|
|
111
|
-
|
|
140
|
+
def human_roles_string
|
|
141
|
+
roles.map do |role|
|
|
142
|
+
self.class.human_rolename(role)
|
|
143
|
+
end.to_sentence
|
|
112
144
|
end
|
|
113
145
|
|
|
114
146
|
def store_request_time!
|