alchemy_cms 2.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/.yardopts +6 -0
- data/Gemfile +8 -0
- data/LICENSE +619 -0
- data/README.md +113 -0
- data/Rakefile +30 -0
- data/TODO.txt +1 -0
- data/alchemy.gemspec +36 -0
- data/app/controllers/admin/attachments_controller.rb +119 -0
- data/app/controllers/admin/clipboard_controller.rb +43 -0
- data/app/controllers/admin/contents_controller.rb +69 -0
- data/app/controllers/admin/elements_controller.rb +137 -0
- data/app/controllers/admin/essence_audios_controller.rb +14 -0
- data/app/controllers/admin/essence_files_controller.rb +35 -0
- data/app/controllers/admin/essence_flashes_controller.rb +14 -0
- data/app/controllers/admin/essence_pictures_controller.rb +89 -0
- data/app/controllers/admin/essence_videos_controller.rb +14 -0
- data/app/controllers/admin/languages_controller.rb +70 -0
- data/app/controllers/admin/layoutpages_controller.rb +11 -0
- data/app/controllers/admin/pages_controller.rb +244 -0
- data/app/controllers/admin/pictures_controller.rb +132 -0
- data/app/controllers/admin/trash_controller.rb +25 -0
- data/app/controllers/admin/users_controller.rb +75 -0
- data/app/controllers/admin_controller.rb +78 -0
- data/app/controllers/alchemy_controller.rb +239 -0
- data/app/controllers/attachments_controller.rb +30 -0
- data/app/controllers/elements_controller.rb +18 -0
- data/app/controllers/messages_controller.rb +98 -0
- data/app/controllers/pages_controller.rb +137 -0
- data/app/controllers/pictures_controller.rb +68 -0
- data/app/helpers/admin/attachments_helper.rb +7 -0
- data/app/helpers/admin/elements_helper.rb +28 -0
- data/app/helpers/admin/pages_helper.rb +3 -0
- data/app/helpers/admin/pictures_helper.rb +26 -0
- data/app/helpers/alchemy_helper.rb +1168 -0
- data/app/helpers/elements_helper.rb +2 -0
- data/app/helpers/errors_helper.rb +37 -0
- data/app/helpers/layout_helper.rb +37 -0
- data/app/helpers/pages_helper.rb +141 -0
- data/app/mailers/messages.rb +15 -0
- data/app/mailers/notifications.rb +23 -0
- data/app/models/attachment.rb +73 -0
- data/app/models/cell.rb +63 -0
- data/app/models/content.rb +145 -0
- data/app/models/element.rb +423 -0
- data/app/models/essence_audio.rb +17 -0
- data/app/models/essence_date.rb +20 -0
- data/app/models/essence_file.rb +17 -0
- data/app/models/essence_flash.rb +15 -0
- data/app/models/essence_html.rb +19 -0
- data/app/models/essence_picture.rb +27 -0
- data/app/models/essence_richtext.rb +50 -0
- data/app/models/essence_text.rb +28 -0
- data/app/models/essence_video.rb +17 -0
- data/app/models/folded_page.rb +3 -0
- data/app/models/language.rb +75 -0
- data/app/models/message.rb +57 -0
- data/app/models/page.rb +501 -0
- data/app/models/picture.rb +100 -0
- data/app/models/user.rb +72 -0
- data/app/models/user_session.rb +10 -0
- data/app/sweepers/content_sweeper.rb +20 -0
- data/app/sweepers/pages_sweeper.rb +46 -0
- data/app/sweepers/pictures_sweeper.rb +20 -0
- data/app/views/_contact.html.erb +3 -0
- data/app/views/_intro.html.erb +3 -0
- data/app/views/_news.html.erb +3 -0
- data/app/views/_newsletter_layout.html.erb +1 -0
- data/app/views/_search.html.erb +3 -0
- data/app/views/_standard.html.erb +1 -0
- data/app/views/admin/attachments/_attachment.html.erb +58 -0
- data/app/views/admin/attachments/_file_to_assign.html.erb +20 -0
- data/app/views/admin/attachments/_files_list.html.erb +24 -0
- data/app/views/admin/attachments/archive_overlay.html.erb +8 -0
- data/app/views/admin/attachments/create.js.erb +6 -0
- data/app/views/admin/attachments/edit.html.erb +12 -0
- data/app/views/admin/attachments/index.html.erb +30 -0
- data/app/views/admin/attachments/new.html.erb +11 -0
- data/app/views/admin/clipboard/clear.js.erb +6 -0
- data/app/views/admin/clipboard/index.html.erb +19 -0
- data/app/views/admin/clipboard/insert.js.erb +14 -0
- data/app/views/admin/clipboard/remove.js.erb +10 -0
- data/app/views/admin/contents/_missing.html.erb +20 -0
- data/app/views/admin/contents/create.js.erb +93 -0
- data/app/views/admin/contents/new.html.erb +15 -0
- data/app/views/admin/elements/_add_content.html.erb +16 -0
- data/app/views/admin/elements/_element.html.erb +22 -0
- data/app/views/admin/elements/_element_foot.html.erb +35 -0
- data/app/views/admin/elements/_element_head.html.erb +29 -0
- data/app/views/admin/elements/_elements_select.html.erb +8 -0
- data/app/views/admin/elements/_new_element_form.html.erb +25 -0
- data/app/views/admin/elements/_picture_editor.html.erb +25 -0
- data/app/views/admin/elements/create.js.erb +20 -0
- data/app/views/admin/elements/destroy.js.erb +6 -0
- data/app/views/admin/elements/fold.js.erb +37 -0
- data/app/views/admin/elements/index.html.erb +33 -0
- data/app/views/admin/elements/list.js.erb +20 -0
- data/app/views/admin/elements/new.html.erb +33 -0
- data/app/views/admin/elements/order.js.erb +7 -0
- data/app/views/admin/elements/trash.js.erb +13 -0
- data/app/views/admin/elements/update.js.erb +10 -0
- data/app/views/admin/essence_files/edit.html.erb +91 -0
- data/app/views/admin/essence_pictures/assign.js.erb +15 -0
- data/app/views/admin/essence_pictures/crop.html.erb +36 -0
- data/app/views/admin/essence_pictures/destroy.js.erb +17 -0
- data/app/views/admin/essence_pictures/edit.html.erb +75 -0
- data/app/views/admin/essence_pictures/update.js.erb +16 -0
- data/app/views/admin/index.html.erb +92 -0
- data/app/views/admin/infos.html.erb +5 -0
- data/app/views/admin/languages/_form.html.erb +34 -0
- data/app/views/admin/languages/_language.html.erb +35 -0
- data/app/views/admin/languages/edit.html.erb +1 -0
- data/app/views/admin/languages/index.html.erb +41 -0
- data/app/views/admin/languages/new.html.erb +1 -0
- data/app/views/admin/layoutpages/_layoutpage.html.erb +80 -0
- data/app/views/admin/layoutpages/index.html.erb +75 -0
- data/app/views/admin/leave.html.erb +11 -0
- data/app/views/admin/login.html.erb +46 -0
- data/app/views/admin/logout.html.erb +5 -0
- data/app/views/admin/pages/_contactform_links.html.erb +66 -0
- data/app/views/admin/pages/_create_language_form.html.erb +42 -0
- data/app/views/admin/pages/_external_link.html.erb +54 -0
- data/app/views/admin/pages/_file_link.html.erb +52 -0
- data/app/views/admin/pages/_internal_link.html.erb +47 -0
- data/app/views/admin/pages/_new_page_form.html.erb +29 -0
- data/app/views/admin/pages/_page.html.erb +114 -0
- data/app/views/admin/pages/_page_for_links.html.erb +43 -0
- data/app/views/admin/pages/_page_infos.html.erb +3 -0
- data/app/views/admin/pages/_page_status.html.erb +9 -0
- data/app/views/admin/pages/_sitemap.html.erb +99 -0
- data/app/views/admin/pages/configure.html.erb +71 -0
- data/app/views/admin/pages/configure_external.html.erb +40 -0
- data/app/views/admin/pages/destroy.js.erb +12 -0
- data/app/views/admin/pages/edit.html.erb +185 -0
- data/app/views/admin/pages/flush.js.erb +2 -0
- data/app/views/admin/pages/fold.js.erb +4 -0
- data/app/views/admin/pages/index.html.erb +108 -0
- data/app/views/admin/pages/link.html.erb +30 -0
- data/app/views/admin/pages/locked.html.erb +3 -0
- data/app/views/admin/pages/new.html.erb +50 -0
- data/app/views/admin/pages/show.html.erb +1 -0
- data/app/views/admin/pages/sort.js.erb +6 -0
- data/app/views/admin/pages/unlock.js.erb +8 -0
- data/app/views/admin/pages/update.js.erb +19 -0
- data/app/views/admin/partials/_flash.html.erb +4 -0
- data/app/views/admin/partials/_flash_notices.html.erb +5 -0
- data/app/views/admin/partials/_mainnavigation_entry.html.erb +27 -0
- data/app/views/admin/partials/_pagination_links.html.erb +7 -0
- data/app/views/admin/partials/_per_page_links.html.erb +17 -0
- data/app/views/admin/partials/_remote_pagination_links.html.erb +11 -0
- data/app/views/admin/partials/_remote_search_form.html.erb +36 -0
- data/app/views/admin/partials/_search_form.html.erb +17 -0
- data/app/views/admin/partials/_sub_navigation.html.erb +14 -0
- data/app/views/admin/partials/_upload_form.html.erb +116 -0
- data/app/views/admin/pictures/_archive_overlay_images.html.erb +17 -0
- data/app/views/admin/pictures/_filter_and_size_bar.html.erb +88 -0
- data/app/views/admin/pictures/_picture.html.erb +36 -0
- data/app/views/admin/pictures/_picture_to_assign.html.erb +32 -0
- data/app/views/admin/pictures/_pictures_list.html.erb +12 -0
- data/app/views/admin/pictures/archive_overlay.html.erb +3 -0
- data/app/views/admin/pictures/create.js.erb +12 -0
- data/app/views/admin/pictures/index.html.erb +56 -0
- data/app/views/admin/pictures/new.html.erb +11 -0
- data/app/views/admin/pictures/show_in_window.html.erb +1 -0
- data/app/views/admin/pictures/update.js.erb +11 -0
- data/app/views/admin/signup.html.erb +16 -0
- data/app/views/admin/trash/index.html.erb +25 -0
- data/app/views/admin/users/_table.html.erb +54 -0
- data/app/views/admin/users/_user.html.erb +36 -0
- data/app/views/admin/users/edit.html.erb +6 -0
- data/app/views/admin/users/index.html.erb +41 -0
- data/app/views/admin/users/new.html.erb +6 -0
- data/app/views/attachments/show.html.erb +1 -0
- data/app/views/elements/_article_editor.html.erb +4 -0
- data/app/views/elements/_article_view.html.erb +25 -0
- data/app/views/elements/_bild_editor.html.erb +1 -0
- data/app/views/elements/_bild_text_editor.html.erb +2 -0
- data/app/views/elements/_bild_text_view.html.erb +9 -0
- data/app/views/elements/_bild_view.html.erb +9 -0
- data/app/views/elements/_claim_editor.html.erb +1 -0
- data/app/views/elements/_claim_view.html.erb +1 -0
- data/app/views/elements/_contactform_editor.html.erb +7 -0
- data/app/views/elements/_contactform_view.html.erb +92 -0
- data/app/views/elements/_editor_not_found.html.erb +5 -0
- data/app/views/elements/_footnote_editor.html.erb +1 -0
- data/app/views/elements/_footnote_view.html.erb +5 -0
- data/app/views/elements/_header_editor.html.erb +1 -0
- data/app/views/elements/_header_view.html.erb +1 -0
- data/app/views/elements/_headline_editor.html.erb +1 -0
- data/app/views/elements/_headline_view.html.erb +1 -0
- data/app/views/elements/_image_mosaic_editor.html.erb +2 -0
- data/app/views/elements/_image_mosaic_view.html.erb +12 -0
- data/app/views/elements/_intro_editor.html.erb +1 -0
- data/app/views/elements/_intro_image_text_editor.html.erb +3 -0
- data/app/views/elements/_intro_image_text_view.html.erb +16 -0
- data/app/views/elements/_intro_view.html.erb +3 -0
- data/app/views/elements/_news_editor.html.erb +3 -0
- data/app/views/elements/_news_view.html.erb +11 -0
- data/app/views/elements/_searchresult_editor.html.erb +1 -0
- data/app/views/elements/_searchresult_view.html.erb +42 -0
- data/app/views/elements/_sitemap_editor.html.erb +3 -0
- data/app/views/elements/_sitemap_view.html.erb +38 -0
- data/app/views/elements/_sitename_editor.html.erb +1 -0
- data/app/views/elements/_sitename_view.html.erb +1 -0
- data/app/views/elements/_subheadline_editor.html.erb +1 -0
- data/app/views/elements/_subheadline_view.html.erb +5 -0
- data/app/views/elements/_text_editor.html.erb +1 -0
- data/app/views/elements/_text_view.html.erb +3 -0
- data/app/views/elements/_view_not_found.html.erb +1 -0
- data/app/views/elements/show.html.erb +6 -0
- data/app/views/elements/show.js.erb +11 -0
- data/app/views/essences/_essence_audio_editor.html.erb +1 -0
- data/app/views/essences/_essence_audio_view.html.erb +33 -0
- data/app/views/essences/_essence_date_editor.html.erb +12 -0
- data/app/views/essences/_essence_date_view.html.erb +7 -0
- data/app/views/essences/_essence_file_editor.html.erb +63 -0
- data/app/views/essences/_essence_file_view.html.erb +6 -0
- data/app/views/essences/_essence_flash_editor.html.erb +1 -0
- data/app/views/essences/_essence_flash_view.html.erb +26 -0
- data/app/views/essences/_essence_html_editor.html.erb +8 -0
- data/app/views/essences/_essence_html_view.html.erb +1 -0
- data/app/views/essences/_essence_picture_editor.html.erb +70 -0
- data/app/views/essences/_essence_picture_tools.html.erb +60 -0
- data/app/views/essences/_essence_picture_view.html.erb +42 -0
- data/app/views/essences/_essence_richtext_editor.html.erb +9 -0
- data/app/views/essences/_essence_richtext_view.html.erb +5 -0
- data/app/views/essences/_essence_text_editor.html.erb +82 -0
- data/app/views/essences/_essence_text_view.html.erb +11 -0
- data/app/views/essences/_essence_video_editor.html.erb +1 -0
- data/app/views/essences/_essence_video_view.html.erb +35 -0
- data/app/views/layouts/alchemy.html.erb +60 -0
- data/app/views/layouts/login.html.erb +60 -0
- data/app/views/layouts/pages.html.erb +31 -0
- data/app/views/layouts/sitemap.xml.erb +4 -0
- data/app/views/messages/mail.text.erb +10 -0
- data/app/views/messages/new.html.erb +1 -0
- data/app/views/notifications/admin_user_created.text.erb +13 -0
- data/app/views/notifications/registered_user_created.text.erb +10 -0
- data/app/views/page_layouts/_contact.html.erb +14 -0
- data/app/views/page_layouts/_external.html.erb +1 -0
- data/app/views/page_layouts/_intro.html.erb +14 -0
- data/app/views/page_layouts/_layout_footer.html.erb +14 -0
- data/app/views/page_layouts/_layout_header.html.erb +14 -0
- data/app/views/page_layouts/_news.html.erb +14 -0
- data/app/views/page_layouts/_newsletter_layout.html.erb +1 -0
- data/app/views/page_layouts/_search.html.erb +14 -0
- data/app/views/page_layouts/_standard.html.erb +14 -0
- data/app/views/pages/show.html.erb +1 -0
- data/app/views/pages/show.rss.builder +27 -0
- data/app/views/pages/sitemap.xml.erb +8 -0
- data/app/views/partials/_navigation_image_link.html.erb +14 -0
- data/app/views/partials/_navigation_link.html.erb +20 -0
- data/app/views/partials/_navigation_renderer.html.erb +23 -0
- data/app/views/pictures/show.gif.flexi +19 -0
- data/app/views/pictures/show.jpg.flexi +19 -0
- data/app/views/pictures/show.png.flexi +19 -0
- data/app/views/pictures/thumbnail.png.flexi +13 -0
- data/app/views/pictures/zoom.png.flexi +3 -0
- data/assets/images/ajax_loader.gif +0 -0
- data/assets/images/alchemy-logo.png +0 -0
- data/assets/images/flags.png +0 -0
- data/assets/images/gui/navi-tab.png +0 -0
- data/assets/images/gui/shading.png +0 -0
- data/assets/images/gui/shading_90.png +0 -0
- data/assets/images/gui/toggle.png +0 -0
- data/assets/images/icons.png +0 -0
- data/assets/images/jquery-sb/select_arrow.gif +0 -0
- data/assets/images/jquery-sb/select_arrow_bg.gif +0 -0
- data/assets/images/jquery-sb/select_arrow_bg_hover.gif +0 -0
- data/assets/images/jquery-ui/ui-icons_666666_256x240.png +0 -0
- data/assets/images/placeholder.png +0 -0
- data/assets/images/swfupload/browse_button.png +0 -0
- data/assets/javascripts/alchemy.element_editor_selector.js +88 -0
- data/assets/javascripts/alchemy.growler.js +44 -0
- data/assets/javascripts/alchemy.image_cropper.js +56 -0
- data/assets/javascripts/alchemy.js +892 -0
- data/assets/javascripts/alchemy.link_overlay.js +221 -0
- data/assets/javascripts/alchemy.page_sorter.js +42 -0
- data/assets/javascripts/alchemy.preview.js +145 -0
- data/assets/javascripts/jquery-ui.js +428 -0
- data/assets/javascripts/jquery.Jcrop.min.js +246 -0
- data/assets/javascripts/jquery.dialogextend.min.js +8 -0
- data/assets/javascripts/jquery.in-place-edit.js +171 -0
- data/assets/javascripts/jquery.js +18 -0
- data/assets/javascripts/jquery.rails.js +315 -0
- data/assets/javascripts/jquery.sb.min.js +14 -0
- data/assets/javascripts/jquery.scrollTo-1.4.2-min.js +11 -0
- data/assets/javascripts/jquery.ui.nestedSortable.js +291 -0
- data/assets/javascripts/jquery.ui.tabspaging.js +281 -0
- data/assets/javascripts/swfupload/fileprogress.js +203 -0
- data/assets/javascripts/swfupload/handlers.js +171 -0
- data/assets/javascripts/swfupload/queue.js +98 -0
- data/assets/javascripts/swfupload/swfupload.js +980 -0
- data/assets/javascripts/swfupload/swfupload.swf +0 -0
- data/assets/javascripts/tiny_mce/jquery.tinymce.js +1 -0
- data/assets/javascripts/tiny_mce/langs/de.js +1 -0
- data/assets/javascripts/tiny_mce/langs/en.js +223 -0
- data/assets/javascripts/tiny_mce/license.txt +504 -0
- data/assets/javascripts/tiny_mce/plugins/alchemy_link/editor_plugin.js +43 -0
- data/assets/javascripts/tiny_mce/plugins/alchemy_link/langs/de.js +4 -0
- data/assets/javascripts/tiny_mce/plugins/alchemy_link/langs/en.js +4 -0
- data/assets/javascripts/tiny_mce/plugins/fullscreen/editor_plugin.js +1 -0
- data/assets/javascripts/tiny_mce/plugins/fullscreen/fullscreen.htm +109 -0
- data/assets/javascripts/tiny_mce/plugins/inlinepopups/editor_plugin.js +1 -0
- data/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/alchemy/window.css +402 -0
- data/assets/javascripts/tiny_mce/plugins/inlinepopups/template.htm +387 -0
- data/assets/javascripts/tiny_mce/plugins/lists/editor_plugin.js +1 -0
- data/assets/javascripts/tiny_mce/plugins/paste/editor_plugin.js +1 -0
- data/assets/javascripts/tiny_mce/plugins/paste/js/pastetext.js +36 -0
- data/assets/javascripts/tiny_mce/plugins/paste/js/pasteword.js +51 -0
- data/assets/javascripts/tiny_mce/plugins/paste/langs/de_dlg.js +1 -0
- data/assets/javascripts/tiny_mce/plugins/paste/langs/en_dlg.js +5 -0
- data/assets/javascripts/tiny_mce/plugins/paste/pastetext.htm +27 -0
- data/assets/javascripts/tiny_mce/plugins/paste/pasteword.htm +21 -0
- data/assets/javascripts/tiny_mce/plugins/table/cell.htm +180 -0
- data/assets/javascripts/tiny_mce/plugins/table/css/cell.css +17 -0
- data/assets/javascripts/tiny_mce/plugins/table/css/row.css +25 -0
- data/assets/javascripts/tiny_mce/plugins/table/css/table.css +13 -0
- data/assets/javascripts/tiny_mce/plugins/table/editor_plugin.js +1 -0
- data/assets/javascripts/tiny_mce/plugins/table/js/cell.js +319 -0
- data/assets/javascripts/tiny_mce/plugins/table/js/merge_cells.js +27 -0
- data/assets/javascripts/tiny_mce/plugins/table/js/row.js +237 -0
- data/assets/javascripts/tiny_mce/plugins/table/js/table.js +450 -0
- data/assets/javascripts/tiny_mce/plugins/table/langs/de_dlg.js +1 -0
- data/assets/javascripts/tiny_mce/plugins/table/langs/en_dlg.js +75 -0
- data/assets/javascripts/tiny_mce/plugins/table/merge_cells.htm +32 -0
- data/assets/javascripts/tiny_mce/plugins/table/row.htm +158 -0
- data/assets/javascripts/tiny_mce/plugins/table/table.htm +188 -0
- data/assets/javascripts/tiny_mce/themes/advanced/about.htm +52 -0
- data/assets/javascripts/tiny_mce/themes/advanced/anchor.htm +26 -0
- data/assets/javascripts/tiny_mce/themes/advanced/charmap.htm +51 -0
- data/assets/javascripts/tiny_mce/themes/advanced/color_picker.htm +74 -0
- data/assets/javascripts/tiny_mce/themes/advanced/editor_template.js +1 -0
- data/assets/javascripts/tiny_mce/themes/advanced/image.htm +80 -0
- data/assets/javascripts/tiny_mce/themes/advanced/img/colorpicker.jpg +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/img/flash.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/img/icons.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/img/iframe.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/img/pagebreak.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/img/quicktime.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/img/realmedia.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/img/shockwave.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/img/trans.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/img/video.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/img/windowsmedia.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/js/about.js +73 -0
- data/assets/javascripts/tiny_mce/themes/advanced/js/anchor.js +42 -0
- data/assets/javascripts/tiny_mce/themes/advanced/js/charmap.js +355 -0
- data/assets/javascripts/tiny_mce/themes/advanced/js/color_picker.js +329 -0
- data/assets/javascripts/tiny_mce/themes/advanced/js/image.js +247 -0
- data/assets/javascripts/tiny_mce/themes/advanced/js/link.js +153 -0
- data/assets/javascripts/tiny_mce/themes/advanced/js/source_editor.js +56 -0
- data/assets/javascripts/tiny_mce/themes/advanced/langs/de.js +1 -0
- data/assets/javascripts/tiny_mce/themes/advanced/langs/de_dlg.js +1 -0
- data/assets/javascripts/tiny_mce/themes/advanced/langs/en.js +68 -0
- data/assets/javascripts/tiny_mce/themes/advanced/langs/en_dlg.js +54 -0
- data/assets/javascripts/tiny_mce/themes/advanced/link.htm +57 -0
- data/assets/javascripts/tiny_mce/themes/advanced/shortcuts.htm +47 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/default/content.css +47 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/default/dialog.css +117 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/buttons.png +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/items.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/menu_arrow.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/menu_check.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/progress.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/tabs.gif +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/default/ui.css +214 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/highcontrast/content.css +23 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/highcontrast/dialog.css +105 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/highcontrast/ui.css +102 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/content.css +46 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/dialog.css +117 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/img/button_bg.png +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/img/button_bg_black.png +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/img/button_bg_silver.png +0 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui.css +217 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui_black.css +8 -0
- data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui_silver.css +5 -0
- data/assets/javascripts/tiny_mce/themes/advanced/source_editor.htm +25 -0
- data/assets/javascripts/tiny_mce/themes/simple/langs/de.js +1 -0
- data/assets/javascripts/tiny_mce/tiny_mce.js +1 -0
- data/assets/javascripts/tiny_mce/tiny_mce_popup.js +5 -0
- data/assets/javascripts/tiny_mce/utils/editable_selects.js +70 -0
- data/assets/javascripts/tiny_mce/utils/form_utils.js +210 -0
- data/assets/javascripts/tiny_mce/utils/mctabs.js +162 -0
- data/assets/javascripts/tiny_mce/utils/validate.js +252 -0
- data/assets/stylesheets/Jcrop.gif +0 -0
- data/assets/stylesheets/alchemy.css +3629 -0
- data/assets/stylesheets/alchemy_tinymce_content.css +94 -0
- data/assets/stylesheets/alchemy_tinymce_dialog.css +415 -0
- data/assets/stylesheets/default/img/tabs.gif +0 -0
- data/assets/stylesheets/elements.css +900 -0
- data/assets/stylesheets/flags.css +1 -0
- data/assets/stylesheets/ie6.css +18 -0
- data/assets/stylesheets/jquery-ui-1.8.7.alchemy.css +2023 -0
- data/assets/stylesheets/jquery.Jcrop.css +35 -0
- data/assets/stylesheets/jquery.sb.css +244 -0
- data/assets/stylesheets/standard_set.css +374 -0
- data/bin/alchemy +347 -0
- data/config/alchemy/config.yml +199 -0
- data/config/alchemy/elements.yml +219 -0
- data/config/alchemy/page_layouts.yml +65 -0
- data/config/asset_packages.yml +32 -0
- data/config/authorization_rules.rb +96 -0
- data/config/initializers/authorization.rb +4 -0
- data/config/initializers/cache_storage.rb +1 -0
- data/config/initializers/fast_gettext.rb +2 -0
- data/config/initializers/tiny_mce_hammer.rb +32 -0
- data/config/locales/de.yml +370 -0
- data/config/locales/en.yml +364 -0
- data/config/routes.rb +141 -0
- data/db/migrate/20100607143125_create_pages.rb +34 -0
- data/db/migrate/20100607144254_create_elements.rb +20 -0
- data/db/migrate/20100607145256_create_contents.rb +18 -0
- data/db/migrate/20100607145719_create_users.rb +32 -0
- data/db/migrate/20100607150611_create_pictures.rb +16 -0
- data/db/migrate/20100607150812_create_attachments.rb +16 -0
- data/db/migrate/20100607153647_create_folded_pages.rb +13 -0
- data/db/migrate/20100607161345_create_essence_texts.rb +19 -0
- data/db/migrate/20100607162339_create_elements_pages.rb +12 -0
- data/db/migrate/20100607193638_create_essence_pictures.rb +23 -0
- data/db/migrate/20100607193646_create_essence_richtexts.rb +16 -0
- data/db/migrate/20100607193653_create_essence_htmls.rb +13 -0
- data/db/migrate/20100609111653_create_essence_dates.rb +13 -0
- data/db/migrate/20100609111809_create_essence_files.rb +15 -0
- data/db/migrate/20100609111821_create_essence_flashes.rb +16 -0
- data/db/migrate/20100609111837_create_essence_videos.rb +18 -0
- data/db/migrate/20100616150753_create_essence_audios.rb +17 -0
- data/db/migrate/20100812085225_add_crop_from_and_crop_size_to_essence_pictures.rb +11 -0
- data/db/migrate/20100909140701_change_essence_htmls_source_column_type.rb +9 -0
- data/db/migrate/20101109150312_alter_pages_visible_column_default.rb +9 -0
- data/db/migrate/20101109151812_create_languages.rb +19 -0
- data/db/migrate/20101216151419_add_language_id_to_pages.rb +19 -0
- data/db/migrate/20101216155216_add_index_to_languages.rb +9 -0
- data/db/migrate/20101216173323_add_default_to_languages.rb +9 -0
- data/db/migrate/20101218130049_add_urlname_index_to_pages.rb +9 -0
- data/db/migrate/20110115123343_remove_css_class_default_from_essence_pictures.rb +11 -0
- data/db/migrate/20110224105120_change_pages_visible_default.rb +11 -0
- data/db/migrate/20110228182659_remove_default_page_layout_from_pages.rb +11 -0
- data/db/migrate/20110414163140_remove_display_name_from_elements.rb +11 -0
- data/db/migrate/20110511100516_rename_essence_texts_title_to_link_title.rb +9 -0
- data/db/migrate/20110529130429_create_cells.rb +14 -0
- data/db/migrate/20110529130500_add_cell_id_to_elements.rb +11 -0
- data/db/migrate/20110530102804_change_pages_page_layout_column.rb +11 -0
- data/db/migrate/20110707190728_add_render_size_to_essence_pictures.rb +9 -0
- data/db/migrate/20110711142057_change_open_link_in_new_window_to_link_target.rb +19 -0
- data/lib/alchemy.rb +24 -0
- data/lib/alchemy/config.rb +51 -0
- data/lib/alchemy/controller.rb +79 -0
- data/lib/alchemy/engine.rb +29 -0
- data/lib/alchemy/essence.rb +178 -0
- data/lib/alchemy/file_utilz.rb +73 -0
- data/lib/alchemy/page_layout.rb +66 -0
- data/lib/alchemy/remote_pagination_link_renderer.rb +17 -0
- data/lib/alchemy/seeder.rb +112 -0
- data/lib/alchemy/version.rb +5 -0
- data/lib/extensions/action_view.rb +17 -0
- data/lib/extensions/array.rb +25 -0
- data/lib/extensions/hash.rb +34 -0
- data/lib/middleware/flash_session_cookie.rb +22 -0
- data/lib/rails/generators/alchemy/elements/elements_generator.rb +35 -0
- data/lib/rails/generators/alchemy/elements/templates/editor.html.erb +9 -0
- data/lib/rails/generators/alchemy/elements/templates/view.html.erb +21 -0
- data/lib/rails/generators/alchemy/page_layouts/page_layouts_generator.rb +32 -0
- data/lib/rails/generators/alchemy/page_layouts/templates/layout.html.erb +1 -0
- data/lib/rails/generators/alchemy/plugin/plugin_generator.rb +29 -0
- data/lib/rails/generators/alchemy/plugin/templates/authorization_rules.rb +5 -0
- data/lib/rails/generators/alchemy/plugin/templates/config.yml +30 -0
- data/lib/rails/generators/alchemy/plugin/templates/init.rb +4 -0
- data/lib/rails/generators/alchemy/plugin/templates/routes.rb +4 -0
- data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +35 -0
- data/lib/rails/generators/alchemy/scaffold/templates/elements.yml +91 -0
- data/lib/rails/generators/alchemy/scaffold/templates/page_layouts.yml +29 -0
- data/lib/rails/templates/alchemy.rb +14 -0
- data/lib/tasks/fleximage.rake +154 -0
- data/lib/tasks/gettext.rake +75 -0
- data/lib/tasks/install.rake +123 -0
- data/lib/tasks/upgrade.rake +211 -0
- data/lib/translation_extras/alchemy_core_modules.rb +11 -0
- data/lib/vendor/i18n_label.rb +23 -0
- data/locale/alchemy.pot +1728 -0
- data/locale/de/LC_MESSAGES/alchemy.mo +0 -0
- data/locale/de/alchemy.po +1774 -0
- data/locale/en/LC_MESSAGES/alchemy.mo +0 -0
- data/locale/en/alchemy.po +1742 -0
- data/locale/missing_translations.rb +4 -0
- data/locale/model_attributes.rb +56 -0
- data/recipes/alchemy_capistrano_tasks.rb +83 -0
- metadata +769 -0
@@ -0,0 +1,30 @@
|
|
1
|
+
class AttachmentsController < AlchemyController
|
2
|
+
|
3
|
+
unloadable
|
4
|
+
|
5
|
+
# sends file inline. i.e. for viewing pdfs/movies in browser
|
6
|
+
def show
|
7
|
+
@attachment = Attachment.find(params[:id])
|
8
|
+
send_file(
|
9
|
+
@attachment.public_filename,
|
10
|
+
{
|
11
|
+
:name => @attachment.filename,
|
12
|
+
:type => @attachment.content_type,
|
13
|
+
:disposition => 'inline'
|
14
|
+
}
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
# sends file as attachment. aka download
|
19
|
+
def download
|
20
|
+
@attachment = Attachment.find(params[:id])
|
21
|
+
send_file(
|
22
|
+
@attachment.full_filename, {
|
23
|
+
:name => @attachment.filename,
|
24
|
+
:type => @attachment.content_type,
|
25
|
+
:disposition => 'attachment'
|
26
|
+
}
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class ElementsController < AlchemyController
|
2
|
+
|
3
|
+
unloadable
|
4
|
+
|
5
|
+
filter_access_to [:show], :attribute_check => true
|
6
|
+
layout false
|
7
|
+
|
8
|
+
# Returns the element partial as HTML or as JavaScript that tries to replace a given +container_id+ with the partial content via jQuery.
|
9
|
+
def show
|
10
|
+
@element = Element.find(params[:id])
|
11
|
+
@page = @element.page
|
12
|
+
respond_to do |format|
|
13
|
+
format.html
|
14
|
+
format.js
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# == Sending Messages:
|
2
|
+
# To send Messages via contact forms you can create your form fields in the config.yml
|
3
|
+
# === Example:
|
4
|
+
# Make an Element with this options inside your elements.yml file:
|
5
|
+
#
|
6
|
+
# - name: contact
|
7
|
+
# display_name: Kontaktformular
|
8
|
+
# contents:
|
9
|
+
# - name: mail_to
|
10
|
+
# type: EssenceText
|
11
|
+
# - name: subject
|
12
|
+
# type: EssenceText
|
13
|
+
# - name: mail_from
|
14
|
+
# type: EssenceText
|
15
|
+
# - name: success_page
|
16
|
+
# type: EssenceText
|
17
|
+
#
|
18
|
+
# The fields mail_to, mail_from, subject and success_page are recommended.
|
19
|
+
# The MessagesController uses them to send your mails. So your customer has full controll of these values inside his contactform element.
|
20
|
+
#
|
21
|
+
# Then make a page layout for your contact page in the page_layouts.yml file:
|
22
|
+
#
|
23
|
+
# - name: contact
|
24
|
+
# display_name: Kontakt
|
25
|
+
# unique: true
|
26
|
+
# cache: false
|
27
|
+
# elements: [pageheading, heading, contact, bild, absatz, file_download]
|
28
|
+
# autogenerate: [contact]
|
29
|
+
#
|
30
|
+
# Disabling the page caching is stronlgy recommended!
|
31
|
+
#
|
32
|
+
# The editor view for your element should have this layout:
|
33
|
+
#
|
34
|
+
# <%= render_essence_editor_by_name(element, 'mail_from') %>
|
35
|
+
# <%= render_essence_editor_by_name(element, 'mail_to') %>
|
36
|
+
# <%= render_essence_editor_by_name(element, 'subject') %>
|
37
|
+
# <p>
|
38
|
+
# Folgeseite: <%= page_selector(element, 'success_page') %>
|
39
|
+
# </p>
|
40
|
+
#
|
41
|
+
# Please have a look at the vendor/plugins/alchemy/config/config.yml file for further Message settings.
|
42
|
+
|
43
|
+
class MessagesController < AlchemyController
|
44
|
+
|
45
|
+
unloadable
|
46
|
+
|
47
|
+
helper :pages
|
48
|
+
|
49
|
+
def new#:nodoc:
|
50
|
+
@message = Message.new
|
51
|
+
@page = Page.find_by_page_layout(Alchemy::Config.get(:mailer)[:form_layout_name])
|
52
|
+
@root_page = Page.language_root_for(session[:language_id])
|
53
|
+
raise "Page for page_layout #{configuration(:mailer)[:page_layout_name]} not found" if @page.blank?
|
54
|
+
render :template => '/pages/show', :layout => 'pages'
|
55
|
+
end
|
56
|
+
|
57
|
+
def index#:nodoc:
|
58
|
+
@page = Page.find_by_page_layout(configuration(:mailer)[:page_layout_name])
|
59
|
+
raise "Page for page_layout #{configuration(:mailer)[:page_layout_name]} not found" if @page.blank?
|
60
|
+
redirect_to send("show_page#{multi_language? ? '_with_language' : '' }_path", :urlname => @page.urlname, :lang => multi_language? ? @page.language_code : nil)
|
61
|
+
end
|
62
|
+
|
63
|
+
def create#:nodoc:
|
64
|
+
@message = Message.new(params[:mail])
|
65
|
+
@message.ip = request.remote_ip
|
66
|
+
element = Element.find_by_id(@message.contact_form_id)
|
67
|
+
@page = element.page
|
68
|
+
@root_page = @page.get_language_root
|
69
|
+
if @message.save
|
70
|
+
if params[:mail_to].blank?
|
71
|
+
mail_to = element.ingredient("mail_to")
|
72
|
+
else
|
73
|
+
mail_to = Alchemy::Config.get(:mailer)[:mail_addresses].detect{ |c| c[0] == params[:mail_to] }[1]
|
74
|
+
end
|
75
|
+
mail_from = element.ingredient("mail_from") rescue configuration(:mailer)[:mail_from]
|
76
|
+
subject = element.ingredient("subject") rescue configuration(:mailer)[:subject]
|
77
|
+
|
78
|
+
Messages.mail(@message, mail_to, mail_from, subject).deliver
|
79
|
+
|
80
|
+
if element.ingredient("success_page")
|
81
|
+
if multi_language?
|
82
|
+
language = Language.find(session[:language_id])
|
83
|
+
redirect_to show_page_with_language_url(:urlname => element.ingredient("success_page"), :lang => language.code)
|
84
|
+
else
|
85
|
+
redirect_to show_page_url(:urlname => element.ingredient("success_page"))
|
86
|
+
end
|
87
|
+
elsif configuration(:mailer)[:forward_to_page] && configuration(:mailer)[:mail_success_page]
|
88
|
+
redirect_to :controller => 'pages', :action => 'show', :urlname => Page.find_by_urlname(configuration(:mailer)[:mail_success_page]).urlname
|
89
|
+
else
|
90
|
+
flash[:notice] = I18n.t('alchemy.contactform.messages.success')
|
91
|
+
redirect_to :controller => 'pages', :action => 'show', :urlname => Page.language_root_for(session[:language_id]).urlname
|
92
|
+
end
|
93
|
+
else
|
94
|
+
render :template => '/pages/show', :layout => 'pages'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
class PagesController < AlchemyController
|
2
|
+
|
3
|
+
unloadable
|
4
|
+
|
5
|
+
before_filter :set_language_from_client, :only => [:show, :sitemap]
|
6
|
+
before_filter :get_page_from_urlname, :only => [:show, :sitemap]
|
7
|
+
|
8
|
+
filter_access_to :show, :attribute_check => true
|
9
|
+
|
10
|
+
caches_action(
|
11
|
+
:show,
|
12
|
+
:layout => false,
|
13
|
+
:cache_path => Proc.new { |c| c.multi_language? ? "#{session[:language_code]}/#{c.params[:urlname]}" : "#{c.params[:urlname]}" },
|
14
|
+
:if => Proc.new { |c|
|
15
|
+
if Alchemy::Config.get(:cache_pages)
|
16
|
+
page = Page.find_by_urlname_and_language_id_and_public(
|
17
|
+
c.params[:urlname],
|
18
|
+
session[:language_id],
|
19
|
+
true,
|
20
|
+
:select => 'page_layout, language_id, urlname'
|
21
|
+
)
|
22
|
+
if page
|
23
|
+
pagelayout = Alchemy::PageLayout.get(page.page_layout)
|
24
|
+
pagelayout['cache'].nil? || pagelayout['cache']
|
25
|
+
end
|
26
|
+
else
|
27
|
+
false
|
28
|
+
end
|
29
|
+
}
|
30
|
+
)
|
31
|
+
|
32
|
+
# Showing page from params[:urlname]
|
33
|
+
# @page is fetched via before filter
|
34
|
+
# @root_page is fetched via before filter
|
35
|
+
# @language fetched via before_filter in alchemy_controller
|
36
|
+
# rendering page and querying for search results if any query is present
|
37
|
+
def show
|
38
|
+
if configuration(:ferret) && !params[:query].blank?
|
39
|
+
perform_search
|
40
|
+
end
|
41
|
+
render :layout => params[:layout].blank? ? 'pages' : params[:layout] == 'none' ? false : params[:layout]
|
42
|
+
end
|
43
|
+
|
44
|
+
# Renders a Google conform sitemap in xml
|
45
|
+
def sitemap
|
46
|
+
@pages = Page.find_all_by_sitemap_and_public(true, true)
|
47
|
+
respond_to do |format|
|
48
|
+
format.xml { render :layout => "sitemap" }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def get_page_from_urlname
|
55
|
+
if params[:urlname].blank?
|
56
|
+
@page = Page.language_root_for(session[:language_id])
|
57
|
+
else
|
58
|
+
@page = Page.find_by_urlname_and_language_id(params[:urlname], session[:language_id])
|
59
|
+
end
|
60
|
+
if User.admins.count == 0 && @page.nil?
|
61
|
+
redirect_to signup_path
|
62
|
+
elsif @page.blank?
|
63
|
+
render(:file => "#{Rails.root}/public/404.html", :status => 404, :layout => false)
|
64
|
+
elsif multi_language? && params[:lang].blank?
|
65
|
+
redirect_to show_page_with_language_path(:urlname => @page.urlname, :lang => session[:language_code]), :status => 301
|
66
|
+
elsif multi_language? && params[:urlname].blank? && !params[:lang].blank?
|
67
|
+
redirect_to show_page_with_language_path(:urlname => @page.urlname, :lang => params[:lang]), :status => 301
|
68
|
+
elsif configuration(:redirect_to_public_child) && !@page.public?
|
69
|
+
redirect_to_public_child
|
70
|
+
elsif !multi_language? && !params[:lang].blank?
|
71
|
+
redirect_to show_page_path(:urlname => @page.urlname), :status => 301
|
72
|
+
elsif @page.has_controller?
|
73
|
+
redirect_to(@page.controller_and_action)
|
74
|
+
else
|
75
|
+
if params[:urlname].blank?
|
76
|
+
@root_page = @page
|
77
|
+
else
|
78
|
+
@root_page = Page.language_root_for(session[:language_id])
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def perform_search
|
84
|
+
@rtf_search_results = EssenceRichtext.find_with_ferret(
|
85
|
+
"*" + params[:query] + "*",
|
86
|
+
{:limit => :all},
|
87
|
+
{:conditions => "public = 1"}
|
88
|
+
)
|
89
|
+
@text_search_results = EssenceText.find_with_ferret(
|
90
|
+
"*" + params[:query] + "*",
|
91
|
+
{:limit => :all},
|
92
|
+
{:conditions => "public = 1"}
|
93
|
+
)
|
94
|
+
end
|
95
|
+
|
96
|
+
def find_first_public(page)
|
97
|
+
if(page.public == true)
|
98
|
+
return page
|
99
|
+
end
|
100
|
+
page.children.each do |child|
|
101
|
+
result = find_first_public(child)
|
102
|
+
if(result!=nil)
|
103
|
+
return result
|
104
|
+
end
|
105
|
+
end
|
106
|
+
return nil
|
107
|
+
end
|
108
|
+
|
109
|
+
def redirect_to_public_child
|
110
|
+
@page = find_first_public(@page)
|
111
|
+
if @page.blank?
|
112
|
+
render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
|
113
|
+
else
|
114
|
+
redirect_page
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def redirect_page
|
119
|
+
get_additional_params
|
120
|
+
redirect_to(
|
121
|
+
send(
|
122
|
+
"show_page_#{multi_language? ? 'with_language_' : nil }path".to_sym, {
|
123
|
+
:lang => (multi_language? ? @page.language_code : nil),
|
124
|
+
:urlname => @page.urlname
|
125
|
+
}.merge(@additional_params)
|
126
|
+
),
|
127
|
+
:status => 301
|
128
|
+
)
|
129
|
+
end
|
130
|
+
|
131
|
+
def get_additional_params
|
132
|
+
@additional_params = params.clone.delete_if do |key, value|
|
133
|
+
["action", "controller", "urlname", "lang"].include?(key)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
class PicturesController < AlchemyController
|
2
|
+
|
3
|
+
unloadable
|
4
|
+
|
5
|
+
caches_page :show, :thumbnail, :zoom
|
6
|
+
|
7
|
+
filter_access_to :thumbnail
|
8
|
+
|
9
|
+
def show
|
10
|
+
@picture = Picture.find(params[:id])
|
11
|
+
@size = params[:size]
|
12
|
+
@crop = !params[:crop].nil?
|
13
|
+
@crop_from = normalized_size(params[:crop_from])
|
14
|
+
@crop_size = params[:crop_size]
|
15
|
+
@padding = params[:padding]
|
16
|
+
@upsample = !params[:upsample].nil? ? true : false
|
17
|
+
@effects = params[:effects]
|
18
|
+
respond_to do |format|
|
19
|
+
format.jpg
|
20
|
+
format.png
|
21
|
+
format.gif
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def thumbnail
|
26
|
+
@picture = Picture.find(params[:id])
|
27
|
+
case params[:size]
|
28
|
+
when "small"
|
29
|
+
then
|
30
|
+
@size = "80x60"
|
31
|
+
when "medium"
|
32
|
+
then
|
33
|
+
@size = "160x120"
|
34
|
+
when "large"
|
35
|
+
then
|
36
|
+
@size = "240x180"
|
37
|
+
when nil
|
38
|
+
@size = "111x93"
|
39
|
+
else
|
40
|
+
@size = params[:size]
|
41
|
+
end
|
42
|
+
if !params[:crop_size].blank? && !params[:crop_from].blank?
|
43
|
+
@crop = true
|
44
|
+
elsif params[:crop] == 'crop'
|
45
|
+
@default_crop = true
|
46
|
+
end
|
47
|
+
respond_to do |format|
|
48
|
+
format.png
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def zoom
|
53
|
+
@picture = Picture.find(params[:id])
|
54
|
+
respond_to do |format|
|
55
|
+
format.png
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def normalized_size(size)
|
62
|
+
return "" if size.blank?
|
63
|
+
size.split("x").map do |s|
|
64
|
+
s.to_i < 0 ? 0 : s.to_i
|
65
|
+
end.join('x')
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Admin::ElementsHelper
|
2
|
+
|
3
|
+
# Returns an Array for essence_text_editor select options_for_select.
|
4
|
+
def elements_by_name_for_select(name, options={})
|
5
|
+
defaults = {
|
6
|
+
:grouped_by_page => true,
|
7
|
+
:from_page => :all
|
8
|
+
}
|
9
|
+
options = defaults.merge(options)
|
10
|
+
elements = all_elements_by_name(
|
11
|
+
name,
|
12
|
+
:from_page => options[:from_page]
|
13
|
+
)
|
14
|
+
if options[:grouped_by_page] && options[:from_page] == :all
|
15
|
+
elements_for_options = {}
|
16
|
+
pages = elements.collect(&:page).compact.uniq
|
17
|
+
pages.sort{ |x,y| x.name <=> y.name }.each do |page|
|
18
|
+
page_elements = page.elements.select { |e| e.name == name }
|
19
|
+
elements_for_options[page.name] = page_elements.map { |pe| [pe.preview_text, pe.id.to_s] }
|
20
|
+
end
|
21
|
+
else
|
22
|
+
elements_for_options = elements.map { |e| [e.preview_text, e.id.to_s] }
|
23
|
+
elements_for_options = [''] + elements_for_options
|
24
|
+
end
|
25
|
+
return elements_for_options
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Admin::PicturesHelper
|
2
|
+
|
3
|
+
def create_or_assign_url(picture_to_assign, options)
|
4
|
+
if @content.nil?
|
5
|
+
{
|
6
|
+
:controller => :contents,
|
7
|
+
:action => :create,
|
8
|
+
:picture_id => picture_to_assign.id,
|
9
|
+
:content => {
|
10
|
+
:essence_type => "EssencePicture",
|
11
|
+
:element_id => @element.id
|
12
|
+
},
|
13
|
+
:options => options
|
14
|
+
}
|
15
|
+
else
|
16
|
+
{
|
17
|
+
:controller => :essence_pictures,
|
18
|
+
:action => :assign,
|
19
|
+
:picture_id => picture_to_assign.id,
|
20
|
+
:id => @content.id,
|
21
|
+
:options => options
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,1168 @@
|
|
1
|
+
# All methods (helpers) in this helper are used by Alchemy to render elements, contents and layouts on the Page.
|
2
|
+
#
|
3
|
+
# TODO: list all important infos here.
|
4
|
+
#
|
5
|
+
# Most Important Infos:
|
6
|
+
# ---
|
7
|
+
#
|
8
|
+
# 1. The most important helpers for webdevelopers are the render_navigation(), render_elements() and the render_page_layout() helpers.
|
9
|
+
# 2. The currently displayed page can be accessed via the @page variable.
|
10
|
+
# 3. All important meta data from @page will be rendered via the render_meta_data() helper.
|
11
|
+
|
12
|
+
module AlchemyHelper
|
13
|
+
|
14
|
+
include FastGettext::Translation
|
15
|
+
|
16
|
+
def configuration(name)
|
17
|
+
return Alchemy::Config.get(name)
|
18
|
+
end
|
19
|
+
|
20
|
+
# An alias for truncate.
|
21
|
+
# Left here for downwards compatibilty.
|
22
|
+
def shorten(text, length)
|
23
|
+
text.truncate(:length => length)
|
24
|
+
end
|
25
|
+
|
26
|
+
def render_editor(element)
|
27
|
+
render_element(element, :editor)
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_content(element, position)
|
31
|
+
return element.contents[position - 1]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Renders all elements from @page.
|
35
|
+
# ---
|
36
|
+
# == Options are:
|
37
|
+
# :only => [] A list of element names to be rendered only. Very usefull if you want to render a specific element type in a special html part (e.g.. <div>) of your page and all other elements in another part.
|
38
|
+
# :except => [] A list of element names to be rendered. The opposite of the only option.
|
39
|
+
# :from_page The Page.page_layout string from which the elements are rendered from, or you even pass a Page object.
|
40
|
+
# :count The amount of elements to be rendered (beginns with first element found)
|
41
|
+
# :fallback => {:for => 'ELEMENT_NAME', :with => 'ELEMENT_NAME', :from => 'PAGE_LAYOUT'} when no element from this name is found on page, then use this element from that page
|
42
|
+
# :sort_by => Content#name A Content name to sort the elements by
|
43
|
+
# :reverse => boolean Reverse the rendering order
|
44
|
+
#
|
45
|
+
# This helper also stores all pages where elements gets rendered on, so we can sweep them later if caching expires!
|
46
|
+
#
|
47
|
+
def render_elements(options = {})
|
48
|
+
default_options = {
|
49
|
+
:except => [],
|
50
|
+
:only => [],
|
51
|
+
:from_page => "",
|
52
|
+
:count => nil,
|
53
|
+
:offset => nil,
|
54
|
+
:locals => {},
|
55
|
+
:render_format => "html",
|
56
|
+
:fallback => nil
|
57
|
+
}
|
58
|
+
options = default_options.merge(options)
|
59
|
+
if options[:from_page].blank?
|
60
|
+
page = @page
|
61
|
+
else
|
62
|
+
if options[:from_page].class == Page
|
63
|
+
page = options[:from_page]
|
64
|
+
else
|
65
|
+
page = Page.find_all_by_page_layout_and_language_id(options[:from_page], session[:language_id])
|
66
|
+
end
|
67
|
+
end
|
68
|
+
if page.blank?
|
69
|
+
warning('Page is nil')
|
70
|
+
return ""
|
71
|
+
else
|
72
|
+
show_non_public = configuration(:cache_pages) ? false : defined?(current_user)
|
73
|
+
if page.class == Array
|
74
|
+
all_elements = page.collect { |p| p.find_elements(options, show_non_public) }.flatten
|
75
|
+
else
|
76
|
+
all_elements = page.find_elements(options, show_non_public)
|
77
|
+
end
|
78
|
+
unless options[:sort_by].blank?
|
79
|
+
all_elements = all_elements.sort_by { |e| e.contents.detect { |c| c.name == options[:sort_by] }.ingredient }
|
80
|
+
end
|
81
|
+
all_elements.reverse! if options[:reverse_sort] || options[:reverse]
|
82
|
+
element_string = ""
|
83
|
+
if options[:fallback]
|
84
|
+
unless all_elements.detect { |e| e.name == options[:fallback][:for] }
|
85
|
+
if from = Page.find_by_page_layout(options[:fallback][:from])
|
86
|
+
all_elements += from.elements.find_all_by_name(options[:fallback][:with].blank? ? options[:fallback][:for] : options[:fallback][:with])
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
all_elements.each_with_index do |element, i|
|
91
|
+
element_string += render_element(element, :view, options, i+1)
|
92
|
+
end
|
93
|
+
element_string.html_safe
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# This helper renders the Element partial for either the view or the editor part.
|
98
|
+
# Generate element partials with ./script/generate elements
|
99
|
+
def render_element(element, part = :view, options = {}, i = 1)
|
100
|
+
begin
|
101
|
+
if element.blank?
|
102
|
+
warning('Element is nil')
|
103
|
+
render :partial => "elements/#{part}_not_found", :locals => {:name => 'nil'}
|
104
|
+
else
|
105
|
+
default_options = {
|
106
|
+
:shorten_to => nil,
|
107
|
+
:render_format => "html"
|
108
|
+
}
|
109
|
+
options = default_options.merge(options)
|
110
|
+
element.store_page(@page) if part == :view
|
111
|
+
path1 = "#{Rails.root}/app/views/elements/"
|
112
|
+
path2 = "#{Rails.root}/vendor/plugins/alchemy/app/views/elements/"
|
113
|
+
partial_name = "_#{element.name.underscore}_#{part}.html.erb"
|
114
|
+
locals = options.delete(:locals)
|
115
|
+
render(
|
116
|
+
:partial => "elements/#{element.name.underscore}_#{part}.#{options[:render_format]}.erb",
|
117
|
+
:locals => {
|
118
|
+
:element => element,
|
119
|
+
:options => options,
|
120
|
+
:counter => i
|
121
|
+
}.merge(locals || {})
|
122
|
+
)
|
123
|
+
end
|
124
|
+
rescue ActionView::MissingTemplate
|
125
|
+
warning(%(
|
126
|
+
Element #{part} partial not found for #{element.name}.\n
|
127
|
+
Looking for #{partial_name}, but not found
|
128
|
+
neither in #{path1}
|
129
|
+
nor in #{path2}
|
130
|
+
Use ./script/generate elements to generate them.
|
131
|
+
Maybe you still have old style partial names? (like .rhtml). Then please rename them in .html.erb'
|
132
|
+
))
|
133
|
+
render :partial => "elements/#{part}_not_found", :locals => {:name => element.name, :error => "Element #{part} partial not found. Use ./script/generate elements to generate them."}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Renders the Content partial that is given (:editor, or :view).
|
138
|
+
# You can pass several options that are used by the different contents.
|
139
|
+
#
|
140
|
+
# For the view partial:
|
141
|
+
# :image_size => "111x93" Used by EssencePicture to render the image via RMagick to that size.
|
142
|
+
# :css_class => "" This css class gets attached to the content view.
|
143
|
+
# :date_format => "Am %d. %m. %Y, um %H:%Mh" Espacially fot the EssenceDate. See Date.strftime for date formatting.
|
144
|
+
# :caption => true Pass true to enable that the EssencePicture.caption value gets rendered.
|
145
|
+
# :blank_value => "" Pass a String that gets rendered if the content.essence is blank.
|
146
|
+
#
|
147
|
+
# For the editor partial:
|
148
|
+
# :css_class => "" This css class gets attached to the content editor.
|
149
|
+
# :last_image_deletable => false Pass true to enable that the last image of an imagecollection (e.g. image gallery) is deletable.
|
150
|
+
def render_essence(content, part = :view, options = {}, html_options = {})
|
151
|
+
if content.nil?
|
152
|
+
return part == :view ? "" : warning('Content is nil', _("content_not_found"))
|
153
|
+
elsif content.essence.nil?
|
154
|
+
return part == :view ? "" : warning('Essence is nil', _("content_essence_not_found"))
|
155
|
+
end
|
156
|
+
defaults = {
|
157
|
+
:for_editor => {
|
158
|
+
:as => 'text_field',
|
159
|
+
:css_class => 'long',
|
160
|
+
:render_format => "html"
|
161
|
+
},
|
162
|
+
:for_view => {
|
163
|
+
:image_size => "120x90",
|
164
|
+
:css_class => "",
|
165
|
+
:date_format => "%d. %m. %Y, %H:%Mh",
|
166
|
+
:caption => true,
|
167
|
+
:blank_value => "",
|
168
|
+
:render_format => "html"
|
169
|
+
}
|
170
|
+
}
|
171
|
+
options_for_partial = defaults[('for_' + part.to_s).to_sym].merge(options[('for_' + part.to_s).to_sym])
|
172
|
+
options = options.merge(defaults)
|
173
|
+
render(
|
174
|
+
:partial => "essences/#{content.essence.class.name.underscore}_#{part.to_s}.#{options_for_partial[:render_format]}.erb",
|
175
|
+
:locals => {
|
176
|
+
:content => content,
|
177
|
+
:options => options_for_partial,
|
178
|
+
:html_options => html_options
|
179
|
+
}
|
180
|
+
)
|
181
|
+
end
|
182
|
+
|
183
|
+
# Renders the Content editor partial from the given Content.
|
184
|
+
# For options see -> render_essence
|
185
|
+
def render_essence_editor(content, options = {})
|
186
|
+
render_essence(content, :editor, :for_editor => options)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Renders the Content view partial from the given Content.
|
190
|
+
# For options see -> render_essence
|
191
|
+
def render_essence_view(content, options = {}, html_options = {})
|
192
|
+
render_essence(content, :view, {:for_view => options}, html_options)
|
193
|
+
end
|
194
|
+
|
195
|
+
# Renders the Content editor partial from essence_type.
|
196
|
+
#
|
197
|
+
# Options are:
|
198
|
+
# * element (Element) - the Element the contents are in (obligatory)
|
199
|
+
# * type (String) - the type of Essence (obligatory)
|
200
|
+
# * options (Hash):
|
201
|
+
# ** :position (Integer) - The position of the Content inside the Element. I.E. for getting the n-th EssencePicture. Default is 1 (the first)
|
202
|
+
# ** :all (String) - Pass :all to get all Contents of that name. Default false
|
203
|
+
# * editor_options (Hash) - Will be passed to the render_essence_editor partial renderer
|
204
|
+
#
|
205
|
+
def render_essence_editor_by_type(element, essence_type, options = {}, editor_options = {})
|
206
|
+
return warning('Element is nil', _("no_element_given")) if element.blank?
|
207
|
+
return warning('EssenceType is blank', _("No EssenceType given")) if essence_type.blank?
|
208
|
+
defaults = {
|
209
|
+
:position => 1,
|
210
|
+
:all => false
|
211
|
+
}
|
212
|
+
options = defaults.merge(options)
|
213
|
+
return_string = ""
|
214
|
+
if options[:all]
|
215
|
+
contents = element.contents.find_all_by_essence_type_and_name(essence_type, options[:all])
|
216
|
+
contents.each do |content|
|
217
|
+
return_string << render_essence(content, :editor, :for_editor => editor_options)
|
218
|
+
end
|
219
|
+
else
|
220
|
+
content = element.contents.find_by_essence_type_and_position(essence_type, options[:position])
|
221
|
+
return_string = render_essence(content, :editor, :for_editor => editor_options)
|
222
|
+
end
|
223
|
+
return_string
|
224
|
+
end
|
225
|
+
|
226
|
+
# Renders the Content view partial from the given Element for the essence_type (e.g. EssenceRichtext).
|
227
|
+
# For multiple contents of same kind inside one molecue just pass a position so that will be rendered.
|
228
|
+
# Otherwise the first content found for this type will be rendered.
|
229
|
+
# For options see -> render_essence
|
230
|
+
def render_essence_view_by_type(element, type, position, options = {}, html_options = {})
|
231
|
+
if element.blank?
|
232
|
+
warning('Element is nil')
|
233
|
+
return ""
|
234
|
+
end
|
235
|
+
if position.nil?
|
236
|
+
content = element.content_by_type(type)
|
237
|
+
else
|
238
|
+
content = element.contents.find_by_essence_type_and_position(type, position)
|
239
|
+
end
|
240
|
+
render_essence(content, :view, :for_view => options)
|
241
|
+
end
|
242
|
+
|
243
|
+
# Renders the Content view partial from the given Element by position (e.g. 1).
|
244
|
+
# For options see -> render_essence
|
245
|
+
def render_essence_view_by_position(element, position, options = {}, html_options = {})
|
246
|
+
if element.blank?
|
247
|
+
warning('Element is nil')
|
248
|
+
return ""
|
249
|
+
end
|
250
|
+
content = element.contents.find_by_position(position)
|
251
|
+
render_essence(content, :view, {:for_view => options}, html_options)
|
252
|
+
end
|
253
|
+
|
254
|
+
# Renders the Content editor partial from the given Element by position (e.g. 1).
|
255
|
+
# For options see -> render_essence
|
256
|
+
def render_essence_editor_by_position(element, position, options = {})
|
257
|
+
if element.blank?
|
258
|
+
warning('Element is nil')
|
259
|
+
return ""
|
260
|
+
end
|
261
|
+
content = element.contents.find_by_position(position)
|
262
|
+
render_essence(content, :editor, :for_editor => options)
|
263
|
+
end
|
264
|
+
|
265
|
+
# Renders the Content editor partial found in views/contents/ for the content with name inside the passed Element.
|
266
|
+
# For options see -> render_essence
|
267
|
+
#
|
268
|
+
# Content creation on the fly:
|
269
|
+
#
|
270
|
+
# If you update the elements.yml file after creating an element this helper displays a error message with an option to create the content.
|
271
|
+
#
|
272
|
+
def render_essence_editor_by_name(element, name, options = {})
|
273
|
+
if element.blank?
|
274
|
+
return warning('Element is nil', _("no_element_given"))
|
275
|
+
end
|
276
|
+
content = element.content_by_name(name)
|
277
|
+
if content.blank?
|
278
|
+
render :partial => 'admin/contents/missing', :locals => {:element => element, :name => name}
|
279
|
+
else
|
280
|
+
render_essence(content, :editor, :for_editor => options)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
|
284
|
+
# Renders the Content view partial from the passed Element for passed content name.
|
285
|
+
# For options see -> render_essence
|
286
|
+
def render_essence_view_by_name(element, name, options = {}, html_options = {})
|
287
|
+
if element.blank?
|
288
|
+
warning('Element is nil')
|
289
|
+
return ""
|
290
|
+
end
|
291
|
+
content = element.content_by_name(name)
|
292
|
+
render_essence(content, :view, {:for_view => options}, html_options)
|
293
|
+
end
|
294
|
+
|
295
|
+
# Renders the name of elements content or the default name defined in elements.yml
|
296
|
+
def render_content_name(content)
|
297
|
+
if content.blank?
|
298
|
+
warning('Element is nil')
|
299
|
+
return ""
|
300
|
+
else
|
301
|
+
content_name = content.name_for_label
|
302
|
+
end
|
303
|
+
if content.description.blank?
|
304
|
+
warning("Content #{content.name} is missing its description")
|
305
|
+
title = _("Warning: Content '%{contentname}' is missing its description.") % {:contentname => content.name}
|
306
|
+
content_name = %(<span class="warning icon" title="#{title}"></span> ) + content_name
|
307
|
+
end
|
308
|
+
content.has_validations? ? "#{content_name}<span class='validation_indicator'>*</span>" : content_name
|
309
|
+
end
|
310
|
+
|
311
|
+
# Returns @page.title
|
312
|
+
#
|
313
|
+
# The options are:
|
314
|
+
# :prefix => ""
|
315
|
+
# :seperator => "|"
|
316
|
+
#
|
317
|
+
# == Webdevelopers:
|
318
|
+
# Please use the render_meta_data() helper. There all important meta information gets rendered in one helper.
|
319
|
+
# So you dont have to worry about anything.
|
320
|
+
def render_page_title options={}
|
321
|
+
default_options = {
|
322
|
+
:prefix => "",
|
323
|
+
:seperator => "|"
|
324
|
+
}
|
325
|
+
default_options.update(options)
|
326
|
+
unless @page.title.blank?
|
327
|
+
h("#{default_options[:prefix]} #{default_options[:seperator]} #{@page.title}")
|
328
|
+
else
|
329
|
+
h("")
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
# Returns a complete html <title> tag for the <head> part of the html document.
|
334
|
+
#
|
335
|
+
# == Webdevelopers:
|
336
|
+
# Please use the render_meta_data() helper. There all important meta information gets rendered in one helper.
|
337
|
+
# So you dont have to worry about anything.
|
338
|
+
def render_title_tag options={}
|
339
|
+
default_options = {
|
340
|
+
:prefix => "",
|
341
|
+
:seperator => "|"
|
342
|
+
}
|
343
|
+
options = default_options.merge(options)
|
344
|
+
title = render_page_title(options)
|
345
|
+
%(<title>#{title}</title>).html_safe
|
346
|
+
end
|
347
|
+
|
348
|
+
# Renders a html <meta> tag for :name => "" and :content => ""
|
349
|
+
#
|
350
|
+
# == Webdevelopers:
|
351
|
+
# Please use the render_meta_data() helper. There all important meta information gets rendered in one helper.
|
352
|
+
# So you dont have to worry about anything.
|
353
|
+
def render_meta_tag(options={})
|
354
|
+
default_options = {
|
355
|
+
:name => "",
|
356
|
+
:default_language => "de",
|
357
|
+
:content => ""
|
358
|
+
}
|
359
|
+
options = default_options.merge(options)
|
360
|
+
lang = (@page.language.blank? ? options[:default_language] : @page.language.code)
|
361
|
+
%(<meta name="#{options[:name]}" content="#{options[:content]}" lang="#{lang}" />).html_safe
|
362
|
+
end
|
363
|
+
|
364
|
+
# Renders a html <meta http-equiv="Content-Language" content="#{lang}" /> for @page.language.
|
365
|
+
#
|
366
|
+
# == Webdevelopers:
|
367
|
+
# Please use the render_meta_data() helper. There all important meta information gets rendered in one helper.
|
368
|
+
# So you dont have to worry about anything.
|
369
|
+
def render_meta_content_language_tag(options={})
|
370
|
+
default_options = {
|
371
|
+
:default_language => "de"
|
372
|
+
}
|
373
|
+
options = default_options.merge(options)
|
374
|
+
lang = (@page.language_code.blank? ? options[:default_language] : @page.language_code)
|
375
|
+
%(<meta http-equiv="Content-Language" content="#{lang}" />).html_safe
|
376
|
+
end
|
377
|
+
|
378
|
+
# = This helper takes care of all important meta tags for your @page.
|
379
|
+
# ---
|
380
|
+
# The meta data is been taken from the @page.title, @page.meta_description, @page.meta_keywords, @page.updated_at and @page.language database entries managed by the Alchemy user via the Alchemy cockpit.
|
381
|
+
#
|
382
|
+
# Assume that the user has entered following data into the Alchemy cockpit of the Page "home" and that the user wants that the searchengine (aka. google) robot should index the page and should follow all links on this page:
|
383
|
+
#
|
384
|
+
# Title = Homepage
|
385
|
+
# Description = Your page description
|
386
|
+
# Keywords: cms, ruby, rubyonrails, rails, software, development, html, javascript, ajax
|
387
|
+
#
|
388
|
+
# Then placing render_meta_data(:title_prefix => "company", :title_seperator => "::") into the <head> part of the pages.html.erb layout produces:
|
389
|
+
#
|
390
|
+
# <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
391
|
+
# <meta http-equiv="Content-Language" content="de" />
|
392
|
+
# <title>Company :: #{@page.title}</title>
|
393
|
+
# <meta name="description" content="Your page description" />
|
394
|
+
# <meta name="keywords" content="cms, ruby, rubyonrails, rails, software, development, html, javascript, ajax" />
|
395
|
+
# <meta name="generator" content="Alchemy VERSION" />
|
396
|
+
# <meta name="date" content="Tue Dec 16 10:21:26 +0100 2008" />
|
397
|
+
# <meta name="robots" content="index, follow" />
|
398
|
+
#
|
399
|
+
def render_meta_data options={}
|
400
|
+
if @page.blank?
|
401
|
+
warning("No Page found!")
|
402
|
+
return nil
|
403
|
+
end
|
404
|
+
default_options = {
|
405
|
+
:title_prefix => "",
|
406
|
+
:title_seperator => "|",
|
407
|
+
:default_lang => "de"
|
408
|
+
}
|
409
|
+
options = default_options.merge(options)
|
410
|
+
#render meta description of the root page from language if the current meta description is empty
|
411
|
+
if @page.meta_description.blank?
|
412
|
+
description = Page.find_by_language_root_and_language_id(true, session[:language_id]).meta_description rescue ""
|
413
|
+
else
|
414
|
+
description = @page.meta_description
|
415
|
+
end
|
416
|
+
#render meta keywords of the root page from language if the current meta keywords is empty
|
417
|
+
if @page.meta_keywords.blank?
|
418
|
+
keywords = Page.find_by_language_root_and_language_id(true, session[:language_id]).meta_keywords rescue ""
|
419
|
+
else
|
420
|
+
keywords = @page.meta_keywords
|
421
|
+
end
|
422
|
+
robot = "#{@page.robot_index? ? "" : "no"}index, #{@page.robot_follow? ? "" : "no"}follow"
|
423
|
+
meta_string = %(
|
424
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
425
|
+
#{render_meta_content_language_tag}
|
426
|
+
#{render_title_tag( :prefix => options[:title_prefix], :seperator => options[:title_seperator])}
|
427
|
+
#{render_meta_tag( :name => "description", :content => description)}
|
428
|
+
#{render_meta_tag( :name => "keywords", :content => keywords)}
|
429
|
+
<meta name="generator" content="Alchemy #{Alchemy::VERSION}" />
|
430
|
+
<meta name="date" content="#{@page.updated_at}" />
|
431
|
+
<meta name="robots" content="#{robot}" />
|
432
|
+
)
|
433
|
+
if @page.contains_feed?
|
434
|
+
meta_string += %(
|
435
|
+
<link rel="alternate" type="application/rss+xml" title="RSS" href="#{multi_language? ? show_page_with_language_url(:protocol => 'feed', :urlname => @page.urlname, :lang => @page.language_code, :format => :rss) : show_page_url(:protocol => 'feed', :urlname => @page.urlname, :format => :rss)}" />
|
436
|
+
)
|
437
|
+
end
|
438
|
+
return meta_string.html_safe
|
439
|
+
end
|
440
|
+
|
441
|
+
# Returns an array of all pages in the same branch from current. Used internally to find the active page in navigations.
|
442
|
+
def breadcrumb(current)
|
443
|
+
return [] if current.nil?
|
444
|
+
result = Array.new
|
445
|
+
result << current
|
446
|
+
while current = current.parent
|
447
|
+
result << current
|
448
|
+
end
|
449
|
+
return result.reverse
|
450
|
+
end
|
451
|
+
|
452
|
+
# Returns a html string for a linked breadcrumb from root to current page.
|
453
|
+
# == Options:
|
454
|
+
# :seperator => %(<span class="seperator">></span>) Maybe you don't want this seperator. Pass another one.
|
455
|
+
# :page => @page Pass a different Page instead of the default (@page).
|
456
|
+
# :without => nil Pass Pageobject or array of Pages that must not be displayed.
|
457
|
+
# :public_only => false Pass boolean for displaying hidden pages only.
|
458
|
+
# :visible_only => true Pass boolean for displaying (in navigation) visible pages only.
|
459
|
+
# :restricted_only => false Pass boolean for displaying restricted pages only.
|
460
|
+
# :reverse => false Pass boolean for displaying reversed breadcrumb.
|
461
|
+
def render_breadcrumb(options={})
|
462
|
+
default_options = {
|
463
|
+
:seperator => %(<span class="seperator">></span>),
|
464
|
+
:page => @page,
|
465
|
+
:without => nil,
|
466
|
+
:public_only => false,
|
467
|
+
:visible_only => true,
|
468
|
+
:restricted_only => false,
|
469
|
+
:reverse => false
|
470
|
+
}
|
471
|
+
options = default_options.merge(options)
|
472
|
+
pages = breadcrumb(options[:page])
|
473
|
+
pages.delete(Page.root)
|
474
|
+
unless options[:without].nil?
|
475
|
+
unless options[:without].class == Array
|
476
|
+
pages.delete(options[:without])
|
477
|
+
else
|
478
|
+
pages = pages - options[:without]
|
479
|
+
end
|
480
|
+
end
|
481
|
+
if(options[:visible_only])
|
482
|
+
pages.reject!{|p| !p.visible? }
|
483
|
+
end
|
484
|
+
if(options[:public_only])
|
485
|
+
pages.reject!{|p| !p.public? }
|
486
|
+
end
|
487
|
+
if(options[:restricted_only])
|
488
|
+
pages.reject!{|p| !p.restricted? }
|
489
|
+
end
|
490
|
+
if(options[:reverse])
|
491
|
+
pages.reverse!
|
492
|
+
end
|
493
|
+
bc = []
|
494
|
+
pages.each do |page|
|
495
|
+
urlname = page.urlname
|
496
|
+
(page.name == @page.name) ? css_class = "active" : nil
|
497
|
+
if page == pages.last
|
498
|
+
css_class.blank? ? css_class = "last" : css_class = [css_class, "last"].join(" ")
|
499
|
+
elsif page == pages.first
|
500
|
+
css_class.blank? ? css_class = "first" : css_class = [css_class, "last"].join(" ")
|
501
|
+
end
|
502
|
+
if multi_language?
|
503
|
+
url = show_page_with_language_url(:urlname => urlname, :lang => page.language_code)
|
504
|
+
else
|
505
|
+
url = show_page_url(:urlname => urlname)
|
506
|
+
end
|
507
|
+
bc << link_to( h(page.name), url, :class => css_class, :title => page.title )
|
508
|
+
end
|
509
|
+
bc.join(options[:seperator]).html_safe
|
510
|
+
end
|
511
|
+
|
512
|
+
# returns true if page is in the active branch
|
513
|
+
def page_active? page
|
514
|
+
@breadcrumb ||= breadcrumb(@page)
|
515
|
+
@breadcrumb.include? page
|
516
|
+
end
|
517
|
+
|
518
|
+
# = This helper renders the navigation.
|
519
|
+
#
|
520
|
+
# It produces a html <ul><li></li></ul> structure with all necessary classes and ids so you can produce nearly every navigation the web uses today.
|
521
|
+
# E.G. dropdown-navigations, simple mainnavigations or even complex nested ones.
|
522
|
+
# ---
|
523
|
+
# == En detail:
|
524
|
+
#
|
525
|
+
# <ul>
|
526
|
+
# <li class="first" id="home"><a href="home" class="active">Homepage</a></li>
|
527
|
+
# <li id="contact"><a href="contact">Contact</a></li>
|
528
|
+
# <li class="last" id="imprint"><a href="imprint">Imprint</a></li>
|
529
|
+
# </ul>
|
530
|
+
#
|
531
|
+
# As you can see: Everything you need.
|
532
|
+
#
|
533
|
+
# Not pleased with the way Alchemy produces the navigation structure?
|
534
|
+
# Then feel free to overwrite the partials (_navigation_renderer.html.erb and _navigation_link.html.erb) found in views/pages/partials/ or pass different partials via the options :navigation_partial and :navigation_link_partial.
|
535
|
+
#
|
536
|
+
# == The options are:
|
537
|
+
#
|
538
|
+
# :submenu => false Do you want a nested <ul> <li> structure for the deeper levels of your navigation, or not? Used to display the subnavigation within the mainnaviagtion. E.g. for dropdown menues.
|
539
|
+
# :from_page => @root_page Do you want to render a navigation from a different page then the current page? Then pass an Page instance or a Alchemy::PageLayout name as string.
|
540
|
+
# :spacer => "" Yeah even a spacer for the entries can be passed. Simple string, or even a complex html structure. E.g: "<span class='spacer'>|</spacer>". Only your imagination is the limit. And the W3C of course :)
|
541
|
+
# :navigation_partial => "navigation_renderer" Pass a different partial to be taken for the navigation rendering. CAUTION: Only for the advanced Alchemy webdevelopers. The standard partial takes care of nearly everything. But maybe you are an adventures one ^_^
|
542
|
+
# :navigation_link_partial => "navigation_link" Alchemy places an <a> html link in <li> tags. The tag automatically has an active css class if necessary. So styling is everything. But maybe you don't want this. So feel free to make you own partial and pass the filename here.
|
543
|
+
# :show_nonactive => false Commonly Alchemy only displays the submenu of the active page (if :submenu => true). If you want to display all child pages then pass true (together with :submenu => true of course). E.g. for the popular css-driven dropdownmenues these days.
|
544
|
+
# :show_title => true For our beloved SEOs :). Appends a title attribute to all links and places the page.title content into it.
|
545
|
+
def render_navigation(options = {})
|
546
|
+
default_options = {
|
547
|
+
:submenu => false,
|
548
|
+
:all_sub_menues => false,
|
549
|
+
:from_page => @root_page,
|
550
|
+
:spacer => "",
|
551
|
+
:navigation_partial => "partials/navigation_renderer",
|
552
|
+
:navigation_link_partial => "partials/navigation_link",
|
553
|
+
:show_nonactive => false,
|
554
|
+
:restricted_only => nil,
|
555
|
+
:show_title => true,
|
556
|
+
:reverse => false,
|
557
|
+
:reverse_children => false
|
558
|
+
}
|
559
|
+
options = default_options.merge(options)
|
560
|
+
if options[:from_page].is_a?(String)
|
561
|
+
page = Page.find_by_page_layout_and_language_id(options[:from_page], session[:language_id])
|
562
|
+
else
|
563
|
+
page = options[:from_page]
|
564
|
+
end
|
565
|
+
if page.blank?
|
566
|
+
warning("No Page found for #{options[:from_page]}")
|
567
|
+
return ""
|
568
|
+
end
|
569
|
+
conditions = {
|
570
|
+
:parent_id => page.id,
|
571
|
+
:restricted => options[:restricted_only] || false,
|
572
|
+
:visible => true
|
573
|
+
}
|
574
|
+
if options[:restricted_only].nil?
|
575
|
+
conditions.delete(:restricted)
|
576
|
+
end
|
577
|
+
pages = Page.where(conditions).order("lft ASC")
|
578
|
+
if options[:reverse]
|
579
|
+
pages.reverse!
|
580
|
+
end
|
581
|
+
render :partial => options[:navigation_partial], :locals => {:options => options, :pages => pages}
|
582
|
+
end
|
583
|
+
|
584
|
+
# Renders the children of the given page (standard is the current page), the given page and its siblings if there are no children, or it renders just nil.
|
585
|
+
# Use this helper if you want to render the subnavigation independent from the mainnavigation. E.g. to place it in a different layer on your website.
|
586
|
+
# If :from_page's level in the site-hierarchy is greater than :level (standard is 2) and the given page has no children, the returned output will be the :from_page and it's siblings
|
587
|
+
# This method will assign all its options to the the render_navigation method, so you are able to assign the same options as to the render_navigation method.
|
588
|
+
# Normally there is no need to change the level parameter, just in a few special cases.
|
589
|
+
def render_subnavigation(options = {})
|
590
|
+
default_options = {
|
591
|
+
:from_page => @page,
|
592
|
+
:level => 2
|
593
|
+
}
|
594
|
+
options = default_options.merge(options)
|
595
|
+
if !options[:from_page].nil?
|
596
|
+
if (options[:from_page].children.blank? && options[:from_page].level > options[:level])
|
597
|
+
options = options.merge(:from_page => Page.find(options[:from_page].parent_id))
|
598
|
+
end
|
599
|
+
render_navigation(options)
|
600
|
+
else
|
601
|
+
return nil
|
602
|
+
end
|
603
|
+
end
|
604
|
+
|
605
|
+
# Returns true if the current_user (The logged-in Alchemy User) has the admin role.
|
606
|
+
def is_admin?
|
607
|
+
return false if !current_user
|
608
|
+
current_user.admin?
|
609
|
+
end
|
610
|
+
|
611
|
+
# This helper renders the link for a protoypejs-window overlay. We use this for our fancy modal overlay windows in the Alchemy cockpit.
|
612
|
+
def link_to_overlay_window(content, url, options={}, html_options={})
|
613
|
+
default_options = {
|
614
|
+
:size => "100x100",
|
615
|
+
:resizable => false,
|
616
|
+
:modal => true,
|
617
|
+
:overflow => false
|
618
|
+
}
|
619
|
+
options = default_options.merge(options)
|
620
|
+
link_to_function(
|
621
|
+
content,
|
622
|
+
"Alchemy.openWindow(
|
623
|
+
\'#{url}\',
|
624
|
+
\'#{options[:title]}\',
|
625
|
+
\'#{options[:size].split('x')[0].to_s}\',
|
626
|
+
\'#{options[:size].split('x')[1].to_s}\',
|
627
|
+
#{options[:resizable]},
|
628
|
+
#{options[:modal]},
|
629
|
+
#{options[:overflow]}
|
630
|
+
)",
|
631
|
+
html_options
|
632
|
+
)
|
633
|
+
end
|
634
|
+
|
635
|
+
# Used for rendering the folder link in Admin::Pages.index sitemap.
|
636
|
+
def sitemapFolderLink(page)
|
637
|
+
return '' if page.level == 1
|
638
|
+
if page.folded?(current_user.id)
|
639
|
+
css_class = 'folded'
|
640
|
+
title = _('Show childpages')
|
641
|
+
else
|
642
|
+
css_class = 'collapsed'
|
643
|
+
title = _('Hide childpages')
|
644
|
+
end
|
645
|
+
link_to(
|
646
|
+
'',
|
647
|
+
fold_admin_page_path(page),
|
648
|
+
:remote => true,
|
649
|
+
:method => :post,
|
650
|
+
:class => "page_folder #{css_class}",
|
651
|
+
:title => title,
|
652
|
+
:id => "fold_button_#{page.id}"
|
653
|
+
)
|
654
|
+
end
|
655
|
+
|
656
|
+
# Renders an image_tag from for an image in public/images folder so it can be cached.
|
657
|
+
# *Not really working!*
|
658
|
+
def static_image_tag image, options={}
|
659
|
+
image_tag url_for(:controller => :images, :action => :show_static, :image => image)
|
660
|
+
end
|
661
|
+
|
662
|
+
# Renders the layout from @page.page_layout. File resists in /app/views/page_layouts/_LAYOUT-NAME.html.erb
|
663
|
+
def render_page_layout(options={})
|
664
|
+
default_options = {
|
665
|
+
:render_format => "html"
|
666
|
+
}
|
667
|
+
options = default_options.merge(options)
|
668
|
+
render :partial => "page_layouts/#{@page.page_layout.downcase}.#{options[:render_format]}.erb"
|
669
|
+
rescue ActionView::MissingTemplate
|
670
|
+
warning("PageLayout: '#{@page.page_layout}' not found. Rendering standard page_layout.")
|
671
|
+
render :partial => "page_layouts/standard"
|
672
|
+
end
|
673
|
+
|
674
|
+
# Returns @current_language set in the action (e.g. Page.show)
|
675
|
+
def current_language
|
676
|
+
if @current_language.nil?
|
677
|
+
warning('@current_language is not set')
|
678
|
+
return nil
|
679
|
+
else
|
680
|
+
@current_language
|
681
|
+
end
|
682
|
+
end
|
683
|
+
|
684
|
+
# Returns true if the current page is the root page in the nested set of Pages, false if not.
|
685
|
+
def root_page?
|
686
|
+
@page == @root_page
|
687
|
+
end
|
688
|
+
|
689
|
+
# Returns the full url containing host, page and anchor for the given element
|
690
|
+
def full_url_for_element element
|
691
|
+
"http://" + request.env["HTTP_HOST"] + "/" + element.page.urlname + "##{element.name}_#{element.id}"
|
692
|
+
end
|
693
|
+
|
694
|
+
# Used for language selector in Alchemy cockpit sitemap. So the user can select the language branche of the page.
|
695
|
+
def language_codes_for_select
|
696
|
+
configuration(:languages).collect{ |language|
|
697
|
+
language[:language_code]
|
698
|
+
}
|
699
|
+
end
|
700
|
+
|
701
|
+
# Used for translations selector in Alchemy cockpit user settings.
|
702
|
+
def translations_for_select
|
703
|
+
configuration(:translations).collect{ |translation|
|
704
|
+
[translation[:language], translation[:language_code]]
|
705
|
+
}
|
706
|
+
end
|
707
|
+
|
708
|
+
# Used by Alchemy to display a javascript driven filter for lists in the Alchemy cockpit.
|
709
|
+
def js_filter_field options = {}
|
710
|
+
default_options = {
|
711
|
+
:class => "thin_border js_filter_field",
|
712
|
+
:onkeyup => "Alchemy.ListFilter('#contact_list li')",
|
713
|
+
:id => "search_field"
|
714
|
+
}
|
715
|
+
options = default_options.merge(options)
|
716
|
+
options[:onkeyup] << ";jQuery('#search_field').val().length >= 1 ? jQuery('.js_filter_field_clear').show() : jQuery('.js_filter_field_clear').hide();"
|
717
|
+
filter_field = "<div class=\"js_filter_field_box\">"
|
718
|
+
filter_field << text_field_tag("filter", '', options)
|
719
|
+
filter_field << content_tag('span', '', :class => 'icon search')
|
720
|
+
filter_field << link_to_function(
|
721
|
+
"",
|
722
|
+
"jQuery('##{options[:id]}').val('');#{options[:onkeyup]}",
|
723
|
+
:class => "js_filter_field_clear",
|
724
|
+
:style => "display:none",
|
725
|
+
:title => _("click_to_show_all")
|
726
|
+
)
|
727
|
+
filter_field << "<label for=\"search_field\">" + _("search") + "</label>"
|
728
|
+
filter_field << "</div>"
|
729
|
+
filter_field
|
730
|
+
end
|
731
|
+
|
732
|
+
def clipboard_select_tag(items, html_options = {})
|
733
|
+
options = [[_('Please choose'), ""]]
|
734
|
+
items.each do |item|
|
735
|
+
options << [item.class.to_s == 'Element' ? item.display_name_with_preview_text : item.name, item.id]
|
736
|
+
end
|
737
|
+
select_tag(
|
738
|
+
'paste_from_clipboard',
|
739
|
+
options_for_select(options),
|
740
|
+
{
|
741
|
+
:class => html_options[:class] || 'very_long',
|
742
|
+
:style => html_options[:style]
|
743
|
+
}
|
744
|
+
)
|
745
|
+
end
|
746
|
+
|
747
|
+
# Returns all elements that could be placed on that page because of the pages layout.
|
748
|
+
# The elements are returned as an array to be used in alchemy_selectbox form builder.
|
749
|
+
def elements_for_select(elements)
|
750
|
+
return [] if elements.nil?
|
751
|
+
options = elements.collect{ |e| [I18n.t("alchemy.element_names.#{e['name']}", :default => e['name'].capitalize), e["name"]] }
|
752
|
+
return options_for_select(options)
|
753
|
+
end
|
754
|
+
|
755
|
+
# Returns all elements that could be placed on that page because of the pages layout.
|
756
|
+
# The elements will be grouped by cell.
|
757
|
+
def grouped_elements_for_select(elements)
|
758
|
+
return [] if elements.nil?
|
759
|
+
cells_definition = Cell.definitions
|
760
|
+
return [] if cells_definition.blank?
|
761
|
+
options = {}
|
762
|
+
celled_elements = []
|
763
|
+
cells_definition.each do |cell|
|
764
|
+
cell_elements = elements.select { |e| cell['elements'].include?(e['name']) }
|
765
|
+
celled_elements += cell_elements
|
766
|
+
optgroup_label = Cell.translated_label_for(cell['name'])
|
767
|
+
options[optgroup_label] = cell_elements.map { |e| [I18n.t("alchemy.element_names.#{e['name']}", :default => e['name'].capitalize), e['name'] + "##{cell['name']}"] }
|
768
|
+
end
|
769
|
+
other_elements = elements - celled_elements
|
770
|
+
unless other_elements.blank?
|
771
|
+
optgroup_label = _('other Elements')
|
772
|
+
options[optgroup_label] = other_elements.map { |e| [I18n.t("alchemy.element_names.#{e['name']}", :default => e['name'].capitalize), e['name']] }
|
773
|
+
end
|
774
|
+
return grouped_options_for_select(options)
|
775
|
+
end
|
776
|
+
|
777
|
+
def link_to_confirmation_window(link_string = "", message = "", url = "", html_options = {})
|
778
|
+
title = _("please_confirm")
|
779
|
+
ok_lable = _("yes")
|
780
|
+
cancel_lable = _("no")
|
781
|
+
link_to_function(
|
782
|
+
link_string,
|
783
|
+
"Alchemy.confirmToDeleteWindow('#{url}', '#{title}', '#{message}', '#{ok_lable}', '#{cancel_lable}');",
|
784
|
+
html_options
|
785
|
+
)
|
786
|
+
end
|
787
|
+
|
788
|
+
# Renders a form select tag for storing page urlnames
|
789
|
+
# Options:
|
790
|
+
# * element - element the Content find via content_name to store the pages urlname in.
|
791
|
+
# * content_name - the name of the content from element to store the pages urlname in.
|
792
|
+
# * options (Hash)
|
793
|
+
# ** :only (Hash) - pass page_layout names to :page_layout => [""] so only pages with this page_layout will be displayed inside the select.
|
794
|
+
# ** :except (Hash) - pass page_layout names to :page_layout => [""] so all pages except these with this page_layout will be displayed inside the select.
|
795
|
+
# ** :page_attribute (Symbol) - The Page attribute which will be stored.
|
796
|
+
# * select_options (Hash) - will be passed to the select_tag helper
|
797
|
+
def page_selector(element, content_name, options = {}, select_options = {})
|
798
|
+
default_options = {
|
799
|
+
:except => {
|
800
|
+
:page_layout => [""]
|
801
|
+
},
|
802
|
+
:only => {
|
803
|
+
:page_layout => [""]
|
804
|
+
},
|
805
|
+
:page_attribute => :urlname,
|
806
|
+
:prompt => _('Choose page')
|
807
|
+
}
|
808
|
+
options = default_options.merge(options)
|
809
|
+
content = element.content_by_name(content_name)
|
810
|
+
if content.nil?
|
811
|
+
return warning('Content', _('content_not_found'))
|
812
|
+
elsif content.essence.nil?
|
813
|
+
return warning('Content', _('content_essence_not_found'))
|
814
|
+
end
|
815
|
+
pages = Page.where({
|
816
|
+
:language_id => session[:language_id],
|
817
|
+
:page_layout => options[:only][:page_layout],
|
818
|
+
:public => true
|
819
|
+
})
|
820
|
+
select_tag(
|
821
|
+
"contents[content_#{content.id}][body]",
|
822
|
+
pages_for_select(pages, content.essence.body, options[:prompt], options[:page_attribute]),
|
823
|
+
select_options
|
824
|
+
)
|
825
|
+
end
|
826
|
+
|
827
|
+
# Returns an Array build for passing it to the options_for_select helper inside an essence editor partial.
|
828
|
+
# Usefull for the select_values options from the render_essence_editor helpers.
|
829
|
+
# Options:
|
830
|
+
# * :from_page (String, Page) - Return only elements from this page. You can either pass a Page instance, or a page_layout name
|
831
|
+
# * :elements_with_name (Array, String) - Return only elements with this name(s).
|
832
|
+
def elements_for_essence_editor_select(options={})
|
833
|
+
defaults = {
|
834
|
+
:from_page => nil,
|
835
|
+
:elements_with_name => nil,
|
836
|
+
:prompt => _('Please choose')
|
837
|
+
}
|
838
|
+
options = defaults.merge(options)
|
839
|
+
if options[:from_page]
|
840
|
+
page = options[:from_page].is_a?(String) ? Page.find_by_page_layout(options[:from_page]) : options[:from_page]
|
841
|
+
end
|
842
|
+
if page
|
843
|
+
elements = options[:elements_with_name].blank? ? page.elements.find_all_by_public(true) : page.elements.find_all_by_public_and_name(true, options[:elements_with_name])
|
844
|
+
else
|
845
|
+
elements = options[:elements_with_name].blank? ? Element.find_all_by_public(true) : Element.find_all_by_public_and_name(true, options[:elements_with_name])
|
846
|
+
end
|
847
|
+
select_options = [[options[:prompt], ""]]
|
848
|
+
elements.each do |e|
|
849
|
+
select_options << [e.display_name_with_preview_text, e.id.to_s]
|
850
|
+
end
|
851
|
+
select_options
|
852
|
+
end
|
853
|
+
|
854
|
+
# Returns all Pages found in the database as an array for the rails select_tag helper.
|
855
|
+
# You can pass a collection of pages to only returns these pages as array.
|
856
|
+
# Pass an Page.name or Page.id as second parameter to pass as selected for the options_for_select helper.
|
857
|
+
def pages_for_select(pages = nil, selected = nil, prompt = "", page_attribute = :id)
|
858
|
+
result = [[prompt.blank? ? _('Choose page') : prompt, ""]]
|
859
|
+
if pages.blank?
|
860
|
+
pages = Page.find_all_by_language_id_and_public(session[:language_id], true)
|
861
|
+
end
|
862
|
+
pages.each do |p|
|
863
|
+
result << [p.name, p.send(page_attribute).to_s]
|
864
|
+
end
|
865
|
+
options_for_select(result, selected.to_s)
|
866
|
+
end
|
867
|
+
|
868
|
+
# Returns all public elements found by Element.name.
|
869
|
+
# Pass a count to return only an limited amount of elements.
|
870
|
+
def all_elements_by_name(name, options = {})
|
871
|
+
warning('options[:language] option not allowed any more in all_elements_by_name helper') unless options[:language].blank?
|
872
|
+
default_options = {
|
873
|
+
:count => :all,
|
874
|
+
:from_page => :all
|
875
|
+
}
|
876
|
+
options = default_options.merge(options)
|
877
|
+
if options[:from_page] == :all
|
878
|
+
elements = Element.find_all_by_name_and_public(name, true, :limit => options[:count] == :all ? nil : options[:count])
|
879
|
+
elsif options[:from_page].class == String
|
880
|
+
page = Page.find_by_page_layout_and_language_id(options[:from_page], session[:language_id])
|
881
|
+
return [] if page.blank?
|
882
|
+
elements = page.elements.find_all_by_name_and_public(name, true, :limit => options[:count] == :all ? nil : options[:count])
|
883
|
+
else
|
884
|
+
elements = options[:from_page].elements.find_all_by_name_and_public(name, true, :limit => options[:count] == :all ? nil : options[:count])
|
885
|
+
end
|
886
|
+
end
|
887
|
+
|
888
|
+
# Returns the public element found by Element.name from the given public Page, either by Page.id or by Page.urlname
|
889
|
+
def element_from_page(options = {})
|
890
|
+
default_options = {
|
891
|
+
:page_urlname => "",
|
892
|
+
:page_id => nil,
|
893
|
+
:element_name => ""
|
894
|
+
}
|
895
|
+
options = default_options.merge(options)
|
896
|
+
if options[:page_id].blank?
|
897
|
+
page = Page.find_by_urlname_and_public(options[:page_urlname], true)
|
898
|
+
else
|
899
|
+
page = Page.find_by_id_and_public(options[:page_id], true)
|
900
|
+
end
|
901
|
+
return "" if page.blank?
|
902
|
+
element = page.elements.find_by_name_and_public(options[:element_name], true)
|
903
|
+
return element
|
904
|
+
end
|
905
|
+
|
906
|
+
# This helper renderes the picture editor for the elements on the Alchemy Desktop.
|
907
|
+
# It brings full functionality for adding images to the element, deleting images from it and sorting them via drag'n'drop.
|
908
|
+
# Just place this helper inside your element editor view, pass the element as parameter and that's it.
|
909
|
+
#
|
910
|
+
# Options:
|
911
|
+
# :maximum_amount_of_images (integer), default nil. This option let you handle the amount of images your customer can add to this element.
|
912
|
+
def render_picture_editor(element, options={})
|
913
|
+
default_options = {
|
914
|
+
:last_image_deletable => true,
|
915
|
+
:maximum_amount_of_images => nil,
|
916
|
+
:refresh_sortable => true
|
917
|
+
}
|
918
|
+
options = default_options.merge(options)
|
919
|
+
picture_contents = element.all_contents_by_type("EssencePicture")
|
920
|
+
render(
|
921
|
+
:partial => "admin/elements/picture_editor",
|
922
|
+
:locals => {
|
923
|
+
:picture_contents => picture_contents,
|
924
|
+
:element => element,
|
925
|
+
:options => options
|
926
|
+
}
|
927
|
+
)
|
928
|
+
end
|
929
|
+
|
930
|
+
def render_essence_selection_editor(element, content, select_options)
|
931
|
+
if content.class == String
|
932
|
+
content = element.contents.find_by_name(content)
|
933
|
+
else
|
934
|
+
content = element.contents[content - 1]
|
935
|
+
end
|
936
|
+
if content.essence.nil?
|
937
|
+
return warning('Element', _('content_essence_not_found'))
|
938
|
+
end
|
939
|
+
select_options = options_for_select(select_options, content.essence.content)
|
940
|
+
select_tag(
|
941
|
+
"contents[content_#{content.id}]",
|
942
|
+
select_options
|
943
|
+
)
|
944
|
+
end
|
945
|
+
|
946
|
+
# TOOD: include these via asset_packer yml file
|
947
|
+
def stylesheets_from_plugins
|
948
|
+
Dir.glob("vendor/plugins/*/assets/stylesheets/*.css").inject("") do |acc, s|
|
949
|
+
filename = File.basename(s)
|
950
|
+
plugin = s.split("/")[2]
|
951
|
+
acc << stylesheet_link_tag("#{plugin}/#{filename}")
|
952
|
+
end
|
953
|
+
end
|
954
|
+
|
955
|
+
# TOOD: include these via asset_packer yml file
|
956
|
+
def javascripts_from_plugins
|
957
|
+
Dir.glob("vendor/plugins/*/assets/javascripts/*.js").inject("") do |acc, s|
|
958
|
+
filename = File.basename(s)
|
959
|
+
plugin = s.split("/")[2]
|
960
|
+
acc << javascript_include_tag("#{plugin}/#{filename}")
|
961
|
+
end
|
962
|
+
end
|
963
|
+
|
964
|
+
def admin_main_navigation
|
965
|
+
navigation_entries = alchemy_plugins.collect{ |p| p["navigation"] }
|
966
|
+
render :partial => 'admin/partials/mainnavigation_entry', :collection => navigation_entries.flatten
|
967
|
+
end
|
968
|
+
|
969
|
+
# Renders the Subnavigation for the admin interface.
|
970
|
+
def render_admin_subnavigation(entries)
|
971
|
+
render :partial => "admin/partials/sub_navigation", :locals => {:entries => entries}
|
972
|
+
end
|
973
|
+
|
974
|
+
def admin_subnavigation
|
975
|
+
plugin = alchemy_plugin(:controller => params[:controller], :action => params[:action])
|
976
|
+
unless plugin.nil?
|
977
|
+
entries = plugin["navigation"]['sub_navigation']
|
978
|
+
render_admin_subnavigation(entries) unless entries.nil?
|
979
|
+
else
|
980
|
+
""
|
981
|
+
end
|
982
|
+
end
|
983
|
+
|
984
|
+
def admin_mainnavi_active?(mainnav)
|
985
|
+
subnavi = mainnav["sub_navigation"]
|
986
|
+
nested = mainnav["nested"]
|
987
|
+
if !subnavi.blank?
|
988
|
+
(!subnavi.detect{ |subnav| subnav["controller"] == params[:controller] && subnav["action"] == params[:action] }.blank?) ||
|
989
|
+
(!nested.nil? && !nested.detect{ |n| n["controller"] == params[:controller] && n["action"] == params[:action] }.blank?)
|
990
|
+
else
|
991
|
+
mainnav["controller"] == params[:controller] && mainnav["action"] == params["action"]
|
992
|
+
end
|
993
|
+
end
|
994
|
+
|
995
|
+
# Generates the url for the preview frame.
|
996
|
+
# target_url must contain target_controller and target_action.
|
997
|
+
def generate_preview_url(target_url)
|
998
|
+
preview_url = url_for(
|
999
|
+
:controller => ('/' + target_url["target_controller"]),
|
1000
|
+
:action => target_url["target_action"],
|
1001
|
+
:id => params[:id]
|
1002
|
+
)
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
# Returns a string for the id attribute of a html element for the given element
|
1006
|
+
def element_dom_id(element)
|
1007
|
+
return "" if element.nil?
|
1008
|
+
"#{element.name}_#{element.id}"
|
1009
|
+
end
|
1010
|
+
|
1011
|
+
# Returns a string for the id attribute of a html element for the given content
|
1012
|
+
def content_dom_id(content)
|
1013
|
+
return "" if content.nil?
|
1014
|
+
if content.class == String
|
1015
|
+
a = Content.find_by_name(content)
|
1016
|
+
return "" if a.nil?
|
1017
|
+
else
|
1018
|
+
a = content
|
1019
|
+
end
|
1020
|
+
"#{a.essence_type.underscore}_#{a.id}"
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
# Helper for including the nescessary javascripts and stylesheets for the different views.
|
1024
|
+
# Together with the rails caching we achieve a good load time.
|
1025
|
+
def alchemy_assets_set(setname = 'combined')
|
1026
|
+
asset_sets = YAML.load_file(File.join(File.dirname(__FILE__), '..', '..', 'config/asset_packages.yml'))
|
1027
|
+
content_for(:javascript_includes) do
|
1028
|
+
js_set = asset_sets['javascripts'].detect { |js| js[setname.to_s] }[setname.to_s]
|
1029
|
+
javascript_include_tag(js_set, :cache => 'alchemy/' + setname.to_s)
|
1030
|
+
end
|
1031
|
+
content_for(:stylesheets) do
|
1032
|
+
css_set = asset_sets['stylesheets'].detect { |css| css[setname.to_s] }[setname.to_s]
|
1033
|
+
stylesheet_link_tag(css_set, :cache => 'alchemy/' + setname.to_s)
|
1034
|
+
end
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
def parse_sitemap_name(page)
|
1038
|
+
if multi_language?
|
1039
|
+
pathname = "/#{session[:language_code]}/#{page.urlname}"
|
1040
|
+
else
|
1041
|
+
pathname = "/#{page.urlname}"
|
1042
|
+
end
|
1043
|
+
pathname
|
1044
|
+
end
|
1045
|
+
|
1046
|
+
def render_new_content_link(element)
|
1047
|
+
link_to_overlay_window(
|
1048
|
+
_('add new content'),
|
1049
|
+
new_admin_element_content_path(element),
|
1050
|
+
{
|
1051
|
+
:size => '305x40',
|
1052
|
+
:title => _('Select an content'),
|
1053
|
+
:overflow => true
|
1054
|
+
},
|
1055
|
+
{
|
1056
|
+
:id => "add_content_for_element_#{element.id}",
|
1057
|
+
:class => 'button new_content_link'
|
1058
|
+
}
|
1059
|
+
)
|
1060
|
+
end
|
1061
|
+
|
1062
|
+
def render_create_content_link(element, options = {})
|
1063
|
+
defaults = {
|
1064
|
+
:label => _('add new content')
|
1065
|
+
}
|
1066
|
+
options = defaults.merge(options)
|
1067
|
+
link_to(
|
1068
|
+
options[:label],
|
1069
|
+
admin_contents_path(
|
1070
|
+
:content => {
|
1071
|
+
:name => options[:content_name],
|
1072
|
+
:element_id => element.id
|
1073
|
+
}
|
1074
|
+
),
|
1075
|
+
:method => 'post',
|
1076
|
+
:remote => true,
|
1077
|
+
:id => "add_content_for_element_#{element.id}",
|
1078
|
+
:class => 'button new_content_link'
|
1079
|
+
)
|
1080
|
+
end
|
1081
|
+
|
1082
|
+
# Returns an icon
|
1083
|
+
def render_icon(icon_class)
|
1084
|
+
content_tag('span', '', :class => "icon #{icon_class}")
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
def alchemy_preview_mode_code
|
1088
|
+
javascript_include_tag("alchemy/alchemy.preview") if @preview_mode
|
1089
|
+
end
|
1090
|
+
|
1091
|
+
# Renders the data-alchemy-element HTML attribut used for the preview window hover effect.
|
1092
|
+
def element_preview_code(element)
|
1093
|
+
" data-alchemy-element='#{element.id}'" if @preview_mode && element.page == @page
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
# Logs a message in the Rails logger (warn level) and optionally displays an error message to the user.
|
1097
|
+
def warning(message, text = nil)
|
1098
|
+
logger.warn %(\n
|
1099
|
+
++++ WARNING: #{message}! from: #{caller.first}\n
|
1100
|
+
)
|
1101
|
+
unless text.nil?
|
1102
|
+
warning = content_tag('p', :class => 'content_editor_error') do
|
1103
|
+
render_icon('warning') + text
|
1104
|
+
end
|
1105
|
+
return warning
|
1106
|
+
end
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
def alchemy_combined_assets
|
1110
|
+
alchemy_assets_set
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
# This helper returns a path for use inside a link_to helper.
|
1114
|
+
# You may pass a page_layout or an urlname.
|
1115
|
+
# Any additional options are passed to the url_helper, so you can add arguments to your url.
|
1116
|
+
# Example:
|
1117
|
+
# <%= link_to '» order now', page_path_for(:page_layout => 'orderform', :product_id => element.id) %>
|
1118
|
+
def page_path_for(options={})
|
1119
|
+
return warning("No page_layout, or urlname given. I got #{options.inspect} ") if options[:page_layout].blank? && options[:urlname].blank?
|
1120
|
+
if options[:urlname].blank?
|
1121
|
+
page = Page.find_by_page_layout(options[:page_layout])
|
1122
|
+
return warning("No page found for #{options.inspect} ") if page.blank?
|
1123
|
+
urlname = page.urlname
|
1124
|
+
else
|
1125
|
+
urlname = options[:urlname]
|
1126
|
+
end
|
1127
|
+
if multi_language?
|
1128
|
+
show_page_with_language_path({:urlname => urlname, :lang => @language.code}.merge(options.except(:page_layout, :urlname)))
|
1129
|
+
else
|
1130
|
+
show_page_path({:urlname => urlname}.merge(options.except(:page_layout, :urlname)))
|
1131
|
+
end
|
1132
|
+
end
|
1133
|
+
|
1134
|
+
# Returns the current page.
|
1135
|
+
def current_page
|
1136
|
+
@page
|
1137
|
+
end
|
1138
|
+
|
1139
|
+
# Renders the partial for the cell with the given name of the current page.
|
1140
|
+
# Cell partials are located in +app/views/cells/+ of your project.
|
1141
|
+
def render_cell(name)
|
1142
|
+
cell = @page.cells.find_by_name(name)
|
1143
|
+
return "" if cell.blank?
|
1144
|
+
render :partial => "cells/#{name}", :locals => {:cell => cell}
|
1145
|
+
end
|
1146
|
+
|
1147
|
+
# Renders all element partials from given cell.
|
1148
|
+
def render_cell_elements(cell)
|
1149
|
+
return warning("No cell given.") if cell.blank?
|
1150
|
+
ret = ""
|
1151
|
+
cell.elements.each do |element|
|
1152
|
+
ret << render_element(element)
|
1153
|
+
end
|
1154
|
+
ret.html_safe
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
# Returns true or false if no elements are in the cell found by name.
|
1158
|
+
def cell_empty?(name)
|
1159
|
+
cell = @page.cells.find_by_name(name)
|
1160
|
+
return true if cell.blank?
|
1161
|
+
cell.elements.blank?
|
1162
|
+
end
|
1163
|
+
|
1164
|
+
def necessary_options_for_cropping_provided?(options)
|
1165
|
+
options[:crop].to_s == 'true' && !options[:image_size].blank?
|
1166
|
+
end
|
1167
|
+
|
1168
|
+
end
|