tribeca_cms 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +58 -0
- data/LICENSE +1 -0
- data/README.textile +0 -0
- data/app/assets/images/locomotive/background/body.png +0 -0
- data/app/assets/images/locomotive/datepicker/ui-widget-content-top.png +0 -0
- data/app/assets/images/locomotive/form/error-arrow.png +0 -0
- data/app/assets/images/locomotive/form/input-sep.png +0 -0
- data/app/assets/images/locomotive/icons/flags/de.png +0 -0
- data/app/assets/images/locomotive/icons/flags/en.png +0 -0
- data/app/assets/images/locomotive/icons/flags/es.png +0 -0
- data/app/assets/images/locomotive/icons/flags/et.png +0 -0
- data/app/assets/images/locomotive/icons/flags/fr.png +0 -0
- data/app/assets/images/locomotive/icons/flags/it.png +0 -0
- data/app/assets/images/locomotive/icons/flags/nb.png +0 -0
- data/app/assets/images/locomotive/icons/flags/nl.png +0 -0
- data/app/assets/images/locomotive/icons/flags/pl.png +0 -0
- data/app/assets/images/locomotive/icons/flags/pt-BR.png +0 -0
- data/app/assets/images/locomotive/icons/flags/ru.png +0 -0
- data/app/assets/images/locomotive/icons/start.png +0 -0
- data/app/assets/images/locomotive/list/empty.png +0 -0
- data/app/assets/images/locomotive/list/item-left.png +0 -0
- data/app/assets/images/locomotive/nocoffee.png +0 -0
- data/app/assets/images/locomotive/plugins/sites_picker_top_arrow.png +0 -0
- data/app/assets/images/locomotive/rails.png +0 -0
- data/app/assets/javascripts/aloha/plugins/custom/locomotive_media/css/image.css +3 -0
- data/app/assets/javascripts/aloha/plugins/custom/locomotive_media/img/image.gif +0 -0
- data/app/assets/javascripts/aloha/plugins/custom/locomotive_media/lib/locomotive_media-plugin.js +96 -0
- data/app/assets/javascripts/aloha/plugins/custom/locomotive_media/nls/fr/i18n.js +1 -0
- data/app/assets/javascripts/aloha/plugins/custom/locomotive_media/nls/i18n.js +4 -0
- data/app/assets/javascripts/aloha/plugins/custom/locomotive_media/package.json +1 -0
- data/app/assets/javascripts/locomotive.js +25 -0
- data/app/assets/javascripts/locomotive/aloha.js.coffee +2 -0
- data/app/assets/javascripts/locomotive/application.js.coffee +12 -0
- data/app/assets/javascripts/locomotive/inline_editor.js.coffee +22 -0
- data/app/assets/javascripts/locomotive/models/account.js.coffee +11 -0
- data/app/assets/javascripts/locomotive/models/content_asset.js.coffee +20 -0
- data/app/assets/javascripts/locomotive/models/content_entry.js.coffee +61 -0
- data/app/assets/javascripts/locomotive/models/content_type.js.coffee +26 -0
- data/app/assets/javascripts/locomotive/models/custom_field.js.coffee +38 -0
- data/app/assets/javascripts/locomotive/models/custom_field_select_option.js.coffee +16 -0
- data/app/assets/javascripts/locomotive/models/domain.js.coffee +3 -0
- data/app/assets/javascripts/locomotive/models/editable_element.js.coffee +27 -0
- data/app/assets/javascripts/locomotive/models/membership.js.coffee +13 -0
- data/app/assets/javascripts/locomotive/models/page.js.coffee +27 -0
- data/app/assets/javascripts/locomotive/models/site.js.coffee +34 -0
- data/app/assets/javascripts/locomotive/models/snippet.js.coffee +11 -0
- data/app/assets/javascripts/locomotive/models/theme_asset.js.coffee +11 -0
- data/app/assets/javascripts/locomotive/models/translation.js.coffee +5 -0
- data/app/assets/javascripts/locomotive/not_logged_in.js.coffee +1 -0
- data/app/assets/javascripts/locomotive/utils/aloha_settings.js.coffee +37 -0
- data/app/assets/javascripts/locomotive/utils/core_ext.js +75 -0
- data/app/assets/javascripts/locomotive/utils/growl.js +14 -0
- data/app/assets/javascripts/locomotive/utils/handlebar_helpers.js.coffee +9 -0
- data/app/assets/javascripts/locomotive/utils/tinymce_settings.js.coffee +48 -0
- data/app/assets/javascripts/locomotive/views/application_view.js.coffee +92 -0
- data/app/assets/javascripts/locomotive/views/content_assets/picker_item_view.js.coffee +30 -0
- data/app/assets/javascripts/locomotive/views/content_assets/picker_view.js.coffee +58 -0
- data/app/assets/javascripts/locomotive/views/content_entries/_form_view.js.coffee +144 -0
- data/app/assets/javascripts/locomotive/views/content_entries/_popup_form_view.js.coffee +90 -0
- data/app/assets/javascripts/locomotive/views/content_entries/edit_view.js.coffee +9 -0
- data/app/assets/javascripts/locomotive/views/content_entries/index_view.js.coffee +36 -0
- data/app/assets/javascripts/locomotive/views/content_entries/new_view.js.coffee +8 -0
- data/app/assets/javascripts/locomotive/views/content_types/_form_view.js.coffee +86 -0
- data/app/assets/javascripts/locomotive/views/content_types/custom_field_entry_view.js.coffee +104 -0
- data/app/assets/javascripts/locomotive/views/content_types/custom_fields_view.coffee +94 -0
- data/app/assets/javascripts/locomotive/views/content_types/edit_view.coffee +14 -0
- data/app/assets/javascripts/locomotive/views/content_types/new_view.js.coffee +11 -0
- data/app/assets/javascripts/locomotive/views/content_types/select_options_view.js.coffee +89 -0
- data/app/assets/javascripts/locomotive/views/current_site/edit_view.js.coffee +86 -0
- data/app/assets/javascripts/locomotive/views/editable_elements/control_view.js.coffee +24 -0
- data/app/assets/javascripts/locomotive/views/editable_elements/edit_all_view.js.coffee +83 -0
- data/app/assets/javascripts/locomotive/views/editable_elements/file_view.js.coffee +74 -0
- data/app/assets/javascripts/locomotive/views/editable_elements/long_text_view.js.coffee +36 -0
- data/app/assets/javascripts/locomotive/views/editable_elements/short_text_view.js.coffee +22 -0
- data/app/assets/javascripts/locomotive/views/inline_editor/application_view.js.coffee +124 -0
- data/app/assets/javascripts/locomotive/views/inline_editor/toolbar_view.js.coffee +145 -0
- data/app/assets/javascripts/locomotive/views/my_account/edit_view.js.coffee +24 -0
- data/app/assets/javascripts/locomotive/views/pages/_form_view.js.coffee +162 -0
- data/app/assets/javascripts/locomotive/views/pages/edit_view.js.coffee +31 -0
- data/app/assets/javascripts/locomotive/views/pages/index_view.js.coffee +11 -0
- data/app/assets/javascripts/locomotive/views/pages/list_view.js.coffee +40 -0
- data/app/assets/javascripts/locomotive/views/pages/new_view.js.coffee +8 -0
- data/app/assets/javascripts/locomotive/views/shared/asset_picker_view.js.coffee +92 -0
- data/app/assets/javascripts/locomotive/views/shared/fields/file_view.js.coffee +88 -0
- data/app/assets/javascripts/locomotive/views/shared/fields/has_many_view.js.coffee +125 -0
- data/app/assets/javascripts/locomotive/views/shared/fields/many_to_many_view.js.coffee +131 -0
- data/app/assets/javascripts/locomotive/views/shared/fields/select_view.js.coffee +83 -0
- data/app/assets/javascripts/locomotive/views/shared/form_view.js.coffee +138 -0
- data/app/assets/javascripts/locomotive/views/shared/list_item_view.js.coffee +22 -0
- data/app/assets/javascripts/locomotive/views/shared/list_view.js.coffee +53 -0
- data/app/assets/javascripts/locomotive/views/sites/domain_entry_view.js.coffee +26 -0
- data/app/assets/javascripts/locomotive/views/sites/domains_view.js.coffee +84 -0
- data/app/assets/javascripts/locomotive/views/sites/membership_entry_view.js.coffee +31 -0
- data/app/assets/javascripts/locomotive/views/sites/memberships_view.js.coffee +41 -0
- data/app/assets/javascripts/locomotive/views/sites/new_view.js.coffee +43 -0
- data/app/assets/javascripts/locomotive/views/snippets/_form_view.js.coffee +75 -0
- data/app/assets/javascripts/locomotive/views/snippets/edit_view.js.coffee +6 -0
- data/app/assets/javascripts/locomotive/views/snippets/list_item_view.js.coffee +8 -0
- data/app/assets/javascripts/locomotive/views/snippets/list_view.js.coffee +17 -0
- data/app/assets/javascripts/locomotive/views/snippets/new_view.js.coffee +8 -0
- data/app/assets/javascripts/locomotive/views/theme_assets/_form_view.js.coffee +104 -0
- data/app/assets/javascripts/locomotive/views/theme_assets/edit_view.js.coffee +16 -0
- data/app/assets/javascripts/locomotive/views/theme_assets/image_picker_view.js.coffee +48 -0
- data/app/assets/javascripts/locomotive/views/theme_assets/index_view.js.coffee +91 -0
- data/app/assets/javascripts/locomotive/views/theme_assets/list_item_view.js.coffee +8 -0
- data/app/assets/javascripts/locomotive/views/theme_assets/list_view.js.coffee +17 -0
- data/app/assets/javascripts/locomotive/views/theme_assets/new_view.js.coffee +8 -0
- data/app/assets/javascripts/locomotive/views/translations/_form_view.js.coffee +20 -0
- data/app/assets/javascripts/locomotive/views/translations/edit_view.js.coffee +6 -0
- data/app/assets/javascripts/locomotive/views/translations/new_view.js.coffee +8 -0
- data/app/assets/javascripts/tinymce/plugins/jqueryinlinepopups/editor_plugin.js +240 -0
- data/app/assets/javascripts/tinymce/plugins/locomotive_media/editor_plugin.js +78 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/content.css +66 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/dialog.css.scss +78 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/butt2.png +0 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/button-bg.png +0 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/buttons.png +0 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/down_arrow.gif +0 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/fade-butt.png +0 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/icons.png +0 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/items.gif +0 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/menu-arrow.png +0 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/menu-check.png +0 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/progress.gif +0 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/tabs.gif +0 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/img/toolbarbg.png +0 -0
- data/app/assets/javascripts/tinymce/themes/advanced/skins/locomotive/ui.css +1018 -0
- data/app/assets/stylesheets/locomotive.css +16 -0
- data/app/assets/stylesheets/locomotive/backoffice/_box.css.scss +157 -0
- data/app/assets/stylesheets/locomotive/backoffice/_buttons.css.scss +178 -0
- data/app/assets/stylesheets/locomotive/backoffice/application.css.scss +332 -0
- data/app/assets/stylesheets/locomotive/backoffice/codemirror_changes.css.scss +19 -0
- data/app/assets/stylesheets/locomotive/backoffice/content_assets.css.scss +130 -0
- data/app/assets/stylesheets/locomotive/backoffice/datepicker.css.scss +178 -0
- data/app/assets/stylesheets/locomotive/backoffice/dialog_changes.css.scss +141 -0
- data/app/assets/stylesheets/locomotive/backoffice/editable_elements.css.scss +71 -0
- data/app/assets/stylesheets/locomotive/backoffice/formtastic_changes.css.scss +735 -0
- data/app/assets/stylesheets/locomotive/backoffice/layout.css.scss +205 -0
- data/app/assets/stylesheets/locomotive/backoffice/menu.css +8 -0
- data/app/assets/stylesheets/locomotive/backoffice/menu/_colors.css.scss +125 -0
- data/app/assets/stylesheets/locomotive/backoffice/menu/_helpers.css.scss +6 -0
- data/app/assets/stylesheets/locomotive/backoffice/menu/default.css.scss +32 -0
- data/app/assets/stylesheets/locomotive/backoffice/menu/main.css.scss +127 -0
- data/app/assets/stylesheets/locomotive/backoffice/menu/sub.css.scss +276 -0
- data/app/assets/stylesheets/locomotive/backoffice/sites_picker.css.scss +12 -0
- data/app/assets/stylesheets/locomotive/inline_editor.css +13 -0
- data/app/assets/stylesheets/locomotive/inline_editor/_buttons.css.scss +60 -0
- data/app/assets/stylesheets/locomotive/inline_editor/layout.css.scss +22 -0
- data/app/assets/stylesheets/locomotive/inline_editor/toolbar.css.scss +114 -0
- data/app/assets/stylesheets/locomotive/not_logged_in.css +8 -0
- data/app/assets/stylesheets/locomotive/not_logged_in/installation.css.scss +62 -0
- data/app/assets/stylesheets/locomotive/not_logged_in/layout.css.scss +185 -0
- data/app/assets/stylesheets/locomotive/shared/_helpers.css.scss +150 -0
- data/app/assets/stylesheets/locomotive/shared/_picker.css.scss +73 -0
- data/app/assets/stylesheets/locomotive/shared/common.css.scss +34 -0
- data/app/assets/stylesheets/locomotive/shared/content_locale_picker.css.scss +80 -0
- data/app/assets/stylesheets/locomotive/shared/growl.css.scss +29 -0
- data/app/cells/locomotive/content_locale_picker/show.html.haml +7 -0
- data/app/cells/locomotive/content_locale_picker_cell.rb +21 -0
- data/app/cells/locomotive/global_actions/show.html.haml +12 -0
- data/app/cells/locomotive/global_actions_cell.rb +36 -0
- data/app/cells/locomotive/main_menu/show.html.haml +13 -0
- data/app/cells/locomotive/main_menu_cell.rb +12 -0
- data/app/cells/locomotive/menu/show.html.haml +1 -0
- data/app/cells/locomotive/menu_cell.rb +102 -0
- data/app/cells/locomotive/settings_menu_cell.rb +14 -0
- data/app/cells/locomotive/sub_menu/show.html.haml +4 -0
- data/app/cells/locomotive/sub_menu_cell.rb +13 -0
- data/app/controllers/locomotive/accounts_controller.rb +18 -0
- data/app/controllers/locomotive/api/accounts_controller.rb +79 -0
- data/app/controllers/locomotive/api/base_controller.rb +50 -0
- data/app/controllers/locomotive/api/content_assets_controller.rb +39 -0
- data/app/controllers/locomotive/api/content_entries_controller.rb +45 -0
- data/app/controllers/locomotive/api/content_types_controller.rb +39 -0
- data/app/controllers/locomotive/api/current_site_controller.rb +58 -0
- data/app/controllers/locomotive/api/documentation_controller.rb +15 -0
- data/app/controllers/locomotive/api/memberships_controller.rb +97 -0
- data/app/controllers/locomotive/api/my_account_controller.rb +35 -0
- data/app/controllers/locomotive/api/pages_controller.rb +41 -0
- data/app/controllers/locomotive/api/sites_controller.rb +93 -0
- data/app/controllers/locomotive/api/snippets_controller.rb +40 -0
- data/app/controllers/locomotive/api/theme_assets_controller.rb +39 -0
- data/app/controllers/locomotive/api/tokens_controller.rb +54 -0
- data/app/controllers/locomotive/api/translations_controller.rb +31 -0
- data/app/controllers/locomotive/base_controller.rb +61 -0
- data/app/controllers/locomotive/content_assets_controller.rb +23 -0
- data/app/controllers/locomotive/content_entries_controller.rb +71 -0
- data/app/controllers/locomotive/content_types_controller.rb +40 -0
- data/app/controllers/locomotive/current_site_controller.rb +52 -0
- data/app/controllers/locomotive/installation_controller.rb +72 -0
- data/app/controllers/locomotive/memberships_controller.rb +29 -0
- data/app/controllers/locomotive/my_account_controller.rb +24 -0
- data/app/controllers/locomotive/pages_controller.rb +63 -0
- data/app/controllers/locomotive/passwords_controller.rb +19 -0
- data/app/controllers/locomotive/public/base_controller.rb +22 -0
- data/app/controllers/locomotive/public/content_entries_controller.rb +55 -0
- data/app/controllers/locomotive/public/pages_controller.rb +50 -0
- data/app/controllers/locomotive/public/robots_controller.rb +16 -0
- data/app/controllers/locomotive/public/sitemaps_controller.rb +14 -0
- data/app/controllers/locomotive/sessions_controller.rb +29 -0
- data/app/controllers/locomotive/sites_controller.rb +33 -0
- data/app/controllers/locomotive/snippets_controller.rb +47 -0
- data/app/controllers/locomotive/theme_assets_controller.rb +52 -0
- data/app/controllers/locomotive/translations_controller.rb +32 -0
- data/app/helpers/locomotive/accounts_helper.rb +13 -0
- data/app/helpers/locomotive/base_helper.rb +182 -0
- data/app/helpers/locomotive/content_entries_helper.rb +15 -0
- data/app/helpers/locomotive/content_types_helper.rb +72 -0
- data/app/helpers/locomotive/custom_fields_helper.rb +70 -0
- data/app/helpers/locomotive/installation_helper.rb +9 -0
- data/app/helpers/locomotive/pages_helper.rb +95 -0
- data/app/helpers/locomotive/sites_helper.rb +15 -0
- data/app/helpers/locomotive/snippets_helper.rb +20 -0
- data/app/helpers/locomotive/theme_assets_helper.rb +30 -0
- data/app/helpers/locomotive/translations_helper.rb +19 -0
- data/app/inputs/locomotive/code_input.rb +51 -0
- data/app/inputs/locomotive/empty_input.rb +35 -0
- data/app/inputs/locomotive/file_input.rb +45 -0
- data/app/inputs/locomotive/locale_input.rb +40 -0
- data/app/inputs/locomotive/locales_input.rb +60 -0
- data/app/inputs/locomotive/rte_input.rb +13 -0
- data/app/inputs/locomotive/small_code_input.rb +22 -0
- data/app/inputs/locomotive/subdomain_input.rb +22 -0
- data/app/inputs/locomotive/toggle_input.rb +13 -0
- data/app/mailers/locomotive/devise_mailer.rb +10 -0
- data/app/mailers/locomotive/notifications.rb +15 -0
- data/app/models/locomotive/ability.rb +89 -0
- data/app/models/locomotive/account.rb +117 -0
- data/app/models/locomotive/content_asset.rb +40 -0
- data/app/models/locomotive/content_entry.rb +197 -0
- data/app/models/locomotive/content_type.rb +224 -0
- data/app/models/locomotive/editable_control.rb +52 -0
- data/app/models/locomotive/editable_element.rb +122 -0
- data/app/models/locomotive/editable_file.rb +85 -0
- data/app/models/locomotive/editable_long_text.rb +5 -0
- data/app/models/locomotive/editable_short_text.rb +66 -0
- data/app/models/locomotive/extensions/asset/types.rb +31 -0
- data/app/models/locomotive/extensions/asset/vignette.rb +19 -0
- data/app/models/locomotive/extensions/content_type/default_values.rb +57 -0
- data/app/models/locomotive/extensions/content_type/item_template.rb +49 -0
- data/app/models/locomotive/extensions/content_type/sync.rb +62 -0
- data/app/models/locomotive/extensions/page/editable_elements.rb +105 -0
- data/app/models/locomotive/extensions/page/listed.rb +18 -0
- data/app/models/locomotive/extensions/page/parse.rb +125 -0
- data/app/models/locomotive/extensions/page/redirect.rb +25 -0
- data/app/models/locomotive/extensions/page/render.rb +93 -0
- data/app/models/locomotive/extensions/page/templatized.rb +163 -0
- data/app/models/locomotive/extensions/page/tree.rb +133 -0
- data/app/models/locomotive/extensions/shared/seo.rb +16 -0
- data/app/models/locomotive/extensions/site/first_installation.rb +20 -0
- data/app/models/locomotive/extensions/site/locales.rb +112 -0
- data/app/models/locomotive/extensions/site/subdomain_domains.rb +91 -0
- data/app/models/locomotive/membership.rb +75 -0
- data/app/models/locomotive/page.rb +130 -0
- data/app/models/locomotive/site.rb +79 -0
- data/app/models/locomotive/snippet.rb +70 -0
- data/app/models/locomotive/theme_asset.rb +175 -0
- data/app/models/locomotive/translation.rb +32 -0
- data/app/presenters/locomotive/account_presenter.rb +19 -0
- data/app/presenters/locomotive/base_presenter.rb +99 -0
- data/app/presenters/locomotive/content_asset_presenter.rb +43 -0
- data/app/presenters/locomotive/content_entry_presenter.rb +217 -0
- data/app/presenters/locomotive/content_field_presenter.rb +71 -0
- data/app/presenters/locomotive/content_type_presenter.rb +68 -0
- data/app/presenters/locomotive/editable_control_presenter.rb +19 -0
- data/app/presenters/locomotive/editable_element_presenter.rb +40 -0
- data/app/presenters/locomotive/editable_file_presenter.rb +29 -0
- data/app/presenters/locomotive/editable_long_text_presenter.rb +5 -0
- data/app/presenters/locomotive/editable_short_text_presenter.rb +27 -0
- data/app/presenters/locomotive/membership_presenter.rb +36 -0
- data/app/presenters/locomotive/page_presenter.rb +58 -0
- data/app/presenters/locomotive/site_presenter.rb +36 -0
- data/app/presenters/locomotive/snippet_presenter.rb +22 -0
- data/app/presenters/locomotive/theme_asset_presenter.rb +61 -0
- data/app/presenters/locomotive/translation_presenter.rb +9 -0
- data/app/uploaders/locomotive/content_asset_uploader.rb +13 -0
- data/app/uploaders/locomotive/editable_file_uploader.rb +15 -0
- data/app/uploaders/locomotive/theme_asset_uploader.rb +28 -0
- data/app/views/locomotive/accounts/new.html.haml +21 -0
- data/app/views/locomotive/content_assets/_asset.html.haml +5 -0
- data/app/views/locomotive/content_assets/_picker.html.haml +33 -0
- data/app/views/locomotive/content_entries/_form.html.haml +22 -0
- data/app/views/locomotive/content_entries/_list.html.haml +18 -0
- data/app/views/locomotive/content_entries/edit.html.haml +21 -0
- data/app/views/locomotive/content_entries/index.html.haml +32 -0
- data/app/views/locomotive/content_entries/new.html.haml +19 -0
- data/app/views/locomotive/content_types/_form.html.haml +39 -0
- data/app/views/locomotive/content_types/edit.html.haml +19 -0
- data/app/views/locomotive/content_types/new.html.haml +15 -0
- data/app/views/locomotive/current_site/_form.html.haml +36 -0
- data/app/views/locomotive/current_site/edit.html.haml +19 -0
- data/app/views/locomotive/custom_fields/_form.html.haml +61 -0
- data/app/views/locomotive/custom_fields/_select_templates.html.haml +16 -0
- data/app/views/locomotive/custom_fields/types/_belongs_to.html.haml +5 -0
- data/app/views/locomotive/custom_fields/types/_boolean.html.haml +4 -0
- data/app/views/locomotive/custom_fields/types/_date.html.haml +5 -0
- data/app/views/locomotive/custom_fields/types/_file.html.haml +4 -0
- data/app/views/locomotive/custom_fields/types/_has_many.html.haml +70 -0
- data/app/views/locomotive/custom_fields/types/_many_to_many.html.haml +41 -0
- data/app/views/locomotive/custom_fields/types/_select.html.haml +34 -0
- data/app/views/locomotive/custom_fields/types/_string.html.haml +4 -0
- data/app/views/locomotive/custom_fields/types/_text.html.haml +5 -0
- data/app/views/locomotive/devise_mailer/reset_password_instructions.html.haml +12 -0
- data/app/views/locomotive/errors/404.html.haml +7 -0
- data/app/views/locomotive/errors/500.html.haml +7 -0
- data/app/views/locomotive/errors/no_page.html.haml +1 -0
- data/app/views/locomotive/errors/no_site.html.haml +1 -0
- data/app/views/locomotive/installation/step_1.html.haml +23 -0
- data/app/views/locomotive/installation/step_2.html.haml +24 -0
- data/app/views/locomotive/layouts/application.html.haml +34 -0
- data/app/views/locomotive/layouts/error.html.haml +1 -0
- data/app/views/locomotive/layouts/not_logged_in.html.haml +18 -0
- data/app/views/locomotive/memberships/new.html.haml +14 -0
- data/app/views/locomotive/my_account/edit.html.haml +40 -0
- data/app/views/locomotive/notifications/new_content_entry.html.haml +29 -0
- data/app/views/locomotive/pages/_editable_elements.html.haml +64 -0
- data/app/views/locomotive/pages/_form.html.haml +61 -0
- data/app/views/locomotive/pages/_page.html.haml +42 -0
- data/app/views/locomotive/pages/edit.html.haml +18 -0
- data/app/views/locomotive/pages/index.html.haml +19 -0
- data/app/views/locomotive/pages/new.html.haml +15 -0
- data/app/views/locomotive/passwords/edit.html.haml +18 -0
- data/app/views/locomotive/passwords/new.html.haml +17 -0
- data/app/views/locomotive/public/pages/show_toolbar.html.haml +64 -0
- data/app/views/locomotive/public/sitemaps/show.xml.builder +29 -0
- data/app/views/locomotive/sessions/new.html.haml +17 -0
- data/app/views/locomotive/shared/_footer.html.haml +1 -0
- data/app/views/locomotive/shared/_form_actions.html.haml +14 -0
- data/app/views/locomotive/shared/_head.html.haml +38 -0
- data/app/views/locomotive/shared/_header.html.haml +10 -0
- data/app/views/locomotive/shared/_locale_picker_link.html.haml +6 -0
- data/app/views/locomotive/shared/_main_app_head.html.haml +1 -0
- data/app/views/locomotive/shared/_site_picker.html.haml +10 -0
- data/app/views/locomotive/shared/actions/_contents.html.haml +7 -0
- data/app/views/locomotive/shared/menu/_contents.html.haml +51 -0
- data/app/views/locomotive/sites/_domains.html.haml +22 -0
- data/app/views/locomotive/sites/_form.html.haml +12 -0
- data/app/views/locomotive/sites/_memberships.html.haml +27 -0
- data/app/views/locomotive/sites/new.html.haml +12 -0
- data/app/views/locomotive/snippets/_form.html.haml +13 -0
- data/app/views/locomotive/snippets/_snippet.html.haml +8 -0
- data/app/views/locomotive/snippets/edit.html.haml +18 -0
- data/app/views/locomotive/snippets/new.html.haml +15 -0
- data/app/views/locomotive/theme_assets/_asset.html.haml +11 -0
- data/app/views/locomotive/theme_assets/_form.html.haml +35 -0
- data/app/views/locomotive/theme_assets/_list.html.haml +7 -0
- data/app/views/locomotive/theme_assets/_picker.html.haml +25 -0
- data/app/views/locomotive/theme_assets/edit.html.haml +21 -0
- data/app/views/locomotive/theme_assets/index.html.haml +50 -0
- data/app/views/locomotive/theme_assets/new.html.haml +12 -0
- data/app/views/locomotive/translations/_form.html.haml +12 -0
- data/app/views/locomotive/translations/edit.html.haml +15 -0
- data/app/views/locomotive/translations/index.html.haml +26 -0
- data/app/views/locomotive/translations/new.html.haml +12 -0
- data/config/cucumber.yml +8 -0
- data/config/initializers/deny_phantomjs_ttf.rb +29 -0
- data/config/initializers/devise.rb +15 -0
- data/config/initializers/formtastic.rb +4 -0
- data/config/initializers/haml.rb +2 -0
- data/config/initializers/locomotive_loaded_first.rb +19 -0
- data/config/locales/admin_ui.de.yml +316 -0
- data/config/locales/admin_ui.en.yml +332 -0
- data/config/locales/admin_ui.es.yml +296 -0
- data/config/locales/admin_ui.et.yml +315 -0
- data/config/locales/admin_ui.fr.yml +326 -0
- data/config/locales/admin_ui.it.yml +295 -0
- data/config/locales/admin_ui.nb.yml +314 -0
- data/config/locales/admin_ui.nl.yml +279 -0
- data/config/locales/admin_ui.pl.yml +319 -0
- data/config/locales/admin_ui.pt-BR.yml +274 -0
- data/config/locales/admin_ui.ru.yml +313 -0
- data/config/locales/carrierwave.de.yml +4 -0
- data/config/locales/carrierwave.en.yml +4 -0
- data/config/locales/carrierwave.es.yml +4 -0
- data/config/locales/carrierwave.et.yml +4 -0
- data/config/locales/carrierwave.fr.yml +4 -0
- data/config/locales/carrierwave.it.yml +4 -0
- data/config/locales/carrierwave.nb.yml +4 -0
- data/config/locales/carrierwave.nl.yml +4 -0
- data/config/locales/carrierwave.pl.yml +4 -0
- data/config/locales/carrierwave.pt-BR.yml +4 -0
- data/config/locales/carrierwave.ru.yml +4 -0
- data/config/locales/default.de.yml +244 -0
- data/config/locales/default.en.yml +43 -0
- data/config/locales/default.es.yml +216 -0
- data/config/locales/default.et.yml +240 -0
- data/config/locales/default.fr.yml +224 -0
- data/config/locales/default.it.yml +243 -0
- data/config/locales/default.nb.yml +313 -0
- data/config/locales/default.nl.yml +170 -0
- data/config/locales/default.pl.yml +317 -0
- data/config/locales/default.pt-BR.yml +211 -0
- data/config/locales/default.ru.yml +279 -0
- data/config/locales/devise.de.yml +62 -0
- data/config/locales/devise.en.yml +63 -0
- data/config/locales/devise.es.yml +63 -0
- data/config/locales/devise.et.yml +64 -0
- data/config/locales/devise.fr.yml +67 -0
- data/config/locales/devise.it.yml +63 -0
- data/config/locales/devise.nb.yml +63 -0
- data/config/locales/devise.nl.yml +63 -0
- data/config/locales/devise.pl.yml +63 -0
- data/config/locales/devise.pt-BR.yml +61 -0
- data/config/locales/devise.ru.yml +63 -0
- data/config/locales/flash.de.yml +106 -0
- data/config/locales/flash.en.yml +115 -0
- data/config/locales/flash.es.yml +106 -0
- data/config/locales/flash.et.yml +106 -0
- data/config/locales/flash.fr.yml +106 -0
- data/config/locales/flash.it.yml +106 -0
- data/config/locales/flash.nb.yml +106 -0
- data/config/locales/flash.nl.yml +106 -0
- data/config/locales/flash.pl.yml +106 -0
- data/config/locales/flash.pt-BR.yml +106 -0
- data/config/locales/flash.ru.yml +106 -0
- data/config/locales/formtastic.de.yml +97 -0
- data/config/locales/formtastic.en.yml +105 -0
- data/config/locales/formtastic.es.yml +84 -0
- data/config/locales/formtastic.et.yml +103 -0
- data/config/locales/formtastic.fr.yml +94 -0
- data/config/locales/formtastic.it.yml +99 -0
- data/config/locales/formtastic.nb.yml +103 -0
- data/config/locales/formtastic.nl.yml +85 -0
- data/config/locales/formtastic.pl.yml +105 -0
- data/config/locales/formtastic.pt-BR.yml +70 -0
- data/config/locales/formtastic.ru.yml +103 -0
- data/config/routes.rb +116 -0
- data/lib/generators/locomotive/install/install_generator.rb +35 -0
- data/lib/generators/locomotive/install/templates/README +26 -0
- data/lib/generators/locomotive/install/templates/carrierwave.rb +28 -0
- data/lib/generators/locomotive/install/templates/dragonfly.rb +22 -0
- data/lib/generators/locomotive/install/templates/locomotive.rb +69 -0
- data/lib/generators/locomotive/install/templates/mongoid.yml +34 -0
- data/lib/locomotive.rb +136 -0
- data/lib/locomotive/action_controller.rb +5 -0
- data/lib/locomotive/action_controller/locale_helpers.rb +61 -0
- data/lib/locomotive/action_controller/public_responder.rb +17 -0
- data/lib/locomotive/action_controller/responder.rb +78 -0
- data/lib/locomotive/action_controller/section_helpers.rb +29 -0
- data/lib/locomotive/action_controller/url_helpers.rb +38 -0
- data/lib/locomotive/carrierwave.rb +10 -0
- data/lib/locomotive/carrierwave/asset.rb +72 -0
- data/lib/locomotive/carrierwave/base.rb +15 -0
- data/lib/locomotive/carrierwave/patches.rb +32 -0
- data/lib/locomotive/configuration.rb +122 -0
- data/lib/locomotive/core_ext.rb +64 -0
- data/lib/locomotive/custom_fields.rb +66 -0
- data/lib/locomotive/dependencies.rb +30 -0
- data/lib/locomotive/devise.rb +1 -0
- data/lib/locomotive/dragonfly.rb +38 -0
- data/lib/locomotive/engine.rb +37 -0
- data/lib/locomotive/formtastic.rb +13 -0
- data/lib/locomotive/haml.rb +1 -0
- data/lib/locomotive/httparty.rb +2 -0
- data/lib/locomotive/httparty/patches.rb +18 -0
- data/lib/locomotive/httparty/webservice.rb +42 -0
- data/lib/locomotive/kaminari.rb +35 -0
- data/lib/locomotive/liquid.rb +7 -0
- data/lib/locomotive/liquid/drops/base.rb +42 -0
- data/lib/locomotive/liquid/drops/content_entry.rb +76 -0
- data/lib/locomotive/liquid/drops/content_types.rb +50 -0
- data/lib/locomotive/liquid/drops/current_user.rb +21 -0
- data/lib/locomotive/liquid/drops/page.rb +55 -0
- data/lib/locomotive/liquid/drops/proxy_collection.rb +56 -0
- data/lib/locomotive/liquid/drops/site.rb +19 -0
- data/lib/locomotive/liquid/drops/uploader.rb +15 -0
- data/lib/locomotive/liquid/errors.rb +7 -0
- data/lib/locomotive/liquid/filters/base.rb +47 -0
- data/lib/locomotive/liquid/filters/date.rb +54 -0
- data/lib/locomotive/liquid/filters/html.rb +115 -0
- data/lib/locomotive/liquid/filters/misc.rb +65 -0
- data/lib/locomotive/liquid/filters/resize.rb +16 -0
- data/lib/locomotive/liquid/filters/text.rb +45 -0
- data/lib/locomotive/liquid/filters/translate.rb +16 -0
- data/lib/locomotive/liquid/patches.rb +21 -0
- data/lib/locomotive/liquid/tags/consume.rb +67 -0
- data/lib/locomotive/liquid/tags/csrf.rb +40 -0
- data/lib/locomotive/liquid/tags/editable.rb +5 -0
- data/lib/locomotive/liquid/tags/editable/base.rb +88 -0
- data/lib/locomotive/liquid/tags/editable/control.rb +31 -0
- data/lib/locomotive/liquid/tags/editable/file.rb +39 -0
- data/lib/locomotive/liquid/tags/editable/long_text.rb +33 -0
- data/lib/locomotive/liquid/tags/editable/short_text.rb +41 -0
- data/lib/locomotive/liquid/tags/extends.rb +47 -0
- data/lib/locomotive/liquid/tags/google_analytics.rb +39 -0
- data/lib/locomotive/liquid/tags/inherited_block.rb +31 -0
- data/lib/locomotive/liquid/tags/inline_editor.rb +40 -0
- data/lib/locomotive/liquid/tags/locale_switcher.rb +83 -0
- data/lib/locomotive/liquid/tags/nav.rb +155 -0
- data/lib/locomotive/liquid/tags/paginate.rb +111 -0
- data/lib/locomotive/liquid/tags/seo.rb +72 -0
- data/lib/locomotive/liquid/tags/snippet.rb +75 -0
- data/lib/locomotive/liquid/tags/with_scope.rb +47 -0
- data/lib/locomotive/logger.rb +11 -0
- data/lib/locomotive/middlewares.rb +4 -0
- data/lib/locomotive/middlewares/cache.rb +27 -0
- data/lib/locomotive/middlewares/fonts.rb +42 -0
- data/lib/locomotive/middlewares/inline_editor.rb +36 -0
- data/lib/locomotive/middlewares/seo_trailing_slash.rb +24 -0
- data/lib/locomotive/misc/api_documentation.rb +96 -0
- data/lib/locomotive/misc/api_documentation/bootstrap.html.haml +119 -0
- data/lib/locomotive/mongoid.rb +4 -0
- data/lib/locomotive/mongoid/document.rb +19 -0
- data/lib/locomotive/mongoid/liquid.rb +39 -0
- data/lib/locomotive/mongoid/patches.rb +106 -0
- data/lib/locomotive/mongoid/presenter.rb +73 -0
- data/lib/locomotive/presentable.rb +212 -0
- data/lib/locomotive/rails.rb +1 -0
- data/lib/locomotive/rails/action_view.rb +9 -0
- data/lib/locomotive/regexps.rb +11 -0
- data/lib/locomotive/render.rb +177 -0
- data/lib/locomotive/routing.rb +2 -0
- data/lib/locomotive/routing/default_constraint.rb +42 -0
- data/lib/locomotive/routing/site_dispatcher.rb +54 -0
- data/lib/locomotive/session_store.rb +64 -0
- data/lib/locomotive/version.rb +3 -0
- data/lib/locomotive_cms.rb +1 -0
- data/lib/tasks/cucumber.rake +66 -0
- data/lib/tasks/locomotive.rake +220 -0
- data/public/favicon.ico +0 -0
- data/vendor/assets/fonts/locomotive/fontawesome-webfont.eot +0 -0
- data/vendor/assets/fonts/locomotive/fontawesome-webfont.svg +255 -0
- data/vendor/assets/fonts/locomotive/fontawesome-webfont.ttf +0 -0
- data/vendor/assets/fonts/locomotive/fontawesome-webfont.woff +0 -0
- data/vendor/assets/javascripts/locomotive/ICanHandlebarz.js +88 -0
- data/vendor/assets/javascripts/locomotive/backbone.modelbinding.js +565 -0
- data/vendor/assets/javascripts/locomotive/backbone.sync.js +113 -0
- data/vendor/assets/javascripts/locomotive/cmd.js +31 -0
- data/vendor/assets/javascripts/locomotive/cookies.js +96 -0
- data/vendor/assets/javascripts/locomotive/datepicker_i18n.js.erb +28 -0
- data/vendor/assets/javascripts/locomotive/editable_field.js +50 -0
- data/vendor/assets/javascripts/locomotive/form_submit_notification.js +39 -0
- data/vendor/assets/javascripts/locomotive/growl.js +143 -0
- data/vendor/assets/javascripts/locomotive/handlebars.js +1493 -0
- data/vendor/assets/javascripts/locomotive/liquid_mode.js +42 -0
- data/vendor/assets/javascripts/locomotive/menu_toggler.js +37 -0
- data/vendor/assets/javascripts/locomotive/resize.js +9 -0
- data/vendor/assets/javascripts/locomotive/slugify.js +31 -0
- data/vendor/assets/javascripts/locomotive/smartupdater.js +296 -0
- data/vendor/assets/javascripts/locomotive/subscribe.js +367 -0
- data/vendor/assets/javascripts/locomotive/toggle.js +143 -0
- data/vendor/assets/javascripts/locomotive/vendor.js +1 -0
- data/vendor/assets/stylesheets/locomotive/blueprint/ie.css +26 -0
- data/vendor/assets/stylesheets/locomotive/blueprint/print.css +30 -0
- data/vendor/assets/stylesheets/locomotive/blueprint/screen.css +253 -0
- data/vendor/assets/stylesheets/locomotive/font-awesome.scss +329 -0
- data/vendor/assets/stylesheets/locomotive/jquery.css +3 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-icons_222222_256x240.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-icons_2e83ff_256x240.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-icons_454545_256x240.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-icons_888888_256x240.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/images/ui-icons_ffffff_256x240.png +0 -0
- data/vendor/assets/stylesheets/locomotive/jquery/ui.css +406 -0
- data/vendor/assets/stylesheets/locomotive/liquid_mode.css +7 -0
- data/vendor/assets/stylesheets/locomotive/toggle.css.scss +75 -0
- metadata +1171 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
module Locomotive
|
2
|
+
class Account
|
3
|
+
|
4
|
+
include Locomotive::Mongoid::Document
|
5
|
+
|
6
|
+
devise *Locomotive.config.devise_modules
|
7
|
+
|
8
|
+
## devise fields (need to be declared since 2.x) ##
|
9
|
+
field :remember_created_at, :type => Time
|
10
|
+
field :email, :type => String, :null => false
|
11
|
+
field :encrypted_password, :type => String, :null => false
|
12
|
+
field :authentication_token, :type => String
|
13
|
+
field :reset_password_token, :type => String
|
14
|
+
field :reset_password_sent_at, :type => Time
|
15
|
+
field :password_salt, :type => String
|
16
|
+
field :sign_in_count, :type => Integer
|
17
|
+
field :current_sign_in_at, :type => Time
|
18
|
+
field :last_sign_in_at, :type => Time
|
19
|
+
field :current_sign_in_ip, :type => String
|
20
|
+
field :last_sign_in_ip, :type => String
|
21
|
+
|
22
|
+
## attributes ##
|
23
|
+
field :name
|
24
|
+
field :locale, :default => Locomotive.config.default_locale.to_s or 'en'
|
25
|
+
|
26
|
+
## validations ##
|
27
|
+
validates_presence_of :name
|
28
|
+
|
29
|
+
## associations ##
|
30
|
+
|
31
|
+
## callbacks ##
|
32
|
+
before_destroy :remove_memberships!
|
33
|
+
|
34
|
+
## methods ##
|
35
|
+
|
36
|
+
def sites
|
37
|
+
@sites ||= Site.where('memberships.account_id' => self._id)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Tell if the account has admin privileges or not.
|
41
|
+
# Actually, an account is considered as an admin if
|
42
|
+
# it owns at least one admin membership in all its sites.
|
43
|
+
#
|
44
|
+
# @return [ Boolean ] True if admin
|
45
|
+
#
|
46
|
+
def admin?
|
47
|
+
Site.where(:memberships => { '$elemMatch' => { :account_id => self._id, :role => :admin } }).count > 0
|
48
|
+
end
|
49
|
+
|
50
|
+
# Create the API token which will be passed to all the requests to the Locomotive API.
|
51
|
+
# It requires the credentials of an account with admin role.
|
52
|
+
# If an error occurs (invalid account, ...etc), this method raises an exception that has
|
53
|
+
# to be caught somewhere.
|
54
|
+
#
|
55
|
+
# @param [ Site ] site The site where the authentication request is made
|
56
|
+
# @param [ String ] email The email of the account
|
57
|
+
# @param [ String ] password The password of the account
|
58
|
+
#
|
59
|
+
# @return [ String ] The API token
|
60
|
+
#
|
61
|
+
def self.create_api_token(site, email, password)
|
62
|
+
raise 'The request must contain the user email and password.' if email.blank? or password.blank?
|
63
|
+
|
64
|
+
account = self.where(:email => email.downcase).first
|
65
|
+
|
66
|
+
raise 'Invalid email or password.' if account.nil?
|
67
|
+
|
68
|
+
account.ensure_authentication_token!
|
69
|
+
|
70
|
+
if not account.valid_password?(password) # TODO: check admin roles
|
71
|
+
raise 'Invalid email or password.'
|
72
|
+
end
|
73
|
+
|
74
|
+
account.authentication_token
|
75
|
+
end
|
76
|
+
|
77
|
+
# Logout the user responding to the token passed in parameter from the API.
|
78
|
+
# An exception is raised if no account corresponds to the token.
|
79
|
+
#
|
80
|
+
# @param [ String ] token The API token created by the create_api_token method.
|
81
|
+
#
|
82
|
+
# @return [ String ] The API token
|
83
|
+
#
|
84
|
+
def self.invalidate_api_token(token)
|
85
|
+
account = self.where(:authentication_token => token).first
|
86
|
+
|
87
|
+
raise 'Invalid token.' if account.nil?
|
88
|
+
|
89
|
+
account.reset_authentication_token!
|
90
|
+
|
91
|
+
token
|
92
|
+
end
|
93
|
+
|
94
|
+
def devise_mailer
|
95
|
+
Locomotive::DeviseMailer
|
96
|
+
end
|
97
|
+
|
98
|
+
protected
|
99
|
+
|
100
|
+
def password_required?
|
101
|
+
!persisted? || !password.blank? || !password_confirmation.blank?
|
102
|
+
end
|
103
|
+
|
104
|
+
def remove_memberships!
|
105
|
+
self.sites.each do |site|
|
106
|
+
membership = site.memberships.where(:account_id => self._id).first
|
107
|
+
|
108
|
+
if site.admin_memberships.size == 1 && membership.admin?
|
109
|
+
raise ::I18n.t('errors.messages.needs_admin_account')
|
110
|
+
else
|
111
|
+
membership.destroy
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Locomotive
|
2
|
+
class ContentAsset
|
3
|
+
|
4
|
+
include Locomotive::Mongoid::Document
|
5
|
+
|
6
|
+
## extensions ##
|
7
|
+
include Extensions::Asset::Types
|
8
|
+
include Extensions::Asset::Vignette
|
9
|
+
|
10
|
+
## fields ##
|
11
|
+
field :content_type, :type => String
|
12
|
+
field :width, :type => Integer
|
13
|
+
field :height, :type => Integer
|
14
|
+
field :size, :type => Integer
|
15
|
+
field :position, :type => Integer, :default => 0
|
16
|
+
|
17
|
+
## associations ##
|
18
|
+
belongs_to :site, :class_name => 'Locomotive::Site'
|
19
|
+
|
20
|
+
## validations ##
|
21
|
+
validates_presence_of :source
|
22
|
+
|
23
|
+
## behaviours ##
|
24
|
+
mount_uploader :source, ContentAssetUploader, :mount_on => :source_filename
|
25
|
+
|
26
|
+
## methods ##
|
27
|
+
|
28
|
+
alias :name :source_filename
|
29
|
+
|
30
|
+
def extname
|
31
|
+
return nil unless self.source?
|
32
|
+
File.extname(self.source_filename).gsub(/^\./, '')
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_liquid
|
36
|
+
{ :url => self.source.url }.merge(self.attributes).stringify_keys
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
module Locomotive
|
2
|
+
class ContentEntry
|
3
|
+
|
4
|
+
include Locomotive::Mongoid::Document
|
5
|
+
|
6
|
+
## extensions ##
|
7
|
+
include ::CustomFields::Target
|
8
|
+
include Extensions::Shared::Seo
|
9
|
+
|
10
|
+
## fields ##
|
11
|
+
field :_slug
|
12
|
+
field :_label_field_name
|
13
|
+
field :_position, :type => Integer, :default => 0
|
14
|
+
field :_visible, :type => Boolean, :default => true
|
15
|
+
|
16
|
+
## validations ##
|
17
|
+
validates :_slug, :presence => true, :uniqueness => { :scope => :content_type_id }
|
18
|
+
|
19
|
+
## associations ##
|
20
|
+
belongs_to :site, :class_name => 'Locomotive::Site'
|
21
|
+
belongs_to :content_type, :class_name => 'Locomotive::ContentType', :inverse_of => :entries
|
22
|
+
|
23
|
+
## callbacks ##
|
24
|
+
before_validation :set_slug
|
25
|
+
before_save :set_site
|
26
|
+
before_save :set_visibility
|
27
|
+
before_save :set_label_field_name
|
28
|
+
before_create :add_to_list_bottom
|
29
|
+
after_create :send_notifications
|
30
|
+
|
31
|
+
## named scopes ##
|
32
|
+
scope :visible, :where => { :_visible => true }
|
33
|
+
scope :latest_updated, :order_by => :updated_at.desc, :limit => Locomotive.config.ui[:latest_entries_nb]
|
34
|
+
|
35
|
+
## methods ##
|
36
|
+
|
37
|
+
alias :visible? :_visible?
|
38
|
+
alias :_permalink :_slug
|
39
|
+
alias :_permalink= :_slug=
|
40
|
+
|
41
|
+
# Any content entry owns a label property which is used in the back-office UI
|
42
|
+
# to represent it. The field used as the label is defined within the parent content type.
|
43
|
+
#
|
44
|
+
# @param [ Object ] (optional) The content type to avoid to run another MongoDB and useless query.
|
45
|
+
#
|
46
|
+
# @return [ String ] The "label" of the content entry
|
47
|
+
#
|
48
|
+
def _label(type = nil)
|
49
|
+
value = if self._label_field_name
|
50
|
+
self.send(self._label_field_name.to_sym)
|
51
|
+
else
|
52
|
+
self.send((type || self.content_type).label_field_name.to_sym)
|
53
|
+
end
|
54
|
+
|
55
|
+
value.respond_to?(:to_label) ? value.to_label : value.to_s
|
56
|
+
end
|
57
|
+
|
58
|
+
alias :to_label :_label
|
59
|
+
|
60
|
+
# Tell if the content entry has been translated or not.
|
61
|
+
# It just checks if the field used for the label has been translated.
|
62
|
+
#
|
63
|
+
# @return [ Boolean ] True if translated, false otherwise
|
64
|
+
#
|
65
|
+
def translated?
|
66
|
+
if self.respond_to?(:"#{self._label_field_name}_translations")
|
67
|
+
self.send(:"#{self._label_field_name}_translations").key?(::Mongoid::Fields::I18n.locale.to_s) #rescue false
|
68
|
+
else
|
69
|
+
true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Return the locales the content entry has been translated to.
|
74
|
+
#
|
75
|
+
# @return [ Array ] The list of locales. Nil if not localized
|
76
|
+
#
|
77
|
+
def translated_in
|
78
|
+
if self.respond_to?(:"#{self._label_field_name}_translations")
|
79
|
+
self.send(:"#{self._label_field_name}_translations").keys
|
80
|
+
else
|
81
|
+
nil
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Return the next content entry based on the order defined in the parent content type.
|
86
|
+
#
|
87
|
+
# @param [ Object ] The next content entry or nil if not found
|
88
|
+
#
|
89
|
+
def next
|
90
|
+
next_or_previous :gt
|
91
|
+
end
|
92
|
+
|
93
|
+
# Return the previous content entry based on the order defined in the parent content type.
|
94
|
+
#
|
95
|
+
# @param [ Object ] The previous content entry or nil if not found
|
96
|
+
#
|
97
|
+
def previous
|
98
|
+
next_or_previous :lt
|
99
|
+
end
|
100
|
+
|
101
|
+
# Find a content entry by its permalink
|
102
|
+
#
|
103
|
+
# @param [ String ] The permalink
|
104
|
+
#
|
105
|
+
# @return [ Object ] The content entry matching the permalink or nil if not found
|
106
|
+
#
|
107
|
+
def self.find_by_permalink(permalink)
|
108
|
+
self.where(:_slug => permalink).first
|
109
|
+
end
|
110
|
+
|
111
|
+
# Sort the content entries from an ordered array of content entry ids.
|
112
|
+
# Their new positions are persisted.
|
113
|
+
#
|
114
|
+
# @param [ Array ] The ordered array of ids
|
115
|
+
#
|
116
|
+
def self.sort_entries!(ids)
|
117
|
+
list = self.any_in(:_id => ids.map { |id| BSON::ObjectId.from_string(id.to_s) }).to_a
|
118
|
+
ids.each_with_index do |id, position|
|
119
|
+
if entry = list.detect { |e| e._id.to_s == id.to_s }
|
120
|
+
entry.update_attributes :_position => position
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
protected
|
126
|
+
|
127
|
+
# Retrieve the next or the previous entry following the order
|
128
|
+
# defined in the parent content type.
|
129
|
+
#
|
130
|
+
# @param [ Symbol ] :gt for the next element, :lt for the previous element
|
131
|
+
#
|
132
|
+
# @return [ Object ] The next or previous content entry or nil if none
|
133
|
+
#
|
134
|
+
def next_or_previous(matcher = :gt)
|
135
|
+
order_by = self.content_type.order_by_definition(matcher == :lt)
|
136
|
+
criterion = self.content_type.order_by_attribute.to_sym.send(matcher)
|
137
|
+
value = self.send(self.content_type.order_by_attribute.to_sym)
|
138
|
+
|
139
|
+
self.class.where(criterion => value).order_by([order_by]).limit(1).first
|
140
|
+
end
|
141
|
+
|
142
|
+
# Sets the slug of the instance by using the value of the highlighted field
|
143
|
+
# (if available). If a sibling content instance has the same permalink then a
|
144
|
+
# unique one will be generated
|
145
|
+
def set_slug
|
146
|
+
self._slug = self._label.dup if self._slug.blank? && self._label.present?
|
147
|
+
|
148
|
+
if self._slug.present?
|
149
|
+
self._slug.permalink!
|
150
|
+
self._slug = self.next_unique_slug if self.slug_already_taken?
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Return the next available unique slug as a string
|
155
|
+
def next_unique_slug
|
156
|
+
slug = self._slug.gsub(/-\d*$/, '')
|
157
|
+
last_slug = self.class.where(:_id.ne => self._id, :_slug => /^#{slug}-?\d*?$/i).order_by(:_slug).last._slug
|
158
|
+
next_number = last_slug.scan(/-(\d)$/).flatten.first.to_i + 1
|
159
|
+
[slug, next_number].join('-')
|
160
|
+
end
|
161
|
+
|
162
|
+
def slug_already_taken?
|
163
|
+
self.class.where(:_id.ne => self._id, :_slug => self._slug).any?
|
164
|
+
end
|
165
|
+
|
166
|
+
def set_site
|
167
|
+
self.site ||= self.content_type.site
|
168
|
+
end
|
169
|
+
|
170
|
+
def set_visibility
|
171
|
+
if self.respond_to?(:visible)
|
172
|
+
self.visible = true if self.visible.nil?
|
173
|
+
self._visible = self.visible
|
174
|
+
return
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def set_label_field_name
|
179
|
+
self._label_field_name = self.content_type.label_field_name
|
180
|
+
end
|
181
|
+
|
182
|
+
def add_to_list_bottom
|
183
|
+
self._position = self.class.max(:_position).to_i + 1
|
184
|
+
end
|
185
|
+
|
186
|
+
def send_notifications
|
187
|
+
return if !self.content_type.public_submission_enabled? || self.content_type.public_submission_accounts.blank?
|
188
|
+
|
189
|
+
self.site.accounts.each do |account|
|
190
|
+
next unless self.content_type.public_submission_accounts.map(&:to_s).include?(account._id.to_s)
|
191
|
+
|
192
|
+
Locomotive::Notifications.new_content_entry(account, self).deliver
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
end
|
@@ -0,0 +1,224 @@
|
|
1
|
+
module Locomotive
|
2
|
+
class ContentType
|
3
|
+
|
4
|
+
include Locomotive::Mongoid::Document
|
5
|
+
|
6
|
+
## extensions ##
|
7
|
+
include CustomFields::Source
|
8
|
+
include Extensions::ContentType::DefaultValues
|
9
|
+
include Extensions::ContentType::ItemTemplate
|
10
|
+
include Extensions::ContentType::Sync
|
11
|
+
|
12
|
+
## fields ##
|
13
|
+
field :name
|
14
|
+
field :description
|
15
|
+
field :slug
|
16
|
+
field :label_field_id, :type => BSON::ObjectId
|
17
|
+
field :label_field_name
|
18
|
+
field :group_by_field_id, :type => BSON::ObjectId
|
19
|
+
field :order_by
|
20
|
+
field :order_direction, :default => 'asc'
|
21
|
+
field :public_submission_enabled, :type => Boolean, :default => false
|
22
|
+
field :public_submission_accounts, :type => Array
|
23
|
+
|
24
|
+
## associations ##
|
25
|
+
belongs_to :site, :class_name => 'Locomotive::Site'
|
26
|
+
has_many :entries, :class_name => 'Locomotive::ContentEntry', :dependent => :destroy
|
27
|
+
|
28
|
+
## named scopes ##
|
29
|
+
scope :ordered, :order_by => :updated_at.desc
|
30
|
+
|
31
|
+
## indexes ##
|
32
|
+
index [[:site_id, Mongo::ASCENDING], [:slug, Mongo::ASCENDING]]
|
33
|
+
|
34
|
+
## callbacks ##
|
35
|
+
before_validation :normalize_slug
|
36
|
+
before_validation :sanitize_public_submission_accounts
|
37
|
+
after_validation :bubble_fields_errors_up
|
38
|
+
before_update :update_label_field_name_in_entries
|
39
|
+
|
40
|
+
## validations ##
|
41
|
+
validates_presence_of :site, :name, :slug
|
42
|
+
validates_uniqueness_of :slug, :scope => :site_id
|
43
|
+
validates_size_of :entries_custom_fields, :minimum => 1, :message => :too_few_custom_fields
|
44
|
+
|
45
|
+
## behaviours ##
|
46
|
+
custom_fields_for :entries
|
47
|
+
|
48
|
+
## methods ##
|
49
|
+
|
50
|
+
def order_manually?
|
51
|
+
self.order_by == '_position'
|
52
|
+
end
|
53
|
+
|
54
|
+
def order_by_definition(reverse_order = false)
|
55
|
+
direction = self.order_manually? ? 'asc' : self.order_direction || 'asc'
|
56
|
+
|
57
|
+
if reverse_order
|
58
|
+
direction = (direction == 'asc' ? 'desc' : 'asc')
|
59
|
+
end
|
60
|
+
|
61
|
+
[order_by_attribute, direction]
|
62
|
+
end
|
63
|
+
|
64
|
+
def ordered_entries(conditions = {})
|
65
|
+
_order_by_definition = (conditions || {}).delete(:order_by).try(:split) || self.order_by_definition
|
66
|
+
self.entries.order_by([_order_by_definition]).where(conditions)
|
67
|
+
end
|
68
|
+
|
69
|
+
def groupable?
|
70
|
+
!!self.group_by_field && %w(select belongs_to).include?(group_by_field.type)
|
71
|
+
end
|
72
|
+
|
73
|
+
def group_by_field
|
74
|
+
self.find_entries_custom_field(self.group_by_field_id)
|
75
|
+
end
|
76
|
+
|
77
|
+
def list_or_group_entries
|
78
|
+
if self.groupable?
|
79
|
+
if group_by_field.type == 'select'
|
80
|
+
self.entries.group_by_select_option(self.group_by_field.name, self.order_by_definition)
|
81
|
+
else
|
82
|
+
group_by_belongs_to_field(self.group_by_field)
|
83
|
+
end
|
84
|
+
else
|
85
|
+
self.ordered_entries
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def class_name_to_content_type(class_name)
|
90
|
+
self.class.class_name_to_content_type(class_name, self.site)
|
91
|
+
end
|
92
|
+
|
93
|
+
def label_field_id=(value)
|
94
|
+
# update the label_field_name if the label_field_id is changed
|
95
|
+
new_label_field_name = self.entries_custom_fields.where(:_id => value).first.try(:name)
|
96
|
+
self.label_field_name = new_label_field_name
|
97
|
+
super(value)
|
98
|
+
end
|
99
|
+
|
100
|
+
def label_field_name=(value)
|
101
|
+
# mandatory if we allow the API to set the label field name without an id of the field
|
102
|
+
@new_label_field_name = value unless value.blank?
|
103
|
+
super(value)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Get the class name of the entries.
|
107
|
+
#
|
108
|
+
# @return [ String ] The class name of all the entries
|
109
|
+
#
|
110
|
+
def entries_class_name
|
111
|
+
self.klass_with_custom_fields(:entries).to_s
|
112
|
+
end
|
113
|
+
|
114
|
+
# Find a custom field describing an entry based on its id
|
115
|
+
# in first or its name if not found.
|
116
|
+
#
|
117
|
+
# @param [ String ] id_or_name The id of name of the field
|
118
|
+
#
|
119
|
+
# @return [ Object ] The custom field or nit if not found
|
120
|
+
#
|
121
|
+
def find_entries_custom_field(id_or_name)
|
122
|
+
return nil if id_or_name.nil? # bypass the memoization
|
123
|
+
|
124
|
+
_field = self.entries_custom_fields.find(id_or_name) rescue nil
|
125
|
+
_field || self.entries_custom_fields.where(:name => id_or_name).first
|
126
|
+
end
|
127
|
+
|
128
|
+
# Retrieve from a class name the associated content type within the scope of a site.
|
129
|
+
# If no content type is found, the method returns nil
|
130
|
+
#
|
131
|
+
# @param [ String ] class_name The class name
|
132
|
+
# @param [ Locomotive::Site ] site The Locomotive site
|
133
|
+
#
|
134
|
+
# @return [ Locomotive::ContentType ] The content type matching the class_name
|
135
|
+
#
|
136
|
+
def self.class_name_to_content_type(class_name, site)
|
137
|
+
if class_name =~ /^Locomotive::Entry(.*)/
|
138
|
+
site.content_types.find($1)
|
139
|
+
else
|
140
|
+
nil
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
protected
|
145
|
+
|
146
|
+
def group_by_belongs_to_field(field)
|
147
|
+
grouped_entries = self.ordered_entries.group_by(&:"#{field.name}_id")
|
148
|
+
columns = grouped_entries.keys
|
149
|
+
target_content_type = self.class_name_to_content_type(field.class_name)
|
150
|
+
all_columns = target_content_type.ordered_entries
|
151
|
+
|
152
|
+
all_columns.map do |column|
|
153
|
+
if columns.include?(column._id)
|
154
|
+
{
|
155
|
+
:name => column._label(target_content_type),
|
156
|
+
:entries => grouped_entries.delete(column._id)
|
157
|
+
}
|
158
|
+
else
|
159
|
+
nil
|
160
|
+
end
|
161
|
+
end.compact.tap do |groups|
|
162
|
+
unless grouped_entries.empty? # "orphans" ?
|
163
|
+
groups << { :name => nil, :entries => grouped_entries.values.flatten }
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def order_by_attribute
|
169
|
+
return self.order_by if %w(created_at updated_at _position).include?(self.order_by)
|
170
|
+
self.entries_custom_fields.find(self.order_by).name rescue 'created_at'
|
171
|
+
end
|
172
|
+
|
173
|
+
def normalize_slug
|
174
|
+
self.slug = self.name.clone if self.slug.blank? && self.name.present?
|
175
|
+
self.slug.permalink! if self.slug.present?
|
176
|
+
end
|
177
|
+
|
178
|
+
# We do not want to have a blank value in the list of accounts.
|
179
|
+
def sanitize_public_submission_accounts
|
180
|
+
if self.public_submission_accounts
|
181
|
+
self.public_submission_accounts.reject! { |id| id.blank? }
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
def bubble_fields_errors_up
|
186
|
+
return if self.errors[:entries_custom_fields].empty?
|
187
|
+
|
188
|
+
hash = { :base => self.errors[:entries_custom_fields] }
|
189
|
+
|
190
|
+
self.entries_custom_fields.each do |field|
|
191
|
+
next if field.valid?
|
192
|
+
key = field.persisted? ? field._id.to_s : field.position.to_i
|
193
|
+
hash[key] = field.errors.to_a
|
194
|
+
end
|
195
|
+
|
196
|
+
self.errors.set(:entries_custom_fields, hash)
|
197
|
+
end
|
198
|
+
|
199
|
+
def update_label_field_name_in_entries
|
200
|
+
self.klass_with_custom_fields(:entries).update_all :_label_field_name => self.label_field_name
|
201
|
+
end
|
202
|
+
|
203
|
+
# Makes sure the class_name filled in a belongs_to or has_many field
|
204
|
+
# does not belong to another site. Adds an error if it presents a
|
205
|
+
# security problem.
|
206
|
+
#
|
207
|
+
# @param [ CustomFields::Field ] field The field to check
|
208
|
+
#
|
209
|
+
def ensure_class_name_security(field)
|
210
|
+
if field.class_name =~ /^Locomotive::Entry([a-z0-9]+)$/
|
211
|
+
content_type = Locomotive::ContentType.find($1)
|
212
|
+
|
213
|
+
if content_type.site_id != self.site_id
|
214
|
+
field.errors.add :class_name, :security
|
215
|
+
end
|
216
|
+
else
|
217
|
+
# for now, does not allow external classes
|
218
|
+
field.errors.add :class_name, :security
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|