alchemy_cms 2.0.rc3 → 2.0.rc4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (219) hide show
  1. data/.gitignore +3 -1
  2. data/.rspec +1 -2
  3. data/.travis.yml +11 -0
  4. data/.yardopts +0 -1
  5. data/Gemfile +1 -2
  6. data/README.md +14 -0
  7. data/alchemy_cms.gemspec +4 -2
  8. data/app/controllers/admin/clipboard_controller.rb +8 -9
  9. data/app/controllers/admin/contents_controller.rb +4 -2
  10. data/app/controllers/admin/essence_pictures_controller.rb +2 -2
  11. data/app/controllers/admin/layoutpages_controller.rb +2 -0
  12. data/app/controllers/admin/pages_controller.rb +5 -5
  13. data/app/controllers/admin/pictures_controller.rb +2 -1
  14. data/app/controllers/admin/trash_controller.rb +2 -0
  15. data/app/controllers/alchemy_controller.rb +10 -4
  16. data/app/controllers/elements_controller.rb +1 -1
  17. data/app/helpers/admin/elements_helper.rb +32 -1
  18. data/app/helpers/alchemy_helper.rb +15 -818
  19. data/app/helpers/contents_helper.rb +69 -0
  20. data/app/helpers/elements_helper.rb +161 -0
  21. data/app/helpers/essences_helper.rb +167 -0
  22. data/app/helpers/pages_helper.rb +401 -19
  23. data/app/models/attachment.rb +4 -0
  24. data/app/models/element.rb +27 -14
  25. data/app/models/page.rb +75 -38
  26. data/app/views/admin/essence_pictures/destroy.js.erb +1 -1
  27. data/app/views/admin/pages/_create_language_form.html.erb +2 -1
  28. data/app/views/admin/pages/new.html.erb +1 -1
  29. data/app/views/admin/pages/update.js.erb +1 -1
  30. data/app/views/admin/partials/_upload_form.html.erb +2 -2
  31. data/app/views/admin/pictures/index.html.erb +7 -4
  32. data/app/views/essences/_essence_picture_editor.html.erb +1 -3
  33. data/app/views/layouts/alchemy.html.erb +59 -59
  34. data/app/views/layouts/pages.html.erb +2 -4
  35. data/app/views/{partials/_navigation_image_link.html.erb → navigation/_image_link.html.erb} +0 -0
  36. data/app/views/{partials/_navigation_link.html.erb → navigation/_link.html.erb} +1 -1
  37. data/app/views/{partials/_navigation_renderer.html.erb → navigation/_renderer.html.erb} +0 -0
  38. data/app/views/page_layouts/_contact.html.erb +1 -1
  39. data/app/views/page_layouts/_external.html.erb +0 -1
  40. data/app/views/page_layouts/_intro.html.erb +1 -1
  41. data/app/views/page_layouts/_news.html.erb +1 -1
  42. data/app/views/page_layouts/_search.html.erb +1 -1
  43. data/app/views/page_layouts/_standard.html.erb +1 -1
  44. data/assets/images/icons.png +0 -0
  45. data/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/alchemy/window.css +49 -31
  46. data/assets/stylesheets/alchemy.css +111 -91
  47. data/assets/stylesheets/elements.css +12 -16
  48. data/bin/alchemy +1 -1
  49. data/config/alchemy/config.yml +4 -0
  50. data/config/initializers/tinymce_hammer.rb +1 -0
  51. data/config/locales/de.yml +3 -1
  52. data/config/locales/en.yml +2 -0
  53. data/config/routes.rb +6 -4
  54. data/lib/alchemy/capistrano.rb +4 -7
  55. data/lib/alchemy/page_layout.rb +12 -8
  56. data/lib/alchemy/version.rb +1 -1
  57. data/spec/controllers/admin/clipboard_controller_spec.rb +23 -0
  58. data/spec/dummy/db/schema.rb +9 -9
  59. data/spec/factories.rb +24 -6
  60. data/spec/helpers/admin/elements_helper_spec.rb +20 -0
  61. data/spec/helpers/alchemy_helper_spec.rb +41 -0
  62. data/spec/helpers/contents_helper_spec.rb +27 -0
  63. data/spec/helpers/elements_helper_spec.rb +39 -0
  64. data/spec/helpers/essences_helper_spec.rb +49 -0
  65. data/spec/helpers/pages_helper_spec.rb +140 -0
  66. data/spec/integration/security_spec.rb +1 -1
  67. data/spec/integration/standardset_spec.rb +29 -0
  68. data/spec/models/element_spec.rb +49 -0
  69. data/spec/{language_spec.rb → models/language_spec.rb} +0 -0
  70. data/spec/models/page_spec.rb +139 -0
  71. data/spec/{user_spec.rb → models/user_spec.rb} +0 -0
  72. data/spec/page_layout_spec.rb +21 -0
  73. data/spec/routing_spec.rb +53 -0
  74. data/spec/spec_helper.rb +12 -11
  75. metadata +54 -303
  76. data/spec/dummy/config/alchemy/config.yml +0 -199
  77. data/spec/dummy/config/alchemy/elements.yml +0 -91
  78. data/spec/dummy/config/alchemy/page_layouts.yml +0 -29
  79. data/spec/dummy/public/images/alchemy/ajax_loader.gif +0 -0
  80. data/spec/dummy/public/images/alchemy/alchemy-logo.png +0 -0
  81. data/spec/dummy/public/images/alchemy/flags.png +0 -0
  82. data/spec/dummy/public/images/alchemy/gui/navi-tab.png +0 -0
  83. data/spec/dummy/public/images/alchemy/gui/shading.png +0 -0
  84. data/spec/dummy/public/images/alchemy/gui/shading_90.png +0 -0
  85. data/spec/dummy/public/images/alchemy/gui/toggle.png +0 -0
  86. data/spec/dummy/public/images/alchemy/icons.png +0 -0
  87. data/spec/dummy/public/images/alchemy/jquery-sb/select_arrow.gif +0 -0
  88. data/spec/dummy/public/images/alchemy/jquery-sb/select_arrow_bg.gif +0 -0
  89. data/spec/dummy/public/images/alchemy/jquery-sb/select_arrow_bg_hover.gif +0 -0
  90. data/spec/dummy/public/images/alchemy/jquery-ui/ui-icons_666666_256x240.png +0 -0
  91. data/spec/dummy/public/images/alchemy/placeholder.png +0 -0
  92. data/spec/dummy/public/images/alchemy/swfupload/browse_button.png +0 -0
  93. data/spec/dummy/public/javascripts/alchemy/alchemy.element_editor_selector.js +0 -88
  94. data/spec/dummy/public/javascripts/alchemy/alchemy.growler.js +0 -44
  95. data/spec/dummy/public/javascripts/alchemy/alchemy.image_cropper.js +0 -56
  96. data/spec/dummy/public/javascripts/alchemy/alchemy.js +0 -892
  97. data/spec/dummy/public/javascripts/alchemy/alchemy.link_overlay.js +0 -221
  98. data/spec/dummy/public/javascripts/alchemy/alchemy.page_sorter.js +0 -42
  99. data/spec/dummy/public/javascripts/alchemy/alchemy.preview.js +0 -145
  100. data/spec/dummy/public/javascripts/alchemy/jquery-ui.js +0 -428
  101. data/spec/dummy/public/javascripts/alchemy/jquery.Jcrop.min.js +0 -246
  102. data/spec/dummy/public/javascripts/alchemy/jquery.dialogextend.min.js +0 -8
  103. data/spec/dummy/public/javascripts/alchemy/jquery.in-place-edit.js +0 -171
  104. data/spec/dummy/public/javascripts/alchemy/jquery.js +0 -18
  105. data/spec/dummy/public/javascripts/alchemy/jquery.rails.js +0 -315
  106. data/spec/dummy/public/javascripts/alchemy/jquery.sb.min.js +0 -14
  107. data/spec/dummy/public/javascripts/alchemy/jquery.scrollTo-1.4.2-min.js +0 -11
  108. data/spec/dummy/public/javascripts/alchemy/jquery.ui.nestedSortable.js +0 -291
  109. data/spec/dummy/public/javascripts/alchemy/jquery.ui.tabspaging.js +0 -281
  110. data/spec/dummy/public/javascripts/alchemy/swfupload/fileprogress.js +0 -203
  111. data/spec/dummy/public/javascripts/alchemy/swfupload/handlers.js +0 -171
  112. data/spec/dummy/public/javascripts/alchemy/swfupload/queue.js +0 -98
  113. data/spec/dummy/public/javascripts/alchemy/swfupload/swfupload.js +0 -980
  114. data/spec/dummy/public/javascripts/alchemy/swfupload/swfupload.swf +0 -0
  115. data/spec/dummy/public/javascripts/alchemy/tiny_mce/jquery.tinymce.js +0 -1
  116. data/spec/dummy/public/javascripts/alchemy/tiny_mce/langs/de.js +0 -1
  117. data/spec/dummy/public/javascripts/alchemy/tiny_mce/langs/en.js +0 -223
  118. data/spec/dummy/public/javascripts/alchemy/tiny_mce/license.txt +0 -504
  119. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/alchemy_link/editor_plugin.js +0 -43
  120. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/alchemy_link/langs/de.js +0 -4
  121. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/alchemy_link/langs/en.js +0 -4
  122. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/fullscreen/editor_plugin.js +0 -1
  123. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/fullscreen/fullscreen.htm +0 -109
  124. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/inlinepopups/editor_plugin.js +0 -1
  125. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/inlinepopups/skins/alchemy/window.css +0 -402
  126. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/inlinepopups/template.htm +0 -387
  127. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/lists/editor_plugin.js +0 -1
  128. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/paste/editor_plugin.js +0 -1
  129. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/paste/js/pastetext.js +0 -36
  130. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/paste/js/pasteword.js +0 -51
  131. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/paste/langs/de_dlg.js +0 -1
  132. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/paste/langs/en_dlg.js +0 -5
  133. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/paste/pastetext.htm +0 -27
  134. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/paste/pasteword.htm +0 -21
  135. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/cell.htm +0 -180
  136. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/css/cell.css +0 -17
  137. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/css/row.css +0 -25
  138. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/css/table.css +0 -13
  139. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/editor_plugin.js +0 -1
  140. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/js/cell.js +0 -319
  141. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/js/merge_cells.js +0 -27
  142. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/js/row.js +0 -237
  143. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/js/table.js +0 -450
  144. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/langs/de_dlg.js +0 -1
  145. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/langs/en_dlg.js +0 -75
  146. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/merge_cells.htm +0 -32
  147. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/row.htm +0 -158
  148. data/spec/dummy/public/javascripts/alchemy/tiny_mce/plugins/table/table.htm +0 -188
  149. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/about.htm +0 -52
  150. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/anchor.htm +0 -26
  151. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/charmap.htm +0 -51
  152. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/color_picker.htm +0 -74
  153. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/editor_template.js +0 -1
  154. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/image.htm +0 -80
  155. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/img/colorpicker.jpg +0 -0
  156. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/img/flash.gif +0 -0
  157. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/img/icons.gif +0 -0
  158. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/img/iframe.gif +0 -0
  159. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/img/pagebreak.gif +0 -0
  160. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/img/quicktime.gif +0 -0
  161. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/img/realmedia.gif +0 -0
  162. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/img/shockwave.gif +0 -0
  163. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/img/trans.gif +0 -0
  164. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/img/video.gif +0 -0
  165. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/img/windowsmedia.gif +0 -0
  166. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/js/about.js +0 -73
  167. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/js/anchor.js +0 -42
  168. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/js/charmap.js +0 -355
  169. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/js/color_picker.js +0 -329
  170. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/js/image.js +0 -247
  171. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/js/link.js +0 -153
  172. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/js/source_editor.js +0 -56
  173. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/langs/de.js +0 -1
  174. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/langs/de_dlg.js +0 -1
  175. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/langs/en.js +0 -68
  176. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/langs/en_dlg.js +0 -54
  177. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/link.htm +0 -57
  178. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/shortcuts.htm +0 -47
  179. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/default/content.css +0 -47
  180. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/default/dialog.css +0 -117
  181. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/default/img/buttons.png +0 -0
  182. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/default/img/items.gif +0 -0
  183. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/default/img/menu_arrow.gif +0 -0
  184. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/default/img/menu_check.gif +0 -0
  185. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/default/img/progress.gif +0 -0
  186. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/default/img/tabs.gif +0 -0
  187. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/default/ui.css +0 -214
  188. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/highcontrast/content.css +0 -23
  189. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/highcontrast/dialog.css +0 -105
  190. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/highcontrast/ui.css +0 -102
  191. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/o2k7/content.css +0 -46
  192. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/o2k7/dialog.css +0 -117
  193. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/o2k7/img/button_bg.png +0 -0
  194. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/o2k7/img/button_bg_black.png +0 -0
  195. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/o2k7/img/button_bg_silver.png +0 -0
  196. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/o2k7/ui.css +0 -217
  197. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/o2k7/ui_black.css +0 -8
  198. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/skins/o2k7/ui_silver.css +0 -5
  199. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/advanced/source_editor.htm +0 -25
  200. data/spec/dummy/public/javascripts/alchemy/tiny_mce/themes/simple/langs/de.js +0 -1
  201. data/spec/dummy/public/javascripts/alchemy/tiny_mce/tiny_mce.js +0 -1
  202. data/spec/dummy/public/javascripts/alchemy/tiny_mce/tiny_mce_popup.js +0 -5
  203. data/spec/dummy/public/javascripts/alchemy/tiny_mce/utils/editable_selects.js +0 -70
  204. data/spec/dummy/public/javascripts/alchemy/tiny_mce/utils/form_utils.js +0 -210
  205. data/spec/dummy/public/javascripts/alchemy/tiny_mce/utils/mctabs.js +0 -162
  206. data/spec/dummy/public/javascripts/alchemy/tiny_mce/utils/validate.js +0 -252
  207. data/spec/dummy/public/stylesheets/alchemy/Jcrop.gif +0 -0
  208. data/spec/dummy/public/stylesheets/alchemy/alchemy.css +0 -3653
  209. data/spec/dummy/public/stylesheets/alchemy/alchemy_tinymce_content.css +0 -94
  210. data/spec/dummy/public/stylesheets/alchemy/alchemy_tinymce_dialog.css +0 -415
  211. data/spec/dummy/public/stylesheets/alchemy/default/img/tabs.gif +0 -0
  212. data/spec/dummy/public/stylesheets/alchemy/elements.css +0 -900
  213. data/spec/dummy/public/stylesheets/alchemy/flags.css +0 -1
  214. data/spec/dummy/public/stylesheets/alchemy/ie6.css +0 -18
  215. data/spec/dummy/public/stylesheets/alchemy/jquery-ui-1.8.7.alchemy.css +0 -2023
  216. data/spec/dummy/public/stylesheets/alchemy/jquery.Jcrop.css +0 -35
  217. data/spec/dummy/public/stylesheets/alchemy/jquery.sb.css +0 -244
  218. data/spec/dummy/public/stylesheets/alchemy/standard_set.css +0 -374
  219. data/spec/page_spec.rb +0 -50
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ .idea
1
2
  .yardoc
