alchemy_cms 2.1.beta5 → 2.1.beta6

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 (66) hide show
  1. data/Gemfile +1 -1
  2. data/README.md +14 -0
  3. data/alchemy_cms.gemspec +1 -1
  4. data/app/assets/javascripts/alchemy/alchemy.base.js +8 -2
  5. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.erb +1 -1
  6. data/app/assets/javascripts/alchemy/alchemy.link_overlay.js +1 -10
  7. data/app/assets/javascripts/alchemy/alchemy.routes.js.erb +9 -9
  8. data/app/assets/stylesheets/alchemy/base.css.scss +68 -66
  9. data/app/assets/stylesheets/alchemy/elements.css.scss +3 -2
  10. data/app/assets/stylesheets/alchemy/jquery-ui.alchemy.css.scss +1 -1
  11. data/app/assets/stylesheets/alchemy/jquery.Jcrop.css.scss +1 -1
  12. data/app/assets/stylesheets/alchemy/jquery.sb.css.scss +1 -1
  13. data/app/assets/stylesheets/alchemy/tinymce_content.css.scss +1 -1
  14. data/app/assets/stylesheets/alchemy/tinymce_dialog.css.scss +1 -1
  15. data/app/controllers/alchemy/admin/base_controller.rb +1 -1
  16. data/app/controllers/alchemy/admin/contents_controller.rb +1 -1
  17. data/app/controllers/alchemy/admin/elements_controller.rb +2 -1
  18. data/app/controllers/alchemy/admin/pages_controller.rb +18 -8
  19. data/app/controllers/alchemy/admin/resources_controller.rb +1 -1
  20. data/app/controllers/alchemy/pages_controller.rb +14 -2
  21. data/app/helpers/alchemy/admin/base_helper.rb +2 -2
  22. data/app/helpers/alchemy/admin/elements_helper.rb +1 -1
  23. data/app/helpers/alchemy/admin/essences_helper.rb +1 -1
  24. data/app/helpers/alchemy/base_helper.rb +0 -8
  25. data/app/helpers/alchemy/essences_helper.rb +1 -2
  26. data/app/helpers/alchemy/pages_helper.rb +3 -3
  27. data/app/models/alchemy/content.rb +27 -3
  28. data/app/models/alchemy/element.rb +2 -2
  29. data/app/models/alchemy/page.rb +4 -4
  30. data/app/models/alchemy/user.rb +5 -1
  31. data/app/views/alchemy/admin/clipboard/insert.js.erb +9 -9
  32. data/app/views/alchemy/admin/dashboard/index.html.erb +1 -1
  33. data/app/views/alchemy/admin/elements/create.js.erb +26 -19
  34. data/app/views/alchemy/admin/essence_pictures/assign.js.erb +1 -1
  35. data/app/views/alchemy/admin/essence_pictures/edit.html.erb +4 -4
  36. data/app/views/alchemy/admin/essence_pictures/update.js.erb +1 -1
  37. data/app/views/alchemy/admin/layoutpages/index.html.erb +1 -14
  38. data/app/views/alchemy/admin/pages/_external_link.html.erb +3 -13
  39. data/app/views/alchemy/admin/pages/index.html.erb +1 -14
  40. data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +22 -0
  41. data/app/views/alchemy/admin/partials/_pagination_links.html.erb +3 -1
  42. data/app/views/alchemy/admin/pictures/update.js.erb +2 -0
  43. data/app/views/alchemy/admin/trash/index.html.erb +1 -1
  44. data/app/views/alchemy/admin/users/_user.html.erb +1 -1
  45. data/config/locales/alchemy.de.yml +29 -17
  46. data/config/locales/alchemy.en.yml +5 -4
  47. data/lib/alchemy/capistrano.rb +5 -0
  48. data/lib/alchemy/i18n.rb +1 -1
  49. data/lib/alchemy/page_layout.rb +1 -1
  50. data/lib/alchemy/scoped_pagination_link_renderer.rb +27 -0
  51. data/lib/alchemy/version.rb +1 -1
  52. data/lib/alchemy_cms.rb +1 -1
  53. data/spec/controllers/admin/contents_controller_spec.rb +19 -0
  54. data/spec/controllers/admin/pages_controller_spec.rb +19 -0
  55. data/spec/controllers/base_controller_spec.rb +1 -1
  56. data/spec/controllers/pages_controller_spec.rb +62 -0
  57. data/spec/dummy/app/views/layouts/.gitkeep +0 -0
  58. data/spec/integration/admin/pages_controller_spec.rb +42 -13
  59. data/spec/integration/pages_controller_spec.rb +2 -2
  60. data/spec/models/content_spec.rb +40 -0
  61. data/spec/models/element_spec.rb +50 -0
  62. data/spec/models/page_spec.rb +45 -1
  63. data/spec/routing_spec.rb +27 -29
  64. data/spec/spec_helper.rb +2 -2
  65. metadata +40 -36
  66. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
