alchemy_cms 3.1.0.beta1 → 3.1.0.beta2

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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +4 -2
  4. data/README.md +9 -1
  5. data/alchemy_cms.gemspec +24 -13
  6. data/app/assets/javascripts/alchemy/alchemy.autocomplete.js.coffee +1 -1
  7. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +1 -1
  8. data/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +9 -0
  9. data/app/assets/javascripts/alchemy/alchemy.js +4 -0
  10. data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +3 -2
  11. data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +2 -0
  12. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +43 -1
  13. data/app/assets/stylesheets/alchemy/_mixins.scss +1 -2
  14. data/app/assets/stylesheets/alchemy/archive.scss +1 -1
  15. data/app/assets/stylesheets/alchemy/base.scss +18 -1
  16. data/app/assets/stylesheets/alchemy/buttons.scss +5 -0
  17. data/app/assets/stylesheets/alchemy/dialogs.scss +0 -1
  18. data/app/assets/stylesheets/alchemy/frame.scss +17 -10
  19. data/app/assets/stylesheets/alchemy/menubar.css.scss +3 -0
  20. data/app/assets/stylesheets/alchemy/tables.scss +30 -8
  21. data/app/controllers/alchemy/admin/attachments_controller.rb +9 -1
  22. data/app/controllers/alchemy/admin/essence_files_controller.rb +3 -4
  23. data/app/controllers/alchemy/pages_controller.rb +20 -2
  24. data/app/models/alchemy/content.rb +2 -1
  25. data/app/models/alchemy/element.rb +1 -1
  26. data/app/views/alchemy/admin/attachments/_files_list.html.erb +22 -18
  27. data/app/views/alchemy/admin/attachments/index.html.erb +1 -1
  28. data/app/views/alchemy/admin/languages/_table.html.erb +29 -25
  29. data/app/views/alchemy/admin/languages/index.html.erb +1 -1
  30. data/app/views/alchemy/admin/pictures/info.html.erb +3 -2
  31. data/app/views/alchemy/admin/resources/_table.html.erb +17 -13
  32. data/app/views/alchemy/admin/resources/index.html.erb +1 -1
  33. data/app/views/alchemy/admin/sites/index.html.erb +1 -1
  34. data/app/views/alchemy/admin/tags/edit.html.erb +1 -1
  35. data/app/views/alchemy/admin/tags/index.html.erb +14 -10
  36. data/app/views/alchemy/essences/_essence_file_editor.html.erb +20 -24
  37. data/app/views/alchemy/messages/contact_form_mail.es.text.erb +12 -0
  38. data/app/views/layouts/alchemy/admin.html.erb +2 -0
  39. data/bin/alchemy +58 -26
  40. data/config/locales/alchemy.en.yml +2 -1
  41. data/config/locales/alchemy.es.yml +958 -0
  42. data/config/locales/alchemy.fr.yml +1 -1
  43. data/config/locales/alchemy.ru.yml +837 -0
  44. data/config/locales/simple_form.es.yml +6 -0
  45. data/config/locales/simple_form.ru.yml +25 -0
  46. data/lib/alchemy/engine.rb +11 -0
  47. data/lib/alchemy/essence.rb +12 -1
  48. data/lib/alchemy/resources_helper.rb +3 -1
  49. data/lib/alchemy/test_support/essence_shared_examples.rb +37 -0
  50. data/lib/alchemy/test_support/factories.rb +2 -0
  51. data/lib/alchemy/version.rb +1 -1
  52. data/lib/rails/generators/alchemy/module/templates/module_config.rb.tt +4 -2
  53. data/lib/rails/generators/alchemy/scaffold/files/alchemy.es.yml +31 -0
  54. data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +1 -0
  55. data/lib/rails/templates/alchemy.rb +2 -0
  56. data/lib/tasks/alchemy/install.rake +11 -7
  57. data/spec/controllers/admin/attachments_controller_spec.rb +21 -0
  58. data/spec/controllers/admin/essence_files_controller_spec.rb +13 -12
  59. data/spec/controllers/alchemy/api/contents_controller_spec.rb +4 -4
  60. data/spec/controllers/attachments_controller_spec.rb +18 -0
  61. data/spec/controllers/pages_controller_spec.rb +20 -3
  62. data/spec/dummy/db/migrate/20121026104128_create_events.rb +2 -0
  63. data/spec/dummy/db/schema.rb +5 -3
  64. data/spec/features/admin/resources_integration_spec.rb +5 -0
  65. data/spec/features/page_feature_spec.rb +20 -0
  66. data/spec/models/content_spec.rb +24 -2
  67. data/spec/models/element_spec.rb +11 -0
  68. data/spec/views/essences/essence_file_editor_spec.rb +61 -0
  69. data/vendor/assets/javascripts/jquery_plugins/jquery.floatThead.min.js +3 -0
  70. data/vendor/assets/javascripts/tinymce/langs/es.js +197 -0
  71. data/vendor/assets/javascripts/tinymce/langs/ru.js +197 -0
  72. metadata +53 -38
