alchemy_cms 2.0.pre2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +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,17 @@
|
|
|
1
|
+
class EssenceFile < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
acts_as_essence(
|
|
4
|
+
:ingredient_column => :attachment,
|
|
5
|
+
:preview_text_method => :name
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
belongs_to :attachment
|
|
9
|
+
|
|
10
|
+
# Saves the ingredient
|
|
11
|
+
def save_ingredient(params, options = {})
|
|
12
|
+
return true if params.blank?
|
|
13
|
+
self.attachment_id = params["attachment_id"].to_s
|
|
14
|
+
self.save
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class EssenceFlash < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
acts_as_essence(
|
|
4
|
+
:ingredient_column => :attachment,
|
|
5
|
+
:preview_text_method => :name
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
# Saves the ingredient
|
|
9
|
+
def save_ingredient(params, options = {})
|
|
10
|
+
return true if params.blank?
|
|
11
|
+
self.attachment_id = params["attachment_id"].to_s
|
|
12
|
+
self.save
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class EssenceHtml < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
acts_as_essence(
|
|
4
|
+
:ingredient_column => :source
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
# Returns the first x (default = 30) (HTML escaped) characters from self.source for the Element#preview_text method.
|
|
8
|
+
def preview_text(maxlength = 30)
|
|
9
|
+
CGI.escapeHTML(source.to_s)[0..maxlength]
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Saves the ingredient
|
|
13
|
+
def save_ingredient(params, options = {})
|
|
14
|
+
return true if params.blank?
|
|
15
|
+
self.source = params["source"].to_s
|
|
16
|
+
self.save
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
class EssencePicture < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
acts_as_essence(
|
|
4
|
+
:ingredient_column => :picture,
|
|
5
|
+
:preview_text_method => :name
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
belongs_to :picture
|
|
9
|
+
before_save :replace_newlines
|
|
10
|
+
|
|
11
|
+
def replace_newlines
|
|
12
|
+
return nil if caption.nil?
|
|
13
|
+
caption.gsub!(/(\r\n|\r|\n)/, "<br/>")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Saves the ingredient
|
|
17
|
+
def save_ingredient(params, options = {})
|
|
18
|
+
return true if params.blank?
|
|
19
|
+
self.link_class_name = params['link_class_name']
|
|
20
|
+
self.link_target = params['link_target']
|
|
21
|
+
self.link = params['link']
|
|
22
|
+
self.link_title = params['link_title']
|
|
23
|
+
self.picture_id = params['picture_id']
|
|
24
|
+
self.save
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
class EssenceRichtext < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
acts_as_essence(
|
|
4
|
+
:preview_text_column => :stripped_body
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
acts_as_ferret(:fields => {:stripped_body => {:store => :yes}}, :remote => false) if Alchemy::Config.get(:ferret) == true
|
|
8
|
+
before_save :strip_content
|
|
9
|
+
before_save :check_ferret_indexing if Alchemy::Config.get(:ferret) == true
|
|
10
|
+
|
|
11
|
+
# Saves the ingredient
|
|
12
|
+
def save_ingredient(params, options = {})
|
|
13
|
+
return true if params.blank?
|
|
14
|
+
self.body = params['body'].to_s
|
|
15
|
+
self.public = options[:public]
|
|
16
|
+
self.save
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def strip_content
|
|
22
|
+
self.stripped_body = strip_tags(self.body)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def check_ferret_indexing
|
|
26
|
+
if self.do_not_index
|
|
27
|
+
self.disable_ferret(:always)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Stripping HTML Tags and only returns plain text.
|
|
32
|
+
def strip_tags(html)
|
|
33
|
+
return html if html.blank?
|
|
34
|
+
if html.index("<")
|
|
35
|
+
text = ""
|
|
36
|
+
tokenizer = HTML::Tokenizer.new(html)
|
|
37
|
+
while token = tokenizer.next
|
|
38
|
+
node = HTML::Node.parse(nil, 0, 0, token, false)
|
|
39
|
+
# result is only the content of any Text nodes
|
|
40
|
+
text << node.to_s if node.class == HTML::Text
|
|
41
|
+
end
|
|
42
|
+
# strip any comments, and if they have a newline at the end (ie. line with
|
|
43
|
+
# only a comment) strip that too
|
|
44
|
+
text.gsub(/<!--(.*?)-->[\n]?/m, "")
|
|
45
|
+
else
|
|
46
|
+
html # already plain text
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
class EssenceText < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
acts_as_essence
|
|
4
|
+
acts_as_ferret(:fields => {:body => {:store => :yes}}, :remote => false) if Alchemy::Config.get(:ferret) == true
|
|
5
|
+
|
|
6
|
+
before_save :check_ferret_indexing if Alchemy::Config.get(:ferret) == true
|
|
7
|
+
|
|
8
|
+
# Saves the content from params
|
|
9
|
+
def save_ingredient(params, options = {})
|
|
10
|
+
return true if params.blank?
|
|
11
|
+
self.body = params["body"]
|
|
12
|
+
self.link = params["link"]
|
|
13
|
+
self.link_title = params["link_title"]
|
|
14
|
+
self.link_class_name = params["link_class_name"]
|
|
15
|
+
self.link_target = params["link_target"]
|
|
16
|
+
self.public = options[:public]
|
|
17
|
+
self.save
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def check_ferret_indexing
|
|
23
|
+
if self.do_not_index
|
|
24
|
+
self.disable_ferret(:always)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class EssenceVideo < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
acts_as_essence(
|
|
4
|
+
:ingredient_column => :attachment,
|
|
5
|
+
:preview_text_method => :name
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
belongs_to :attachment
|
|
9
|
+
|
|
10
|
+
# Saves the ingredient
|
|
11
|
+
def save_ingredient(params, options = {})
|
|
12
|
+
return true if params.blank?
|
|
13
|
+
self.attachment_id = params["attachment_id"].to_s
|
|
14
|
+
self.save
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
class Language < ActiveRecord::Base
|
|
2
|
+
|
|
3
|
+
validates_presence_of :name
|
|
4
|
+
validates_presence_of :code
|
|
5
|
+
validates_presence_of :page_layout
|
|
6
|
+
validates_presence_of :frontpage_name
|
|
7
|
+
validates_uniqueness_of :code
|
|
8
|
+
validate :presence_of_default_language
|
|
9
|
+
validate :publicity_of_default_language
|
|
10
|
+
has_many :pages
|
|
11
|
+
after_destroy :delete_language_root_page
|
|
12
|
+
validates_format_of :code, :with => /^[a-z]{2}$/
|
|
13
|
+
before_destroy :check_for_default
|
|
14
|
+
after_update :set_pages_language, :if => proc { |m| m.code_changed? }
|
|
15
|
+
before_update :remove_old_default, :if => proc { |m| m.default_changed? && m != Language.get_default }
|
|
16
|
+
|
|
17
|
+
scope :published, where(:public => true)
|
|
18
|
+
|
|
19
|
+
def self.all_for_created_language_trees
|
|
20
|
+
find(Page.language_roots.collect(&:language_id))
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.all_codes_for_published
|
|
24
|
+
self.published.collect(&:code)
|
|
25
|
+
rescue
|
|
26
|
+
[]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.get_default
|
|
30
|
+
self.find_by_default(true)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def publicity_of_default_language
|
|
36
|
+
if self.default? && !self.public?
|
|
37
|
+
errors.add_to_base(N_("Defaut language has to be public"))
|
|
38
|
+
return false
|
|
39
|
+
else
|
|
40
|
+
return true
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def presence_of_default_language
|
|
45
|
+
if Language.get_default == self && self.default_changed?
|
|
46
|
+
errors.add_to_base(N_("we_need_at_least_one_default"))
|
|
47
|
+
return false
|
|
48
|
+
else
|
|
49
|
+
return true
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def remove_old_default
|
|
54
|
+
lang = Language.get_default
|
|
55
|
+
return true if lang.nil?
|
|
56
|
+
lang.default = false
|
|
57
|
+
lang.save(false)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def set_pages_language
|
|
61
|
+
pages.map { |page| page.language_code = self.code; page.save(false) }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def check_for_default
|
|
65
|
+
raise "Default language not deletable" if self.default?
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def delete_language_root_page
|
|
69
|
+
page = Page.language_root_for(id)
|
|
70
|
+
page.destroy if page
|
|
71
|
+
layoutroot = Page.layout_root_for(id)
|
|
72
|
+
layoutroot.destroy if layoutroot
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# This is a tableless model only used for validating Contactform Fields.
|
|
2
|
+
# You can specify the fields for your contactform in the config/alchemy/config.yml file in the :mailer options
|
|
3
|
+
#
|
|
4
|
+
# === Options:
|
|
5
|
+
#
|
|
6
|
+
# - form_layout_name: A Alchemy::PageLayout name (String). Used to render the contactform on a page with this layout.
|
|
7
|
+
#
|
|
8
|
+
# === Validating fields:
|
|
9
|
+
#
|
|
10
|
+
# Pass the field name as symbol and a message_id (will be translated) to :validate_fields:
|
|
11
|
+
#
|
|
12
|
+
# === Translating the validation messages:
|
|
13
|
+
#
|
|
14
|
+
# Validationmessages will be send to +I18n.t+ method with the scope +"alchemy.contactform.validations.#{field[1][:message].to_s}"+.
|
|
15
|
+
# So a +name+ field with the validation message_id +blank_name+ will be available for translation in your locale files like:
|
|
16
|
+
#
|
|
17
|
+
# de:
|
|
18
|
+
# contactform:
|
|
19
|
+
# validations:
|
|
20
|
+
# blank_name: 'Bitte geben Sie Ihren Namen an'
|
|
21
|
+
#
|
|
22
|
+
# === Example Contactform Configuration:
|
|
23
|
+
#
|
|
24
|
+
# :mailer:
|
|
25
|
+
# :form_layout_name: contact
|
|
26
|
+
# :fields: [subject, name, email, message, info]
|
|
27
|
+
# :validate_fields:
|
|
28
|
+
# :name:
|
|
29
|
+
# :message: blank_name
|
|
30
|
+
# :email:
|
|
31
|
+
# :message: blank_email
|
|
32
|
+
|
|
33
|
+
class Message
|
|
34
|
+
|
|
35
|
+
include ActiveModel::Validations
|
|
36
|
+
|
|
37
|
+
attr_accessor :contact_form_id, :ip
|
|
38
|
+
|
|
39
|
+
Alchemy::Config.get(:mailer)[:fields].each do |field|
|
|
40
|
+
attr_accessor field.keys.first.to_sym
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
validate_fields = Alchemy::Config.get(:mailer)[:validate_fields]
|
|
44
|
+
validate_fields.each do |field|
|
|
45
|
+
validates_presence_of field[0], :message => I18n.t("alchemy.contactform.validations.#{field[1][:message].to_s}")
|
|
46
|
+
if field[0].to_s.include?('email')
|
|
47
|
+
validates_format_of field[0], :with => Authlogic::Regex.email, :message => I18n.t('alchemy.contactform.validations.wrong_email_format'), :if => :email_is_filled
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def email_is_filled #:nodoc:
|
|
54
|
+
!email.blank?
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
data/app/models/page.rb
ADDED
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require 'awesome_nested_set'
|
|
4
|
+
|
|
5
|
+
class Page < ActiveRecord::Base
|
|
6
|
+
|
|
7
|
+
acts_as_nested_set
|
|
8
|
+
stampable
|
|
9
|
+
|
|
10
|
+
has_many :folded_pages
|
|
11
|
+
has_many :cells, :dependent => :destroy
|
|
12
|
+
has_many :elements, :dependent => :destroy, :order => :position
|
|
13
|
+
has_and_belongs_to_many :to_be_sweeped_elements, :class_name => 'Element', :uniq => true
|
|
14
|
+
belongs_to :language
|
|
15
|
+
|
|
16
|
+
validates_presence_of :name, :message => N_("please enter a name")
|
|
17
|
+
validates_presence_of :page_layout, :message => N_("Please choose a page layout.")
|
|
18
|
+
validates_length_of :urlname, :minimum => 3, :too_short => N_("urlname_to_short"), :if => :urlname_entered?
|
|
19
|
+
validates_uniqueness_of :urlname, :message => N_("URL-Name already token"), :scope => 'language_id', :if => :urlname_entered?
|
|
20
|
+
|
|
21
|
+
attr_accessor :do_not_autogenerate
|
|
22
|
+
attr_accessor :do_not_sweep
|
|
23
|
+
attr_accessor :do_not_validate_language
|
|
24
|
+
|
|
25
|
+
before_save :set_url_name, :unless => Proc.new { |page| page.redirects_to_external? }
|
|
26
|
+
before_save :set_title, :unless => Proc.new { |page| page.redirects_to_external? }
|
|
27
|
+
before_save :set_language_code
|
|
28
|
+
after_create :autogenerate_elements, :unless => Proc.new { |page| page.do_not_autogenerate }
|
|
29
|
+
after_create :create_cells
|
|
30
|
+
after_save :set_restrictions_to_child_pages
|
|
31
|
+
|
|
32
|
+
scope :language_roots, where(:language_root => true)
|
|
33
|
+
scope :layoutpages, where(:layoutpage => true)
|
|
34
|
+
scope :all_locked, where(:locked => true)
|
|
35
|
+
scope :visible, where(:visible => true)
|
|
36
|
+
scope :public, where(:public => true)
|
|
37
|
+
scope :accessable, where(:restricted => false)
|
|
38
|
+
scope :restricted, where(:restricted => true)
|
|
39
|
+
scope :public_language_roots, lambda {
|
|
40
|
+
where("language_root = 1 AND language_code IN ('#{Language.all_codes_for_published.join('\',\'')}') AND public = 1")
|
|
41
|
+
}
|
|
42
|
+
scope :all_last_edited_from, lambda { |user| where(:updater_id => user.id).order('updated_at DESC').limit(5) }
|
|
43
|
+
|
|
44
|
+
# Returns all pages for langugae that are not locked and public.
|
|
45
|
+
# Used for flushing all page caches at once.
|
|
46
|
+
scope :flushables, lambda { |language_id| where({:public => true, :locked => false, :language_id => language_id}) }
|
|
47
|
+
|
|
48
|
+
scope :contentpages, where("pages.layoutpage = 0 AND pages.parent_id IS NOT NULL")
|
|
49
|
+
|
|
50
|
+
# Finds selected elements from page either except a passed collection or only the passed collection
|
|
51
|
+
# Collection is an array of strings from element names. E.g.: ['text', 'headline']
|
|
52
|
+
# Returns only public ones
|
|
53
|
+
def find_selected_elements(options, show_non_public = false)
|
|
54
|
+
public_condition = show_non_public ? nil : ' AND elements.public = 1'
|
|
55
|
+
if !options[:except].blank?
|
|
56
|
+
condition = ["elements.name NOT IN (?)#{public_condition}", options[:except]]
|
|
57
|
+
elsif !options[:only].blank?
|
|
58
|
+
condition = ["elements.name IN (?)#{public_condition}", options[:only]]
|
|
59
|
+
else
|
|
60
|
+
condition = show_non_public.nil? ? nil : {:public => true}
|
|
61
|
+
end
|
|
62
|
+
elements = self.elements.where(condition).limit(options[:count]).offset(options[:offset])
|
|
63
|
+
elements.order("RAND()") unless options[:random].blank?
|
|
64
|
+
elements
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def find_elements(options, show_non_public = false)
|
|
68
|
+
if !options[:collection].blank? && options[:collection].is_a?(Array)
|
|
69
|
+
all_elements = options[:collection]
|
|
70
|
+
else
|
|
71
|
+
all_elements = find_selected_elements(options, show_non_public)
|
|
72
|
+
end
|
|
73
|
+
all_elements
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def elements_grouped_by_cells
|
|
77
|
+
group = ActiveSupport::OrderedHash.new
|
|
78
|
+
cells.each { |cell| group[cell] = cell.elements }
|
|
79
|
+
group[Cell.new({:name => 'for_other_elements'})] = elements.find_all_by_cell_id(nil)
|
|
80
|
+
return group
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Finds the previous page on the same structure level. Otherwise it returns nil.
|
|
84
|
+
# Options:
|
|
85
|
+
# => :restricted => boolean (standard: nil) - next restricted page (true), skip restricted pages (false), ignore restriction (nil)
|
|
86
|
+
# => :public => boolean (standard: true) - next public page (true), skip public pages (false)
|
|
87
|
+
def previous_page(options = {})
|
|
88
|
+
default_options = {
|
|
89
|
+
:restricted => nil,
|
|
90
|
+
:public => true
|
|
91
|
+
}
|
|
92
|
+
options = default_options.merge(options)
|
|
93
|
+
find_next_or_previous_page("previous", options)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Finds the next page on the same structure level. Otherwise it returns nil.
|
|
97
|
+
# Options:
|
|
98
|
+
# => :restricted => boolean (standard: nil) - next restricted page (true), skip restricted pages (false), ignore restriction (nil)
|
|
99
|
+
# => :public => boolean (standard: true) - next public page (true), skip public pages (false)
|
|
100
|
+
def next_page(options = {})
|
|
101
|
+
default_options = {
|
|
102
|
+
:restricted => nil,
|
|
103
|
+
:public => true
|
|
104
|
+
}
|
|
105
|
+
options = default_options.merge(options)
|
|
106
|
+
find_next_or_previous_page("next", options)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def find_first_public(page)
|
|
110
|
+
if(page.public == true)
|
|
111
|
+
return page
|
|
112
|
+
end
|
|
113
|
+
page.children.each do |child|
|
|
114
|
+
result = find_first_public(child)
|
|
115
|
+
if(result!=nil)
|
|
116
|
+
return result
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
return nil
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def name_entered?
|
|
123
|
+
!self.name.blank?
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def urlname_entered?
|
|
127
|
+
!self.urlname.blank?
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def set_url_name
|
|
131
|
+
self.urlname = generate_url_name((self.urlname.blank? ? self.name : self.urlname))
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def set_title
|
|
135
|
+
self.title = self.name
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def show_in_navigation?
|
|
139
|
+
if visible?
|
|
140
|
+
return true
|
|
141
|
+
end
|
|
142
|
+
return false
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def lock(user)
|
|
146
|
+
self.locked = true
|
|
147
|
+
self.locked_by = user.id
|
|
148
|
+
self.save(false)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def unlock
|
|
152
|
+
self.locked = false
|
|
153
|
+
self.locked_by = nil
|
|
154
|
+
self.do_not_sweep = true
|
|
155
|
+
self.save
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def public_elements
|
|
159
|
+
self.elements.select{ |m| m.public? }
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Returns the name of the creator of this page.
|
|
163
|
+
def creator
|
|
164
|
+
@page_creator ||= User.find_by_id(creator_id)
|
|
165
|
+
return _('unknown') if @page_creator.nil?
|
|
166
|
+
@page_creator.name
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Returns the name of the last updater of this page.
|
|
170
|
+
def updater
|
|
171
|
+
@page_updater = User.find_by_id(updater_id)
|
|
172
|
+
return _('unknown') if @page_updater.nil?
|
|
173
|
+
@page_updater.name
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
# Returns the name of the user currently editing this page.
|
|
177
|
+
def current_editor
|
|
178
|
+
@current_editor = User.find_by_id(locked_by)
|
|
179
|
+
return _('unknown') if @current_editor.nil?
|
|
180
|
+
@current_editor.name
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def locker
|
|
184
|
+
User.find_by_id(self.locked_by)
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def fold(user_id, status)
|
|
188
|
+
folded_page = FoldedPage.find_or_create_by_user_id_and_page_id(user_id, self.id)
|
|
189
|
+
folded_page.update_attributes(:folded => status)
|
|
190
|
+
folded_page.save
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def folded?(user_id)
|
|
194
|
+
folded_page = FoldedPage.find_by_user_id_and_page_id(user_id, self.id)
|
|
195
|
+
return false if folded_page.nil?
|
|
196
|
+
folded_page.folded
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def elements_by_type type
|
|
200
|
+
elements.select{|m| type.include? m.name}
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
# Returns the translated explanation of seven the page stati.
|
|
204
|
+
def humanized_status
|
|
205
|
+
case self.status
|
|
206
|
+
when 0
|
|
207
|
+
then
|
|
208
|
+
return _('page_status_visible_public_locked')
|
|
209
|
+
when 1
|
|
210
|
+
then
|
|
211
|
+
return _('page_status_visible_unpublic_locked')
|
|
212
|
+
when 2
|
|
213
|
+
then
|
|
214
|
+
return _('page_status_invisible_public_locked')
|
|
215
|
+
when 3
|
|
216
|
+
then
|
|
217
|
+
return _('page_status_invisible_unpublic_locked')
|
|
218
|
+
when 4
|
|
219
|
+
then
|
|
220
|
+
return _('page_status_visible_public')
|
|
221
|
+
when 5
|
|
222
|
+
then
|
|
223
|
+
return _('page_status_visible_unpublic')
|
|
224
|
+
when 6
|
|
225
|
+
then
|
|
226
|
+
return _('page_status_invisible_public')
|
|
227
|
+
when 7
|
|
228
|
+
then
|
|
229
|
+
return _('page_status_invisible_unpublic')
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
# Returns the status code. Used by humanized_status and the page status icon inside the sitemap rendered by Pages.index.
|
|
234
|
+
def status
|
|
235
|
+
if self.locked
|
|
236
|
+
if self.public? && self.visible?
|
|
237
|
+
return 0
|
|
238
|
+
elsif !self.public? && self.visible?
|
|
239
|
+
return 1
|
|
240
|
+
elsif self.public? && !self.visible?
|
|
241
|
+
return 2
|
|
242
|
+
elsif !self.public? && !self.visible?
|
|
243
|
+
return 3
|
|
244
|
+
end
|
|
245
|
+
else
|
|
246
|
+
if self.public? && self.visible?
|
|
247
|
+
return 4
|
|
248
|
+
elsif !self.public? && self.visible?
|
|
249
|
+
return 5
|
|
250
|
+
elsif self.public? && !self.visible?
|
|
251
|
+
return 6
|
|
252
|
+
elsif !self.public? && !self.visible?
|
|
253
|
+
return 7
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
def has_controller?
|
|
259
|
+
!Alchemy::PageLayout.get(self.page_layout).nil? && !Alchemy::PageLayout.get(self.page_layout)["controller"].blank?
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def controller_and_action
|
|
263
|
+
if self.has_controller?
|
|
264
|
+
{:controller => self.layout_description["controller"], :action => self.layout_description["action"]}
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
# Returns the self#page_layout description from config/alchemy/page_layouts.yml file.
|
|
269
|
+
def layout_description
|
|
270
|
+
page_layout = Alchemy::PageLayout.get(self.page_layout)
|
|
271
|
+
if page_layout.nil?
|
|
272
|
+
logger.warn("\n+++++++++++ Warning! Alchemy::PageLayout description not found for layout: #{self.page_layout}\n")
|
|
273
|
+
return nil
|
|
274
|
+
else
|
|
275
|
+
return page_layout
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
alias_method :definition, :layout_description
|
|
279
|
+
|
|
280
|
+
# Returns translated name of the pages page_layout value.
|
|
281
|
+
# Page layout names are defined inside the config/alchemy/page_layouts.yml file.
|
|
282
|
+
# Translate the name in your config/locales language yml file.
|
|
283
|
+
def layout_display_name
|
|
284
|
+
I18n.t("alchemy.page_layout_names.#{page_layout}", :default => page_layout.camelize)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def renamed?
|
|
288
|
+
self.name_was != self.name || self.urlname_was != self.urlname
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def changed_publicity?
|
|
292
|
+
self.public_was != self.public
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def set_restrictions_to_child_pages
|
|
296
|
+
return nil if self.restricted_was == self.restricted
|
|
297
|
+
descendants.each do |child|
|
|
298
|
+
child.restricted = restricted
|
|
299
|
+
child.save
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def contains_feed?
|
|
304
|
+
desc = self.layout_description
|
|
305
|
+
return false if desc.blank?
|
|
306
|
+
desc["feed"]
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# Returns true or false if the pages layout_description for config/alchemy/page_layouts.yml contains redirects_to_external: true
|
|
310
|
+
def redirects_to_external?
|
|
311
|
+
desc = self.layout_description
|
|
312
|
+
return false if desc.blank?
|
|
313
|
+
desc["redirects_to_external"]
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# Returns an array of all pages currently locked by user
|
|
317
|
+
def self.all_locked_by(user)
|
|
318
|
+
find_all_by_locked_and_locked_by(true, user.id)
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def first_public_child
|
|
322
|
+
self.children.where(:public => true).limit(1)
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
def self.language_root_for(language_id)
|
|
326
|
+
self.language_roots.find_by_language_id(language_id)
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
# Creates a copy of source (an Page object) and does a copy of all elements depending to source.
|
|
330
|
+
# You can pass any kind of Page#attributes as a difference to source.
|
|
331
|
+
# Notice: It prevents the element auto_generator from running.
|
|
332
|
+
def self.copy(source, differences = {})
|
|
333
|
+
attributes = source.attributes.symbolize_keys.merge(differences)
|
|
334
|
+
attributes.merge!(
|
|
335
|
+
:do_not_autogenerate => true,
|
|
336
|
+
:do_not_sweep => true,
|
|
337
|
+
:visible => false,
|
|
338
|
+
:public => false,
|
|
339
|
+
:locked => false,
|
|
340
|
+
:locked_by => nil
|
|
341
|
+
)
|
|
342
|
+
page = self.new(attributes.except(["id", "updated_at", "created_at", "created_id", "updater_id"]))
|
|
343
|
+
if page.save
|
|
344
|
+
source.elements.each do |element|
|
|
345
|
+
new_element = Element.copy(element, :page_id => page.id)
|
|
346
|
+
new_element.move_to_bottom
|
|
347
|
+
end
|
|
348
|
+
return page
|
|
349
|
+
else
|
|
350
|
+
raise page.errors.full_messages
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
# Gets the language_root page for page
|
|
355
|
+
def get_language_root
|
|
356
|
+
return self if self.language_root
|
|
357
|
+
page = self
|
|
358
|
+
while page.parent do
|
|
359
|
+
page = page.parent
|
|
360
|
+
break if page.language_root?
|
|
361
|
+
end
|
|
362
|
+
return page
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
def self.layout_root_for(language_id)
|
|
366
|
+
where({:parent_id => Page.root.id, :layoutpage => true, :language_id => language_id}).limit(1).first
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
def self.find_or_create_layout_root_for(language_id)
|
|
370
|
+
layoutroot = layout_root_for(language_id)
|
|
371
|
+
return layoutroot if layoutroot
|
|
372
|
+
language = Language.find(language_id)
|
|
373
|
+
layoutroot = Page.new({
|
|
374
|
+
:name => "Layoutroot for #{language.name}",
|
|
375
|
+
:layoutpage => true,
|
|
376
|
+
:language => language,
|
|
377
|
+
:do_not_autogenerate => true
|
|
378
|
+
})
|
|
379
|
+
if layoutroot.save(false)
|
|
380
|
+
layoutroot.move_to_child_of(Page.root)
|
|
381
|
+
return layoutroot
|
|
382
|
+
else
|
|
383
|
+
raise "Layout root for #{language.name} could not be created"
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
def self.all_from_clipboard(clipboard)
|
|
388
|
+
return [] if clipboard.blank?
|
|
389
|
+
self.find_all_by_id(clipboard)
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
def self.all_from_clipboard_for_select(clipboard, language_id, layoutpage = false)
|
|
393
|
+
return [] if clipboard.blank?
|
|
394
|
+
clipboard_pages = self.all_from_clipboard(clipboard)
|
|
395
|
+
allowed_page_layouts = Alchemy::PageLayout.selectable_layouts(language_id, layoutpage)
|
|
396
|
+
allowed_page_layout_names = allowed_page_layouts.collect{ |p| p['name'] }
|
|
397
|
+
clipboard_pages.select { |cp| allowed_page_layout_names.include?(cp.page_layout) }
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def copy_children_to(new_parent)
|
|
401
|
+
self.children.each do |child|
|
|
402
|
+
next if child == new_parent
|
|
403
|
+
new_child = Page.copy(child, {
|
|
404
|
+
:language_id => new_parent.language_id,
|
|
405
|
+
:language_code => new_parent.language_code,
|
|
406
|
+
:name => child.name + ' (' + _('Copy') + ')',
|
|
407
|
+
:urlname => '',
|
|
408
|
+
:title => ''
|
|
409
|
+
})
|
|
410
|
+
new_child.move_to_child_of(new_parent)
|
|
411
|
+
child.copy_children_to(new_child) unless child.children.blank?
|
|
412
|
+
end
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
# Returns true or false if the page has a page_layout that has cells.
|
|
416
|
+
def has_cells?
|
|
417
|
+
pagelayout = Alchemy::PageLayout.get(self.page_layout)
|
|
418
|
+
return false if pagelayout.blank?
|
|
419
|
+
!pagelayout['cells'].blank?
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
def self.link_target_options
|
|
423
|
+
options = [
|
|
424
|
+
[I18n.t('default', :scope => 'alchemy.link_target_options'), '']
|
|
425
|
+
]
|
|
426
|
+
link_target_options = Alchemy::Config.get(:link_target_options)
|
|
427
|
+
link_target_options.each do |option|
|
|
428
|
+
options << [I18n.t(option, :scope => 'alchemy.link_target_options'), option]
|
|
429
|
+
end
|
|
430
|
+
options
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
def locker_name
|
|
434
|
+
return N_('unknown') if self.locker.nil?
|
|
435
|
+
self.locker.name
|
|
436
|
+
end
|
|
437
|
+
|
|
438
|
+
private
|
|
439
|
+
|
|
440
|
+
def find_next_or_previous_page(direction = "next", options = {})
|
|
441
|
+
if direction == "previous"
|
|
442
|
+
step_direction = ["pages.lft < ?", self.lft]
|
|
443
|
+
order_direction = "lft DESC"
|
|
444
|
+
else
|
|
445
|
+
step_direction = ["pages.lft > ?", self.lft]
|
|
446
|
+
order_direction = "lft"
|
|
447
|
+
end
|
|
448
|
+
conditions = Page.merge_conditions(
|
|
449
|
+
{:parent_id => self.parent_id},
|
|
450
|
+
{:public => options[:public]},
|
|
451
|
+
step_direction
|
|
452
|
+
)
|
|
453
|
+
if !options[:restricted].nil?
|
|
454
|
+
conditions = Page.merge_conditions(conditions, {:restricted => options[:restricted]})
|
|
455
|
+
end
|
|
456
|
+
return Page.where(conditions).order(order_direction).limit(1)
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
def generate_url_name(url_name)
|
|
460
|
+
new_url_name = url_name.to_s.downcase
|
|
461
|
+
new_url_name = new_url_name.gsub(/[ä]/, 'ae')
|
|
462
|
+
new_url_name = new_url_name.gsub(/[ü]/, 'ue')
|
|
463
|
+
new_url_name = new_url_name.gsub(/[ö]/, 'oe')
|
|
464
|
+
new_url_name = new_url_name.gsub(/[Ä]/, 'AE')
|
|
465
|
+
new_url_name = new_url_name.gsub(/[Ü]/, 'UE')
|
|
466
|
+
new_url_name = new_url_name.gsub(/[Ö]/, 'OE')
|
|
467
|
+
new_url_name = new_url_name.gsub(/[ß]/, 'ss')
|
|
468
|
+
new_url_name = new_url_name.gsub(/[^a-zA-Z0-9_]+/, '-')
|
|
469
|
+
if(new_url_name.length < 3)
|
|
470
|
+
new_url_name = "-#{new_url_name}-"
|
|
471
|
+
else
|
|
472
|
+
new_url_name.gsub(/-+$/, '')
|
|
473
|
+
end
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
# Looks in the layout_descripion, if there are elements to autogenerate.
|
|
477
|
+
# If so, it generates them.
|
|
478
|
+
def autogenerate_elements
|
|
479
|
+
return true if self.layout_description.blank?
|
|
480
|
+
elements = self.layout_description["autogenerate"]
|
|
481
|
+
unless (elements.blank?)
|
|
482
|
+
elements.each do |element|
|
|
483
|
+
element = Element.create_from_scratch({'page_id' => self.id, 'name' => element})
|
|
484
|
+
element.move_to_bottom if element
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
def set_language_code
|
|
490
|
+
return false if self.language.blank?
|
|
491
|
+
self.language_code = self.language.code
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
def create_cells
|
|
495
|
+
return true if !has_cells?
|
|
496
|
+
definition['cells'].each do |cellname|
|
|
497
|
+
cells.create({:name => cellname})
|
|
498
|
+
end
|
|
499
|
+
end
|
|
500
|
+
|
|
501
|
+
end
|