@@ -0,0 +1,22 @@
1
+ <div class="button_with_label">
2
+ <%= select_tag(
3
+ 'language',
4
+ options_for_select(@languages.map { |l| [l.name, l.id] }, session[:language_id]),
5
+ :id => 'language_tree_select',
6
+ :class => 'short'
7
+ ) %>
8
+ <label><%= t("Language tree") %></label>
9
+ </div>
10
+
11
+ <% content_for :javascripts do %>
12
+ <script type="text/javascript" charset="utf-8">
13
+ (function($) {
14
+ $('#language_tree_select').on('change', function() {
15
+ Alchemy.pleaseWaitOverlay();
16
+ $.get('<%= switch_language_admin_pages_path %>', {
17
+ language_id: this.value
18
+ });
19
+ });
20
+ })(jQuery);
21
+ </script>
22
+ <% end %>
@@ -1,5 +1,7 @@
1
1
  <%= will_paginate(
2
2
  items,
3
3
  :previous_label => '&laquo; ' + t('pagination.previous_page'),
4
- :next_label => t('pagination.next_page') + ' &raquo;'
4
+ :next_label => t('pagination.next_page') + ' &raquo;',
5
+ :renderer => 'Alchemy::ScopedPaginationLinkRenderer',
6
+ :params => defined?(scope) ? {:scope => scope} : nil
5
7
  ) %>
@@ -1 +1,3 @@
1
1
  Alchemy.growl('<%= @message %>');
2
+ $('.inplace-edit').remove();
3
+ $("#picture_#{@picture.id}").replaceWith('<%= escape_javascript(render("picture", :picture => @picture)) %>');
@@ -6,7 +6,7 @@
6
6
  <%- else -%>
7
7
  <div class="info">
8
8
  <%= render_icon('info') %>
9
- <%= t('Drag an element over to the element window to restore it.') %>
9
+ <%= t('Drag an element over to the element window to restore it') %>
10
10
  </div>
11
11
  <div id="trash_items">
12
12
  <%- @elements.each do |element| -%>
@@ -8,7 +8,7 @@
8
8
  <td><%= user.lastname -%></td>
9
9
  <td class="email"><%= user.email %></td>
10
10
  <td><%= t(user.language, :scope => 'translations') %></td>
11
- <td class="role"><%= t("user_roles.#{user.role}") %></td>
11
+ <td class="role"><%= user.human_role_name %></td>
12
12
  <td class="tools">
13
13
  <%- permitted_to?(:destroy, :alchemy_admin_users) do -%>