@@ -5,7 +5,15 @@ module Alchemy
5
5
 
6
6
  def index
7
7
  @attachments = Attachment.all
8
- @attachments = @attachments.tagged_with(params[:tagged_with]) if params[:tagged_with].present?
8
+ if params[:only].present?
9
+ @attachments = @attachments.where("file_mime_type LIKE '%#{params[:only]}%'")
10
+ end
11
+ if params[:except].present?
12
+ @attachments = @attachments.where("file_mime_type NOT LIKE '%#{params[:except]}%'")
13
+ end
14
+ if params[:tagged_with].present?
15
+ @attachments = @attachments.tagged_with(params[:tagged_with])
16
+ end
9
17
  @attachments = @attachments.find_paginated(params, 15, sort_order)
10
18
  @options = options_from_params
11
19
  if in_overlay?
@@ -6,14 +6,14 @@ module Alchemy
6
6
  helper "Alchemy::Admin::Contents"
7
7
 
8
8
  def edit
9
- @content = Content.find(params[:id])
9
+ @essence_file = EssenceFile.find(params[:id])
10
+ @content = @essence_file.content
10
11
  @options = options_from_params
11
- @essence_file = @content.essence
12
12
  end
13
13
 
14
14
  def update
15
15
  @essence_file = EssenceFile.find(params[:id])
16
- @essence_file.update_attributes(params[:essence_file])
16
+ @essence_file.update(params[:essence_file])
17
17
  end
18
18
 
19
19
  def assign
@@ -22,7 +22,6 @@ module Alchemy
22
22
  @content.essence.attachment = @attachment
23
23
  @options = options_from_params
24
24
  end
25
-
26
25
  end
27
26
  end
28
27
  end
@@ -81,7 +81,10 @@ module Alchemy
81
81
  redirect_to signup_path
82
82
  elsif @page.nil? && last_legacy_url
83
83
  @page = last_legacy_url.page
84
- redirect_page
84
+
85
+ # This drops the given query string.
86
+ redirect_legacy_page
87
+
85
88
  elsif @page.blank?
86
89
  raise_not_found_error
87
90
  elsif multi_language? && params[:lang].blank?
@@ -131,6 +134,17 @@ module Alchemy
131
134
  redirect_to show_page_path(additional_params.merge(options)), :status => 301
132
135
  end
133
136
 
137
+ # Use the bare minimum to redirect to @page
138
+ # Don't use query string of legacy urlname
139
+ def redirect_legacy_page(options={})
140
+ defaults = {
141
+ :lang => (multi_language? ? @page.language_code : nil),
142
+ :urlname => @page.urlname
143
+ }
144
+ options = defaults.merge(options)
145
+ redirect_to show_page_path(options), :status => 301
146
+ end
147
+
134
148
  def additional_params
135
149
  params.each do |key, value|
136
150
  params[key] = nil if ["action", "controller", "urlname", "lang"].include?(key)
@@ -138,7 +152,11 @@ module Alchemy
138
152
  end
139
153
 
140
154
  def legacy_urls
