alchemy_cms 3.0.0 → 3.0.1
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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/README.md +3 -6
- data/alchemy_cms.gemspec +1 -1
- data/app/assets/stylesheets/alchemy/buttons.scss +4 -4
- data/app/assets/stylesheets/alchemy/sitemap.scss +1 -1
- data/app/controllers/alchemy/pages_controller.rb +5 -5
- data/app/helpers/alchemy/admin/elements_helper.rb +3 -3
- data/app/helpers/alchemy/admin/navigation_helper.rb +2 -1
- data/app/models/alchemy/cell.rb +1 -1
- data/app/models/alchemy/element.rb +10 -0
- data/app/models/alchemy/page/page_naming.rb +10 -3
- data/app/models/alchemy/picture.rb +6 -2
- data/app/views/alchemy/admin/pages/_page.html.erb +1 -1
- data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
- data/app/views/alchemy/admin/pages/info.html.erb +10 -1
- data/app/views/alchemy/base/leave.html.erb +1 -1
- data/config/locales/alchemy.de.yml +1 -1
- data/config/locales/alchemy.en.yml +3 -3
- data/config/locales/alchemy.fr.yml +1 -1
- data/config/locales/alchemy.nl.yml +1 -1
- data/lib/alchemy/test_support/factories.rb +4 -4
- data/lib/alchemy/version.rb +1 -1
- data/lib/rails/generators/alchemy/essence/essence_generator.rb +1 -1
- data/lib/rails/generators/alchemy/essence/templates/editor.html.erb +1 -1
- data/spec/features/page_feature_spec.rb +20 -0
- data/spec/helpers/admin/elements_helper_spec.rb +11 -2
- data/spec/helpers/admin/navigation_helper_spec.rb +30 -0
- data/spec/models/element_spec.rb +27 -4
- data/spec/models/page_spec.rb +10 -7
- data/spec/models/picture_spec.rb +19 -0
- data/vendor/assets/javascripts/tinymce/langs/fr.js +184 -0
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 22899ddac5bccee25b1e3438bcec28374381edc6
|
|
4
|
+
data.tar.gz: 92792959062f3873ff293a491a7c981e83ed2797
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ec3084ada69925e12a6458ed3768d4f63e23c3b20def9ebe63543946b05ad3d4288fd040ef20c88fa2857a0c123daa8462ef2f87d2facaa8b78ff7dd4926eea7
|
|
7
|
+
data.tar.gz: 8f0f74f54d0b903c5d02c445107ea8358927c5faa2ff4ab30ac37f0b1612f92ef63ed00d9b4bdbe6cb856200d43664e82754e4d197200a044fe84e797b8dc2c3
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|