14
14
  <%= link_to_confirmation_window(
@@ -2,9 +2,6 @@
2
2
 
3
3
  de:
4
4
 
5
- yes: "Ja"
6
- no: "Nein"
7
-
8
5
  # = Alchemy Translations
9
6
  # All translations used in Alchemy CMS are inside this alchemy namespace.
10
7
  alchemy:
@@ -193,7 +190,7 @@ de:
193
190
  "Do you really want to clear the clipboard?": "Wollen Sie die Zwischenablage wirklich leeren?"
194
191
  "Do you really want to clear the trash?": "Wollen Sie den Papierkorb wirklich leeren?"
195
192
  "Do you really want to delete this content?": "Wollen Sie diesen Inhalt wirklich löschen?"
196
- "Drag an element over to the element window to restore it.": "Ziehen Sie ein Element mit der Maus in das Elemente Fenster, um es wieder herzustellen."
193
+ "Drag an element over to the element window to restore it": "Ziehen Sie ein Element mit der Maus in das Elemente Fenster, um es wieder herzustellen."
197
194
  "Edit Picturemask": "Bildmaske bearbeiten"
198
195
  "Element trashed": "Das Element wurde in den Papierkorb gelegt"
199
196
  "Error with the Flash® Uploader!": "Fehler mit dem Flash® Uploader!"
@@ -210,6 +207,7 @@ de:
210
207
  "If you have any problems using the Flash uploader you can switch to": "Sollten Sie Probleme mit dem Flash® Uploader haben, wechseln Sie einfach zur %{link}"
211
208
  "Image missing": "Bild fehlt"
212
209
  "Image size": "Bildgröße"
210
+ "Image updated successfully": "Bild wurde gespeichert"
213
211
  "Index Error after saving Element. Please try again!": "Indizierungsfehler beim Speichern des Elements. Bitte erneut versuchen!"
214
212
  "Language successfully created.": "Sprache wurde erfolgreich erstellt."
215
213
  "Language successfully destroyed.": "Sprache wurde erfolgreich gelöscht."
@@ -231,12 +229,12 @@ de:
231
229
  "Page saved": "%{name} wurde gespeichert"
232
230
  "Page Preview": "Seitenvorschau"
233
231
  "Page cache flushed": "Seitencache wurde geleert"
234
- "Page not public": "Seite nicht öffentlich"
235
- "Page not restricted": "Seite nicht geschützt"
236
- "Page not visible": "Seite nicht in der Navigation sichtbar"
237
- "Page public": "Seite öffentlich"
238
- "Page restricted": "Seite geschützt"
239
- "Page visible": "Seite in der Navigation sichtbar"
232
+ "Page not public": "Seite ist nicht veröffentlicht"
233
+ "Page not restricted": "Seite ist nicht Passwort geschützt"
234
+ "Page not visible": "Seite ist nicht in der Navigation sichtbar"
235
+ "Page public": "Seite ist veröffentlicht"
236
+ "Page restricted": "Seite ist Passwort geschützt"
237
+ "Page visible": "Seite ist in der Navigation sichtbar"
240
238
  "Pages order saved": "Seitensortierung wurde gespeichert"
241
239
  "Password": "Passwort"
242
240
  "Paste from clipboard": "Aus Zwischenablage"
@@ -434,7 +432,7 @@ de:
434
432
  no_search_results: "Keine Suchergebnisse."
435
433
  "not a valid image": "Keine valide Bilddatei."
436
434
  "other Elements": "sonst. Elemente"
437
- "Page created.": "Seite '%{name}' wurde erstellt."
435
+ "Page created": "Seite '%{name}' wurde erstellt."
438
436
  page_for_links:
439
437
  choose_page: "%{name} wählen"
440
438
  page_locked: "Die Seite ist gesperrt"
@@ -682,6 +680,20 @@ de:
682
680
  name: "Name"
683
681
  public: "sichtbar"
684
682
 
683
+ alchemy/essence_picture:
684
+ caption: "Untertitel"
685
+ title: "Titel"
686
+ alt_tag: "Alternativ-Text"
687
+ link: Link
688
+ link_class_name: "Link CSS-Klasse"
689
+ link_title: Link-Titel
690
+ css_class: CSS-Klasse
691
+ link_target: Link-Ziel
692
+ render_size: Darstellungsgröße
693
+ crop_from: Bildmaskenursprung
694
+ crop_size: Bildmaskenausmaß
695
+ picture_id: Bild
696
+
685
697
  alchemy/language:
686
698
  code: "Sprachkürzel"
687
699
  default: "Standardsprache"
@@ -695,19 +707,19 @@ de:
695
707
  language: "Sprache"
696
708
  locked: "Die Seite ist gesperrt"
697
709
  locked_by: "Gesperrt durch"
698
- meta_description: "Meta Beschreibung"
699
- meta_keywords: "Meta Schlagwörter"
710
+ meta_description: "Seitenbeschreibung"
711
+ meta_keywords: "Suchbegriffe"
700
712
  name: "Name"
701
713
  page_layout: "Seitentyp"
702
- public: "Seite veröffentlichen"
703
- resctricted: "Seite schützen"
714
+ public: "veröffentlicht"
715
+ restricted: "Passwort geschützt"
704
716
  robot_follow: "den Robot Links folgen lassen"
705
717
  robot_index: "durch Robot indizieren"
706
- sitemap: "in der Seitemap anzeigen"
718
+ sitemap: "in der Seitenübersicht sichtbar"
707
719
  title: "Seitentitel"
708
720
  updated_at: "Aktualisiert am"
709
721
  urlname: "URL-Name"
710
- visible: "in der Navigation anzeigen"
722
+ visible: "in der Navigation sichtbar"
711
723
 
712
724
  alchemy/picture:
713
725
  image_filename: "Dateiname"
@@ -208,6 +208,7 @@ en:
208
208
  document: "File"
209
209
  documents: "Files"
210
210
  download_file: "Download file '%{filename}'"
211
+ "Drag an element over to the element window to restore it": "Drag an element over to the element window to restore it."
211
212
  drag_to_sort: "Drag'n'Drop to sort images"
212
213
  edit_file_properties: "Edit Fileproperties"
213
214
  edit_image_properties: "Edit image properties."
@@ -278,7 +279,7 @@ en:
278
279
  no_more_elements_to_add: "No more elements available."
279
280
  no_search_results: "Your search did not return any results."
280
281
  "not a valid image": "This is not an valid image."
281
- "Page created.": "Page: '%{name}' created."
282
+ "Page created": "Page: '%{name}' created."
282
283
  page_for_links.choose_page: "Choose %{name}"
283
284
  page_locked: "This page is locked by another user."
284
285
  page_properties: "page properties"
@@ -503,14 +504,14 @@ en:
503
504
  name: "Name"
504
505
  page_layout: "Pagetype"
505
506
  public: "public"
506
- resctricted: "restricted"
507
+ restricted: "restricted"
507
508
  robot_follow: "robot may follow links"
508
509
  robot_index: "allow robot to index"
509
- sitemap: "show in sitemap"
510
+ sitemap: "visible in sitemap"
510
511
  title: "Title"
511
512
  updated_at: "Updated at"
512
513
  urlname: "Urlname"
513
- visible: "show in navigation"
514
+ visible: "visible in navigation"
514
515
 
515
516
  alchemy/picture:
516
517
  image_filename: "Filename"
@@ -49,6 +49,11 @@ Capistrano::Configuration.instance(:must_exist).load do
49
49
 
50
50
  end
51
51
 
52
+ desc "Upgrades production database to current Alchemy CMS version"
53
+ task :upgrade do
54
+ run "cd #{current_path} && RAILS_ENV=production #{rake} alchemy:upgrade"
55
+ end
56
+
52
57
  namespace :database_yml do
53
58
 
54
59
  desc "Creates the database.yml file"
@@ -22,7 +22,7 @@ module Alchemy
22
22
  #
23
23
  def self.t(msg, *args)
24
24
  options = args.extract_options!
25
- options[:default] = options[:default] ? options[:default] : msg.humanize
25
+ options[:default] = options[:default] ? options[:default] : msg.to_s.humanize
26
26
  scope = ['alchemy']
27
27
  case options[:scope].class.name
28
28
  when "Array"
@@ -61,7 +61,7 @@ module Alchemy
61
61
  def self.get_layouts_for_select(language_id, layoutpage = false)
62
62
  layouts_for_select = [ [ Alchemy::I18n.t("Please choose"), "" ] ]
63
63
  selectable_layouts(language_id, layoutpage).each do |layout|
64
- display_name = Alchemy::I18n.t("alchemy.page_layout_names.#{layout['name']}", :default => layout['name'].camelize)
64
+ display_name = Alchemy::I18n.t("page_layout_names.#{layout['name']}", :default => layout['name'].camelize)
65
65
  layouts_for_select << [display_name, layout["name"]]
66
66
  end
67
67
  layouts_for_select
@@ -0,0 +1,27 @@
1
+ # A custom WillPaginate LinkRenderer Class for scoping the urls.
2
+ require 'will_paginate/view_helpers/action_view'
3
+
4
+ module Alchemy
5
+ class ScopedPaginationLinkRenderer < WillPaginate::ActionView::LinkRenderer
6
+
7
+ def url(page)
8
+ @base_url_params ||= begin
9
+ url_params = merge_get_params(default_url_params)
10
+ merge_optional_params(url_params)
11
+ end
12
+
13
+ url_params = @base_url_params.dup
14
+ add_current_page_param(url_params, page)
15
+
16
+ if url_params[:scope]
17
+ scope = url_params[:scope]
18
+ url_params.delete(:scope)
19
+ url_params.delete(:controller)
20
+ scope.url_for(url_params)
21
+ else
22
+ @template.url_for(url_params)
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -1,5 +1,5 @@
1
1
  module Alchemy
2
2
 
3
- VERSION = "2.1.beta5"
3
+ VERSION = "2.1.beta6"
4
4
 
5
5
  end
@@ -17,7 +17,7 @@ if defined?(Rails) && Rails::VERSION::MAJOR == 3
17
17
  require 'alchemy/version'
18
18
  require 'alchemy/auth_engine'
19
19
  require 'alchemy/engine'
20
- %w(config essence page_layout modules remote_pagination_link_renderer tinymce i18n).each do |class_name|
20
+ %w(config essence page_layout modules scoped_pagination_link_renderer remote_pagination_link_renderer tinymce i18n).each do |class_name|
21
21
  require File.join(File.dirname(__FILE__), "alchemy", class_name)
22
22
  end
23
23
  require File.join(File.dirname(__FILE__), "alchemy", "seeder")
@@ -13,4 +13,23 @@ describe Alchemy::Admin::ContentsController do
13
13
  @element.ingredient('intro').should == "Peters Petshop"
14
14
  end
15
15
 
16
+ describe "#order" do
17
+
18
+ context "with content_ids in params" do
19
+
20
+ before(:each) do
21
+ @element = Factory(:element)
22
+ end
23
+
24
+ it "should reorder the contents" do
25
+ content_ids = @element.contents.essence_texts.collect(&:id)
26
+ post :order, {:content_ids => content_ids.reverse, :format => :js}
27
+ response.status.should == 200
28
+ @element.contents.essence_texts.collect(&:id).should == content_ids.reverse
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
16
35
  end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Alchemy::Admin::PagesController do
4
+
5
+ before(:each) do
6
+ activate_authlogic
7
+ Alchemy::UserSession.create Factory(:admin_user)
8
+ end
9
+
10
+ describe "#flush", :focus => true do
11
+
12
+ it "should remove the cache of all pages" do
13
+ post :flush, {:format => :js}
14
+ response.status.should == 200
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -17,7 +17,7 @@ describe Alchemy::BaseController do
17
17
  controller.session[:language_code].should == @language.code
18
18
  end
19
19
 
20
- it "should set the language from id as string", :focus => true do
20
+ it "should set the language from id as string" do
21
21
  @language = Factory(:language)
22
22
  controller.send :set_language_from, @language.id.to_s
23
23
  controller.session[:language_id].should == @language.id
@@ -37,4 +37,66 @@ describe Alchemy::PagesController do
37
37
 
38
38
  end
39
39
 
40
+ describe "Layout rendering" do
41
+
42
+ context "with param layout set to none" do
43
+
44
+ it "should not render a layout" do
45
+ get :show, :urlname => :home, :layout => false
46
+ response.body.should_not have_content('<head>')
47
+ end
48
+
49
+ end
50
+
51
+ context "with param layout set to a custom layout" do
52
+
53
+ before do
54
+ @custom_layout = Rails.root.join('app/views/layouts', 'custom.html.erb')
55
+ File.open(@custom_layout, 'w') do |custom_layout|
56
+ custom_layout.puts "<html>I am a custom layout</html>"
57
+ end
58
+ end
59
+
60
+ it "should render the custom layout" do
61
+ get :show, :urlname => :home, :layout => 'custom'
62
+ response.body.should have_content('I am a custom layout')
63
+ end
64
+
65
+ after do
66
+ FileUtils.rm(@custom_layout)
67
+ end
68
+
69
+ end
70
+
71
+ context "with application layout absent" do
72
+
73
+ it "should render pages layout" do
74
+ get :show, :urlname => :home
75
+ response.body.should_not have_content('I am the application layout')
76
+ end
77
+
78
+ end
79
+
80
+ context "with application layout present" do
81
+
82
+ before do
83
+ @app_layout = Rails.root.join('app/views/layouts', 'application.html.erb')
84
+ File.open(@app_layout, 'w') do |app_layout|
85
+ app_layout.puts "<html>I am the application layout</html>"
86
+ end
87
+ end
88
+
89
+ it "should render application layout" do
90
+ get :show, :urlname => :home
91
+ response.body.should have_content('I am the application layout')
92
+ end
93
+
94
+ after do
95
+ FileUtils.rm(@app_layout)
96
+ end
97
+
98
+ end
99
+
100
+ end
101
+
40
102
  end
File without changes
@@ -1,46 +1,73 @@
1
+ # Skipping on Travis-CI, because capybara-webkit does not install on travis.
2
+ unless ENV["CI"]
3
+
1
4
  require 'spec_helper'
2
5
 
3
- describe Alchemy::Admin::PagesController do
6
+ describe Alchemy::Admin::PagesController, :js => true do
4
7
 
5
- describe "language tree switching", :js => true do
8
+ describe "language tree switching" do
6
9
 
7
10
  context "in a multilangual environment" do
8
11
 
9
- before(:each) do
12
+ before(:all) do
10
13
  Factory.build(:admin_user).save_without_session_maintenance
11
- Factory(:language)
12
- Factory(:language_root_page, :language => Alchemy::Language.get_default, :name => 'Deutsch')
13
- Factory(:language_root_page, :name => 'Klingonian')
14
+ @language = Factory(:language)
15
+ @german_root = Factory(:language_root_page, :language => Alchemy::Language.get_default, :name => 'Deutsch')
16
+ @klingonian_root = Factory(:language_root_page, :name => 'Klingonian')
14
17
  end
15
18
 
16
19
  it "one should be able to switch the language tree" do
17
- pending "This driver does not execute javascript as it should"
18
20
  login_to_alchemy
19
21
  visit('/alchemy/admin/pages')
20
22
  page.select 'Klingonian', :from => 'language'
21
23
  within('#sitemap') { page.should have_content('Klingonian') }
22
24
  end
23
25
 
26
+ after(:all) {
27
+ @language.destroy
28
+ @klingonian_root.destroy
29
+ @german_root.destroy
30
+ }
31
+
24
32
  end
25
33
 
26
34
  context "with no language root page" do
27
35
 
28
- before(:each) do
36
+ before(:all) do
29
37
  Factory.build(:admin_user).save_without_session_maintenance
38
+ @language = Factory(:language)
30
39
  end
31
40
 
32
- it "it should display the form for creating or copy language root" do
33
- pending "This driver does not work."
41
+ it "it should display the form for creating language root" do
34
42
  login_to_alchemy
35
43
  visit('/alchemy/admin/pages')
36
- save_and_open_page
44
+ page.select 'Klingonian', :from => 'language'
37
45
  within('#archive_all') do
38
46
  page.should have_content('This language tree does not exist')
39
- page.should have_content('Do you want to copy')
40
- page.should have_content('do you want to create a new empty language tree')
41
47
  end
42
48
  end
43
49
 
50
+ after(:all) {
51
+ @language.destroy
52
+ }
53
+
54
+ end
55
+
56
+ end
57
+
58
+ describe "flush complete page cache" do
59
+
60
+ before(:all) do
61
+ Factory.build(:admin_user).save_without_session_maintenance
62
+ end
63
+
64
+ it "should remove the cache of all pages" do
65
+ login_to_alchemy
66
+ visit '/alchemy/admin/pages'
67
+ click_link 'Flush page cache'
68
+ within('#flash_notices') do
69
+ page.should have_content('Page cache flushed')
70
+ end
44
71
  end
45
72
 
46
73
  end
@@ -54,3 +81,5 @@ def login_to_alchemy
54
81
  fill_in('alchemy_user_session_password', :with => 's3cr3t')
55
82
  click_on('Login')
56
83
  end
84
+
85
+ end