alchemy_cms 2.1.beta6 → 2.1.rc2

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.
Files changed (137) hide show
  1. data/.gitignore +3 -1
  2. data/Gemfile +10 -2
  3. data/Guardfile +16 -0
  4. data/README.md +3 -3
  5. data/Rakefile +0 -5
  6. data/alchemy_cms.gemspec +1 -9
  7. data/app/assets/javascripts/alchemy/alchemy.base.js +5 -4
  8. data/app/assets/javascripts/alchemy/{alchemy.dragndrop.js.erb → alchemy.dragndrop.js} +0 -0
  9. data/app/assets/javascripts/alchemy/alchemy.elements_window.js +96 -0
  10. data/app/assets/javascripts/alchemy/alchemy.image_cropper.js +48 -50
  11. data/app/assets/javascripts/alchemy/alchemy.jquery_loader.js +41 -0
  12. data/app/assets/javascripts/alchemy/alchemy.js +2 -0
  13. data/app/assets/javascripts/alchemy/alchemy.menubar.js +55 -0
  14. data/app/assets/javascripts/alchemy/alchemy.preview.js +94 -139
  15. data/app/assets/javascripts/alchemy/alchemy.preview_window.js +98 -0
  16. data/app/assets/javascripts/alchemy/alchemy.windows.js +1 -174
  17. data/app/assets/javascripts/alchemy/menubar.js +2 -0
  18. data/app/assets/javascripts/alchemy/preview.js +2 -1
  19. data/app/assets/stylesheets/alchemy/_defaults.scss +7 -8
  20. data/app/assets/stylesheets/alchemy/base.css.scss +29 -33
  21. data/app/assets/stylesheets/alchemy/elements.css.scss +4 -4
  22. data/app/assets/stylesheets/alchemy/jquery-ui.alchemy.css.scss +1 -1
  23. data/app/assets/stylesheets/alchemy/jquery.Jcrop.css.scss +1 -1
  24. data/app/assets/stylesheets/alchemy/jquery.sb.css.scss +19 -4
  25. data/app/assets/stylesheets/alchemy/menubar.css.scss +85 -0
  26. data/app/assets/stylesheets/alchemy/standard_set.css +3 -5
  27. data/app/assets/stylesheets/alchemy/tinymce_content.css.scss +1 -1
  28. data/app/assets/stylesheets/alchemy/tinymce_dialog.css.scss +1 -1
  29. data/app/controllers/alchemy/admin/attachments_controller.rb +2 -18
  30. data/app/controllers/alchemy/admin/base_controller.rb +1 -1
  31. data/app/controllers/alchemy/admin/elements_controller.rb +2 -2
  32. data/app/controllers/alchemy/admin/essence_files_controller.rb +4 -2
  33. data/app/controllers/alchemy/admin/pictures_controller.rb +6 -20
  34. data/app/controllers/alchemy/admin/resources_controller.rb +7 -5
  35. data/app/controllers/alchemy/base_controller.rb +14 -4
  36. data/app/controllers/alchemy/messages_controller.rb +4 -4
  37. data/app/controllers/alchemy/pages_controller.rb +51 -32
  38. data/app/controllers/alchemy/pictures_controller.rb +0 -3
  39. data/app/controllers/alchemy/user_sessions_controller.rb +1 -1
  40. data/app/helpers/alchemy/admin/base_helper.rb +6 -4
  41. data/app/helpers/alchemy/base_helper.rb +26 -0
  42. data/app/helpers/alchemy/pages_helper.rb +42 -22
  43. data/app/models/alchemy/attachment.rb +10 -2
  44. data/app/models/alchemy/cell.rb +1 -0
  45. data/app/models/alchemy/content.rb +8 -6
  46. data/app/models/alchemy/element.rb +1 -1
  47. data/app/models/alchemy/essence_audio.rb +1 -8
  48. data/app/models/alchemy/essence_date.rb +2 -9
  49. data/app/models/alchemy/essence_file.rb +1 -8
  50. data/app/models/alchemy/essence_flash.rb +0 -7
  51. data/app/models/alchemy/essence_html.rb +1 -8
  52. data/app/models/alchemy/essence_picture.rb +0 -11
  53. data/app/models/alchemy/essence_richtext.rb +4 -12
  54. data/app/models/alchemy/essence_text.rb +1 -13
  55. data/app/models/alchemy/essence_video.rb +1 -8
  56. data/app/models/alchemy/page.rb +28 -22
  57. data/app/models/alchemy/picture.rb +19 -0
  58. data/app/sweepers/alchemy/pages_sweeper.rb +17 -6
  59. data/app/sweepers/alchemy/pictures_sweeper.rb +1 -3
  60. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +2 -2
  61. data/app/views/alchemy/admin/attachments/_attachment.html.erb +1 -1
  62. data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +2 -2
  63. data/app/views/alchemy/admin/attachments/_files_list.html.erb +13 -11
  64. data/app/views/alchemy/admin/attachments/create.js.erb +1 -1
  65. data/app/views/alchemy/admin/attachments/edit.html.erb +2 -2
  66. data/app/views/alchemy/admin/elements/_new_element_form.html.erb +1 -2
  67. data/app/views/alchemy/admin/elements/new.html.erb +1 -1
  68. data/app/views/alchemy/admin/essence_files/edit.html.erb +32 -32
  69. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +29 -29
  70. data/app/views/alchemy/admin/essence_pictures/update.js.erb +13 -12
  71. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +4 -1
  72. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -1
  73. data/app/views/alchemy/admin/pages/edit.html.erb +8 -8
  74. data/app/views/alchemy/admin/pages/index.html.erb +1 -1
  75. data/app/views/alchemy/admin/pages/new.html.erb +1 -1
  76. data/app/views/alchemy/admin/pages/update.js.erb +19 -12
  77. data/app/views/alchemy/admin/pictures/_picture.html.erb +1 -1
  78. data/app/views/alchemy/admin/pictures/_pictures_list.html.erb +8 -6
  79. data/app/views/alchemy/admin/pictures/show_in_window.html.erb +6 -1
  80. data/app/views/alchemy/admin/resources/_table.html.erb +1 -1
  81. data/app/views/alchemy/admin/users/_table.html.erb +13 -13
  82. data/app/views/alchemy/admin/users/_user.html.erb +1 -1
  83. data/app/views/alchemy/admin/users/index.html.erb +2 -2
  84. data/app/views/alchemy/elements/_contactform_view.html.erb +78 -78
  85. data/app/views/alchemy/elements/_download_editor.html.erb +1 -0
  86. data/app/views/alchemy/elements/_download_view.html.erb +3 -0
  87. data/app/views/alchemy/essences/_essence_date_editor.html.erb +1 -1
  88. data/app/views/alchemy/essences/_essence_file_editor.html.erb +1 -0
  89. data/app/views/alchemy/essences/_essence_file_view.html.erb +6 -2
  90. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +3 -2
  91. data/app/views/alchemy/essences/_essence_picture_view.html.erb +1 -1
  92. data/app/views/alchemy/navigation/_link.html.erb +1 -2
  93. data/app/views/alchemy/notifications/admin_user_created.text.erb +7 -7
  94. data/app/views/alchemy/notifications/registered_user_created.text.erb +5 -5
  95. data/app/views/alchemy/user_sessions/login.html.erb +34 -35
  96. data/app/views/layouts/alchemy/login.html.erb +3 -8
  97. data/app/views/layouts/alchemy/pages.html.erb +1 -0
  98. data/bin/alchemy +43 -75
  99. data/config/alchemy/config.yml +10 -0
  100. data/config/alchemy/elements.yml +5 -0
  101. data/config/alchemy/page_layouts.yml +1 -1
  102. data/config/locales/alchemy.de.yml +21 -8
  103. data/config/locales/alchemy.en.yml +20 -4
  104. data/config/routes.rb +25 -20
  105. data/db/migrate/{20111116125112_namespace_models.rb → 20111116125112_namespace_alchemy_models.rb} +1 -1
  106. data/lib/alchemy/capistrano.rb +4 -17
  107. data/lib/alchemy/engine.rb +2 -0
  108. data/lib/alchemy/essence.rb +29 -41
  109. data/lib/alchemy/i18n.rb +1 -1
  110. data/lib/alchemy/mount_point.rb +10 -0
  111. data/lib/alchemy/page_layout.rb +7 -7
  112. data/lib/alchemy/seeder.rb +85 -47
  113. data/lib/alchemy/upgrader.rb +115 -0
  114. data/lib/alchemy/version.rb +1 -1
  115. data/lib/alchemy_cms.rb +4 -3
  116. data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +6 -2
  117. data/lib/tasks/ferret.rake +12 -0
  118. data/lib/tasks/install.rake +16 -105
  119. data/lib/tasks/routes.rake +29 -0
  120. data/lib/tasks/upgrade.rake +5 -67
  121. data/spec/controllers/admin/pages_controller_spec.rb +1 -1
  122. data/spec/controllers/pages_controller_spec.rb +31 -0
  123. data/spec/factories.rb +24 -15
  124. data/spec/helpers/admin/base_helper_spec.rb +0 -7
  125. data/spec/helpers/pages_helper_spec.rb +54 -29
  126. data/spec/helpers/url_helpers_spec.rb +40 -0
  127. data/spec/integration/admin/pages_controller_spec.rb +3 -3
  128. data/spec/integration/pages_controller_spec.rb +80 -6
  129. data/spec/integration/security_spec.rb +2 -2
  130. data/spec/models/content_spec.rb +24 -0
  131. data/spec/models/page_spec.rb +174 -47
  132. data/spec/models/picture_spec.rb +54 -0
  133. data/spec/page_layout_spec.rb +2 -2
  134. data/spec/routing_spec.rb +205 -1
  135. data/spec/spec_helper.rb +53 -32
  136. metadata +51 -46
  137. data/lib/alchemy/file_utilz.rb +0 -73