141
- LegacyPageUrl.joins(:page).where(urlname: params[:urlname], alchemy_pages: {language_id: Language.current.id})
155
+
156
+ # /slug/tree => slug/tree
157
+ urlname = (request.fullpath[1..-1] if request.fullpath[0] == '/') || request.fullpath
158
+
159
+ LegacyPageUrl.joins(:page).where(urlname: urlname, alchemy_pages: {language_id: Language.current.id})
142
160
  end
143
161
 
144
162
  def last_legacy_url
@@ -25,6 +25,7 @@ module Alchemy
25
25
 
26
26
  belongs_to :essence, :polymorphic => true, :dependent => :destroy
27
27
  belongs_to :element, touch: true
28
+ has_one :page, through: :element
28
29
 
29
30
  stampable stamper_class_name: Alchemy.user_class_name
30
31
 
@@ -56,7 +57,7 @@ module Alchemy
56
57
  scope :not_trashed, -> { joins(:element).merge(Element.not_trashed) }
57
58
  scope :not_restricted, -> { joins(:element).merge(Element.not_restricted) }
58
59
 
59
- delegate :restricted?, to: :element, allow_nil: true
60
+ delegate :restricted?, to: :page, allow_nil: true
60
61
  delegate :trashed?, to: :element, allow_nil: true
61
62
  delegate :public?, to: :element, allow_nil: true
62
63
 
@@ -361,7 +361,7 @@ module Alchemy
361
361
  "fields.#{content_name}.#{error}".to_sym,
362
362
  "errors.#{error}".to_sym
363
363
  ],
364
- field: Content.translated_label_for(content_name)
364
+ field: Content.translated_label_for(content_name, name)
365
365
  )
366
366
  end
367
367
  end
@@ -11,25 +11,29 @@
11
11
  <% end %>
12
12
  <table id="all_files" class="list">
13
13
  <% unless @attachments.blank? %>
14
- <tr>
15
- <th class="icon"></th>
16
- <th class="name">
17
- <%= sortable_column(Alchemy::Attachment.human_attribute_name('name'), :column => :name) %>
18
- </th>
19
- <th class="file_name">
20
- <%= sortable_column(Alchemy::Attachment.human_attribute_name('file_name'), :column => :file_name) %>
21
- </th>
22
- <th class="file_type"><%= Alchemy::Attachment.human_attribute_name('file_mime_type') %></th>
23
- <th class="file_size">
24
- <%= sortable_column(Alchemy::Attachment.human_attribute_name('file_size'), :column => :file_size) %>
25
- </th>
26
- <th class="date">
27
- <%= sortable_column(Alchemy::Attachment.human_attribute_name('created_at'), :column => :created_at) %>
28
- </th>
29
- <th class="tools"></th>
30
- </tr>
14
+ <thead>
15
+ <tr>
16
+ <th class="icon"></th>
17
+ <th class="name">
18
+ <%= sortable_column(Alchemy::Attachment.human_attribute_name('name'), column: :name) %>
19
+ </th>
20
+ <th class="file_name">
21
+ <%= sortable_column(Alchemy::Attachment.human_attribute_name('file_name'), column: :file_name) %>
22
+ </th>
23
+ <th class="file_type"><%= Alchemy::Attachment.human_attribute_name('file_mime_type') %></th>
24
+ <th class="file_size">
25
+ <%= sortable_column(Alchemy::Attachment.human_attribute_name('file_size'), column: :file_size) %>
26
+ </th>
27
+ <th class="date">
28
+ <%= sortable_column(Alchemy::Attachment.human_attribute_name('created_at'), column: :created_at) %>
29
+ </th>
30
+ <th class="tools"></th>
31
+ </tr>
32
+ </thead>
31
33
  <% end %>
32
- <%= render :partial => 'alchemy/admin/attachments/attachment', :collection => @attachments %>
34
+ <tbody>
35
+ <%= render partial: 'alchemy/admin/attachments/attachment', collection: @attachments %>
36
+ </tbody>
33
37
  </table>
34
38
 
35
39
  <%= paginate @attachments, theme: 'alchemy' %>
