alchemy_cms 2.0.rc6 → 2.0
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.
- data/.travis.yml +2 -1
- data/LICENSE +24 -619
- data/README.md +38 -36
- data/alchemy_cms.gemspec +1 -1
- data/app/controllers/admin/elements_controller.rb +3 -2
- data/app/controllers/admin/pages_controller.rb +20 -14
- data/app/controllers/admin/trash_controller.rb +4 -0
- data/app/controllers/pages_controller.rb +27 -16
- data/app/helpers/admin/elements_helper.rb +55 -0
- data/app/helpers/alchemy_helper.rb +0 -45
- data/app/helpers/elements_helper.rb +8 -1
- data/app/helpers/pages_helper.rb +0 -10
- data/app/models/element.rb +39 -5
- data/app/models/page.rb +27 -7
- data/app/sweepers/pages_sweeper.rb +0 -9
- data/app/views/admin/pages/update.js.erb +15 -1
- data/app/views/admin/partials/_upload_form.html.erb +2 -2
- data/app/views/elements/_contactform_view.html.erb +10 -23
- data/app/views/elements/_searchresult_view.html.erb +47 -40
- data/app/views/essences/_essence_html_view.html.erb +1 -1
- data/app/views/pages/show.rss.builder +20 -25
- data/assets/javascripts/alchemy.js +2 -2
- data/assets/stylesheets/elements.css +1 -1
- data/assets/stylesheets/standard_set.css +84 -14
- data/config/alchemy/elements.yml +2 -0
- data/config/alchemy/page_layouts.yml +1 -0
- data/config/locales/de.yml +5 -5
- data/lib/alchemy/version.rb +1 -1
- data/lib/rails/generators/alchemy/plugin/templates/config.yml +3 -3
- data/spec/controllers/admin/trash_controller_spec.rb +22 -0
- data/spec/controllers/pages_controller_spec.rb +39 -0
- data/spec/dummy/db/schema.rb +10 -9
- data/spec/factories.rb +5 -0
- data/spec/helpers/elements_helper_spec.rb +7 -0
- data/spec/integration/pages_controller_spec.rb +1 -1
- data/spec/models/element_spec.rb +51 -5
- data/spec/models/page_spec.rb +70 -10
- metadata +10 -7
- data/TODO.txt +0 -1
@@ -428,10 +428,10 @@ if (typeof(Alchemy) === 'undefined') {
|
|
428
428
|
|
429
429
|
openLicencseWindow : function() {
|
430
430
|
var height = $(window).height() - 150;
|
431
|
-
var $iframe = $('<iframe src="
|
431
|
+
var $iframe = $('<iframe src="https://raw.github.com/magiclabs/alchemy_cms/master/LICENSE"></iframe>');
|
432
432
|
$iframe.dialog({
|
433
433
|
bgiframe: true,
|
434
|
-
title: '
|
434
|
+
title: 'Alchemy CMS License',
|
435
435
|
width: 650,
|
436
436
|
height: height,
|
437
437
|
autoResize: true,
|
@@ -1,3 +1,5 @@
|
|
1
|
+
/* @override http://localhost:3000/stylesheets/alchemy/standard_set.css */
|
2
|
+
|
1
3
|
body {
|
2
4
|
margin: 0;
|
3
5
|
padding: 0;
|
@@ -128,11 +130,10 @@ div#header_image {
|
|
128
130
|
#navigation {
|
129
131
|
font-family: "Lucida Grande", Lucida, Verdana, sans-serif;
|
130
132
|
color: #fdfdfd;
|
131
|
-
position: relative;
|
132
|
-
top: 40%;
|
133
133
|
text-transform: uppercase;
|
134
|
-
|
135
|
-
|
134
|
+
position: absolute;
|
135
|
+
top: 215px;
|
136
|
+
z-index: 100;
|
136
137
|
}
|
137
138
|
|
138
139
|
#navigation ul {
|
@@ -333,36 +334,62 @@ input.field {
|
|
333
334
|
margin: 0;
|
334
335
|
font: 12px "Lucida Grande", Lucida, Verdana, sans-serif;
|
335
336
|
border: 1px solid silver;
|
336
|
-
width:
|
337
|
+
width: 310px;
|
338
|
+
}
|
339
|
+
|
340
|
+
td.field {
|
341
|
+
white-space: nowrap;
|
337
342
|
}
|
338
343
|
|
339
344
|
input.field.short {
|
340
|
-
width:
|
345
|
+
width: 105px;
|
341
346
|
}
|
342
347
|
|
343
348
|
input.field.medium {
|
344
|
-
width:
|
349
|
+
width: 200px;
|
345
350
|
}
|
346
351
|
|
347
352
|
td.label {
|
348
|
-
width:
|
353
|
+
width: 130px;
|
349
354
|
}
|
350
355
|
|
351
356
|
textarea {
|
352
|
-
width:
|
357
|
+
width: 310px;
|
353
358
|
padding: 2px;
|
354
359
|
font: 12px "Lucida Grande", Lucida, Verdana, sans-serif;
|
355
360
|
border: 1px solid silver;
|
356
|
-
margin-left:
|
361
|
+
margin-left: 137px;
|
357
362
|
height: 10em;
|
358
363
|
margin-top: 2em;
|
359
364
|
margin-bottom: 1em;
|
360
365
|
}
|
361
366
|
|
367
|
+
div.field_with_errors {
|
368
|
+
color: #fe1b15;
|
369
|
+
}
|
370
|
+
|
371
|
+
div.field_with_errors input.field {
|
372
|
+
border-color: #fe1b15;
|
373
|
+
}
|
374
|
+
|
375
|
+
p.foot_notice {
|
376
|
+
font-size: 0.8em;
|
377
|
+
}
|
378
|
+
|
362
379
|
form#contact {
|
363
|
-
padding:
|
364
|
-
width:
|
365
|
-
|
380
|
+
padding: 0 0 0 12px;
|
381
|
+
width: 450px;
|
382
|
+
}
|
383
|
+
|
384
|
+
#errorExplanation {
|
385
|
+
color: #fe1d16;
|
386
|
+
margin-bottom: 20px;
|
387
|
+
margin-top: 20px;
|
388
|
+
}
|
389
|
+
|
390
|
+
#errorExplanation ul {
|
391
|
+
list-style-type: disc;
|
392
|
+
padding: 0 0 0 1.5em;
|
366
393
|
}
|
367
394
|
|
368
395
|
label {
|
@@ -371,4 +398,47 @@ label {
|
|
371
398
|
|
372
399
|
p.right {
|
373
400
|
text-align: right;
|
374
|
-
}
|
401
|
+
}
|
402
|
+
|
403
|
+
.searchresult {
|
404
|
+
margin-top: 1em;
|
405
|
+
margin-bottom: 1em;
|
406
|
+
}
|
407
|
+
|
408
|
+
.searchresult form {
|
409
|
+
padding-left: 12px;
|
410
|
+
}
|
411
|
+
|
412
|
+
.searchresult h2 {
|
413
|
+
padding-left: 12px;
|
414
|
+
margin-bottom: 2em;
|
415
|
+
margin-top: 1em;
|
416
|
+
}
|
417
|
+
|
418
|
+
.search_results ul {
|
419
|
+
list-style-type: none;
|
420
|
+
padding: 0 0 0 12px;
|
421
|
+
}
|
422
|
+
|
423
|
+
.search_results ul li {
|
424
|
+
margin-bottom: 2em;
|
425
|
+
}
|
426
|
+
|
427
|
+
.search_results ul li p {
|
428
|
+
margin-top: 0.5em;
|
429
|
+
margin-bottom: 0.5em;
|
430
|
+
}
|
431
|
+
|
432
|
+
.search_results ul li h3 {
|
433
|
+
margin-bottom: 0.5em;
|
434
|
+
margin-top: 0.5em;
|
435
|
+
}
|
436
|
+
|
437
|
+
.search_results ul li h4 {
|
438
|
+
margin-top: 0.5em;
|
439
|
+
margin-bottom: 0.5em;
|
440
|
+
}
|
441
|
+
|
442
|
+
.search_results em {
|
443
|
+
font-weight: bold;
|
444
|
+
}
|
data/config/alchemy/elements.yml
CHANGED
data/config/locales/de.yml
CHANGED
@@ -85,7 +85,7 @@ de:
|
|
85
85
|
# == Translations for the build in full text search.
|
86
86
|
search:
|
87
87
|
no_results: 'Ihre Suche ergab kein Ergebnis.'
|
88
|
-
result_heading:
|
88
|
+
result_heading: "Ihre Suche nach '%{query}' hat %{count} Ergebnisse"
|
89
89
|
|
90
90
|
# == Contactform translations
|
91
91
|
contactform:
|
@@ -102,7 +102,7 @@ de:
|
|
102
102
|
email: 'Email'
|
103
103
|
message: 'Nachricht'
|
104
104
|
send: 'Nachricht absenden!'
|
105
|
-
mandatory_fields: 'Pflichtfelder. Vielen Dank!'
|
105
|
+
mandatory_fields: 'Pflichtfelder. Bitte füllen Sie diese Felder aus. Vielen Dank!'
|
106
106
|
success_page: 'Folgeseite'
|
107
107
|
# Translations for the contactform validations.
|
108
108
|
# Validations are set in the config/alchemy/config.yml mailer section.
|
@@ -323,9 +323,9 @@ de:
|
|
323
323
|
errors:
|
324
324
|
template:
|
325
325
|
header:
|
326
|
-
one: "Konnte
|
327
|
-
other: "Konnte
|
328
|
-
body: "
|
326
|
+
one: "Konnte nicht fortfahren, da 1 Fehler auftrat."
|
327
|
+
other: "Konnte nicht fortfahren, da %{count} Fehler auftraten."
|
328
|
+
body: "Fehler:"
|
329
329
|
messages:
|
330
330
|
inclusion: "%{attribute} ist kein gültiger Wert"
|
331
331
|
exclusion: "%{attribute} ist nicht verfügbar"
|
data/lib/alchemy/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# This is your plugin configuration file.
|
2
2
|
# ========================================
|
3
3
|
#
|
4
4
|
# Options:
|
@@ -9,9 +9,9 @@
|
|
9
9
|
# settings: # [Optional] Put your own settings in YAML format into here. You can access them with plugin_conf('<%= @plugin_name.underscore %>')['settings'] [YAML]
|
10
10
|
# navigation:
|
11
11
|
# name: # The name is used in the Alchemy mainnavi. [String]
|
12
|
-
# controller: # The name of the controller to be called when clicking the mainnavi button [String]
|
12
|
+
# controller: # The name of the controller to be called when clicking the mainnavi button. Example usage: 'admin/controllername' [String]
|
13
13
|
# action: # The name of the action from the controller to be called when clicking the mainnavi button [String]
|
14
|
-
#
|
14
|
+
# icon: # CSS classname for the link in the alchemy mainnavi. [String]
|
15
15
|
# sub_navigation: # Your plugins sub navigation. Put as much as sub navi entries as you want into here
|
16
16
|
# - name: # [String]
|
17
17
|
# controller: # Typically your controller and action you set for mainnavi entry.
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Admin::TrashController do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
activate_authlogic
|
7
|
+
UserSession.create Factory(:admin_user)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should hold trashed elements" do
|
11
|
+
pending "The controller behaves correct, the test not."
|
12
|
+
@page = Factory(:page, :parent_id => Page.rootpage.id)
|
13
|
+
@element = Factory(:element, :page => @page)
|
14
|
+
# Rails, RSpec and co. are sucking
|
15
|
+
@element.reload
|
16
|
+
@element.trash
|
17
|
+
@element.reload
|
18
|
+
get :index, :page_id => @page.id
|
19
|
+
response.body.should have_selector('#trash_items #element_4.element_editor')
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PagesController do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@default_language = Language.get_default
|
7
|
+
@default_language_root = Factory(:language_root_page, :language => @default_language, :name => 'Home', :public => true)
|
8
|
+
end
|
9
|
+
|
10
|
+
context "requested for a page containing a feed" do
|
11
|
+
|
12
|
+
before(:each) do
|
13
|
+
@page = Factory(:public_page, :parent_id => @default_language_root.id, :page_layout => 'news', :name => 'News', :language => @default_language)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should render a rss feed" do
|
17
|
+
get :show, :urlname => 'news', :format => :rss
|
18
|
+
response.content_type.should == 'application/rss+xml'
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should include content" do
|
22
|
+
pending "I didn't figured out how to test XML response bodies"
|
23
|
+
@page.elements.first.content_by_name('news_headline').essence.update_attributes({:body => 'Peters Petshop'})
|
24
|
+
get :show, :urlname => 'news', :format => :rss
|
25
|
+
response.body.should match /Peters Petshop/
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
|
30
|
+
context "requested for a page that does not contain a feed" do
|
31
|
+
|
32
|
+
it "should render xml 404 error" do
|
33
|
+
get :show, :urlname => 'home', :format => :rss
|
34
|
+
response.status.should == 404
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
# This file is auto-generated from the current state of the database. Instead
|
2
3
|
# of editing this file, please use the migrations feature of Active Record to
|
3
4
|
# incrementally modify your database, and then regenerate this schema definition.
|
@@ -197,7 +198,7 @@ ActiveRecord::Schema.define(:version => 20110919110451) do
|
|
197
198
|
t.string "urlname"
|
198
199
|
t.string "title"
|
199
200
|
t.string "language_code"
|
200
|
-
t.boolean "language_root"
|
201
|
+
t.boolean "language_root", :limit => 255
|
201
202
|
t.string "page_layout"
|
202
203
|
t.text "meta_keywords"
|
203
204
|
t.text "meta_description"
|
@@ -205,15 +206,15 @@ ActiveRecord::Schema.define(:version => 20110919110451) do
|
|
205
206
|
t.integer "rgt"
|
206
207
|
t.integer "parent_id"
|
207
208
|
t.integer "depth"
|
208
|
-
t.boolean "visible",
|
209
|
-
t.boolean "public",
|
210
|
-
t.boolean "locked",
|
209
|
+
t.boolean "visible", :default => false
|
210
|
+
t.boolean "public", :default => false
|
211
|
+
t.boolean "locked", :default => false
|
211
212
|
t.integer "locked_by"
|
212
|
-
t.boolean "restricted",
|
213
|
-
t.boolean "robot_index",
|
214
|
-
t.boolean "robot_follow",
|
215
|
-
t.boolean "sitemap",
|
216
|
-
t.boolean "layoutpage",
|
213
|
+
t.boolean "restricted", :default => false
|
214
|
+
t.boolean "robot_index", :default => true
|
215
|
+
t.boolean "robot_follow", :default => true
|
216
|
+
t.boolean "sitemap", :default => true
|
217
|
+
t.boolean "layoutpage", :default => false
|
217
218
|
t.datetime "created_at"
|
218
219
|
t.datetime "updated_at"
|
219
220
|
t.integer "creator_id"
|
data/spec/factories.rb
CHANGED
@@ -23,6 +23,13 @@ describe ElementsHelper do
|
|
23
23
|
helper.element_dom_id(@element).should == "#{@element.name}_#{@element.id}"
|
24
24
|
end
|
25
25
|
|
26
|
+
it "should render elements for a cell", :focus => true do
|
27
|
+
cell = Factory(:cell)
|
28
|
+
Factory(:element, :cell_id => cell.id)
|
29
|
+
helper.stub(:configuration).and_return(true)
|
30
|
+
helper.render_cell_elements(cell).should match(/id="article_7"/)
|
31
|
+
end
|
32
|
+
|
26
33
|
context "in preview mode" do
|
27
34
|
|
28
35
|
it "should return the data-alchemy-element HTML attribute for element" do
|
data/spec/models/element_spec.rb
CHANGED
@@ -33,10 +33,10 @@ describe Element do
|
|
33
33
|
definitions.first.fetch("name").should == 'article'
|
34
34
|
end
|
35
35
|
|
36
|
-
|
36
|
+
it "should always return an array calling all_definitions_for()" do
|
37
37
|
definitions = Element.all_definitions_for(nil)
|
38
38
|
definitions.should == []
|
39
|
-
|
39
|
+
end
|
40
40
|
|
41
41
|
it "should raise an error if no descriptions are found" do
|
42
42
|
FileUtils.mv(File.join(File.dirname(__FILE__), '..', '..', 'config', 'alchemy', 'elements.yml'), File.join(File.dirname(__FILE__), '..', '..', 'config', 'alchemy', 'elements.yml.bak'))
|
@@ -44,9 +44,55 @@ describe Element do
|
|
44
44
|
FileUtils.mv(File.join(File.dirname(__FILE__), '..', '..', 'config', 'alchemy', 'elements.yml.bak'), File.join(File.dirname(__FILE__), '..', '..', 'config', 'alchemy', 'elements.yml'))
|
45
45
|
end
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
context "retrieving contents, essences and ingredients" do
|
48
|
+
|
49
|
+
before(:each) do
|
50
|
+
@element = Factory(:element, :name => 'news')
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should return an ingredient by name" do
|
54
|
+
@element.ingredient('news_headline').should == EssenceText.first.ingredient
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should return the content for rss title" do
|
58
|
+
@element.content_for_rss_title.should == @element.contents.find_by_name('news_headline')
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should return the content for rss description" do
|
62
|
+
@element.content_for_rss_description.should == @element.contents.find_by_name('body')
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should return a collection of trashed elements" do
|
68
|
+
@element = Factory(:element)
|
69
|
+
@element.trash
|
70
|
+
Element.trashed.should include(@element)
|
71
|
+
end
|
72
|
+
|
73
|
+
context "trashed" do
|
74
|
+
|
75
|
+
before(:each) do
|
76
|
+
@element = Factory(:element)
|
77
|
+
@element.trash
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should be not public" do
|
81
|
+
@element.public.should be_false
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should have no page" do
|
85
|
+
@element.page.should == nil
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should be folded" do
|
89
|
+
@element.folded.should == true
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should raise error if all_for_page method has no page" do
|
95
|
+
expect { Element.all_for_page(nil) }.should raise_error(TypeError)
|
50
96
|
end
|
51
97
|
|
52
98
|
end
|