2
3
  .DS_Store
3
4
  .svn
@@ -8,4 +9,5 @@ pkg
8
9
  /spec/dummy/log/development.log
9
10
  /spec/dummy/log/test.log
10
11
  /spec/dummy/db/test.sqlite3
11
- /spec/dummy/db/development.sqlite3
12
+ /spec/dummy/db/development.sqlite3
13
+ tmp
data/.rspec CHANGED
@@ -1,3 +1,2 @@
1
1
  --color
2
- --format documentation
3
- --debug
2
+ --format progress
@@ -0,0 +1,11 @@
1
+ rvm:
2
+ - 1.8.7
3
+ branches:
4
+ only:
5
+ - next_stable
6
+ before_script:
7
+ - "mysql -e 'create database alchemy_cms_test;'"
8
+ - "sh -c 'cd spec/dummy && RAILS_ENV=test bundle exec rake db:schema:load'"
9
+ script: "bundle exec rspec spec"
10
+ # env:
11
+ # - DB=mysql
data/.yardopts CHANGED
@@ -2,5 +2,4 @@
2
2
  app/**/*.rb
3
3
  config/**/*.yml
4
4
  lib/**/*
5
- recipes/*.rb
6
5
  README.md
data/Gemfile CHANGED
@@ -5,13 +5,12 @@ gemspec
5
5
 
6
6
  group :development, :test do
7
7
  gem 'gettext', '>=1.9.3', :require => false
8
- gem "rspec-rails", ">= 2.0.0.beta"
9
8
  end
10
9
 
11
10
  group :test do
11
+ gem 'mysql2', '< 0.3'
12
12
  gem 'factory_girl_rails'
13
13
  gem "capybara", ">= 0.4.0"
14
14
  gem "launchy"
15
- gem "sqlite3"
16
15
  gem "database_cleaner"
17
16
  end
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  Alchemy CMS
2
2
  ===========
3
3
 
4
+ [![Build Status](https://secure.travis-ci.org/magiclabs/alchemy_cms.png)](http://travis-ci.org/magiclabs/alchemy_cms)
5
+
4
6
  About
5
7
  -----
6
8
 
@@ -66,6 +68,7 @@ Installation
66
68
 
67
69
  Use the installer (recommended):
68
70
 
71
+ gem install alchemy_cms --pre
69
72
  alchemy new my_magicpage
70
73
 
71
74
  Start the local server:
@@ -74,6 +77,17 @@ Start the local server:
74
77
 
75
78
  Then just switch to your browser and open `http://localhost:3000`.
76
79
 
80
+ Add to existing Rails project:
81
+
82
+ add gem 'alchemy_cms' to Gemfile
83
+
84
+ bundle install
85
+ rake alchemy:prepare
86
+ rake alchemy:standard_set:install (optional)
87
+ rake db:migrate
88
+ rake db:seed
89
+
90
+
77
91
  Tipps
78
92
  -----
79
93
 
@@ -35,6 +35,8 @@ Gem::Specification.new do |s|
35
35
  s.add_runtime_dependency(%q<attachment_magic>, ["~> 0.1"])
36
36
 
37
37
  s.add_development_dependency(%q<capybara>, [">= 0.4.0"])
38
- s.add_development_dependency(%q<rspec-rails>, [">= 2.0.0.beta"])
39
- s.add_development_dependency(%q<sqlite3>)
38
+ s.add_development_dependency(%q<rspec-rails>, [">= 2.0"])
39
+ s.add_development_dependency(%q<sqlite3>)
40
+ s.add_development_dependency(%q<ruby-debug>)
41
+
40
42
  end
@@ -7,7 +7,9 @@ class Admin::ClipboardController < AlchemyController
7
7
  def index
8
8
  clipboard = get_clipboard(params[:remarkable_type].tableize)
9
9
  @clipboard_items = params[:remarkable_type].classify.constantize.all_from_clipboard(clipboard)
10
- render :layout => false
10
+ respond_to do |format|
11
+ format.html { render :layout => false }
12
+ end
11
13
  end
12
14
 
13
15
  def insert
@@ -16,14 +18,8 @@ class Admin::ClipboardController < AlchemyController
16
18
  unless @clipboard.include?(params[:remarkable_id])
17
19
  @clipboard.push(params[:remarkable_id])
18
20
  end
19
- if params[:remove] == 'true'
20
- case params[:remarkable_type]
21
- when 'element' then
22
- @item.page = nil
23
- @item.position = nil
24
- when 'page' then #TODO: page.move feature
25
- end
26
- @item.save(false)
21
+ respond_to do |format|
22
+ format.js
27
23
  end
28
24
  rescue Exception => e
29
25
  exception_handler(e)
@@ -33,6 +29,9 @@ class Admin::ClipboardController < AlchemyController
33
29
  @clipboard = get_clipboard(params[:remarkable_type].tableize)
34
30
  @item = params[:remarkable_type].classify.constantize.find(params[:remarkable_id])
35
31
  @clipboard.delete(params[:remarkable_id])
32
+ respond_to do |format|
33
+ format.js
34
+ end
36
35
  rescue Exception => e
37
36
  exception_handler(e)
38
37
  end
@@ -18,13 +18,13 @@ class Admin::ContentsController < AlchemyController
18
18
  @options = Rack::Utils.parse_query(@options)
19
19
  end
20
20
  if @content.essence_type == "EssencePicture"
21
+ @content.essence.picture = Picture.find(params[:picture_id])
22
+ @content.essence.save
21
23
  @contents_of_this_type = @element.contents.find_all_by_essence_type('EssencePicture')
22
24
  @dragable = @contents_of_this_type.length > 1
23
25
  @options = @options.merge(
24
26
  :dragable => @dragable
25
27
  ) if @options
26
- @content.essence.picture = Picture.find(params[:picture_id])
27
- @content.essence.save
28
28
  end
29
29
  rescue
30
30
  exception_handler($!)
@@ -48,6 +48,8 @@ class Admin::ContentsController < AlchemyController
48
48
  page.call("Alchemy.SortableContents", '#element_area .picture_gallery_images', form_authenticity_token)
49
49
  page.call('Alchemy.reloadPreview')
50
50
  end
51
+ rescue
52
+ exception_handler($!)
51
53
  end
52
54
 
53
55
  def destroy
@@ -79,10 +79,10 @@ class Admin::EssencePicturesController < AlchemyController
79
79
  def destroy
80
80
  content = Content.find_by_id(params[:id])
81
81
  @element = content.element
82
- @essence_pictures = @element.contents.find_all_by_essence_type('EssencePicture')
83
82
  @content_id = content.id
84
- @options = params[:options]
85
83
  content.destroy
84
+ @essence_pictures = @element.contents.find_all_by_essence_type('EssencePicture')
85
+ @options = params[:options]
86
86
  end
87
87
 
88
88
  end
@@ -1,5 +1,7 @@
1
1
  class Admin::LayoutpagesController < AlchemyController
2
2
 
3
+ before_filter :set_translation
4
+
3
5
  filter_access_to :all
4
6
 
5
7
  def index
@@ -46,9 +46,6 @@ class Admin::PagesController < AlchemyController
46
46
  else
47
47
  page = Page.create(params[:page])
48
48
  end
49
- if page.valid? && parent
50
- page.move_to_child_of(parent)
51
- end
52
49
  render_errors_or_redirect(page, parent.layoutpage? ? admin_layoutpages_path : admin_pages_path, _("page '%{name}' created.") % {:name => page.name}, 'form#new_page_form button.button')
53
50
  rescue Exception => e
54
51
  exception_handler(e)
@@ -90,6 +87,7 @@ class Admin::PagesController < AlchemyController
90
87
  name = @page.name
91
88
  @page_id = @page.id
92
89
  @layoutpage = @page.layoutpage?
90
+ session[:language_id] = @page.language_id
93
91
  if @page.destroy
94
92
  @page_root = Page.language_root_for(session[:language_id])
95
93
  get_clipboard('pages').delete(@page.id)
@@ -145,7 +143,7 @@ class Admin::PagesController < AlchemyController
145
143
 
146
144
  def visit
147
145
  @page.unlock
148
- redirect_to multi_language? ? show_page_path(:lang => @page.language_code, :urlname => @page.urlname) : show_page_path(@page.urlname)
146
+ redirect_to show_page_path(:urlname => @page.urlname, :lang => multi_language? ? @page.language_code : nil)
149
147
  end
150
148
 
151
149
  # Sets the page public and sweeps the page cache
@@ -206,7 +204,9 @@ class Admin::PagesController < AlchemyController
206
204
  end
207
205
 
208
206
  def switch_language
209
- set_language_to(params[:language_id])
207
+ # we just set the new session here, because the AlchemyController
208
+ # will set the language via before_filter dependend on the session
209
+ session[:language_id] = params[:language_id]
210
210
  redirect_path = params[:layoutpages] ? admin_layoutpages_path : admin_pages_path
211
211
  if request.xhr?
212
212
  render :update do |page|
@@ -101,7 +101,8 @@ class Admin::PicturesController < AlchemyController
101
101
  expire_page(:controller => '/pictures', :action => 'zoom', :id => picture.id)
102
102
  end
103
103
  render :update do |page|
104
- page.call('Alchemy.growl', _('Picture cache flushed'))
104
+ page.call 'Alchemy.growl', _('Picture cache flushed')
105
+ page.call "Alchemy.pleaseWaitOverlay", false
105
106
  end
106
107
  end
107
108
 
@@ -2,6 +2,8 @@ class Admin::TrashController < AlchemyController
2
2
 
3
3
  filter_access_to [:index, :clear]
4
4
 
5
+ before_filter :set_translation
6
+
5
7
  def index
6
8
  @elements = Element.trashed
7
9
  @page = Page.find_by_id(params[:page_id])
@@ -12,9 +12,15 @@ class AlchemyController < ApplicationController
12
12
  before_filter :set_language
13
13
  before_filter :mailer_set_url_options
14
14
 
15
- helper_method :current_server, :configuration, :multi_language?, :current_user, :clipboard_empty?, :trash_empty?, :get_clipboard
15
+ helper_method :current_server, :configuration, :multi_language?, :current_user, :clipboard_empty?, :trash_empty?, :get_clipboard, :is_admin?
16
16
  helper :layout
17
-
17
+
18
+ # Returns true if the current_user (The logged-in Alchemy User) has the admin role.
19
+ def is_admin?
20
+ return false if !current_user
21
+ current_user.admin?
22
+ end
23
+
18
24
  def render_errors_or_redirect(object, redicrect_url, flash_notice, button = nil)
19
25
  if object.errors.empty?
20
26
  flash[:notice] = _(flash_notice)
@@ -23,7 +29,7 @@ class AlchemyController < ApplicationController
23
29
  render_remote_errors(object, button)
24
30
  end
25
31
  end
26
-
32
+
27
33
  def render_remote_errors(object, button = nil)
28
34
  render :update do |page|
29
35
  page << "jQuery('#errors').html('<ul>" + object.errors.sum { |a, b| "<li>" + _(b) + "</li>" } + "</ul>')"
@@ -31,7 +37,7 @@ class AlchemyController < ApplicationController
31
37
  page << "Alchemy.enableButton('#{button}')" unless button.blank?
32
38
  end
33
39
  end
34
-
40
+
35
41
  # Returns a host string with the domain the app is running on.
36
42
  def current_server
37
43
  # For local development server
@@ -2,7 +2,7 @@ class ElementsController < AlchemyController
2
2
 
3
3
  filter_access_to [:show], :attribute_check => true
4
4
  layout false
5
-
5
+
6
6
  # Returns the element partial as HTML or as JavaScript that tries to replace a given +container_id+ with the partial content via jQuery.
7
7
  def show
8
8
  @element = Element.find(params[:id])
@@ -1,5 +1,7 @@
1
1
  module Admin::ElementsHelper
2
2
 
3
+ include ::ElementsHelper
4
+
3
5
  # Returns an Array for essence_text_editor select options_for_select.
4
6
  def elements_by_name_for_select(name, options={})
5
7
  defaults = {
@@ -24,5 +26,34 @@ module Admin::ElementsHelper
24
26
  end
25
27
  return elements_for_options
26
28
  end
27
-
29
+
30
+ # Renders the element editor partial
31
+ def render_editor(element)
32
+ render_element(element, :editor)
33
+ end
34
+
35
+ # This helper renderes the picture editor for the elements on the Alchemy Desktop.
36
+ # It brings full functionality for adding images to the element, deleting images from it and sorting them via drag'n'drop.
37
+ # Just place this helper inside your element editor view, pass the element as parameter and that's it.
38
+ #
39
+ # Options:
40
+ # :maximum_amount_of_images (integer), default nil. This option let you handle the amount of images your customer can add to this element.
41
+ def render_picture_editor(element, options={})
42
+ default_options = {
43
+ :last_image_deletable => true,
44
+ :maximum_amount_of_images => nil,
45
+ :refresh_sortable => true
46
+ }
47
+ options = default_options.merge(options)
48
+ picture_contents = element.all_contents_by_type("EssencePicture")
49
+ render(
50
+ :partial => "admin/elements/picture_editor",
51
+ :locals => {
52
+ :picture_contents => picture_contents,
53
+ :element => element,
54
+ :options => options
55
+ }
56
+ )
57
+ end
58
+
28
59
  end
@@ -1,614 +1,15 @@
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
1
  module AlchemyHelper
13
2
 
14
3
  include FastGettext::Translation
15
4
 
16
- def configuration(name)
17
- return Alchemy::Config.get(name)
18
- end
19
-
20
5
  # An alias for truncate.
21
6
  # Left here for downwards compatibilty.
22
7
  def shorten(text, length)
23
8
  text.truncate(:length => length)
24
9
  end
25
10
 
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 rails generate alchemy: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 rails generate alchemy: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>&nbsp;) + 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_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">&gt;</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_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.
11
+ # This helper renders the link for an overlay window.
12
+ # We use this for our fancy modal overlay windows in the Alchemy cockpit.
612
13
  def link_to_overlay_window(content, url, options={}, html_options={})
613
14
  default_options = {
614
15
  :size => "100x100",
@@ -653,24 +54,6 @@ module AlchemyHelper
653
54
  )
654
55
  end
655
56
 
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
57
  # Returns @current_language set in the action (e.g. Page.show)
675
58
  def current_language
676
59
  if @current_language.nil?
@@ -681,16 +64,6 @@ module AlchemyHelper
681
64
  end
682
65
  end
683
66
 
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
67
  # Used for language selector in Alchemy cockpit sitemap. So the user can select the language branche of the page.
695
68
  def language_codes_for_select
696
69
  configuration(:languages).collect{ |language|
@@ -784,7 +157,7 @@ module AlchemyHelper
784
157
  html_options
785
158
  )
786
159
  end
787
-
160
+
788
161
  # Renders a form select tag for storing page urlnames
789
162
  # Options:
790
163
  # * element - element the Content find via content_name to store the pages urlname in.
@@ -865,68 +238,6 @@ module AlchemyHelper
865
238
  options_for_select(result, selected.to_s)
866
239
  end
867
240
 
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
241
  def render_essence_selection_editor(element, content, select_options)
931
242
  if content.class == String
932
243
  content = element.contents.find_by_name(content)
@@ -992,34 +303,6 @@ module AlchemyHelper
992
303
  end
993
304
  end
994
305
 
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
306
  # Helper for including the nescessary javascripts and stylesheets for the different views.
1024
307
  # Together with the rails caching we achieve a good load time.
1025
308
  def alchemy_assets_set(setname = 'combined')
@@ -1047,56 +330,11 @@ module AlchemyHelper
1047
330
  pathname
1048
331
  end
1049
332
 
1050
- def render_new_content_link(element)
1051
- link_to_overlay_window(
1052
- _('add new content'),
1053
- new_admin_element_content_path(element),
1054
- {
1055
- :size => '305x40',
1056
- :title => _('Select an content'),
1057
- :overflow => true
1058
- },
1059
- {
1060
- :id => "add_content_for_element_#{element.id}",
1061
- :class => 'button new_content_link'
1062
- }
1063
- )
1064
- end
1065
-
1066
- def render_create_content_link(element, options = {})
1067
- defaults = {
1068
- :label => _('add new content')
1069
- }
1070
- options = defaults.merge(options)
1071
- link_to(
1072
- options[:label],
1073
- admin_contents_path(
1074
- :content => {
1075
- :name => options[:content_name],
1076
- :element_id => element.id
1077
- }
1078
- ),
1079
- :method => 'post',
1080
- :remote => true,
1081
- :id => "add_content_for_element_#{element.id}",
1082
- :class => 'button new_content_link'
1083
- )
1084
- end
1085
-
1086
333
  # Returns an icon
1087
334
  def render_icon(icon_class)
1088
335
  content_tag('span', '', :class => "icon #{icon_class}")
1089
336
  end
1090
337
 
1091
- def alchemy_preview_mode_code
1092
- javascript_include_tag("alchemy/alchemy.preview") if @preview_mode
1093
- end
1094
-
1095
- # Renders the data-alchemy-element HTML attribut used for the preview window hover effect.
1096
- def element_preview_code(element)
1097
- " data-alchemy-element='#{element.id}'" if @preview_mode && element.page == @page
1098
- end
1099
-
1100
338
  # Logs a message in the Rails logger (warn level) and optionally displays an error message to the user.
1101
339
  def warning(message, text = nil)
1102
340
  logger.warn %(\n
@@ -1114,61 +352,11 @@ module AlchemyHelper
1114
352
  alchemy_assets_set
1115
353
  end
1116
354
 
1117
- # This helper returns a path for use inside a link_to helper.
1118
- # You may pass a page_layout or an urlname.
1119
- # Any additional options are passed to the url_helper, so you can add arguments to your url.
1120
- # Example:
1121
- # <%= link_to '&raquo order now', page_path_for(:page_layout => 'orderform', :product_id => element.id) %>
1122
- def page_path_for(options={})
1123
- return warning("No page_layout, or urlname given. I got #{options.inspect} ") if options[:page_layout].blank? && options[:urlname].blank?
1124
- if options[:urlname].blank?
1125
- page = Page.find_by_page_layout(options[:page_layout])
1126
- return warning("No page found for #{options.inspect} ") if page.blank?
1127
- urlname = page.urlname
1128
- else
1129
- urlname = options[:urlname]
1130
- end
1131
- if multi_language?
1132
- show_page_path({:urlname => urlname, :lang => @language.code}.merge(options.except(:page_layout, :urlname)))
1133
- else
1134
- show_page_path({:urlname => urlname}.merge(options.except(:page_layout, :urlname)))
1135
- end
1136
- end
1137
-
1138
- # Returns the current page.
1139
- def current_page
1140
- @page
1141
- end
1142
-
1143
- # Renders the partial for the cell with the given name of the current page.
1144
- # Cell partials are located in +app/views/cells/+ of your project.
1145
- def render_cell(name)
1146
- cell = @page.cells.find_by_name(name)
1147
- return "" if cell.blank?
1148
- render :partial => "cells/#{name}", :locals => {:cell => cell}
1149
- end
1150
-
1151
- # Renders all element partials from given cell.
1152
- def render_cell_elements(cell)
1153
- return warning("No cell given.") if cell.blank?
1154
- ret = ""
1155
- cell.elements.each do |element|
1156
- ret << render_element(element)
1157
- end
1158
- ret.html_safe
1159
- end
1160
-
1161
- # Returns true or false if no elements are in the cell found by name.
1162
- def cell_empty?(name)
1163
- cell = @page.cells.find_by_name(name)
1164
- return true if cell.blank?
1165
- cell.elements.blank?
1166
- end
1167
-
1168
355
  def necessary_options_for_cropping_provided?(options)
1169
356
  options[:crop].to_s == 'true' && !options[:image_size].blank?
1170
357
  end
1171
358
 
359
+ # Renders translated Module Names for html title element.
1172
360
  def render_alchemy_title
1173
361
  key = 'module: ' + controller_name
1174
362
  if content_for?(:title)
@@ -1181,10 +369,19 @@ module AlchemyHelper
1181
369
  "Alchemy CMS - #{title}"
1182
370
  end
1183
371
 
372
+ # Returns max image count as integer or nil. Used for the picture editor in element editor views.
1184
373
  def max_image_count
1185
374
  return nil if !@options
1186
- image_count = @options[:maximum_amount_of_images] || @options[:max_images]
1187
- image_count.to_i unless image_count.blank?
375
+ if @options[:maximum_amount_of_images].blank?
376
+ image_count = @options[:max_images]
377
+ else
378
+ image_count = @options[:maximum_amount_of_images]
379
+ end
380
+ if image_count.blank?
381
+ nil
382
+ else
383
+ image_count.to_i
384
+ end
1188
385
  end
1189
386
 
1190
387
  end