@@ -1,6 +1,12 @@
1
1
  module Alchemy
2
2
  class PagesController < Alchemy::BaseController
3
3
 
4
+ # We need to include this helper because we need the breadcrumb method.
5
+ # And we cannot define the breadcrump method as helper_method, because rspec does not see helper_methods.
6
+ # Not the best solution, but's working.
7
+ # Anyone with a better idea please provide a patch.
8
+ include Alchemy::BaseHelper
9
+
4
10
  before_filter :render_page_or_redirect, :only => [:show, :sitemap]
5
11
  before_filter :perform_search, :only => :show, :if => proc { configuration(:ferret) }
6
12
 
@@ -9,7 +15,7 @@ module Alchemy
9
15
  caches_action(
10
16
  :show,
11
17
  :cache_path => proc { show_page_url(:urlname => params[:urlname], :lang => multi_language? ? params[:lang] : nil) },
12
- :if => proc do
18
+ :if => proc {
13
19
  if Alchemy::Config.get(:cache_pages)
14
20
  page = Page.find_by_urlname_and_language_id_and_public(
15
21
  params[:urlname],
@@ -24,20 +30,20 @@ module Alchemy
24
30
  else
25
31
  false
26
32
  end
27
- end
33
+ },
34
+ :layout => false
28
35
  )
29
36
 
37
+ layout :layout_for_page
38
+
30
39
  # Showing page from params[:urlname]
31
40
  # @page is fetched via before filter
32
41
  # @root_page is fetched via before filter
33
42
  # @language fetched via before_filter in alchemy_controller
34
43
  # querying for search results if any query is present via before_filter
35
- # rendering page
36
44
  def show
37
45
  respond_to do |format|
38
- format.html {
39
- render :layout => layout_for_page
40
- }
46
+ format.html { render }
41
47
  format.rss {
42
48
  if @page.contains_feed?
43
49
  render :action => "show.rss.builder", :layout => false
@@ -79,7 +85,7 @@ module Alchemy
79
85
  if User.admins.count == 0 && @page.nil?
80
86
  redirect_to signup_path
81
87
  elsif @page.blank?
82
- render(:file => "#{Rails.root}/public/404.html", :status => 404, :layout => false)
88
+ render_404
83
89
  elsif multi_language? && params[:lang].blank?
84
90
  redirect_page(:lang => session[:language_code])
85
91
  elsif multi_language? && params[:urlname].blank? && !params[:lang].blank? && configuration(:redirect_index)
@@ -90,8 +96,14 @@ module Alchemy
90
96
  redirect_page
91
97
  elsif !multi_language? && !params[:lang].blank?
92
98
  redirect_page
99
+ elsif configuration(:url_nesting) && url_levels.any? && !levels_are_in_page_branch?
100
+ render_404
101
+ elsif configuration(:url_nesting) && should_be_nested? && !url_levels.any?
102
+ redirect_page(params_for_nested_url)
103
+ elsif !configuration(:url_nesting) && url_levels.any?
104
+ redirect_page
93
105
  elsif @page.has_controller?
94
- redirect_to(@page.controller_and_action)
106
+ redirect_to main_app.url_for(@page.controller_and_action)
95
107
  else
96
108
  # setting the language to page.language to be sure it's correct
97
109
  set_language_from(@page.language_id)
@@ -113,28 +125,29 @@ module Alchemy
113
125
  if searchresult_page_layouts.any?
114
126
  @search_result_page = Page.find_by_page_layout_and_public_and_language_id(searchresult_page_layouts.first["name"], true, session[:language_id])
115
127
  if !params[:query].blank? && @search_result_page
116
- @rtf_search_results = EssenceRichtext.find_with_ferret(
117
- "*#{params[:query]}*",
118
- {:limit => :all},
119
- {:conditions => ["public = ?", true]}
120
- )
121
- @text_search_results = EssenceText.find_with_ferret(
122
- "*#{params[:query]}*",
123
- {:limit => :all},
124
- {:conditions => ["public = ?", true]}
125
- )
126
- @search_results = (@text_search_results + @rtf_search_results).sort{ |y, x| x.ferret_score <=> y.ferret_score }
128
+ @search_results = []
129
+ %w(Alchemy::EssenceText Alchemy::EssenceRichtext).each do |e|
130
+ @search_results += e.constantize.includes(:contents => {:element => :page}).find_with_ferret(
131
+ "*#{params[:query]}*",
132
+ {:limit => :all},
133
+ {:conditions => [
134
+ 'alchemy_pages.public = ? AND alchemy_pages.layoutpage = ? AND alchemy_pages.restricted = ?',
135
+ true, false, false
136
+ ]}
137
+ )
138
+ end
139
+ return @search_results.sort{ |y, x| x.ferret_score <=> y.ferret_score } if @search_results.any?
127
140
  end
128
141
  end
129
142
  end
130
143
 
131
144
  def find_first_public(page)
132
- if(page.public == true)
145
+ if page.public == true
133
146
  return page
134
147
  end
135
148
  page.children.each do |child|
136
149
  result = find_first_public(child)
137
- if(result!=nil)
150
+ if result != nil
138
151
  return result
139
152
  end
140
153
  end
@@ -161,20 +174,26 @@ module Alchemy
161
174
 
162
175
  def additional_params
163
176
  params.clone.delete_if do |key, value|
164
- ["action", "controller", "urlname", "lang"].include?(key)
177
+ ["action", "controller", "urlname", "lang", "level1", "level2", "level3"].include?(key)
165
178
  end
166
179
  end
167
180
 
168
- def layout_for_page
169
- if params[:layout] == 'none'
170
- false
171
- elsif not params[:layout].blank?
172
- params[:layout]
173
- elsif File.exist?(Rails.root.join('app/views/layouts', 'application.html.erb'))
174
- 'application'
175
- else
176
- 'alchemy/pages'
177
- end
181
+ def render_404
182
+ render(:file => "#{Rails.root}/public/404.html", :status => 404, :layout => false)
183
+ end
184
+
185
+ def url_levels
186
+ params.keys.grep(/^level[1-3]$/)
187
+ end
188
+
189
+ def levels_are_in_page_branch?
190
+ nested_urlnames = breadcrumb(@page).collect(&:urlname)
191
+ level_names = params.select { |k, v| url_levels.include?(k) }.map(&:second)
192
+ level_names & nested_urlnames == level_names
193
+ end
194
+
195
+ def should_be_nested?
196
+ !params_for_nested_url.blank?
178
197
  end
179
198
 
180
199
  end
@@ -44,9 +44,6 @@ module Alchemy
44
44
 
45
45
  def zoom
46
46
  @picture = Picture.find(params[:id])
47
- respond_to do |format|
48
- format.png
49
- end
50
47
  end
51
48
 
52
49
  private
@@ -24,7 +24,7 @@ module Alchemy
24
24
 
25
25
  def login
26
26
  if current_user
27
- redirect_to admin_dashboard_path, :notice => t('You are already logged in.')
27
+ redirect_to admin_dashboard_path, :notice => t('You are already logged in')
28
28
  else
29
29
  if request.get?
30
30
  @user_session = UserSession.new()
@@ -341,10 +341,12 @@ module Alchemy
341
341
  options.symbolize_keys!
342
342
  defaults = {
343
343
  :overlay => true,
344
- :skip_permission_check => false
344
+ :skip_permission_check => false,
345
+ :active => false,
346
+ :link_options => {}
345
347
  }
346
348
  options = defaults.merge(options)
347
- button = content_tag('div', :class => 'button_with_label') do
349
+ button = content_tag('div', :class => 'button_with_label' + (options[:active] ? ' active' : '')) do
348
350
  link = if options[:overlay]
349
351
  link_to_overlay_window(
350
352
  render_icon(options[:icon]),
@@ -392,8 +394,8 @@ module Alchemy
392
394
  options = defaults.merge(options)
393
395
  content_for(:toolbar) do
394
396
  content = <<-CONTENT
395
- #{options[:buttons].map { |button_options| toolbar_button(button_options) }.join()}
396
- #{render('alchemy/admin/partials/search_form', :url => options[:search_url]) if options[:search]}
397
+ #{options[:buttons].map { |button_options| toolbar_button(button_options) }.join()}
398
+ #{render('alchemy/admin/partials/search_form', :url => options[:search_url]) if options[:search]}
397
399
  CONTENT
398
400
  content.html_safe
399
401
  end
@@ -53,5 +53,31 @@ module Alchemy
53
53
  content_tag('span', '', :class => "icon #{icon_class}")
54
54
  end
55
55
 
56
+ # Returns an array of all pages in the same branch from current.
57
+ # I.e. used to find the active page in navigation.
58
+ def breadcrumb(current)
59
+ return [] if current.nil?
60
+ result = Array.new
61
+ result << current
62
+ while current = current.parent
63
+ result << current
64
+ end
65
+ return result.reverse
66
+ end
67
+
68
+ # Returns a hash with urlname for each url level.
69
+ # I.e.: +{:level1 => 'company', :level2 => 'history'}+
70
+ def params_for_nested_url(page = nil)
71
+ page ||= @page
72
+ raise ArgumentError if page.nil?
73
+ nested_urL_params = {}
74
+ page_bread_crumb = breadcrumb(page)
75
+ urlnames = page_bread_crumb[2..page_bread_crumb.length-2].collect(&:urlname)
76
+ urlnames.each_with_index do |urlname, i|
77
+ nested_urL_params["level#{i+1}"] = urlname
78
+ end
79
+ nested_urL_params.symbolize_keys
80
+ end
81
+
56
82
  end
57
83
  end
@@ -310,18 +310,6 @@ module Alchemy
310
310
  bc.join(options[:seperator]).html_safe
311
311
  end
312
312
 
313
- # Returns an array of all pages in the same branch from current.
314
- # I.e. used to find the active page in navigation.
315
- def breadcrumb(current)
316
- return [] if current.nil?
317
- result = Array.new
318
- result << current
319
- while current = current.parent
320
- result << current
321
- end
322
- return result.reverse
323
- end
324
-
325
313
  # Returns @page.title
326
314
  #
327
315
  # The options are:
@@ -427,17 +415,16 @@ module Alchemy
427
415
  end
428
416
  robot = "#{@page.robot_index? ? "" : "no"}index, #{@page.robot_follow? ? "" : "no"}follow"
429
417
  meta_string = %(
430
- <meta charset=UTF-8">
418
+ <meta charset="UTF-8">
431
419
  #{render_title_tag(:prefix => options[:title_prefix], :seperator => options[:title_seperator])}
432
420
  #{render_meta_tag(:name => "description", :content => description)}
433
421
  #{render_meta_tag(:name => "keywords", :content => keywords)}
434
- <meta name="generator" content="Alchemy #{Alchemy::VERSION}">
435
- <meta name="date" content="#{@page.updated_at}">
422
+ <meta name="created" content="#{@page.updated_at}">
436
423
  <meta name="robots" content="#{robot}">
437
424
  )
438
425
  if @page.contains_feed?
439
426
  meta_string += %(
440
- <link rel="alternate" type="application/rss+xml" title="RSS" href="#{multi_language? ? alchemy.show_page_url(:protocol => 'feed', :urlname => @page.urlname, :lang => @page.language_code, :format => :rss) : show_page_url(:protocol => 'feed', :urlname => @page.urlname, :format => :rss)}">
427
+ <link rel="alternate" type="application/rss+xml" title="RSS" href="#{show_alchemy_page_url(@page, :protocol => 'feed', :format => :rss)}">
441
428
  )
442
429
  end
443
430
  return meta_string.html_safe
@@ -456,7 +443,10 @@ module Alchemy
456
443
  return warning("No page_layout, or urlname given. I got #{options.inspect} ") if options[:page_layout].blank? && options[:urlname].blank?
457
444
  if options[:urlname].blank?
458
445
  page = Page.find_by_page_layout(options[:page_layout])
459
- return warning("No page found for #{options.inspect} ") if page.blank?
446
+ if page.blank?
447
+ warning("No page found for #{options.inspect} ")
448
+ return
449
+ end
460
450
  urlname = page.urlname
461
451
  else
462
452
  urlname = options[:urlname]
@@ -491,7 +481,10 @@ module Alchemy
491
481
  :html5 => false
492
482
  }
493
483
  options = default_options.merge(options)
494
- return warning(t("No page found for #{options[:page].inspect}")) if options[:page].class.name != "Alchemy::Page"
484
+ if options[:page].class.name != "Alchemy::Page"
485
+ warning("No page found for #{options[:page].inspect}")
486
+ return
487
+ end
495
488
  form_tag(show_alchemy_page_path(options[:page]), :method => :get, :class => 'fulltext_search') do
496
489
  if options[:html5]
497
490
  search_field_tag(:query, params[:query])
@@ -510,7 +503,7 @@ module Alchemy
510
503
  :show_heading => true
511
504
  }
512
505
  options = default_options.merge(options)
513
- return content_tag :h2, t('search.no_results') if @search_results.blank?
506
+ return content_tag :h2, t('search_result_page.no_results'), :class => 'no_search_results' if @search_results.blank?
514
507
  results = ""
515
508
  @search_results.each do |essence|
516
509
  result = essence.highlight(
@@ -520,19 +513,20 @@ module Alchemy
520
513
  results << render(:partial => options[:partial], :locals => {:result => result, :options => options, :page => essence.page}) if essence.page
521
514
  end
522
515
  output = ""
523
- output << content_tag(:h1, t("search.result_heading", :query => h(params[:query])), :class => 'search_results_heading') if options[:show_heading]
524
- output << content_tag(:h2, t("search.result_count", :result_count => @search_results.length), :class => 'search_result_count') if options[:show_result_count]
516
+ output << content_tag(:h1, t("search_result_page.result_heading", :query => h(params[:query])), :class => 'search_results_heading') if options[:show_heading]
517
+ output << content_tag(:h2, t("search_result_page.result_count", :count => @search_results.length), :class => 'search_result_count') if options[:show_result_count]
525
518
  output << content_tag(:ul, results.html_safe, :class => 'search_result_list')
526
519
  content_tag :div, :class => 'search_results' do
527
520
  output.html_safe
528
521
  end
529
522
  end
530
-
523
+
531
524
  # Returns the correct params-hash for passing to show_page_path
532
525
  def show_page_path_params(page=nil, optional_params={})
533
526
  return nil if page.class.name != "Alchemy::Page"
534
527
  url_params = {:urlname => page.urlname}
535
528
  url_params.update(optional_params) if optional_params.class.name == "Hash"
529
+ url_params.update(params_for_nested_url(page)) if configuration(:url_nesting)
536
530
  return multi_language? ? url_params.update(:lang => page.language_code) : url_params
537
531
  end
538
532
 
@@ -546,5 +540,31 @@ module Alchemy
546
540
  alchemy.show_page_url(show_page_path_params(page, optional_params))
547
541
  end
548
542
 
543
+ # Renders a menubar for logged in users that are visiting a page.
544
+ def alchemy_menu_bar
545
+ return if @preview_mode
546
+ if permitted_to?(:edit, :alchemy_admin_pages)
547
+ menu_bar_string = ""
548
+ menu_bar_string += stylesheet_link_tag("alchemy/menubar")
549
+ menu_bar_string += javascript_include_tag('alchemy/menubar')
550
+ menu_bar_string += <<-STR
551
+ <script type="text/javascript">
552
+ try {
553
+ Alchemy.loadAlchemyMenuBar({
554
+ page_id: #{@page.id},
555
+ route: '#{Alchemy.mount_point}',
556
+ locale: '#{current_user.language}'
557
+ });
558
+ } catch(e) {
559
+ if(console){console.log(e)}
560
+ }
561
+ </script>
562
+ STR
563
+ content_for(:layout) { menu_bar_string.html_safe }
564
+ else
565
+ nil
566
+ end
567
+ end
568
+
549
569
  end
550
570
  end
@@ -10,8 +10,16 @@ module Alchemy
10
10
  )
11
11
  validates_as_attachment
12
12
 
13
- def name
14
- read_attribute(:name).split('.').first
13
+ def self.find_paginated(params, per_page)
14
+ cond = "name LIKE '%#{params[:query]}%' OR filename LIKE '%#{params[:query]}%'"
15
+ self.where(cond).paginate(
16
+ :page => (params[:page] || 1),
17
+ :per_page => per_page
18
+ ).order(:name)
19
+ end
20
+
21
+ def urlname
22
+ CGI.escape(read_attribute(:filename).split('.').first)
15
23
  end
16
24
 
17
25
  def extension
@@ -14,6 +14,7 @@ module Alchemy
14
14
  class Cell < ActiveRecord::Base
15
15
 
16
16
  belongs_to :page
17
+ validates_uniqueness_of :name, :scope => :page_id
17
18
  has_many :elements, :dependent => :destroy, :order => :position
18
19
 
19
20
  def self.definitions
@@ -12,6 +12,7 @@ module Alchemy
12
12
  "element_id = '#{element_id}' AND essence_type = '#{essence_type}'"
13
13
  end
14
14
 
15
+ validates_uniqueness_of :name, :scope => :element_id
15
16
  validates_uniqueness_of :position, :scope => [:element_id, :essence_type]
16
17
 
17
18
  scope :essence_pictures, where(:essence_type => "Alchemy::EssencePicture")
@@ -96,19 +97,20 @@ module Alchemy
96
97
  self.essence.ingredient
97
98
  end
98
99
 
99
- # Calls essence.save_ingredient. Called from ElementController#update for each content in element.
100
- # Adding errors if essence validation fails.
101
- def save_essence(params, options = {})
102
- if essence.save_ingredient(params, options)
100
+ # Calls essence.update_attributes. Called from +Alchemy::Element#save_contents+
101
+ # Ads errors to self.base if essence validation fails.
102
+ def update_essence(params={})
103
+ raise "Essence not found" if essence.nil?
104
+ if essence.update_attributes(params)
103
105
  return true
104
106
  else
105
- errors.add(:base, :essence_validation_failed)
107
+ errors.add(:essence, :validation_failed)
106
108
  return false
107
109
  end
108
110
  end
109
111
 
110
112
  def essence_validation_failed?
111
- !essence.essence_errors.blank?
113
+ essence.errors.any?
112
114
  end
113
115
 
114
116
  def has_validations?
@@ -321,7 +321,7 @@ module Alchemy
321
321
 
322
322
  def save_contents(params)
323
323
  contents.each do |content|
324
- unless content.save_essence(params[:contents]["content_#{content.id}"], :public => !params["public"].nil?)
324
+ unless content.update_essence(params[:contents]["content_#{content.id}"])
325
325
  errors.add(:base, :essence_validation_failed)
326
326
  end
327
327
  end
@@ -5,15 +5,8 @@ module Alchemy
5
5
  :ingredient_column => :attachment,
6
6
  :preview_text_method => :name
7
7
  )
8
-
8
+
9
9
  belongs_to :attachment
10
-
11
- # Saves the ingredient
12
- def save_ingredient(params, options = {})
13
- return true if params.blank?
14
- self.attachment_id = params["attachment_id"].to_s
15
- self.save
16
- end
17
10
 
18
11
  end
19
12
  end
@@ -4,18 +4,11 @@ module Alchemy
4
4
  acts_as_essence(
5
5
  :ingredient_column => :date
6
6
  )
7
-
7
+
8
8
  # Returns self.date for the Element#preview_text method.
9
9
  def preview_text(foo=nil)
10
10
  return "" if date.blank?
11
- ::I18n.l(date)
12
- end
13
-
14
- # Saves the ingredient
15
- def save_ingredient(params, options = {})
16
- return true if params.blank?
17
- self.date = DateTime.parse(params['date'].values.join('-'))
18
- self.save
11
+ ::I18n.l(date, :format => :date)
19
12
  end
20
13
 
21
14
  end