|
|
2
2
|
|
|
3
3
|
[](http://badge.fury.io/rb/alchemy_cms)
|
|
4
|
-
[](https://travis-ci.org/magiclabs/alchemy_cms) [](https://codeclimate.com/github/magiclabs/alchemy_cms) [](https://coveralls.io/r/magiclabs/alchemy_cms?branch=3.0-stable)
|
|
5
5
|
|
|
6
6
|
About
|
|
7
7
|
-----
|
|
@@ -10,9 +10,6 @@ Alchemy is the most powerful, userfriendly and flexible Rails CMS.
|
|
|
10
10
|
|
|
11
11
|
Read more on the [website](http://alchemy-cms.com) and in the [guidelines](http://guides.alchemy-cms.com).
|
|
12
12
|
|
|
13
|
-
**This master branch is a development branch that can contain bugs. For productive environments you should use the [current Ruby gem version](http://rubygems.org/gems/alchemy_cms/versions/3.0.0),
|
|
14
|
-
or the [latest stable branch (3.0-stable)](https://github.com/magiclabs/alchemy_cms/tree/3.0-stable).**
|
|
15
|
-
|
|
16
13
|
Features
|
|
17
14
|
--------
|
|
18
15
|
|
|
@@ -60,7 +57,7 @@ Installation
|
|
|
60
57
|
|
|
61
58
|
#### 1. Use the installer:
|
|
62
59
|
|
|
63
|
-
gem install alchemy_cms
|
|
60
|
+
gem install alchemy_cms
|
|
64
61
|
alchemy new my_magicpage
|
|
65
62
|
cd my_magicpage
|
|
66
63
|
|
|
@@ -84,7 +81,7 @@ Open `http://localhost:3000` and follow the on screen instructions.
|
|
|
84
81
|
|
|
85
82
|
In your App's Gemfile:
|
|
86
83
|
|
|
87
|
-
gem 'alchemy_cms', github: 'magiclabs/alchemy_cms', branch: '
|
|
84
|
+
gem 'alchemy_cms', github: 'magiclabs/alchemy_cms', branch: '3.0-stable'
|
|
88
85
|
|
|
89
86
|
#### 2. Install Alchemy into your app:
|
|
90
87
|
|
data/alchemy_cms.gemspec
CHANGED
|
@@ -25,7 +25,7 @@ Gem::Specification.new do |gem|
|
|
|
25
25
|
gem.add_runtime_dependency 'acts-as-taggable-on', '~> 3.1'
|
|
26
26
|
gem.add_runtime_dependency 'cancan', '~> 1.6.10'
|
|
27
27
|
gem.add_runtime_dependency 'dragonfly', '~> 1.0.1'
|
|
28
|
-
gem.add_runtime_dependency 'kaminari', '~> 0.15
|
|
28
|
+
gem.add_runtime_dependency 'kaminari', '~> 0.15'
|
|
29
29
|
gem.add_runtime_dependency 'acts_as_list', '~> 0.3.0'
|
|
30
30
|
gem.add_runtime_dependency 'magiclabs-userstamp', '~> 2.1.0'
|
|
31
31
|
gem.add_runtime_dependency 'simple_form', '~> 3.0.1'
|
|
@@ -117,12 +117,12 @@ button, input[type="submit"], a.button, input.button {
|
|
|
117
117
|
border: $default-border-width $default-border-style $button-hover-border-color;
|
|
118
118
|
@include border-radius($default-border-radius);
|
|
119
119
|
background: $button-hover-bg-color;
|
|
120
|
-
top:
|
|
121
|
-
right:
|
|
120
|
+
top: -1px;
|
|
121
|
+
right: -1px;
|
|
122
122
|
|
|
123
123
|
.icon {
|
|
124
|
-
left:
|
|
125
|
-
top:
|
|
124
|
+
left: 1px;
|
|
125
|
+
top: 3px;
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
}
|
|
@@ -8,20 +8,20 @@ module Alchemy
|
|
|
8
8
|
|
|
9
9
|
rescue_from ActionController::RoutingError, :with => :render_404
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
before_filter :load_page
|
|
14
|
-
authorize_resource only: 'show'
|
|
11
|
+
before_action :enforce_primary_host_for_site
|
|
12
|
+
before_action :render_page_or_redirect, only: [:show]
|
|
15
13
|
|
|
16
14
|
# Showing page from params[:urlname]
|
|
17
15
|
#
|
|
18
16
|
def show
|
|
17
|
+
authorize! :show, @page
|
|
18
|
+
|
|
19
19
|
if render_fresh_page?
|
|
20
20
|
respond_to do |format|
|
|
21
21
|
format.html { render layout: !request.xhr? }
|
|
22
22
|
format.rss do
|
|
23
23
|
if @page.contains_feed?
|
|
24
|
-
render
|
|
24
|
+
render layout: false, handlers: [:builder]
|
|
25
25
|
else
|
|
26
26
|
render xml: {error: 'Not found'}, status: 404
|
|
27
27
|
end
|
|
@@ -72,12 +72,12 @@ module Alchemy
|
|
|
72
72
|
end
|
|
73
73
|
other_elements = elements - celled_elements
|
|
74
74
|
unless other_elements.blank?
|
|
75
|
-
|
|
76
|
-
options[optgroup_label] = other_elements.map do |e|
|
|
75
|
+
options[_t(:main_content)] = other_elements.map do |e|
|
|
77
76
|
element_array_for_options(e, object_method)
|
|
78
77
|
end
|
|
79
78
|
end
|
|
80
|
-
|
|
79
|
+
# We don't want to show empty cells
|
|
80
|
+
options.delete_if { |cell, elements| elements.blank? }
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
def element_array_for_options(e, object_method, cell = nil)
|
data/app/models/alchemy/cell.rb
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
#
|
|
20
20
|
# Render cells with the +render_cell+ helper
|
|
21
21
|
#
|
|
22
|
-
# Views for cells are inside the +app/views/cells+ folder in
|
|
22
|
+
# Views for cells are inside the +app/views/cells+ folder in your project.
|
|
23
23
|
#
|
|
24
24
|
module Alchemy
|
|
25
25
|
class Cell < ActiveRecord::Base
|
|
@@ -47,6 +47,7 @@ module Alchemy
|
|
|
47
47
|
|
|
48
48
|
after_create :create_contents, :unless => proc { |e| e.create_contents_after_create == false }
|
|
49
49
|
after_update :touch_pages
|
|
50
|
+
after_update :touch_cell, unless: -> { self.cell.nil? }
|
|
50
51
|
|
|
51
52
|
scope :trashed, -> { where(position: nil).order('updated_at DESC') }
|
|
52
53
|
scope :not_trashed, -> { where(Element.arel_table[:position].not_eq(nil)) }
|
|
@@ -461,5 +462,14 @@ module Alchemy
|
|
|
461
462
|
available_page_cells(page).collect(&:name).uniq
|
|
462
463
|
end
|
|
463
464
|
|
|
465
|
+
# If element has a +cell+ associated,
|
|
466
|
+
# it updates it's timestamp.
|
|
467
|
+
#
|
|
468
|
+
# Called after_update
|
|
469
|
+
#
|
|
470
|
+
def touch_cell
|
|
471
|
+
self.cell.touch
|
|
472
|
+
end
|
|
473
|
+
|
|
464
474
|
end
|
|
465
475
|
end
|
|
@@ -72,11 +72,11 @@ module Alchemy
|
|
|
72
72
|
def set_urlname
|
|
73
73
|
if Config.get(:url_nesting)
|
|
74
74
|
url_name = [
|
|
75
|
-
|
|
76
|
-
convert_url_name(
|
|
75
|
+
parent_urlname,
|
|
76
|
+
convert_url_name(urlname.blank? ? name : slug)
|
|
77
77
|
].compact.join('/')
|
|
78
78
|
else
|
|
79
|
-
url_name = convert_url_name(
|
|
79
|
+
url_name = convert_url_name(urlname.blank? ? name : urlname)
|
|
80
80
|
end
|
|
81
81
|
write_attribute :urlname, url_name
|
|
82
82
|
end
|
|
@@ -98,5 +98,12 @@ module Alchemy
|
|
|
98
98
|
url_name
|
|
99
99
|
end
|
|
100
100
|
end
|
|
101
|
+
|
|
102
|
+
# Urlname of parent page.
|
|
103
|
+
# Returns nil, if the parent is either a language root page or the root page itself
|
|
104
|
+
def parent_urlname
|
|
105
|
+
return if parent.nil? || parent.language_root? || parent.root?
|
|
106
|
+
parent.urlname
|
|
107
|
+
end
|
|
101
108
|
end
|
|
102
109
|
end
|
|
@@ -39,9 +39,13 @@ module Alchemy
|
|
|
39
39
|
raise PictureInUseError, I18n.t(:cannot_delete_picture_notice) % { name: name }
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
+
# Enables Dragonfly image processing
|
|
42
43
|
dragonfly_accessor :image_file, app: :alchemy_pictures do
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
# Preprocess after uploading the picture
|
|
45
|
+
after_assign do |p|
|
|
46
|
+
if Config.get(:preprocess_image_resize).present?
|
|
47
|
+
p.thumb!("#{Config.get(:preprocess_image_resize)}>")
|
|
48
|
+
end
|
|
45
49
|
end
|
|
46
50
|
end
|
|
47
51
|
|
|
@@ -5,9 +5,18 @@
|
|
|
5
5
|
<% end %>
|
|
6
6
|
<% end %>
|
|
7
7
|
<div class="value">
|
|
8
|
-
<label><%=
|
|
8
|
+
<label><%= Alchemy::Page.human_attribute_name(:page_layout) %></label>
|
|
9
9
|
<p><%= @page.layout_display_name %></p>
|
|
10
10
|
</div>
|
|
11
|
+
<div class="value">
|
|
12
|
+
<% if @page.redirects_to_external? %>
|
|
13
|
+
<label><%= Alchemy::Page.human_attribute_name(:urlname) %></label>
|
|
14
|
+
<p><%= @page.urlname %></p>
|
|
15
|
+
<% else %>
|
|
16
|
+
<label><%= Alchemy::LegacyPageUrl.human_attribute_name(:urlname) %></label>
|
|
17
|
+
<p><%= "/#{@page.urlname}" %></p>
|
|
18
|
+
<% end %>
|
|
19
|
+
</div>
|
|
11
20
|
<div class="value">
|
|
12
21
|
<label><%= _t(:page_status) %></label>
|
|
13
22
|
<p><%= combined_page_status(@page) %></p>
|
|
@@ -6,6 +6,6 @@
|
|
|
6
6
|
<%= link_to _t('stay logged in'), alchemy.root_path, class: 'button' %>
|
|
7
7
|
</p>
|
|
8
8
|
<%= form_tag Alchemy.logout_path, method: 'delete', class: 'buttons' do %>
|
|
9
|
-
<label><%= _t('or to
|
|
9
|
+
<label><%= _t('or to completely') %></label>
|
|
10
10
|
<%= button _t(:logout), autofocus: true %>
|
|
11
11
|
<% end %>
|
|
@@ -579,7 +579,7 @@ de:
|
|
|
579
579
|
"You are about to leave Alchemy": "Sie sind dabei Alchemy zu verlassen"
|
|
580
580
|
"Do you want to": "Wollen Sie dabei"
|
|
581
581
|
"stay logged in": "angemeldet bleiben"
|
|
582
|
-
"or to
|
|
582
|
+
"or to completely": "oder Sich komplett"
|
|
583
583
|
"Are you sure?": "Sind Sie sicher?"
|
|
584
584
|
"Create": "Hinzufügen"
|
|
585
585
|
"Edit": "Bearbeiten"
|
|
@@ -201,7 +201,7 @@ en:
|
|
|
201
201
|
"Hide Elements": "Hide Elements"
|
|
202
202
|
"If you have any problems using the Flash uploader you can switch to": "If you have any problems using the Flash uploader you can switch to %{link}"
|
|
203
203
|
"Image missing": "Image missing"
|
|
204
|
-
"Image size": "
|
|
204
|
+
"Image size": "Image size"
|
|
205
205
|
"Language successfully created": "Language successfully created."
|
|
206
206
|
"Language successfully removed": "Language successfully removed."
|
|
207
207
|
"Language successfully updated": "Language successfully updated."
|
|
@@ -244,7 +244,7 @@ en:
|
|
|
244
244
|
"Please enter a new password": "Please enter a new password."
|
|
245
245
|
"Please enter your email address": "Please enter your email address."
|
|
246
246
|
"Please log in": "Please log in."
|
|
247
|
-
"Please seperate the tags with commata": "* Please seperate the tags with
|
|
247
|
+
"Please seperate the tags with commata": "* Please seperate the tags with commas."
|
|
248
248
|
"Properties": "Properties"
|
|
249
249
|
"Publish page": "Publish page"
|
|
250
250
|
"Read the License": "Read the License"
|
|
@@ -579,7 +579,7 @@ en:
|
|
|
579
579
|
"You are about to leave Alchemy": "You are about to leave Alchemy"
|
|
580
580
|
"Do you want to": "Do you want to"
|
|
581
581
|
"stay logged in": "stay logged in"
|
|
582
|
-
"or to
|
|
582
|
+
"or to completely": "or to completely"
|
|
583
583
|
"Are you sure?": "Are you sure?"
|
|
584
584
|
"Create": "Create"
|
|
585
585
|
"Edit": "Edit"
|
|
@@ -605,7 +605,7 @@ fr:
|
|
|
605
605
|
"You are about to leave Alchemy": "Vous êtes sur le point de quitter l'Alchimie"
|
|
606
606
|
"Do you want to": "Voulez-vous "
|
|
607
607
|
"stay logged in": "rester connecté"
|
|
608
|
-
"or to
|
|
608
|
+
"or to completely": "ou vous-même complètement"
|
|
609
609
|
"Please wait. Flash® is loading...": "S'il vous plaît attendre. Uploader Flash ® est en cours de chargement..."
|
|
610
610
|
"Are you sure?": "Etes-vous sûr?"
|
|
611
611
|
"Create": "ajouter"
|
|
@@ -579,7 +579,7 @@ nl:
|
|
|
579
579
|
"You are about to leave Alchemy": "U staat op het punt de NVM Regiosite te verlaten"
|
|
580
580
|
"Do you want to": "Wilt u"
|
|
581
581
|
"stay logged in": "ingelogd blijven"
|
|
582
|
-
"or to
|
|
582
|
+
"or to completely": "of compleet"
|
|
583
583
|
"Are you sure?": "Weet u het zeker?"
|
|
584
584
|
"Create": "Aanmaken"
|
|
585
585
|
"Edit": "Aanpassen"
|
|
@@ -5,19 +5,19 @@ FactoryGirl.define do
|
|
|
5
5
|
password 's3cr3t'
|
|
6
6
|
|
|
7
7
|
factory :admin_user do
|
|
8
|
-
alchemy_roles 'admin'
|
|
8
|
+
alchemy_roles ['admin']
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
factory :member_user do
|
|
12
|
-
alchemy_roles 'member'
|
|
12
|
+
alchemy_roles ['member']
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
factory :author_user do
|
|
16
|
-
alchemy_roles 'author'
|
|
16
|
+
alchemy_roles ['author']
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
factory :editor_user do
|
|
20
|
-
alchemy_roles 'editor'
|
|
20
|
+
alchemy_roles ['editor']
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
|
data/lib/alchemy/version.rb
CHANGED
|
@@ -36,7 +36,7 @@ CLASSMETHOD
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def copy_templates
|
|
39
|
-
essence_name = @essence_name.classify.demodulize
|
|
39
|
+
essence_name = @essence_name.classify.demodulize.underscore
|
|
40
40
|
template "view.html.erb", "#{@essence_view_path}/_#{essence_name}_view.html.erb"
|
|
41
41
|
template "editor.html.erb", "#{@essence_view_path}/_#{essence_name}_editor.html.erb"
|
|
42
42
|
end
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
Please consult Alchemy::Content.rb docs for further methods on the content object
|
|
7
7
|
%>
|
|
8
8
|
<%% cache(content) do %>
|
|
9
|
-
<div class="content_editor <%= @essence_name.classify.demodulize %>" id="<%%= content.dom_id %>">
|
|
9
|
+
<div class="content_editor <%= @essence_name.classify.demodulize.underscore %>" id="<%%= content.dom_id %>" data-content-id="<%%= content.id %>">
|
|
10
10
|
<%%= label_and_remove_link(content) %>
|
|
11
11
|
<%%= text_field_tag(
|
|
12
12
|
content.form_field_name,
|
|
@@ -234,5 +234,25 @@ module Alchemy
|
|
|
234
234
|
end
|
|
235
235
|
end
|
|
236
236
|
|
|
237
|
+
describe 'accessing restricted pages' do
|
|
238
|
+
let!(:restricted_page) { create(:restricted_page, public: true) }
|
|
239
|
+
|
|
240
|
+
context 'as a guest user' do
|
|
241
|
+
it "I am not able to visit the page" do
|
|
242
|
+
visit restricted_page.urlname
|
|
243
|
+
current_path.should == Alchemy.login_path
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
context 'as a member user' do
|
|
248
|
+
before { authorize_as_admin(create(:member_user)) }
|
|
249
|
+
|
|
250
|
+
it "I am able to visit the page" do
|
|
251
|
+
visit restricted_page.urlname
|
|
252
|
+
current_path.should == "/#{restricted_page.urlname}"
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
|
|
237
257
|
end
|
|
238
258
|
end
|
|
@@ -26,8 +26,11 @@ module Alchemy
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
before do
|
|
29
|
-
page.stub(layout_description: {'name' => "foo", 'cells' => ["foo_cell"]})
|
|
30
|
-
cell_descriptions = [
|
|
29
|
+
page.stub(layout_description: {'name' => "foo", 'cells' => ["foo_cell", "empty_cell"]})
|
|
30
|
+
cell_descriptions = [
|
|
31
|
+
{'name' => "foo_cell", 'elements' => ["1", "2"]},
|
|
32
|
+
{'name' => 'empty_cell', 'elements' => []}
|
|
33
|
+
]
|
|
31
34
|
Cell.stub(:definitions).and_return(cell_descriptions)
|
|
32
35
|
helper.instance_variable_set('@page', page)
|
|
33
36
|
end
|
|
@@ -48,6 +51,12 @@ module Alchemy
|
|
|
48
51
|
helper.grouped_elements_for_select(elements).should == ""
|
|
49
52
|
end
|
|
50
53
|
end
|
|
54
|
+
|
|
55
|
+
context "with cell having no elements" do
|
|
56
|
+
it "should remove that cell from hash" do
|
|
57
|
+
expect(helper.grouped_elements_for_select(elements)['Empty cell']).to be_nil
|
|
58
|
+
end
|
|
59
|
+
end
|
|
51
60
|
end
|
|
52
61
|
|
|
53
62
|
describe "#elements_for_select" do
|
|
@@ -27,6 +27,24 @@ describe Alchemy::Admin::NavigationHelper do
|
|
|
27
27
|
}
|
|
28
28
|
} }
|
|
29
29
|
|
|
30
|
+
let(:event_module_with_params) { {
|
|
31
|
+
'navigation' => {
|
|
32
|
+
'controller' => '/admin/events',
|
|
33
|
+
'action' => 'index',
|
|
34
|
+
'params' => {
|
|
35
|
+
'key' => 'value'
|
|
36
|
+
},
|
|
37
|
+
'sub_navigation' => [{
|
|
38
|
+
'controller' => '/admin/events',
|
|
39
|
+
'action' => 'index',
|
|
40
|
+
'params' => {
|
|
41
|
+
'key' => 'value',
|
|
42
|
+
'key2' => 'value2'
|
|
43
|
+
}
|
|
44
|
+
}]
|
|
45
|
+
}
|
|
46
|
+
} }
|
|
47
|
+
|
|
30
48
|
let(:navigation) { alchemy_module['navigation'] }
|
|
31
49
|
|
|
32
50
|
describe '#alchemy_main_navigation_entry' do
|
|
@@ -180,6 +198,10 @@ describe Alchemy::Admin::NavigationHelper do
|
|
|
180
198
|
it "returns correct url string" do
|
|
181
199
|
helper.url_for_module(event_module).should == '/admin/events'
|
|
182
200
|
end
|
|
201
|
+
|
|
202
|
+
it "returns correct url string with params" do
|
|
203
|
+
helper.url_for_module(event_module_with_params).should == '/admin/events?key=value'
|
|
204
|
+
end
|
|
183
205
|
end
|
|
184
206
|
end
|
|
185
207
|
|
|
@@ -209,6 +231,14 @@ describe Alchemy::Admin::NavigationHelper do
|
|
|
209
231
|
end
|
|
210
232
|
end
|
|
211
233
|
|
|
234
|
+
context "with module within host app with params" do
|
|
235
|
+
let(:current_module) { event_module_with_params }
|
|
236
|
+
|
|
237
|
+
it "returns correct url string with params" do
|
|
238
|
+
should == '/admin/events?key2=value2&key=value'
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
212
242
|
context 'without module found' do
|
|
213
243
|
before do
|
|
214
244
|
helper.stub(module_definition_for: nil)
|
data/spec/models/element_spec.rb
CHANGED
|
@@ -422,16 +422,20 @@ module Alchemy
|
|
|
422
422
|
end
|
|
423
423
|
|
|
424
424
|
describe '.after_update' do
|
|
425
|
+
let(:page) { create(:page) }
|
|
426
|
+
let(:element) { create(:element, page: page) }
|
|
427
|
+
let(:now) { Time.now }
|
|
428
|
+
|
|
429
|
+
before do
|
|
430
|
+
Time.stub(now: now)
|
|
431
|
+
end
|
|
432
|
+
|
|
425
433
|
context 'with touchable pages' do
|
|
426
434
|
let(:locker) { mock_model('DummyUser') }
|
|
427
|
-
let(:page) { create(:page) }
|
|
428
|
-
let(:element) { create(:element, page: page) }
|
|
429
|
-
let(:now) { Time.now }
|
|
430
435
|
let(:pages) { [page] }
|
|
431
436
|
|
|
432
437
|
before do
|
|
433
438
|
Alchemy.user_class.stub(:stamper).and_return(locker.id)
|
|
434
|
-
Time.stub(now: now)
|
|
435
439
|
end
|
|
436
440
|
|
|
437
441
|
it "updates page timestamps" do
|
|
@@ -446,6 +450,25 @@ module Alchemy
|
|
|
446
450
|
page.updater_id.should eq(locker.id)
|
|
447
451
|
end
|
|
448
452
|
end
|
|
453
|
+
|
|
454
|
+
context 'with cell associated' do
|
|
455
|
+
let(:cell) { mock_model('Cell') }
|
|
456
|
+
|
|
457
|
+
before do
|
|
458
|
+
element.stub(cell: cell)
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
it "updates timestamp of cell" do
|
|
462
|
+
element.cell.should_receive(:touch)
|
|
463
|
+
element.save
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
context 'without cell associated' do
|
|
468
|
+
it "does not update timestamp of cell" do
|
|
469
|
+
expect { element.save }.to_not raise_error
|
|
470
|
+
end
|
|
471
|
+
end
|
|
449
472
|
end
|
|
450
473
|
|
|
451
474
|
describe '#taggable?' do
|
data/spec/models/page_spec.rb
CHANGED
|
@@ -1203,12 +1203,13 @@ module Alchemy
|
|
|
1203
1203
|
end
|
|
1204
1204
|
|
|
1205
1205
|
context 'urlname updating' do
|
|
1206
|
-
let(:parentparent)
|
|
1207
|
-
let(:parent)
|
|
1208
|
-
let(:page)
|
|
1209
|
-
let(:invisible)
|
|
1210
|
-
let(:contact)
|
|
1211
|
-
let(:external)
|
|
1206
|
+
let(:parentparent) { FactoryGirl.create(:page, name: 'parentparent', visible: true) }
|
|
1207
|
+
let(:parent) { FactoryGirl.create(:page, parent_id: parentparent.id, name: 'parent', visible: true) }
|
|
1208
|
+
let(:page) { FactoryGirl.create(:page, parent_id: parent.id, name: 'page', visible: true) }
|
|
1209
|
+
let(:invisible) { FactoryGirl.create(:page, parent_id: page.id, name: 'invisible', visible: false) }
|
|
1210
|
+
let(:contact) { FactoryGirl.create(:page, parent_id: invisible.id, name: 'contact', visible: true) }
|
|
1211
|
+
let(:external) { FactoryGirl.create(:page, parent_id: parent.id, name: 'external', page_layout: 'external', urlname: 'http://google.com') }
|
|
1212
|
+
let(:language_root) { parentparent.parent }
|
|
1212
1213
|
|
|
1213
1214
|
context "with activated url_nesting" do
|
|
1214
1215
|
before { Config.stub(:get).and_return(true) }
|
|
@@ -1218,7 +1219,9 @@ module Alchemy
|
|
|
1218
1219
|
end
|
|
1219
1220
|
|
|
1220
1221
|
it "should not include the root page" do
|
|
1221
|
-
|
|
1222
|
+
Page.root.update_column(:urlname, 'root')
|
|
1223
|
+
language_root.update(urlname: 'new-urlname')
|
|
1224
|
+
language_root.urlname.should_not =~ /root/
|
|
1222
1225
|
end
|
|
1223
1226
|
|
|
1224
1227
|
it "should not include the language root page" do
|
data/spec/models/picture_spec.rb
CHANGED
|
@@ -32,6 +32,25 @@ module Alchemy
|
|
|
32
32
|
picture.should be_valid
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
+
context 'with enabled preprocess_image_resize config option' do
|
|
36
|
+
let(:image_file) do
|
|
37
|
+
File.new(File.expand_path('../../fixtures/80x60.png', __FILE__))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
before do
|
|
41
|
+
Config.stub(:get) do |arg|
|
|
42
|
+
if arg == :preprocess_image_resize
|
|
43
|
+
'10x10'
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it "it resizes the image after upload" do
|
|
49
|
+
picture = Picture.new(image_file: image_file)
|
|
50
|
+
expect(picture.image_file.data[0x10..0x18].unpack('NN')).to eq([10, 8])
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
35
54
|
describe '#suffix' do
|
|
36
55
|
it "should return the suffix of original filename" do
|
|
37
56
|
pic = stub_model(Picture, image_file_name: 'kitten.JPG')
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
tinymce.addI18n('fr',{
|
|
2
|
+
"Cut": "Couper",
|
|
3
|
+
"Header 2": "Titre 2",
|
|
4
|
+
"Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "Votre navigateur ne supporte pas la copie directe. Merci d'utiliser les touches Ctrl+X\/C\/V.",
|
|
5
|
+
"Div": "Div",
|
|
6
|
+
"Paste": "Coller",
|
|
7
|
+
"Close": "Fermer",
|
|
8
|
+
"Font Family": "Polices de caract\u00e8res",
|
|
9
|
+
"Pre": "Pre",
|
|
10
|
+
"Align right": "Aligner \u00e0 droite",
|
|
11
|
+
"New document": "Nouveau document",
|
|
12
|
+
"Blockquote": "Citation",
|
|
13
|
+
"Numbered list": "Num\u00e9rotation",
|
|
14
|
+
"Increase indent": "Augmenter le retrait",
|
|
15
|
+
"Formats": "Formats",
|
|
16
|
+
"Headers": "Titres",
|
|
17
|
+
"Select all": "Tout s\u00e9lectionner",
|
|
18
|
+
"Header 3": "Titre 3",
|
|
19
|
+
"Blocks": "Blocs",
|
|
20
|
+
"Undo": "Annuler",
|
|
21
|
+
"Strikethrough": "Barr\u00e9",
|
|
22
|
+
"Bullet list": "Puces",
|
|
23
|
+
"Header 1": "Titre 1",
|
|
24
|
+
"Superscript": "Exposant",
|
|
25
|
+
"Clear formatting": "Effacer la mise en forme",
|
|
26
|
+
"Font Sizes": "Tailles de la police",
|
|
27
|
+
"Subscript": "Indice",
|
|
28
|
+
"Header 6": "Titre 6",
|
|
29
|
+
"Redo": "R\u00e9tablir",
|
|
30
|
+
"Paragraph": "Paragraphe",
|
|
31
|
+
"Ok": "Ok",
|
|
32
|
+
"Bold": "Gras",
|
|
33
|
+
"Code": "Code",
|
|
34
|
+
"Italic": "Italique",
|
|
35
|
+
"Align center": "Aligner au centre",
|
|
36
|
+
"Header 5": "Titre 5",
|
|
37
|
+
"Decrease indent": "Diminuer le retrait",
|
|
38
|
+
"Header 4": "Titre 4",
|
|
39
|
+
"Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "Le presse-papiers est maintenant en mode \"texte plein\". Les contenus seront coll\u00e9s sans retenir les formatages jusqu'\u00e0 ce que vous d\u00e9sactiviez cette option.",
|
|
40
|
+
"Underline": "Soulign\u00e9",
|
|
41
|
+
"Cancel": "Annuler",
|
|
42
|
+
"Justify": "Justifi\u00e9",
|
|
43
|
+
"Inline": "En ligne",
|
|
44
|
+
"Copy": "Copier",
|
|
45
|
+
"Align left": "Aligner \u00e0 gauche",
|
|
46
|
+
"Visual aids": "Aides visuelle",
|
|
47
|
+
"Lower Greek": "Grec minuscule",
|
|
48
|
+
"Square": "Carr\u00e9",
|
|
49
|
+
"Default": "Par d\u00e9faut",
|
|
50
|
+
"Lower Alpha": "Alpha minuscule",
|
|
51
|
+
"Circle": "Cercle",
|
|
52
|
+
"Disc": "Disque",
|
|
53
|
+
"Upper Alpha": "Alpha majuscule",
|
|
54
|
+
"Upper Roman": "Romain majuscule",
|
|
55
|
+
"Lower Roman": "Romain minuscule",
|
|
56
|
+
"Name": "Nom",
|
|
57
|
+
"Anchor": "Ancre",
|
|
58
|
+
"You have unsaved changes are you sure you want to navigate away?": "Vous avez des modifications non enregistr\u00e9es, \u00eates-vous s\u00fbr de quitter la page?",
|
|
59
|
+
"Restore last draft": "Restaurer le dernier brouillon",
|
|
60
|
+
"Special character": "Caract\u00e8res sp\u00e9ciaux",
|
|
61
|
+
"Source code": "Code source",
|
|
62
|
+
"Right to left": "Droite \u00e0 gauche",
|
|
63
|
+
"Left to right": "Gauche \u00e0 droite",
|
|
64
|
+
"Emoticons": "Emotic\u00f4nes",
|
|
65
|
+
"Robots": "Robots",
|
|
66
|
+
"Document properties": "Propri\u00e9t\u00e9 du document",
|
|
67
|
+
"Title": "Titre",
|
|
68
|
+
"Keywords": "Mots-cl\u00e9s",
|
|
69
|
+
"Encoding": "Encodage",
|
|
70
|
+
"Description": "Description",
|
|
71
|
+
"Author": "Auteur",
|
|
72
|
+
"Fullscreen": "Plein \u00e9cran",
|
|
73
|
+
"Horizontal line": "Ligne horizontale",
|
|
74
|
+
"Horizontal space": "Espacement horizontal",
|
|
75
|
+
"Insert\/edit image": "Ins\u00e9rer\/\u00e9diter une image",
|
|
76
|
+
"General": "G\u00e9n\u00e9ral",
|
|
77
|
+
"Advanced": "Avanc\u00e9",
|
|
78
|
+
"Source": "Source",
|
|
79
|
+
"Border": "Bordure",
|
|
80
|
+
"Constrain proportions": "Contraindre les proportions",
|
|
81
|
+
"Vertical space": "Espacement vertical",
|
|
82
|
+
"Image description": "Description de l'image",
|
|
83
|
+
"Style": "Style",
|
|
84
|
+
"Dimensions": "Dimensions",
|
|
85
|
+
"Insert image": "Ins\u00e9rer une image",
|
|
86
|
+
"Insert date\/time": "Ins\u00e9rer date\/heure",
|
|
87
|
+
"Remove link": "Enlever le lien",
|
|
88
|
+
"Url": "Url",
|
|
89
|
+
"Text to display": "Texte \u00e0 afficher",
|
|
90
|
+
"Anchors": "Ancres",
|
|
91
|
+
"Insert link": "Ins\u00e9rer un lien",
|
|
92
|
+
"New window": "Nouvelle fen\u00eatre",
|
|
93
|
+
"None": "n\/a",
|
|
94
|
+
"The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "L'URL que vous avez entr\u00e9e semble \u00eatre un lien externe. Voulez-vous ajouter le pr\u00e9fixe http:\/\/ n\u00e9cessaire?",
|
|
95
|
+
"Target": "Cible",
|
|
96
|
+
"The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "L'URL que vous avez entr\u00e9e semble \u00eatre une adresse e-mail. Voulez-vous ajouter le pr\u00e9fixe mailto: n\u00e9cessaire?",
|
|
97
|
+
"Insert\/edit link": "Ins\u00e9rer\/\u00e9diter un lien",
|
|
98
|
+
"Insert\/edit video": "Ins\u00e9rer\/\u00e9diter une vid\u00e9o",
|
|
99
|
+
"Poster": "Publier",
|
|
100
|
+
"Alternative source": "Source alternative",
|
|
101
|
+
"Paste your embed code below:": "Collez votre code d'int\u00e9gration ci-dessous :",
|
|
102
|
+
"Insert video": "Ins\u00e9rer une vid\u00e9o",
|
|
103
|
+
"Embed": "Ins\u00e9rer",
|
|
104
|
+
"Nonbreaking space": "Espace ins\u00e9cable",
|
|
105
|
+
"Page break": "Saut de page",
|
|
106
|
+
"Paste as text": "Coller comme texte",
|
|
107
|
+
"Preview": "Pr\u00e9visualiser",
|
|
108
|
+
"Print": "Imprimer",
|
|
109
|
+
"Save": "Enregistrer",
|
|
110
|
+
"Could not find the specified string.": "Impossible de trouver la cha\u00eene sp\u00e9cifi\u00e9e.",
|
|
111
|
+
"Replace": "Remplacer",
|
|
112
|
+
"Next": "Suiv",
|
|
113
|
+
"Whole words": "Mots entiers",
|
|
114
|
+
"Find and replace": "Trouver et remplacer",
|
|
115
|
+
"Replace with": "Remplacer par",
|
|
116
|
+
"Find": "Chercher",
|
|
117
|
+
"Replace all": "Tout remplacer",
|
|
118
|
+
"Match case": "Respecter la casse",
|
|
119
|
+
"Prev": "Pr\u00e9c ",
|
|
120
|
+
"Spellcheck": "V\u00e9rification orthographique",
|
|
121
|
+
"Finish": "Finie",
|
|
122
|
+
"Ignore all": "Tout ignorer",
|
|
123
|
+
"Ignore": "Ignorer",
|
|
124
|
+
"Insert row before": "Ins\u00e9rer une ligne avant",
|
|
125
|
+
"Rows": "Lignes",
|
|
126
|
+
"Height": "Hauteur",
|
|
127
|
+
"Paste row after": "Coller la ligne apr\u00e8s",
|
|
128
|
+
"Alignment": "Alignement",
|
|
129
|
+
"Column group": "Groupe de colonnes",
|
|
130
|
+
"Row": "Ligne",
|
|
131
|
+
"Insert column before": "Ins\u00e9rer une colonne avant",
|
|
132
|
+
"Split cell": "Diviser la cellule",
|
|
133
|
+
"Cell padding": "Espacement interne cellule",
|
|
134
|
+
"Cell spacing": "Espacement inter-cellulles",
|
|
135
|
+
"Row type": "Type de ligne",
|
|
136
|
+
"Insert table": "Ins\u00e9rer un tableau",
|
|
137
|
+
"Body": "Corps",
|
|
138
|
+
"Caption": "Titre",
|
|
139
|
+
"Footer": "Pied",
|
|
140
|
+
"Delete row": "Effacer la ligne",
|
|
141
|
+
"Paste row before": "Coller la ligne avant",
|
|
142
|
+
"Scope": "Etendue",
|
|
143
|
+
"Delete table": "Supprimer le tableau",
|
|
144
|
+
"H Align": "Alignement H",
|
|
145
|
+
"Top": "Haut",
|
|
146
|
+
"Header cell": "Cellule d'en-t\u00eate",
|
|
147
|
+
"Column": "Colonne",
|
|
148
|
+
"Row group": "Groupe de lignes",
|
|
149
|
+
"Cell": "Cellule",
|
|
150
|
+
"Middle": "Milieu",
|
|
151
|
+
"Cell type": "Type de cellule",
|
|
152
|
+
"Copy row": "Copier la ligne",
|
|
153
|
+
"Row properties": "Propri\u00e9t\u00e9s de la ligne",
|
|
154
|
+
"Table properties": "Propri\u00e9t\u00e9s du tableau",
|
|
155
|
+
"Bottom": "Bas",
|
|
156
|
+
"V Align": "Alignement V",
|
|
157
|
+
"Header": "En-t\u00eate",
|
|
158
|
+
"Right": "Droite",
|
|
159
|
+
"Insert column after": "Ins\u00e9rer une colonne apr\u00e8s",
|
|
160
|
+
"Cols": "Colonnes",
|
|
161
|
+
"Insert row after": "Ins\u00e9rer une ligne apr\u00e8s",
|
|
162
|
+
"Width": "Largeur",
|
|
163
|
+
"Cell properties": "Propri\u00e9t\u00e9s de la cellule",
|
|
164
|
+
"Left": "Gauche",
|
|
165
|
+
"Cut row": "Couper la ligne",
|
|
166
|
+
"Delete column": "Effacer la colonne",
|
|
167
|
+
"Center": "Centr\u00e9",
|
|
168
|
+
"Merge cells": "Fusionner les cellules",
|
|
169
|
+
"Insert template": "Ajouter un th\u00e8me",
|
|
170
|
+
"Templates": "Th\u00e8mes",
|
|
171
|
+
"Background color": "Couleur d'arri\u00e8re-plan",
|
|
172
|
+
"Text color": "Couleur du texte",
|
|
173
|
+
"Show blocks": "Afficher les blocs",
|
|
174
|
+
"Show invisible characters": "Afficher les caract\u00e8res invisibles",
|
|
175
|
+
"Words: {0}": "Mots : {0}",
|
|
176
|
+
"Insert": "Ins\u00e9rer",
|
|
177
|
+
"File": "Fichier",
|
|
178
|
+
"Edit": "Editer",
|
|
179
|
+
"Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "Zone Texte Riche. Appuyer sur ALT-F9 pour le menu. Appuyer sur ALT-F10 pour la barre d'outils. Appuyer sur ALT-0 pour de l'aide.",
|
|
180
|
+
"Tools": "Outils",
|
|
181
|
+
"View": "Voir",
|
|
182
|
+
"Table": "Tableau",
|
|
183
|
+
"Format": "Format"
|
|
184
|
+
});
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: alchemy_cms
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.0.
|
|
4
|
+
version: 3.0.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Thomas von Deyen
|
|
@@ -12,7 +12,7 @@ authors:
|
|
|
12
12
|
autorequire:
|
|
13
13
|
bindir: bin
|
|
14
14
|
cert_chain: []
|
|
15
|
-
date: 2014-
|
|
15
|
+
date: 2014-09-11 00:00:00.000000000 Z
|
|
16
16
|
dependencies:
|
|
17
17
|
- !ruby/object:Gem::Dependency
|
|
18
18
|
name: rails
|
|
@@ -110,14 +110,14 @@ dependencies:
|
|
|
110
110
|
requirements:
|
|
111
111
|
- - "~>"
|
|
112
112
|
- !ruby/object:Gem::Version
|
|
113
|
-
version: 0.15
|
|
113
|
+
version: '0.15'
|
|
114
114
|
type: :runtime
|
|
115
115
|
prerelease: false
|
|
116
116
|
version_requirements: !ruby/object:Gem::Requirement
|
|
117
117
|
requirements:
|
|
118
118
|
- - "~>"
|
|
119
119
|
- !ruby/object:Gem::Version
|
|
120
|
-
version: 0.15
|
|
120
|
+
version: '0.15'
|
|
121
121
|
- !ruby/object:Gem::Dependency
|
|
122
122
|
name: acts_as_list
|
|
123
123
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -1075,6 +1075,7 @@ files:
|
|
|
1075
1075
|
- vendor/assets/javascripts/requestAnimationFrame.js
|
|
1076
1076
|
- vendor/assets/javascripts/spin.min.js
|
|
1077
1077
|
- vendor/assets/javascripts/tinymce/langs/de.js
|
|
1078
|
+
- vendor/assets/javascripts/tinymce/langs/fr.js
|
|
1078
1079
|
- vendor/assets/javascripts/tinymce/langs/nl.js
|
|
1079
1080
|
- vendor/assets/javascripts/tinymce/license.txt
|
|
1080
1081
|
- vendor/assets/javascripts/tinymce/plugins/anchor/plugin.min.js
|