alchemy_cms 3.1.0.beta5 → 3.1.0.beta6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.editorconfig +23 -0
- data/app/assets/stylesheets/alchemy/frame.scss +4 -0
- data/app/assets/stylesheets/alchemy/icons.scss +2 -0
- data/app/controllers/alchemy/admin/languages_controller.rb +5 -6
- data/app/controllers/alchemy/api/base_controller.rb +1 -1
- data/app/controllers/alchemy/api/contents_controller.rb +1 -1
- data/app/controllers/alchemy/api/elements_controller.rb +1 -1
- data/app/controllers/alchemy/api/pages_controller.rb +1 -1
- data/app/models/alchemy/page.rb +1 -0
- data/app/models/alchemy/page/page_natures.rb +3 -3
- data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +4 -0
- data/app/views/alchemy/admin/layoutpages/edit.html.erb +5 -1
- data/app/views/alchemy/admin/pages/_form.html.erb +5 -1
- data/app/views/alchemy/admin/pages/_locked_page.html.erb +3 -0
- data/app/views/alchemy/admin/pages/_page.html.erb +5 -1
- data/app/views/alchemy/admin/pages/_page_status.html.erb +3 -0
- data/app/views/alchemy/admin/pages/info.html.erb +6 -1
- data/app/views/alchemy/admin/resources/_form.html.erb +1 -1
- data/config/locales/alchemy.de.yml +1 -0
- data/config/locales/alchemy.en.yml +2 -1
- data/config/routes.rb +1 -4
- data/lib/alchemy/capistrano.rb +3 -4
- data/lib/alchemy/errors.rb +0 -4
- data/lib/alchemy/mount_point.rb +30 -30
- data/lib/alchemy/resource.rb +18 -2
- data/lib/alchemy/test_support/factories.rb +2 -2
- data/lib/alchemy/version.rb +1 -1
- data/lib/rails/generators/alchemy/deploy_script/deploy_script_generator.rb +25 -9
- data/lib/rails/generators/alchemy/deploy_script/templates/deploy.rb.tt +0 -1
- data/spec/controllers/admin/languages_controller_spec.rb +35 -11
- data/spec/controllers/alchemy/api/contents_controller_spec.rb +1 -1
- data/spec/controllers/alchemy/api/elements_controller_spec.rb +1 -1
- data/spec/controllers/alchemy/api/pages_controller_spec.rb +1 -1
- data/spec/dummy/config/alchemy/page_layouts.yml +1 -1
- data/spec/dummy/config/application.rb +0 -2
- data/spec/dummy/config/environments/test.rb +1 -1
- data/spec/libraries/mount_point_spec.rb +41 -26
- data/spec/libraries/page_layout_spec.rb +9 -3
- data/spec/libraries/resource_spec.rb +24 -0
- data/spec/models/page_spec.rb +25 -26
- metadata +3 -4
- data/app/views/layouts/alchemy/login.html.erb +0 -2
- data/config/initializers/inflections.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ee349e3c1603a85fa273cfbb168e88190db26c8f
|
4
|
+
data.tar.gz: c3288e7a9f128291320f6646dd41ab78f65f23ea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4b86afe18307827a65c0ecff2894ac39df62a39430d8c9da38d455a49ace528caf9a94b0b91b7e93477a2188ea407c21c700f161ac067e11b26411481f6e5f1
|
7
|
+
data.tar.gz: 52dcf130529e8494da6e49babc0ab1bed1ce6e752aea27aaadce37081dee615892f62c4f5ff4cccd3ae00bf32de1ea4e7b001beb848ca08f6d022428a91a1d44
|
data/.editorconfig
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# EditorConfig is awesome: http://EditorConfig.org
|
2
|
+
|
3
|
+
# top-most EditorConfig file
|
4
|
+
root = true
|
5
|
+
|
6
|
+
# Unix-style newlines with a newline ending every file
|
7
|
+
[*]
|
8
|
+
charset = utf-8
|
9
|
+
end_of_line = lf
|
10
|
+
indent_size = 2
|
11
|
+
indent_style = space
|
12
|
+
insert_final_newline = true
|
13
|
+
trim_trailing_whitespace = true
|
14
|
+
tab_width = 2
|
15
|
+
|
16
|
+
[**.rb]
|
17
|
+
max_line_length = 80
|
18
|
+
|
19
|
+
[**.js, **.coffee]
|
20
|
+
max_line_length = 120
|
21
|
+
|
22
|
+
[*.md]
|
23
|
+
trim_trailing_whitespace = false
|
@@ -1,18 +1,17 @@
|
|
1
1
|
module Alchemy
|
2
2
|
module Admin
|
3
|
-
class LanguagesController <
|
3
|
+
class LanguagesController < ResourcesController
|
4
4
|
|
5
5
|
def new
|
6
|
-
@language =
|
7
|
-
@language.page_layout =
|
6
|
+
@language = Language.new
|
7
|
+
@language.page_layout = configured_page_layout || @language.page_layout
|
8
8
|
end
|
9
9
|
|
10
|
-
|
10
|
+
private
|
11
11
|
|
12
12
|
def configured_page_layout
|
13
|
-
|
13
|
+
Config.get(:default_language).try('[]', 'page_layout')
|
14
14
|
end
|
15
|
-
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
data/app/models/alchemy/page.rb
CHANGED
@@ -67,10 +67,10 @@ module Alchemy
|
|
67
67
|
return {} if self.systempage?
|
68
68
|
description = PageLayout.get(self.page_layout)
|
69
69
|
if description.nil?
|
70
|
-
|
71
|
-
|
72
|
-
description
|
70
|
+
log_warning "Page layout description for `#{self.page_layout}` not found. Please check `page_layouts.yml` file."
|
71
|
+
return {}
|
73
72
|
end
|
73
|
+
description
|
74
74
|
end
|
75
75
|
alias_method :definition, :layout_description
|
76
76
|
|
@@ -1,7 +1,11 @@
|
|
1
1
|
<li class="page_level_<%= layoutpage.level %>" id="page_<%= layoutpage.id %>">
|
2
2
|
<div class="sitemap_page<%= layoutpage.locked ? ' locked' : '' %>">
|
3
3
|
<div class="sitemap_left_images">
|
4
|
+
<% if layoutpage.layout_description.blank? %>
|
5
|
+
<span class="inline warning icon" title="<%= _t(:page_layout_description_missing) %>"></span>
|
6
|
+
<% else %>
|
4
7
|
<%= render_icon(:page) %>
|
8
|
+
<% end %>
|
5
9
|
</div>
|
6
10
|
<div class="sitemap_right_tools">
|
7
11
|
<%- if can?(:configure, layoutpage) -%>
|
@@ -1,5 +1,9 @@
|
|
1
1
|
<%= alchemy_form_for [:admin, @page], class: 'edit_page' do |f| %>
|
2
|
-
<%= f.input :page_layout,
|
2
|
+
<%= f.input :page_layout,
|
3
|
+
collection: @page_layouts,
|
4
|
+
label: @page.layout_description.blank? ? (%(<span class="inline warning icon" title="#{ _t(:page_layout_description_missing) }"></span> ) + _t(:page_type)).html_safe : _t(:page_type),
|
5
|
+
include_blank: false,
|
6
|
+
input_html: {class: 'alchemy_selectbox'} %>
|
3
7
|
<%= f.input :name, autofocus: true %>
|
4
8
|
<% if @page.taggable? %>
|
5
9
|
<div class="input string">
|
@@ -1,5 +1,9 @@
|
|
1
1
|
<%= alchemy_form_for [:admin, @page], class: 'edit_page' do |f| %>
|
2
|
-
<%= f.input :page_layout,
|
2
|
+
<%= f.input :page_layout,
|
3
|
+
collection: @page_layouts,
|
4
|
+
label: @page.layout_description.blank? ? (%(<span class="inline warning icon" title="#{ _t(:page_layout_description_missing) }"></span> ) + _t(:page_type)).html_safe : _t(:page_type),
|
5
|
+
include_blank: false,
|
6
|
+
input_html: {class: 'alchemy_selectbox'} %>
|
3
7
|
<div class="input check_boxes">
|
4
8
|
<label class="control-label"><%= _t(:page_status) %></label>
|
5
9
|
<div class="control_group">
|
@@ -3,6 +3,9 @@
|
|
3
3
|
<% else %>
|
4
4
|
<div class="subnavi_tab wide" id="locked_page_<%= locked_page.id %>">
|
5
5
|
<%= link_to alchemy.edit_admin_page_path(locked_page) do %>
|
6
|
+
<% if locked_page.layout_description.blank? %>
|
7
|
+
<span class="inline warning icon" title="<%= _t(:page_layout_description_missing) %>"></span>
|
8
|
+
<% end %>
|
6
9
|
<span class="page_name" title="<%= locked_page.name %>">
|
7
10
|
<%= truncate locked_page.name, length: 15 %>
|
8
11
|
</span>
|
@@ -2,7 +2,11 @@
|
|
2
2
|
<div class="sitemap_page<%= page.locked ? ' locked' : '' %>" name="<%= page.name %>">
|
3
3
|
<div class="sitemap_left_images">
|
4
4
|
<%= sitemap_folder_link(page) unless page.level == 1 || page.children.blank? || @sorting %>
|
5
|
-
|
5
|
+
<% if page.layout_description.blank? %>
|
6
|
+
<span class="inline warning icon" title="<%= _t(:page_layout_description_missing) %>"></span>
|
7
|
+
<% else %>
|
8
|
+
<div class="page icon <%= @sorting && page.level > 1 ? 'handle' : nil %>"></div>
|
9
|
+
<% end %>
|
6
10
|
</div>
|
7
11
|
<div class="sitemap_right_tools">
|
8
12
|
<%- unless @sorting -%>
|
@@ -1,4 +1,7 @@
|
|
1
1
|
<div class="page_status_and_name" id="page_<%= @page.id %>_status">
|
2
|
+
<% if @page.layout_description.blank? %>
|
3
|
+
<span class="inline warning icon" title="<%= _t(:page_layout_description_missing) %>"></span>
|
4
|
+
<% end %>
|
2
5
|
<span class="page_name"><%= @page.name %></span>
|
3
6
|
<%- if multi_language? -%>
|
4
7
|
<span class="page_language" title="<%= @page.language.name %>">
|
@@ -5,7 +5,12 @@
|
|
5
5
|
<% end %>
|
6
6
|
<% end %>
|
7
7
|
<div class="value">
|
8
|
-
<label
|
8
|
+
<label>
|
9
|
+
<% if @page.layout_description.blank? %>
|
10
|
+
<span class="inline warning icon" title="<%= _t(:page_layout_description_missing) %>"></span>
|
11
|
+
<% end %>
|
12
|
+
<%= Alchemy::Page.human_attribute_name(:page_layout) %>
|
13
|
+
</label>
|
9
14
|
<p><%= @page.layout_display_name %></p>
|
10
15
|
</div>
|
11
16
|
<div class="value">
|
@@ -1,5 +1,5 @@
|
|
1
1
|
<%= alchemy_form_for resource_instance_variable, url: resource_path(resource_instance_variable) do |f| %>
|
2
|
-
<% resource_handler.
|
2
|
+
<% resource_handler.editable_attributes.each do |attribute| %>
|
3
3
|
<% if relation = attribute[:relation] %>
|
4
4
|
<%= f.association relation[:name].to_sym,
|
5
5
|
label_method: relation[:attr_method],
|
@@ -287,6 +287,7 @@ de:
|
|
287
287
|
"Warning!": "Achtung!"
|
288
288
|
content_description_missing: "Warnung: Für diesen Content konnte die Vorlage nicht gefunden werden. Bitte überprüfen Sie die elements.yml Datei."
|
289
289
|
element_description_missing: "Warnung! Für dieses Element konnte die Vorlage nicht gefunden werden. Bitte überprüfen Sie die elements.yml Datei."
|
290
|
+
page_layout_description_missing: "Warnung! Für diese Seite konnte die Vorlage nicht gefunden werden. Bitte überprüfen Sie die page_layouts.yml Datei."
|
290
291
|
"Welcome to Alchemy": "Willkommen in Alchemy"
|
291
292
|
"Who else is online": "Wer ist noch online"
|
292
293
|
"Yes": "Ja"
|
@@ -286,7 +286,8 @@ en:
|
|
286
286
|
"Visit page": "Visit page"
|
287
287
|
"Warning!": "Warning!"
|
288
288
|
content_description_missing: "Warning: Content is missing its description. Please check the elements.yml"
|
289
|
-
element_description_missing: "WARNING! Missing description. Please check your elements.yml file."
|
289
|
+
element_description_missing: "WARNING! Missing element description. Please check your elements.yml file."
|
290
|
+
page_layout_description_missing: "WARNING! Missing page layout description. Please check your page_layouts.yml file."
|
290
291
|
"Welcome to Alchemy": "Welcome to Alchemy"
|
291
292
|
"Who else is online": "Who else is online"
|
292
293
|
"Yes": "Yes"
|
data/config/routes.rb
CHANGED
@@ -4,10 +4,7 @@ Alchemy::Engine.routes.draw do
|
|
4
4
|
|
5
5
|
get '/sitemap.xml' => 'pages#sitemap', format: 'xml'
|
6
6
|
|
7
|
-
get '/admin' => redirect(
|
8
|
-
"#{Alchemy::MountPoint.get}/admin/dashboard"
|
9
|
-
)
|
10
|
-
|
7
|
+
get '/admin' => redirect('admin/dashboard')
|
11
8
|
get '/admin/dashboard' => 'admin/dashboard#index',
|
12
9
|
:as => :admin_dashboard
|
13
10
|
get '/admin/dashboard/info' => 'admin/dashboard#info',
|
data/lib/alchemy/capistrano.rb
CHANGED
@@ -1,9 +1,8 @@
|
|
1
|
-
# This recipe contains Capistrano recipes for handling the uploads
|
2
|
-
#
|
1
|
+
# This recipe contains Capistrano recipes for handling the uploads
|
2
|
+
# and picture cache files while deploying your application.
|
3
|
+
|
3
4
|
require 'fileutils'
|
4
5
|
require 'alchemy/tasks/helpers'
|
5
|
-
# Loading the current Rails app's env, so we can get the Alchemy mount point.
|
6
|
-
require './config/environment.rb'
|
7
6
|
require 'alchemy/mount_point'
|
8
7
|
|
9
8
|
include Alchemy::Tasks::Helpers
|
data/lib/alchemy/errors.rb
CHANGED
@@ -32,10 +32,6 @@ module Alchemy
|
|
32
32
|
# Raised if calling +image_file+ on a Picture object returns nil.
|
33
33
|
end
|
34
34
|
|
35
|
-
class PageLayoutDefinitionError < StandardError
|
36
|
-
# Raised if page_layout definition can not be found.
|
37
|
-
end
|
38
|
-
|
39
35
|
class PictureInUseError < StandardError
|
40
36
|
# Raised if the picture is still in use and can not be deleted.
|
41
37
|
end
|
data/lib/alchemy/mount_point.rb
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
module Alchemy
|
2
|
-
|
2
|
+
|
3
|
+
# Utilities for Alchemy's mount point in the host rails app.
|
3
4
|
#
|
4
5
|
class MountPoint
|
6
|
+
MOUNT_POINT_REGEXP = /mount\sAlchemy::Engine\s=>\s['|"](\/\w*)['|"]/
|
7
|
+
|
8
|
+
class << self
|
5
9
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
# Returns the path of Alchemy's mount point in current rails app.
|
11
|
+
#
|
12
|
+
# @param [Boolean] remove_leading_slash_if_blank
|
13
|
+
# Pass false to not return a leading slash on empty mount point.
|
14
|
+
#
|
15
|
+
def get(remove_leading_slash_if_blank = true)
|
16
|
+
if path == "/" && remove_leading_slash_if_blank
|
17
|
+
path.gsub(/\A\/\z/, '')
|
18
|
+
else
|
19
|
+
path
|
20
|
+
end
|
16
21
|
end
|
17
|
-
end
|
18
22
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
23
|
+
# Returns the mount point path from the Rails app routes.
|
24
|
+
#
|
25
|
+
def path
|
26
|
+
match = File.read(routes_file_path).match(MOUNT_POINT_REGEXP)
|
27
|
+
if match.nil?
|
28
|
+
raise "Alchemy mount point not found! Please run `bin/rake alchemy:mount'"
|
29
|
+
else
|
30
|
+
match[1]
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
24
35
|
|
25
|
-
|
26
|
-
|
27
|
-
# If Alchemy is not mounted in the main app, it falls back to root path.
|
28
|
-
#
|
29
|
-
def self.mount_point
|
30
|
-
if self.routes.nil?
|
31
|
-
::Rails.logger.warn <<-WARN
|
32
|
-
Alchemy is not mounted! Falling back to root path (/).
|
33
|
-
If you want to change Alchemy's mount point, please mount Alchemy::Engine in your config/routes.rb file.
|
34
|
-
WARN
|
35
|
-
return '/'
|
36
|
+
def routes_file_path
|
37
|
+
Rails.root.join('config/routes.rb')
|
36
38
|
end
|
37
|
-
routes.path.spec.to_s
|
38
39
|
end
|
39
|
-
|
40
40
|
end
|
41
41
|
end
|
data/lib/alchemy/resource.rb
CHANGED
@@ -20,7 +20,7 @@ module Alchemy
|
|
20
20
|
#
|
21
21
|
# == Skip attributes
|
22
22
|
#
|
23
|
-
# Usually you don't want your users to edit all attributes provided by a model. Hence some default attributes,
|
23
|
+
# Usually you don't want your users to see and edit all attributes provided by a model. Hence some default attributes,
|
24
24
|
# namely id, updated_at, created_at, creator_id and updater_id are not returned by Resource#attributes.
|
25
25
|
#
|
26
26
|
# If you want to skip a different set of attributes just define a +skipped_alchemy_resource_attributes+ class method in your model class
|
@@ -32,6 +32,17 @@ module Alchemy
|
|
32
32
|
# %w(id updated_at secret_token remote_ip)
|
33
33
|
# end
|
34
34
|
#
|
35
|
+
# == Restrict attributes
|
36
|
+
#
|
37
|
+
# Beside skipping certain attributes you can also restrict them. Restricted attributes can not be edited by the user but still be seen in the index view.
|
38
|
+
# No attributes are restricted by default.
|
39
|
+
#
|
40
|
+
# === Example
|
41
|
+
#
|
42
|
+
# def self.restricted_alchemy_resource_attributes
|
43
|
+
# %w(synced_at remote_record_id)
|
44
|
+
# end
|
45
|
+
#
|
35
46
|
# == Resource relations
|
36
47
|
#
|
37
48
|
# Alchemy::Resource can take care of ActiveRecord relations.
|
@@ -73,7 +84,7 @@ module Alchemy
|
|
73
84
|
# resource = Resource.new('/admin/tags', {"engine_name"=>"alchemy"}, ActsAsTaggableOn::Tag)
|
74
85
|
#
|
75
86
|
class Resource
|
76
|
-
attr_accessor :skipped_attributes, :resource_relations, :model_associations
|
87
|
+
attr_accessor :skipped_attributes, :restricted_attributes, :resource_relations, :model_associations
|
77
88
|
attr_reader :model
|
78
89
|
|
79
90
|
DEFAULT_SKIPPED_ATTRIBUTES = %w(id updated_at created_at creator_id updater_id)
|
@@ -84,6 +95,7 @@ module Alchemy
|
|
84
95
|
@module_definition = module_definition
|
85
96
|
@model = (custom_model or guess_model_from_controller_path)
|
86
97
|
self.skipped_attributes = model.respond_to?(:skipped_alchemy_resource_attributes) ? model.skipped_alchemy_resource_attributes : DEFAULT_SKIPPED_ATTRIBUTES
|
98
|
+
self.restricted_attributes = model.respond_to?(:restricted_alchemy_resource_attributes) ? model.restricted_alchemy_resource_attributes : []
|
87
99
|
if model.respond_to?(:alchemy_resource_relations)
|
88
100
|
if not model.respond_to?(:reflect_on_all_associations)
|
89
101
|
raise MissingActiveRecordAssociation
|
@@ -139,6 +151,10 @@ module Alchemy
|
|
139
151
|
end.compact
|
140
152
|
end
|
141
153
|
|
154
|
+
def editable_attributes
|
155
|
+
attributes.reject { |h| self.restricted_attributes.map(&:to_s).include?(h[:name].to_s) }
|
156
|
+
end
|
157
|
+
|
142
158
|
# Returns all columns that are searchable
|
143
159
|
#
|
144
160
|
# For now it only uses string type columns
|
@@ -28,7 +28,7 @@ FactoryGirl.define do
|
|
28
28
|
code 'de'
|
29
29
|
default true
|
30
30
|
frontpage_name 'Intro'
|
31
|
-
page_layout '
|
31
|
+
page_layout { Alchemy::Config.get(:default_language)['page_layout'] }
|
32
32
|
public true
|
33
33
|
site { Alchemy::Site.first }
|
34
34
|
|
@@ -59,7 +59,7 @@ FactoryGirl.define do
|
|
59
59
|
|
60
60
|
factory :language_root_page do
|
61
61
|
name 'Startseite'
|
62
|
-
page_layout
|
62
|
+
page_layout { language.page_layout }
|
63
63
|
language_root true
|
64
64
|
public true
|
65
65
|
parent_id { Alchemy::Page.root.id }
|
data/lib/alchemy/version.rb
CHANGED
@@ -5,13 +5,31 @@ module Alchemy
|
|
5
5
|
class DeployScriptGenerator < ::Rails::Generators::Base
|
6
6
|
|
7
7
|
desc "This generator generates a Capistrano receipt for deploying Alchemy CMS."
|
8
|
-
|
9
|
-
class_option :
|
8
|
+
|
9
|
+
class_option :scm,
|
10
|
+
type: 'string',
|
11
|
+
desc: "Set the type of scm you use for deployment.",
|
12
|
+
default: 'git'
|
13
|
+
|
14
|
+
class_option :db,
|
15
|
+
type: 'string',
|
16
|
+
desc: "Set the type of database you use on your server.",
|
17
|
+
default: 'mysql'
|
18
|
+
|
10
19
|
source_root File.expand_path('templates', File.dirname(__FILE__))
|
11
20
|
|
12
21
|
def copy_script
|
13
22
|
@scm = options[:scm]
|
14
23
|
@database_type = options[:db]
|
24
|
+
ask_questions
|
25
|
+
template "deploy.rb.tt", Rails.root.join('config', 'deploy.rb')
|
26
|
+
setup_capistrano
|
27
|
+
show_read_me
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def ask_questions
|
15
33
|
@app_name = ask('Please enter a name for your application:')
|
16
34
|
@server = ask('Please enter server ip or domain:')
|
17
35
|
if @store_credentials = yes?('Do want to store the ssh credentials? (PLEASE DO NOT STORE THEM IF THE REPOSITORY IS PUBLIC) (y/N)')
|
@@ -27,13 +45,8 @@ module Alchemy
|
|
27
45
|
if @scm == "svn" && yes?('Is your repository private? (y/N)')
|
28
46
|
ask_for_repo_credentials
|
29
47
|
end
|
30
|
-
template "deploy.rb.tt", Rails.root.join('config', 'deploy.rb')
|
31
|
-
setup_capistrano
|
32
|
-
show_read_me
|
33
48
|
end
|
34
49
|
|
35
|
-
private
|
36
|
-
|
37
50
|
def ask_for_credentials
|
38
51
|
@ssh_user = ask('Please enter ssh username:')
|
39
52
|
port = ask('Please enter ssh port (22):')
|
@@ -59,7 +72,11 @@ module Alchemy
|
|
59
72
|
|
60
73
|
def setup_capistrano
|
61
74
|
puts "\nSetting up Capistrano"
|
62
|
-
|
75
|
+
if system 'capify .'
|
76
|
+
gsub_file 'Capfile',
|
77
|
+
/\s{4}#\sload\s'deploy\/assets'/,
|
78
|
+
"load 'deploy/assets'"
|
79
|
+
end
|
63
80
|
end
|
64
81
|
|
65
82
|
def show_read_me
|
@@ -68,7 +85,6 @@ module Alchemy
|
|
68
85
|
puts "\nIf you want to deploy Alchemy the first time type:\ncap deploy:cold"
|
69
86
|
puts "\nAfter the first deploy you just need to type:\ncap deploy"
|
70
87
|
end
|
71
|
-
|
72
88
|
end
|
73
89
|
end
|
74
90
|
end
|
@@ -1,19 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
class Alchemy::Config;
|
4
|
-
end
|
5
|
-
|
6
3
|
describe Alchemy::Admin::LanguagesController do
|
7
4
|
|
8
5
|
before do
|
9
6
|
sign_in(admin_user)
|
10
7
|
end
|
11
8
|
|
12
|
-
describe "new" do
|
13
|
-
|
9
|
+
describe "#new" do
|
14
10
|
context "when default_language.page_layout is set" do
|
15
|
-
|
16
|
-
# FML :/
|
11
|
+
before do
|
17
12
|
allow(Alchemy::Config).to receive(:get) do |arg|
|
18
13
|
if arg == :default_language
|
19
14
|
{'page_layout' => "new_standard"}
|
@@ -21,17 +16,46 @@ describe Alchemy::Admin::LanguagesController do
|
|
21
16
|
Alchemy::Config.show[arg.to_s]
|
22
17
|
end
|
23
18
|
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "uses it as page_layout-default for the new language" do
|
24
22
|
get :new
|
25
|
-
expect(assigns(:language).page_layout).to
|
23
|
+
expect(assigns(:language).page_layout).to eq("new_standard")
|
26
24
|
end
|
27
25
|
end
|
28
26
|
|
29
|
-
context "when default_language
|
30
|
-
|
27
|
+
context "when default_language is not configured" do
|
28
|
+
before do
|
29
|
+
allow(Alchemy::Config).to receive(:get) do |arg|
|
30
|
+
if arg == :default_language
|
31
|
+
nil
|
32
|
+
else
|
33
|
+
Alchemy::Config.show[arg.to_s]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "falls back to default database value." do
|
31
39
|
get :new
|
32
|
-
expect(assigns(:language).page_layout).to
|
40
|
+
expect(assigns(:language).page_layout).to eq("intro")
|
33
41
|
end
|
34
42
|
end
|
35
43
|
|
44
|
+
context "when default language page_layout is not configured" do
|
45
|
+
before do
|
46
|
+
allow(Alchemy::Config).to receive(:get) do |arg|
|
47
|
+
if arg == :default_language
|
48
|
+
{}
|
49
|
+
else
|
50
|
+
Alchemy::Config.show[arg.to_s]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "falls back to default database value." do
|
56
|
+
get :new
|
57
|
+
expect(assigns(:language).page_layout).to eq("intro")
|
58
|
+
end
|
59
|
+
end
|
36
60
|
end
|
37
61
|
end
|
@@ -18,7 +18,5 @@ module Dummy
|
|
18
18
|
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
19
19
|
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
20
20
|
# config.i18n.default_locale = :de
|
21
|
-
|
22
|
-
I18n.enforce_available_locales = true
|
23
21
|
end
|
24
22
|
end
|
@@ -1,33 +1,34 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'ostruct'
|
3
2
|
|
4
3
|
describe Alchemy::MountPoint do
|
5
|
-
|
6
4
|
describe '.get' do
|
7
|
-
|
8
5
|
it "returns the path of alchemy's mount point" do
|
9
|
-
allow(Alchemy::MountPoint).to receive(:
|
6
|
+
allow(Alchemy::MountPoint).to receive(:path).and_return('/cms')
|
10
7
|
expect(Alchemy::MountPoint.get).to eq('/cms')
|
11
8
|
end
|
12
9
|
|
13
10
|
it "removes the leading slash if root mount point" do
|
14
|
-
allow(Alchemy::MountPoint).to receive(:
|
11
|
+
allow(Alchemy::MountPoint).to receive(:path).and_return('/')
|
15
12
|
expect(Alchemy::MountPoint.get).to eq('')
|
16
13
|
end
|
17
14
|
|
18
15
|
context "with remove_leading_slash_if_blank set to false" do
|
19
|
-
before
|
20
|
-
allow(Alchemy::MountPoint)
|
21
|
-
|
16
|
+
before do
|
17
|
+
allow(Alchemy::MountPoint)
|
18
|
+
.to receive(:path)
|
19
|
+
.and_return('/')
|
20
|
+
end
|
22
21
|
|
23
22
|
it "does not remove the leading white slash of path" do
|
24
23
|
expect(Alchemy::MountPoint.get(false)).to eq('/')
|
25
24
|
end
|
26
25
|
|
27
26
|
context "and with mount point not root" do
|
28
|
-
before
|
29
|
-
allow(Alchemy::MountPoint)
|
30
|
-
|
27
|
+
before do
|
28
|
+
allow(Alchemy::MountPoint)
|
29
|
+
.to receive(:path)
|
30
|
+
.and_return('/cms')
|
31
|
+
end
|
31
32
|
|
32
33
|
it "does not remove the leading white slash of path" do
|
33
34
|
expect(Alchemy::MountPoint.get(false)).to eq('/cms')
|
@@ -36,27 +37,41 @@ describe Alchemy::MountPoint do
|
|
36
37
|
end
|
37
38
|
end
|
38
39
|
|
39
|
-
describe '.
|
40
|
-
|
41
|
-
|
40
|
+
describe '.path' do
|
41
|
+
before do
|
42
|
+
allow(File)
|
43
|
+
.to receive(:read)
|
44
|
+
.and_return("mount Alchemy::Engine => '/cms'")
|
42
45
|
end
|
43
|
-
end
|
44
46
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
47
|
+
it 'returns the mount point path from routes.' do
|
48
|
+
expect(Alchemy::MountPoint.path).to eq('/cms')
|
49
|
+
end
|
50
|
+
|
51
|
+
context "Alchemy mount point could not be found" do
|
52
|
+
before do
|
53
|
+
allow(File)
|
54
|
+
.to receive(:read)
|
55
|
+
.and_return("")
|
56
|
+
end
|
57
|
+
|
58
|
+
it "raises an exception" do
|
59
|
+
expect {
|
60
|
+
Alchemy::MountPoint.path
|
61
|
+
}.to raise_error
|
62
|
+
end
|
49
63
|
end
|
50
64
|
|
51
|
-
context
|
52
|
-
before
|
53
|
-
allow(
|
54
|
-
|
65
|
+
context 'Mount point using double quotes string' do
|
66
|
+
before do
|
67
|
+
allow(File)
|
68
|
+
.to receive(:read)
|
69
|
+
.and_return('mount Alchemy::Engine => "/cms"')
|
70
|
+
end
|
55
71
|
|
56
|
-
it
|
57
|
-
expect(Alchemy::MountPoint.
|
72
|
+
it 'returns the mount point path from routes.' do
|
73
|
+
expect(Alchemy::MountPoint.path).to eq('/cms')
|
58
74
|
end
|
59
75
|
end
|
60
76
|
end
|
61
|
-
|
62
77
|
end
|
@@ -81,12 +81,18 @@ module Alchemy
|
|
81
81
|
|
82
82
|
context "with sites layouts present" do
|
83
83
|
let(:site) { Site.new }
|
84
|
-
|
85
|
-
|
84
|
+
|
85
|
+
let(:definitions) do
|
86
|
+
[{'name' => 'default_site', 'page_layouts' => %w(index)}]
|
87
|
+
end
|
88
|
+
|
89
|
+
before do
|
90
|
+
allow(Site).to receive(:layout_definitions).and_return(definitions)
|
91
|
+
end
|
86
92
|
|
87
93
|
it "should only return layouts for site" do
|
88
94
|
expect(subject.length).to eq(1)
|
89
|
-
expect(subject.first['name']).to eq('
|
95
|
+
expect(subject.first['name']).to eq('index')
|
90
96
|
end
|
91
97
|
end
|
92
98
|
end
|
@@ -63,6 +63,11 @@ module Alchemy
|
|
63
63
|
expect(resource.skipped_attributes).to eq(%w(id updated_at created_at creator_id updater_id))
|
64
64
|
end
|
65
65
|
|
66
|
+
it "sets the restricted attributes accessor to an empty array by default" do
|
67
|
+
resource = Resource.new("admin/parties")
|
68
|
+
expect(resource.restricted_attributes).to eq([])
|
69
|
+
end
|
70
|
+
|
66
71
|
it "sets an instance variable that holds the controller path" do
|
67
72
|
resource = Resource.new("admin/parties")
|
68
73
|
expect(resource.instance_variable_get(:@controller_path)).to eq("admin/parties")
|
@@ -269,6 +274,25 @@ module Alchemy
|
|
269
274
|
end
|
270
275
|
end
|
271
276
|
|
277
|
+
describe "#editable_attributes" do
|
278
|
+
subject { resource.editable_attributes }
|
279
|
+
|
280
|
+
let(:columns) do
|
281
|
+
[
|
282
|
+
double(:column, {name: 'name', type: :string}),
|
283
|
+
double(:column, {name: 'title', type: :string}),
|
284
|
+
double(:column, {name: 'synced_at', type: :datetime}),
|
285
|
+
double(:column, {name: 'remote_record_id', type: :string})
|
286
|
+
]
|
287
|
+
end
|
288
|
+
|
289
|
+
before { resource.restricted_attributes = [:synced_at, :remote_record_id] }
|
290
|
+
|
291
|
+
it "does not contain restricted attributes" do
|
292
|
+
is_expected.to eq([{name: "name", type: :string}, {name: "title", type: :string}])
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
272
296
|
context "when alchemy_resource_relations defined as class method in the model" do
|
273
297
|
let(:resource) { Resource.new("admin/events") }
|
274
298
|
|
data/spec/models/page_spec.rb
CHANGED
@@ -567,22 +567,6 @@ module Alchemy
|
|
567
567
|
end
|
568
568
|
end
|
569
569
|
|
570
|
-
describe '.layout_description' do
|
571
|
-
it "should raise Exception if the page_layout could not be found in the definition file" do
|
572
|
-
expect { page.layout_description }.to raise_error
|
573
|
-
end
|
574
|
-
|
575
|
-
context "for a language root page" do
|
576
|
-
it "should return the page layout description as hash" do
|
577
|
-
expect(language_root.layout_description['name']).to eq('intro')
|
578
|
-
end
|
579
|
-
|
580
|
-
it "should return an empty hash for root page" do
|
581
|
-
expect(rootpage.layout_description).to eq({})
|
582
|
-
end
|
583
|
-
end
|
584
|
-
end
|
585
|
-
|
586
570
|
describe '.layoutpages' do
|
587
571
|
it "should return 1 layoutpage" do
|
588
572
|
FactoryGirl.create(:public_page, :layoutpage => true, :name => 'Layoutpage', :parent_id => rootpage.id, :language => language)
|
@@ -659,16 +643,6 @@ module Alchemy
|
|
659
643
|
end
|
660
644
|
end
|
661
645
|
|
662
|
-
context "for page_layout not existing" do
|
663
|
-
let(:page) { FactoryGirl.build_stubbed(:page, page_layout: 'not_existing_one') }
|
664
|
-
|
665
|
-
it "should raise error" do
|
666
|
-
expect {
|
667
|
-
page.available_element_definitions
|
668
|
-
}.to raise_error(Alchemy::PageLayoutDefinitionError)
|
669
|
-
end
|
670
|
-
end
|
671
|
-
|
672
646
|
context 'limited amount' do
|
673
647
|
let(:page) { FactoryGirl.build_stubbed(:page, page_layout: 'columns') }
|
674
648
|
let(:unique_element) { FactoryGirl.build_stubbed(:unique_element, name: 'unique_headline') }
|
@@ -1026,6 +1000,31 @@ module Alchemy
|
|
1026
1000
|
end
|
1027
1001
|
end
|
1028
1002
|
|
1003
|
+
describe '#layout_description' do
|
1004
|
+
context 'if the page layout could not be found in the definition file' do
|
1005
|
+
let(:page) { build_stubbed(:page, page_layout: 'notexisting') }
|
1006
|
+
|
1007
|
+
it "it loggs a warning." do
|
1008
|
+
expect(Alchemy::Logger).to receive(:warn)
|
1009
|
+
page.layout_description
|
1010
|
+
end
|
1011
|
+
|
1012
|
+
it "it returns empty hash." do
|
1013
|
+
expect(page.layout_description).to eq({})
|
1014
|
+
end
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
context "for a language root page" do
|
1018
|
+
it "it returns the page layout description as hash." do
|
1019
|
+
expect(language_root.layout_description['name']).to eq('index')
|
1020
|
+
end
|
1021
|
+
|
1022
|
+
it "it returns an empty hash for root page." do
|
1023
|
+
expect(rootpage.layout_description).to eq({})
|
1024
|
+
end
|
1025
|
+
end
|
1026
|
+
end
|
1027
|
+
|
1029
1028
|
describe '#lock_to!' do
|
1030
1029
|
let(:page) { create(:page) }
|
1031
1030
|
let(:user) { mock_model('DummyUser') }
|
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.1.0.
|
4
|
+
version: 3.1.0.beta6
|
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: 2015-01-
|
15
|
+
date: 2015-01-08 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: actionpack-page_caching
|
@@ -446,6 +446,7 @@ executables:
|
|
446
446
|
extensions: []
|
447
447
|
extra_rdoc_files: []
|
448
448
|
files:
|
449
|
+
- ".editorconfig"
|
449
450
|
- ".gitignore"
|
450
451
|
- ".rspec"
|
451
452
|
- ".travis.yml"
|
@@ -842,14 +843,12 @@ files:
|
|
842
843
|
- app/views/kaminari/alchemy/_paginator.html.erb
|
843
844
|
- app/views/kaminari/alchemy/_prev_page.html.erb
|
844
845
|
- app/views/layouts/alchemy/admin.html.erb
|
845
|
-
- app/views/layouts/alchemy/login.html.erb
|
846
846
|
- app/views/layouts/alchemy/sitemap.xml.erb
|
847
847
|
- bin/alchemy
|
848
848
|
- bin/rails
|
849
849
|
- config/alchemy/config.yml
|
850
850
|
- config/alchemy/modules.yml
|
851
851
|
- config/initializers/dragonfly.rb
|
852
|
-
- config/initializers/inflections.rb
|
853
852
|
- config/initializers/simple_form.rb
|
854
853
|
- config/locales/alchemy.de.yml
|
855
854
|
- config/locales/alchemy.en.yml
|