@@ -16,7 +16,7 @@
16
16
  }
17
17
  ]
18
18
  ) %>
19
- <div id="archive_all" class="<%= any_tags ? 'with_tag_filter' : nil %>">
19
+ <div id="archive_all" class="<%= any_tags ? 'with_tag_filter ' : nil %>resources-table-wrapper">
20
20
  <%= resources_header %>
21
21
  <%= render partial: 'files_list' %>
22
22
  <% if any_tags %>
@@ -1,30 +1,34 @@
1
1
  <%- if @languages.any? -%>
2
2
  <table class="list" id="languages_list">
3
- <tr>
4
- <th>
5
- <%= sortable_column(Alchemy::Language.human_attribute_name(:name), :column => :name) %>
6
- </th>
7
- <th>
8
- <%= sortable_column(Alchemy::Language.human_attribute_name(:language_code), :column => :language_code) %>
9
- </th>
10
- <th>
11
- <%= sortable_column(Alchemy::Language.human_attribute_name(:country_code), :column => :country_code) %>
12
- </th>
13
- <th>
14
- <%= Alchemy::Language.human_attribute_name(:frontpage_name) %>
15
- </th>
16
- <th>
17
- <%= Alchemy::Language.human_attribute_name(:page_layout) %>
18
- </th>
19
- <th class="center">
20
- <%= Alchemy::Language.human_attribute_name(:public) %>
21
- </th>
22
- <th class="center">
23
- <%= Alchemy::Language.human_attribute_name(:default) %>
24
- </th>
25
- <th class="tools"></th>
26
- </tr>
27
- <%= render_resources %>
3
+ <thead>
4
+ <tr>
5
+ <th>
6
+ <%= sortable_column(Alchemy::Language.human_attribute_name(:name), column: :name) %>
7
+ </th>
8
+ <th>
9
+ <%= sortable_column(Alchemy::Language.human_attribute_name(:language_code), column: :language_code) %>
10
+ </th>
11
+ <th>
12
+ <%= sortable_column(Alchemy::Language.human_attribute_name(:country_code), column: :country_code) %>
13
+ </th>
14
+ <th>
15
+ <%= Alchemy::Language.human_attribute_name(:frontpage_name) %>
16
+ </th>
17
+ <th>
18
+ <%= Alchemy::Language.human_attribute_name(:page_layout) %>
19
+ </th>
20
+ <th class="center">
21
+ <%= Alchemy::Language.human_attribute_name(:public) %>
22
+ </th>
23
+ <th class="center">
24
+ <%= Alchemy::Language.human_attribute_name(:default) %>
25
+ </th>
26
+ <th class="tools"></th>
27
+ </tr>
28
+ </thead>
29
+ <tbody>
30
+ <%= render_resources %>
31
+ </tbody>
28
32
  </table>
29
33
  <%- elsif params[:query] -%>
30
34
  <p><%= _t('Nothing found') %></p>
@@ -17,7 +17,7 @@
17
17
  ]
18
18
  ) %>
19
19
 
20
- <div id="archive_all">
20
+ <div id="archive_all" class="resources-table-wrapper">
21
21
  <%= resources_header %>
22
22
  <%= render 'table' %>
23
23
  </div>
@@ -25,8 +25,9 @@
25
25
  <ul>
26
26
  <% essence_pictures.group_by(&:element).each do |element, essence_pictures| %>
27
27
  <li class="<%= cycle('even', 'odd') %>">
28
- <%= link_to element.display_name_with_preview_text, edit_admin_page_path(page, :anchor => "element_#{element.id}") %> in
29
- <%= essence_pictures.collect { |e| e.content.name_for_label }.to_sentence %>
28
+ <% page_link = link_to element.display_name_with_preview_text, edit_admin_page_path(page, :anchor => "element_#{element.id}") %>
29
+ <% pictures = essence_pictures.collect { |e| e.content.name_for_label }.to_sentence %>
30
+ <%= _t(:pictures_in_page, :page => page_link, :pictures => pictures) %>
30
31
  </li>
31
32
  <% end %>
32
33
  </ul>
