zena 1.0.0.beta2 → 1.0.0.beta3
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/.gitignore +2 -0
- data/History.txt +12 -0
- data/app/controllers/application_controller.rb +0 -1
- data/app/controllers/columns_controller.rb +11 -1
- data/app/controllers/nodes_controller.rb +79 -19
- data/app/controllers/versions_controller.rb +0 -2
- data/app/controllers/virtual_classes_controller.rb +19 -6
- data/app/models/column.rb +5 -1
- data/app/models/comment.rb +1 -6
- data/app/models/node.rb +21 -3
- data/app/models/role.rb +21 -0
- data/app/models/site.rb +7 -2
- data/app/models/template.rb +3 -3
- data/app/models/text_document.rb +4 -4
- data/app/models/user.rb +21 -8
- data/app/views/columns/_li.html.erb +1 -0
- data/app/views/nodes/_groups.rhtml +1 -1
- data/app/views/sites/_form.erb +3 -1
- data/app/views/sites/_li.erb +1 -0
- data/app/views/sites/index.erb +1 -1
- data/app/views/virtual_classes/_form.erb +11 -2
- data/app/views/virtual_classes/_li.erb +5 -2
- data/bin/zena +1 -1
- data/bricks/math/lib/bricks/math.rb +1 -1
- data/bricks/mongrel/README +3 -0
- data/bricks/mongrel/zena/deploy.rb +56 -0
- data/bricks/passenger/README +3 -0
- data/bricks/passenger/zena/deploy.rb +49 -0
- data/config/bricks.yml +6 -0
- data/config/deploy.rb +24 -18
- data/config/gems.yml +3 -3
- data/db/migrate/20100915062903_add_api_group_id_to_site.rb +9 -0
- data/lib/tasks/zena.rake +39 -35
- data/lib/zena.rb +5 -6
- data/lib/zena/acts/enrollable.rb +37 -6
- data/lib/zena/app.rb +4 -2
- data/lib/zena/deploy.rb +110 -150
- data/lib/zena/deploy/awstats.conf.rhtml +4 -4
- data/lib/zena/deploy/httpd.rhtml +2 -1
- data/lib/zena/deploy/stats.vhost.rhtml +7 -7
- data/lib/zena/deploy/vhost.rhtml +1 -1
- data/lib/zena/deploy/vhost_www.rhtml +4 -4
- data/lib/zena/foxy_parser.rb +6 -5
- data/lib/zena/info.rb +1 -1
- data/lib/zena/integration/test_case.rb +8 -3
- data/lib/zena/parser.rb +11 -11
- data/lib/zena/parser/zafu_tags.rb +2 -2
- data/lib/zena/remote.rb +16 -0
- data/lib/zena/remote/connection.rb +67 -0
- data/lib/zena/remote/interface.rb +405 -0
- data/lib/zena/remote/klass.rb +14 -0
- data/lib/zena/remote/mock.rb +58 -0
- data/lib/zena/remote/node.rb +76 -0
- data/lib/zena/routes.rb +2 -1
- data/lib/zena/use.rb +9 -4
- data/lib/zena/use/ajax.rb +3 -3
- data/lib/zena/use/authlogic.rb +8 -1
- data/lib/zena/use/context.rb +22 -21
- data/lib/zena/use/dates.rb +26 -3
- data/lib/zena/use/display.rb +33 -5
- data/lib/zena/use/forms.rb +90 -12
- data/lib/zena/use/fulltext.rb +1 -1
- data/lib/zena/use/i18n.rb +118 -31
- data/lib/zena/use/query_builder.rb +7 -5
- data/lib/zena/use/query_node.rb +30 -4
- data/lib/zena/use/rendering.rb +1 -1
- data/lib/zena/use/search.rb +10 -7
- data/lib/zena/use/urls.rb +3 -3
- data/lib/zena/use/zafu_attributes.rb +2 -2
- data/lib/zena/use/zafu_eval.rb +1 -1
- data/lib/zena/use/zafu_safe_definitions.rb +1 -0
- data/lib/zena/use/zafu_templates.rb +1 -1
- data/lib/zena/zafu_compiler.rb +5 -1
- data/public/javascripts/zena.js +4 -4
- data/public/stylesheets/admin.css +1 -0
- data/test/custom_queries/complex.host.yml +3 -3
- data/test/fixtures/files/translations_fr.yml +4 -1
- data/test/functional/application_controller_test.rb +2 -2
- data/test/functional/nodes_controller_test.rb +57 -5
- data/test/functional/users_controller_test.rb +10 -9
- data/test/functional/virtual_classes_controller_test.rb +48 -0
- data/test/integration/navigation_test.rb +13 -1
- data/test/integration/query_node/filters.yml +5 -0
- data/test/integration/query_node_test.rb +1 -1
- data/test/integration/zafu_compiler/ajax.yml +13 -19
- data/test/integration/zafu_compiler/basic.yml +0 -72
- data/test/integration/zafu_compiler/complex.yml +1 -1
- data/test/integration/zafu_compiler/complex_ok.yml +19 -0
- data/test/integration/zafu_compiler/dates.yml +62 -1
- data/test/integration/zafu_compiler/display.yml +4 -4
- data/test/integration/zafu_compiler/forms.yml +19 -7
- data/test/integration/zafu_compiler/i18n.yml +56 -1
- data/test/integration/zafu_compiler/later.yml +23 -1
- data/test/integration/zafu_compiler/relations.yml +1 -1
- data/test/integration/zafu_compiler/roles.yml +29 -1
- data/test/integration/zafu_compiler/safe_definitions.yml +1 -1
- data/test/integration/zafu_compiler/zafu_attributes.yml +2 -1
- data/test/integration/zafu_compiler_test.rb +5 -3
- data/test/sites/zena/columns.yml +3 -0
- data/test/sites/zena/roles.yml +0 -1
- data/test/sites/zena/sites.yml +1 -0
- data/test/sites/zena/versions.yml +2 -0
- data/test/unit/node_test.rb +27 -9
- data/test/unit/relation_proxy_test.rb +7 -4
- data/test/unit/remote_test.rb +379 -0
- data/test/unit/user_test.rb +47 -0
- data/test/unit/zena/acts/enrollable_test.rb +36 -7
- data/test/unit/zena/acts/serializable_test.rb +14 -2
- data/test/unit/zena/use/i18n_test.rb +32 -5
- data/test/unit/zena/use/query_node_test.rb +13 -1
- data/zena.gemspec +25 -11
- metadata +24 -10
data/.gitignore
CHANGED
data/History.txt
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
== 1.0.0.beta3 2010-09-17
|
|
2
|
+
|
|
3
|
+
* major changes
|
|
4
|
+
* created Zena::Remote API
|
|
5
|
+
* fixed Ajax operations and tests
|
|
6
|
+
* fixed forms to create/update new objects
|
|
7
|
+
* added dynamic translations
|
|
8
|
+
* better querybuilder integration relative to SELECT clauses
|
|
9
|
+
* fixed date parsing
|
|
10
|
+
* added safe 'send' method
|
|
11
|
+
* added support to create and update Roles
|
|
12
|
+
|
|
1
13
|
== 1.0.0.beta2 2010-07-24
|
|
2
14
|
|
|
3
15
|
* major changes
|
|
@@ -7,8 +7,18 @@ class ColumnsController < ApplicationController
|
|
|
7
7
|
# GET /columns
|
|
8
8
|
# GET /columns.xml
|
|
9
9
|
def index
|
|
10
|
+
roles = {}
|
|
10
11
|
secure(Column) do
|
|
11
|
-
@columns = Column.paginate(:all, :order => 'name', :per_page => 20, :page => params[:page])
|
|
12
|
+
@columns = Column.paginate(:all, :order => 'role_id ASC, name ASC', :per_page => 20, :page => params[:page]).sort! do |a, b|
|
|
13
|
+
role_a = (roles[a.role_id] ||= a.role).name
|
|
14
|
+
role_b = (roles[b.role_id] ||= b.role).name
|
|
15
|
+
|
|
16
|
+
if role_a == role_b
|
|
17
|
+
a.name <=> b.name
|
|
18
|
+
else
|
|
19
|
+
role_a <=> role_b
|
|
20
|
+
end
|
|
21
|
+
end
|
|
12
22
|
end
|
|
13
23
|
|
|
14
24
|
@column = Column.new
|
|
@@ -3,22 +3,23 @@
|
|
|
3
3
|
|
|
4
4
|
basepath class and zip optional mode format
|
|
5
5
|
|
|
6
|
-
/projects/art/ project24
|
|
6
|
+
/projects/art/ project24 _print .html
|
|
7
7
|
|
|
8
8
|
Examples:
|
|
9
9
|
/current/art/project24.html << a project inside the 'art' page
|
|
10
10
|
/note24.html << a Note's page
|
|
11
11
|
/note24_print.html << a Note in 'print' mode
|
|
12
|
-
/current/art.html << 'art' page (this page has custom base set
|
|
13
|
-
/current/
|
|
12
|
+
/current/art.html << 'art' page (this page has custom base set, this means no class or zip shown)
|
|
13
|
+
/current/art_print.html << 'art' page in 'print' mode
|
|
14
14
|
/current/art/project24/image28.html << image page (for comments, etc)
|
|
15
|
-
/current/art/project24/image28.jpg << full image
|
|
16
|
-
/current/art/project24/image28_pv.jpg << image in the 'pv' format
|
|
17
|
-
/current/art/project24/
|
|
15
|
+
/current/art/project24/image28.jpg << full image data
|
|
16
|
+
/current/art/project24/image28_pv.jpg << image in the 'pv' image format
|
|
17
|
+
/current/art/project24/image28_print.html << image page in 'print' mode
|
|
18
18
|
|
|
19
19
|
=end
|
|
20
20
|
class NodesController < ApplicationController
|
|
21
21
|
before_filter :check_is_admin, :only => [:export]
|
|
22
|
+
before_filter :check_api_group
|
|
22
23
|
before_filter :find_node, :except => [:index, :create, :not_found, :catch_all, :search]
|
|
23
24
|
before_filter :check_can_drive, :only => [:edit]
|
|
24
25
|
before_filter :check_path, :only => [:index, :show]
|
|
@@ -50,15 +51,46 @@ class NodesController < ApplicationController
|
|
|
50
51
|
raise ActiveRecord::RecordNotFound
|
|
51
52
|
end
|
|
52
53
|
|
|
54
|
+
# Find nodes starting from root node
|
|
53
55
|
def search
|
|
54
|
-
do_search
|
|
55
56
|
respond_to do |format|
|
|
56
|
-
format.html
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
format.html do
|
|
58
|
+
begin
|
|
59
|
+
do_search
|
|
60
|
+
rescue QueryBuilder::Error => err
|
|
61
|
+
flash[:error] = err.message
|
|
62
|
+
end
|
|
63
|
+
render_and_cache :mode => '+search', :cache => false
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
format.xml do
|
|
67
|
+
begin
|
|
68
|
+
do_search
|
|
69
|
+
if @nodes.kind_of?(Fixnum)
|
|
70
|
+
# count
|
|
71
|
+
render :xml => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<count type=\"integer\">#{@nodes}</count>\n"
|
|
72
|
+
elsif @nodes
|
|
73
|
+
render :xml => Array(@nodes).to_xml(:root => 'nodes')
|
|
74
|
+
else
|
|
75
|
+
render :xml => [].to_xml(:root => 'nodes')
|
|
76
|
+
end
|
|
77
|
+
rescue QueryBuilder::Error => err
|
|
78
|
+
render :xml => [{:message => err.message}].to_xml(:root => 'errors'), :status => 401
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
format.js do
|
|
83
|
+
do_search
|
|
84
|
+
render :action => 'search'
|
|
85
|
+
end
|
|
59
86
|
end
|
|
60
87
|
end
|
|
61
88
|
|
|
89
|
+
# Find nodes starting from a given node
|
|
90
|
+
def find
|
|
91
|
+
search
|
|
92
|
+
end
|
|
93
|
+
|
|
62
94
|
# this should not be needed.... but format.js never gets called otherwize.
|
|
63
95
|
def asearch
|
|
64
96
|
do_search
|
|
@@ -180,7 +212,7 @@ class NodesController < ApplicationController
|
|
|
180
212
|
flash[:notice] = 'Node was successfully created.'
|
|
181
213
|
format.html { redirect_to zen_path(@node) }
|
|
182
214
|
format.js
|
|
183
|
-
format.xml { render :xml => @node, :status => :created, :location => node_url(@node) }
|
|
215
|
+
format.xml { render :xml => @node.to_xml(:root => 'node'), :status => :created, :location => node_url(@node) }
|
|
184
216
|
else
|
|
185
217
|
format.html { render :action => "new" }
|
|
186
218
|
format.js
|
|
@@ -312,13 +344,19 @@ class NodesController < ApplicationController
|
|
|
312
344
|
end
|
|
313
345
|
end
|
|
314
346
|
end # parent iframe (upload)
|
|
315
|
-
|
|
347
|
+
else
|
|
316
348
|
respond_to do |format|
|
|
317
349
|
format.html do
|
|
318
|
-
if
|
|
319
|
-
|
|
350
|
+
if @node.errors.empty?
|
|
351
|
+
if params[:edit] == 'popup'
|
|
352
|
+
redirect_to edit_node_version_path(:node_id => @node[:zip], :id => 0, :close => (params[:validate] ? true : nil))
|
|
353
|
+
else
|
|
354
|
+
redirect_to zen_path(@node, :mode => params[:mode])
|
|
355
|
+
end
|
|
320
356
|
else
|
|
321
|
-
|
|
357
|
+
# FIXME: Render referring page would be better
|
|
358
|
+
# Get mode and details from request.referer
|
|
359
|
+
render_and_cache :mode => 'edit', :cache => false
|
|
322
360
|
end
|
|
323
361
|
end # html
|
|
324
362
|
|
|
@@ -564,6 +602,13 @@ class NodesController < ApplicationController
|
|
|
564
602
|
end
|
|
565
603
|
|
|
566
604
|
def do_search
|
|
605
|
+
if @node
|
|
606
|
+
default_scope = 'self'
|
|
607
|
+
else
|
|
608
|
+
@node = current_site.root_node
|
|
609
|
+
default_scope = 'site'
|
|
610
|
+
end
|
|
611
|
+
|
|
567
612
|
unless query_params = params[:q]
|
|
568
613
|
query_params = params.dup
|
|
569
614
|
%w{controller action format}.each do |key|
|
|
@@ -571,10 +616,18 @@ class NodesController < ApplicationController
|
|
|
571
616
|
end
|
|
572
617
|
end
|
|
573
618
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
619
|
+
if request.format != Mime::XML || params[:page] || params[:per_page]
|
|
620
|
+
@search_per_page = params[:per_page] ? params[:per_page].to_i : 20
|
|
621
|
+
@nodes = secure(Node) { Node.search_records(query_params, :node => @node, :default => {:scope => default_scope}, :page => params[:page], :per_page => @search_per_page) }
|
|
622
|
+
@search_count = 100 # FIXME: @nodes ? @nodes.total_entries : 0
|
|
623
|
+
else
|
|
624
|
+
# XML without pagination
|
|
625
|
+
@nodes = secure(Node) { Node.search_records(query_params, :node => @node, :default => {:scope => default_scope}) }
|
|
626
|
+
end
|
|
627
|
+
|
|
628
|
+
if @nodes.kind_of?(Node)
|
|
629
|
+
@nodes = [@nodes]
|
|
630
|
+
end
|
|
578
631
|
end
|
|
579
632
|
|
|
580
633
|
# Document data do not change session[:lang] and can point at cached content (no nee to redirect to AUTHENTICATED_PREFIX).
|
|
@@ -608,5 +661,12 @@ class NodesController < ApplicationController
|
|
|
608
661
|
def check_can_drive
|
|
609
662
|
raise ActiveRecord::RecordNotFound unless @node.can_drive?
|
|
610
663
|
end
|
|
664
|
+
|
|
665
|
+
def check_api_group
|
|
666
|
+
return true if request.format != Mime::XML || visitor.api_authorized?
|
|
667
|
+
|
|
668
|
+
render :xml => [{:message => 'Not in API group.'}].to_xml(:root => 'errors'), :status => 401
|
|
669
|
+
false
|
|
670
|
+
end
|
|
611
671
|
end
|
|
612
672
|
|
|
@@ -6,7 +6,7 @@ class VirtualClassesController < ApplicationController
|
|
|
6
6
|
|
|
7
7
|
def index
|
|
8
8
|
secure(VirtualClass) do
|
|
9
|
-
@virtual_classes =
|
|
9
|
+
@virtual_classes = Role.paginate(:all, :order => 'kpath', :per_page => 20, :page => params[:page])
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
last_kpath = @virtual_classes.last.kpath
|
|
@@ -16,7 +16,17 @@ class VirtualClassesController < ApplicationController
|
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
@virtual_classes.sort!
|
|
19
|
+
@virtual_classes.sort! do |a, b|
|
|
20
|
+
if a.kpath == b.kpath
|
|
21
|
+
# Order VirtualClass first
|
|
22
|
+
b_type = b.kind_of?(Role) ? b.class.to_s : 'V' # sort real classes like VirtualClass
|
|
23
|
+
a_type = a.kind_of?(Role) ? a.class.to_s : 'V'
|
|
24
|
+
|
|
25
|
+
b_type <=> a_type
|
|
26
|
+
else
|
|
27
|
+
a.kpath <=> b.kpath
|
|
28
|
+
end
|
|
29
|
+
end
|
|
20
30
|
|
|
21
31
|
@virtual_class = VirtualClass.new('')
|
|
22
32
|
|
|
@@ -80,7 +90,12 @@ class VirtualClassesController < ApplicationController
|
|
|
80
90
|
end
|
|
81
91
|
|
|
82
92
|
def create
|
|
83
|
-
|
|
93
|
+
type = params[:virtual_class].delete(:type)
|
|
94
|
+
if type == 'Role'
|
|
95
|
+
@virtual_class = Role.new(params[:virtual_class])
|
|
96
|
+
else
|
|
97
|
+
@virtual_class = VirtualClass.new(params[:virtual_class])
|
|
98
|
+
end
|
|
84
99
|
|
|
85
100
|
respond_to do |format|
|
|
86
101
|
if @virtual_class.save
|
|
@@ -97,8 +112,6 @@ class VirtualClassesController < ApplicationController
|
|
|
97
112
|
end
|
|
98
113
|
|
|
99
114
|
def update
|
|
100
|
-
@virtual_class = VirtualClass.find(params[:id])
|
|
101
|
-
|
|
102
115
|
respond_to do |format|
|
|
103
116
|
if @virtual_class.update_attributes(params[:virtual_class])
|
|
104
117
|
flash[:notice] = 'VirtualClass was successfully updated.'
|
|
@@ -125,6 +138,6 @@ class VirtualClassesController < ApplicationController
|
|
|
125
138
|
|
|
126
139
|
protected
|
|
127
140
|
def find_virtual_class
|
|
128
|
-
@virtual_class = secure!(VirtualClass) {
|
|
141
|
+
@virtual_class = secure!(VirtualClass) { Role.find(params[:id])}
|
|
129
142
|
end
|
|
130
143
|
end
|
data/app/models/column.rb
CHANGED
|
@@ -12,11 +12,15 @@ class Column < ActiveRecord::Base
|
|
|
12
12
|
validates_uniqueness_of :name, :scope => :site_id
|
|
13
13
|
validate :name_not_in_models
|
|
14
14
|
|
|
15
|
+
safe_method :name => String
|
|
16
|
+
|
|
15
17
|
class << self
|
|
16
18
|
include Zena::Acts::Secure
|
|
17
19
|
|
|
18
20
|
def roles_for_form
|
|
19
|
-
secure(Role) { Role.all(:order => '
|
|
21
|
+
secure(Role) { Role.all(:order => 'name ASC') }.map do |role|
|
|
22
|
+
[role.name, role.id]
|
|
23
|
+
end
|
|
20
24
|
end
|
|
21
25
|
|
|
22
26
|
# Import a hash of virtual class definitions and try to build the virtual classes.
|
data/app/models/comment.rb
CHANGED
|
@@ -10,7 +10,7 @@ class Comment < ActiveRecord::Base
|
|
|
10
10
|
|
|
11
11
|
safe_attribute :title, :created_at, :updated_at, :status
|
|
12
12
|
safe_method :text => String, :author_name => {:class => String, :nil => true},
|
|
13
|
-
:
|
|
13
|
+
:discussion_id => Number
|
|
14
14
|
|
|
15
15
|
safe_context :replies => ['Comment'], :node => 'Node'
|
|
16
16
|
|
|
@@ -64,11 +64,6 @@ class Comment < ActiveRecord::Base
|
|
|
64
64
|
self[:id]
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
# needed by zafu to group
|
|
68
|
-
def discussion_zip
|
|
69
|
-
self[:discussion_id]
|
|
70
|
-
end
|
|
71
|
-
|
|
72
67
|
# TODO: test
|
|
73
68
|
def can_write?
|
|
74
69
|
is_author? && discussion.open?
|
data/app/models/node.rb
CHANGED
|
@@ -162,7 +162,6 @@ class Node < ActiveRecord::Base
|
|
|
162
162
|
:score => Number, :comments_count => Number,
|
|
163
163
|
:custom_a => Number, :custom_b => Number
|
|
164
164
|
|
|
165
|
-
# FIXME: remove 'zip' and use :id => {:class => Number, :method => 'zip'}
|
|
166
165
|
# same with parent_zip, section_zip, etc...
|
|
167
166
|
|
|
168
167
|
|
|
@@ -808,7 +807,7 @@ class Node < ActiveRecord::Base
|
|
|
808
807
|
transform_attributes(attributes, base_node)
|
|
809
808
|
end
|
|
810
809
|
|
|
811
|
-
def safe_method_type(signature)
|
|
810
|
+
def safe_method_type(signature, receiver = nil)
|
|
812
811
|
if signature.size > 1
|
|
813
812
|
RubyLess::SafeClass.safe_method_type_for(self, signature)
|
|
814
813
|
else
|
|
@@ -818,6 +817,13 @@ class Node < ActiveRecord::Base
|
|
|
818
817
|
elsif method =~ /^(.+)_((id|zip|status|comment)(s?))\Z/ && !instance_methods.include?(method)
|
|
819
818
|
key = $3 == 'id' ? "zip#{$4}" : $2
|
|
820
819
|
{:method => "rel[#{$1.inspect}].try(:other_#{key})", :nil => true, :class => ($4.blank? ? Number : [Number])}
|
|
820
|
+
elsif receiver && query = receiver.opts[:query]
|
|
821
|
+
# Resolve by using information in the SELECT part of the query that found this node
|
|
822
|
+
if query.select_keys.include?(method)
|
|
823
|
+
{:class => String, :method => "attributes[#{method.inspect}]", :nil => true}
|
|
824
|
+
else
|
|
825
|
+
nil
|
|
826
|
+
end
|
|
821
827
|
else
|
|
822
828
|
nil
|
|
823
829
|
end
|
|
@@ -1395,6 +1401,19 @@ class Node < ActiveRecord::Base
|
|
|
1395
1401
|
secure(Node) { Node.find_node_by_pseudo(string, base_node || self) }
|
|
1396
1402
|
end
|
|
1397
1403
|
|
|
1404
|
+
safe_method [:send, String] => {:class => String, :nil => true, :method => 'safe_send'}
|
|
1405
|
+
|
|
1406
|
+
# Safe dynamic method dispatching when the method is not known during compile time. Currently this
|
|
1407
|
+
# only works for methods without arguments.
|
|
1408
|
+
def safe_send(method)
|
|
1409
|
+
# We need to load roles or all properties will be ignored
|
|
1410
|
+
load_roles!
|
|
1411
|
+
|
|
1412
|
+
return nil unless type = safe_method_type([method])
|
|
1413
|
+
res = eval(type[:method])
|
|
1414
|
+
res ? res.to_s : nil
|
|
1415
|
+
end
|
|
1416
|
+
|
|
1398
1417
|
protected
|
|
1399
1418
|
|
|
1400
1419
|
# after node is saved, make sure it's children have the correct section set
|
|
@@ -1721,7 +1740,6 @@ class Node < ActiveRecord::Base
|
|
|
1721
1740
|
end
|
|
1722
1741
|
end
|
|
1723
1742
|
end
|
|
1724
|
-
|
|
1725
1743
|
end
|
|
1726
1744
|
|
|
1727
1745
|
Bricks.apply_patches
|
data/app/models/role.rb
CHANGED
|
@@ -8,6 +8,27 @@ class Role < ActiveRecord::Base
|
|
|
8
8
|
before_validation :set_defaults
|
|
9
9
|
validate :check_can_save
|
|
10
10
|
|
|
11
|
+
include RubyLess
|
|
12
|
+
safe_method :columns => {:class => ['Column'], :method => 'columns.values', :nil => false}
|
|
13
|
+
safe_method :name => String
|
|
14
|
+
|
|
15
|
+
def superclass
|
|
16
|
+
if new_record?
|
|
17
|
+
Node
|
|
18
|
+
else
|
|
19
|
+
Node.get_class_from_kpath(kpath)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def superclass=(klass)
|
|
24
|
+
if k = Node.get_class(klass)
|
|
25
|
+
self.kpath = k.kpath
|
|
26
|
+
else
|
|
27
|
+
errors.add('superclass', 'invalid')
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
|
|
11
32
|
private
|
|
12
33
|
def set_defaults
|
|
13
34
|
self.site_id = visitor.site.id
|
data/app/models/site.rb
CHANGED
|
@@ -19,11 +19,11 @@ The #Site model holds configuration information for a site:
|
|
|
19
19
|
class Site < ActiveRecord::Base
|
|
20
20
|
include RubyLess
|
|
21
21
|
safe_method :host => String, :lang_list => [String]
|
|
22
|
-
safe_context :root => {:class => Node, :method => 'root_node'}
|
|
22
|
+
safe_context :root => {:class => 'Node', :method => 'root_node'}
|
|
23
23
|
|
|
24
24
|
validate :valid_site
|
|
25
25
|
validates_uniqueness_of :host
|
|
26
|
-
attr_accessible :name, :languages, :default_lang, :authentication, :http_auth, :auto_publish, :redit_time
|
|
26
|
+
attr_accessible :name, :languages, :default_lang, :authentication, :http_auth, :auto_publish, :redit_time, :api_group_id
|
|
27
27
|
has_many :groups, :order => "name"
|
|
28
28
|
has_many :nodes
|
|
29
29
|
has_many :users
|
|
@@ -229,6 +229,11 @@ class Site < ActiveRecord::Base
|
|
|
229
229
|
@site_group ||= Group.find(self[:site_group_id])
|
|
230
230
|
end
|
|
231
231
|
|
|
232
|
+
# Return the API group: the one in which API visitors must be to use the API.
|
|
233
|
+
def api_group
|
|
234
|
+
@api_group ||= Group.find_by_id(self[:api_group_id])
|
|
235
|
+
end
|
|
236
|
+
|
|
232
237
|
# Return true if the given user is an administrator for this site.
|
|
233
238
|
def is_admin?(user)
|
|
234
239
|
admin_user_ids.include?(user[:id])
|
data/app/models/template.rb
CHANGED
|
@@ -93,14 +93,14 @@ class Template < TextDocument
|
|
|
93
93
|
self.text = <<END_TXT
|
|
94
94
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
|
95
95
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
96
|
-
<html xmlns=
|
|
96
|
+
<html xmlns='http://www.w3.org/1999/xhtml' do='void' lang='\#{v.lang}' xml:lang='en'>
|
|
97
97
|
<head do='void' name='head'>
|
|
98
98
|
<title do='title_for_layout' do='show' attr='title' name='page_title'>page title</title>
|
|
99
99
|
<!-- link href='favicon.png' rel='shortcut icon' type='image/png' / -->
|
|
100
|
-
<meta http-equiv=
|
|
100
|
+
<meta http-equiv='Content-type' content='text/html; charset=utf-8' />
|
|
101
101
|
<r:void name='stylesheets'>
|
|
102
102
|
<r:stylesheets/>
|
|
103
|
-
<link href=
|
|
103
|
+
<link href='style.css' rel='Stylesheet' type='text/css'/>
|
|
104
104
|
</r:void>
|
|
105
105
|
|
|
106
106
|
<r:javascripts/>
|