@@ -1,18 +1,22 @@
1
1
  <% if resources_instance_variable.any? %>
2
2
  <table class="list" id="<%= resource_handler.resources_name %>_list">
3
- <tr>
4
- <% resource_handler.attributes.each do |attribute| %>
5
- <th class="<%= attribute[:type] %> <%= attribute[:name] %>">
6
- <%= sortable_column(
7
- resource_handler.model.human_attribute_name(attribute[:name]),
8
- :column => sortable_resource_header_column(attribute),
9
- :route_proxy => resource_url_proxy
10
- ) %>
11
- </th>
12
- <% end %>
13
- <th class="tools"></th>
14
- </tr>
15
- <%= render_resources %>
3
+ <thead>
4
+ <tr>
5
+ <% resource_handler.attributes.each do |attribute| %>
6
+ <th class="<%= attribute[:type] %> <%= attribute[:name] %>">
7
+ <%= sortable_column(
8
+ resource_handler.model.human_attribute_name(attribute[:name]),
9
+ :column => sortable_resource_header_column(attribute),
10
+ :route_proxy => resource_url_proxy
11
+ ) %>
12
+ </th>
13
+ <% end %>
14
+ <th class="tools"></th>
15
+ </tr>
16
+ </thead>
17
+ <tbody>
18
+ <%= render_resources %>
19
+ </tbody>
16
20
  </table>
17
21
  <% elsif params[:query] %>
18
22
  <p><%= _t('Nothing found') %></p>
@@ -26,7 +26,7 @@
26
26
  ]
27
27
  ) %>
28
28
 
29
- <div id="archive_all">
29
+ <div id="archive_all" class="resources-table-wrapper">
30
30
  <%= resources_header %>
31
31
  <%= render 'table' %>
32
32
  </div>
@@ -17,7 +17,7 @@
17
17
  ]
18
18
  ) %>
19
19
 
20
- <div id="archive_all">
20
+ <div id="archive_all" class="resources-table-wrapper">
21
21
  <%= resources_header %>
22
22
  <%= render 'table' %>
23
23
  </div>
@@ -11,7 +11,7 @@
11
11
  <%= _t(:or_replace_it_with_an_existing_tag) %>
12
12
  <% end %>
13
13
  <div class="input tags">
14
- <label class="control-label">Tags</label>
14
+ <label class="control-label"><%= _t('Tags') %></label>
15
15
  <div class="control_group" id="tags_tag_list">
16
16
  <%= js_filter_field '#tag_list li' %>
17
17
  <ul id="tag_list" class="tags">
@@ -15,22 +15,26 @@
15
15
  ]
16
16
  ) %>
17
17
 
18
- <div id="archive_all">
19
- <h1>
18
+ <div id="archive_all" class="resources-table-wrapper">
19
+ <h1 class="resources-header">
20
20
  <%= @tags.total_count %>
21
21
  <%= ActsAsTaggableOn::Tag.model_name.human(count: @tags.total_count) %>
22
22
  </h1>
23
23
  <% if @tags.any? %>
24
24
 
25
25
  <table class="list" id="tag_list">
26
- <tr class="legend">
27
- <th class="icon"></th>
28
- <th class="name"><%= sortable_column(ActsAsTaggableOn::Tag.human_attribute_name(:name), column: :name) %></th>
29
- <th class="count"><%= ActsAsTaggableOn::Tag.human_attribute_name(:taggings_types) %></th>
30
- <th class="count"><%= sortable_column(ActsAsTaggableOn::Tag.human_attribute_name(:taggings_count), column: :taggings_count) %></th>
31
- <th class="tools"></th>
32
- </tr>
33
- <%= render partial: 'tag', collection: @tags %>
26
+ <thead>
27
+ <tr>
28
+ <th class="icon"></th>
29
+ <th class="name"><%= sortable_column(ActsAsTaggableOn::Tag.human_attribute_name(:name), column: :name) %></th>
30
+ <th class="count"><%= ActsAsTaggableOn::Tag.human_attribute_name(:taggings_types) %></th>
31
+ <th class="count"><%= sortable_column(ActsAsTaggableOn::Tag.human_attribute_name(:taggings_count), column: :taggings_count) %></th>
32
+ <th class="tools"></th>
33
+ </tr>
34
+ </thead>
35
+ <tbody>
36
+ <%= render partial: 'tag', collection: @tags %>
37
+ </tbody>
34
38
  </table>
35
39
 
36
40
  <%= paginate @tags, theme: 'alchemy' %>
@@ -3,11 +3,9 @@
3
3
  <% dialog_link = link_to_dialog('',
4
4
  alchemy.admin_attachments_path(
5
5
  content_id: content.id,
6
- only: content_settings_value(content,
7
- :file_assign_show_only,
6
+ only: content_settings_value(content, :only,
8
7
  local_assigns.fetch(:options, {})),
9
- except: content_settings_value(content,
10
- :file_assign_do_not_show,
8
+ except: content_settings_value(content, :except,
11
9
  local_assigns.fetch(:options, {})),
12
10
  options: local_assigns.fetch(:options, {}).to_json
13
11
  ),
@@ -26,35 +24,33 @@
26
24
  <%= label_and_remove_link(content) %>
27
25
  <div class="file" id="file_<%= content.id %>">
28
26
  <div class="file_icon">
29
- <% if content.ingredient.nil? %>
30
- <%= dialog_link %>
31
- <% else %>
27
+ <% if content.ingredient %>
32
28
  <%= render_icon(content.ingredient.icon_css_class) %>
29
+ <% else %>
30
+ <%= dialog_link %>
33
31
  <% end %>
34
32
  </div>
35
33
  <div class="file_name">
36
34
  <%= content.ingredient.try(:name) ||
37
35
  ("&#x2190;" + _t(:assign_file_from_archive)).html_safe %>
38
36
  </div>
39
- <% unless content.ingredient.nil? %>
37
+ <div class="essence_file_tools">
38
+ <%= dialog_link %>
39
+ <%= link_to_dialog '',
40
+ alchemy.edit_admin_essence_file_path(
41
+ id: content.essence.id,
42
+ options: local_assigns.fetch(:options, {}).to_json
43
+ ),
44
+ {
45
+ title: _t(:edit_file_properties),
46
+ size: '400x165'
47
+ },
48
+ class: 'edit_file',
49
+ title: _t(:edit_file_properties) %>
50
+ </div>
51
+ <% if content.ingredient %>
40
52
  <%= hidden_field_tag content.form_field_name(:attachment_id),
41
53
  content.ingredient.id %>
42
- <div class="essence_file_tools">
43
- <%= dialog_link %>
44
- <%= link_to_dialog '',
45
- url_for(
46
- controller: 'essence_files',
47
- action: 'edit',
48
- options: local_assigns.fetch(:options, {}).to_json,
49
- id: content
50
- ),
51
- {
52
- title: _t(:edit_file_properties),
53
- size: '400x165'
54
- },
55
- class: 'edit_file',
56
- title: _t(:edit_file_properties) %>
57
- </div>
58
54
  <% end %>
59
55
  </div>
60
56
  </div>
@@ -0,0 +1,12 @@
1
+ <%= @message.message %>
2
+
3
+ --
4
+
5
+ Remitente:
6
+
7
+ <%= Alchemy::I18n.t(@message.salutation, scope: 'contactform.labels') %> <%= @message.firstname %> <%= @message.lastname %>
8
+ <%= @message.address %>
9
+ <%= @message.zip %> <%= @message.city %>
10
+
11
+ Teléfono: <%= @message.phone %>
12
+ Correo electrónico: <%= @message.email %>
@@ -96,6 +96,8 @@
96
96
  <script>
97
97
  // Store current locale for javascript translations.
98
98
  Alchemy.locale = '<%= ::I18n.locale %>';
99
+ // Setting the correct locale for select2 dropdown replacement.
100
+ $.extend($.fn.select2.defaults, $.fn.select2.locales['<%= ::I18n.locale %>']);
99
101
  </script>
100
102
  <%= yield(:javascripts) %>
101
103
  </body>