zena 1.1.2 → 1.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -0
- data/app/controllers/nodes_controller.rb +3 -8
- data/app/models/cached_page.rb +4 -5
- data/app/models/node.rb +2 -7
- data/app/models/site.rb +3 -1
- data/app/models/text_document.rb +10 -0
- data/app/models/user.rb +4 -0
- data/app/models/version.rb +7 -1
- data/app/models/virtual_class.rb +7 -1
- data/app/views/templates/edit_tabs/_title.rhtml +10 -1
- data/app/views/virtual_classes/_form.erb +1 -0
- data/config/environments/production.rb +1 -1
- data/lib/zena/info.rb +1 -1
- data/lib/zena/use/i18n.rb +0 -3
- data/lib/zena/use/rendering.rb +4 -1
- data/lib/zena/use/version_hash.rb +5 -4
- data/lib/zena/use/zafu_templates.rb +1 -1
- data/locale/de/LC_MESSAGES/zena.mo +0 -0
- data/locale/de/zena.po +1 -1
- data/test/unit/cached_page_test.rb +40 -0
- data/test/unit/site_test.rb +5 -1
- data/test/unit/virtual_class_test.rb +6 -0
- data/test/unit/workflow_test.rb +19 -4
- data/zena.gemspec +1 -1
- metadata +3 -3
data/History.txt
CHANGED
@@ -23,7 +23,6 @@ class NodesController < ApplicationController
|
|
23
23
|
before_filter :find_node, :except => [:index, :create, :not_found, :catch_all, :search]
|
24
24
|
before_filter :check_can_drive, :only => [:edit]
|
25
25
|
before_filter :check_path, :only => [:index, :show]
|
26
|
-
after_filter :change_lang, :only => [:create, :update, :save_text]
|
27
26
|
layout :popup_layout, :only => [:edit, :import]
|
28
27
|
|
29
28
|
include Zena::Use::Grid::ControllerMethods
|
@@ -356,7 +355,9 @@ class NodesController < ApplicationController
|
|
356
355
|
params['node'] ||= {}
|
357
356
|
file, file_error = get_attachment
|
358
357
|
params['node']['file'] = file if file
|
359
|
-
|
358
|
+
# Make sure we load the correct version for edited v_lang
|
359
|
+
lang = params['node']['v_lang'] || visitor.lang
|
360
|
+
@node.version(lang)
|
360
361
|
@v_status_before_update = @node.v_status
|
361
362
|
@node.update_attributes_with_transformation(params['node'])
|
362
363
|
# What is this 'extfile' thing ?
|
@@ -576,8 +577,6 @@ class NodesController < ApplicationController
|
|
576
577
|
if params[:link_id]
|
577
578
|
@link = Link.find_through(@node, params[:link_id])
|
578
579
|
end
|
579
|
-
|
580
|
-
@title_for_layout = title_for_layout
|
581
580
|
end
|
582
581
|
|
583
582
|
def set_format(format)
|
@@ -659,10 +658,6 @@ class NodesController < ApplicationController
|
|
659
658
|
end
|
660
659
|
end
|
661
660
|
|
662
|
-
def change_lang
|
663
|
-
set_visitor_lang(params[:node]['v_lang']) if params[:node] && params[:node]['v_lang']
|
664
|
-
end
|
665
|
-
|
666
661
|
def do_search
|
667
662
|
if @node
|
668
663
|
default_scope = 'self'
|
data/app/models/cached_page.rb
CHANGED
@@ -68,13 +68,12 @@ class CachedPage < ActiveRecord::Base
|
|
68
68
|
end
|
69
69
|
|
70
70
|
# Remove cached pages related to the given node.
|
71
|
-
def expire_with(node,
|
72
|
-
if
|
73
|
-
|
71
|
+
def expire_with(node, opts = {})
|
72
|
+
if opts
|
73
|
+
expire(node.cached_pages.find(:all, opts))
|
74
74
|
else
|
75
|
-
|
75
|
+
expire(node.cached_pages)
|
76
76
|
end
|
77
|
-
expire(node.cached_pages + [])
|
78
77
|
end
|
79
78
|
|
80
79
|
private
|
data/app/models/node.rb
CHANGED
@@ -1327,11 +1327,8 @@ class Node < ActiveRecord::Base
|
|
1327
1327
|
end
|
1328
1328
|
|
1329
1329
|
# TODO: test
|
1330
|
-
def sweep_cache
|
1330
|
+
def sweep_cache(opts = {})
|
1331
1331
|
return if current_site.being_created?
|
1332
|
-
# zafu 'erb' rendering cache expire
|
1333
|
-
# TODO: expire only 'dev' rendering if version is a redaction
|
1334
|
-
CachedPage.expire_with(self) if self.kind_of?(Template)
|
1335
1332
|
|
1336
1333
|
# Clear element cache
|
1337
1334
|
Cache.sweep(:visitor_id=>self[:user_id], :visitor_groups=>[rgroup_id, wgroup_id, dgroup_id], :kpath=>self.vclass.kpath)
|
@@ -1343,9 +1340,7 @@ class Node < ActiveRecord::Base
|
|
1343
1340
|
# FIXME: use self + modified relations instead of parent/project
|
1344
1341
|
[self, self.real_project(false), self.real_section(false), self.parent(false)].compact.uniq.each do |obj|
|
1345
1342
|
# destroy all pages in project, parent and section !
|
1346
|
-
CachedPage.expire_with(obj)
|
1347
|
-
# this destroys less cache but might miss things like 'changes in project' that are displayed on every page.
|
1348
|
-
# CachedPage.expire_with(self, [self[:project_id], self[:section_id], self[:parent_id]].compact.uniq)
|
1343
|
+
CachedPage.expire_with(obj, opts)
|
1349
1344
|
end
|
1350
1345
|
|
1351
1346
|
# clear assets
|
data/app/models/site.rb
CHANGED
@@ -187,9 +187,11 @@ class Site < ActiveRecord::Base
|
|
187
187
|
end
|
188
188
|
|
189
189
|
property.string 'usr_prototype_attributes'
|
190
|
+
property.boolean 'expire_in_dev'
|
190
191
|
|
191
192
|
Site.attributes_for_form[:text] << 'usr_prototype_attributes'
|
192
|
-
|
193
|
+
Site.attributes_for_form[:bool] << 'expire_in_dev'
|
194
|
+
attr_accessible :usr_prototype_attributes, :expire_in_dev
|
193
195
|
|
194
196
|
# Return path for static/cached content served by proxy: RAILS_ROOT/sites/_host_/public
|
195
197
|
# If you need to serve from another directory, we do not store the path into the sites table
|
data/app/models/text_document.rb
CHANGED
@@ -163,6 +163,16 @@ class TextDocument < Document
|
|
163
163
|
(super + (content_type == 'text/css' ? ['text'] : [])).uniq
|
164
164
|
end
|
165
165
|
|
166
|
+
# Do not sweep TextDocument cache in dev mode unless expire_in_dev.
|
167
|
+
def sweep_cache
|
168
|
+
if visitor.dev_mode? && !current_site.expire_in_dev?
|
169
|
+
# Only expire templates built for dev mode
|
170
|
+
super(:conditions => ['path like ?', "%/dev_#{visitor.lang}/%"])
|
171
|
+
else
|
172
|
+
super
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
166
176
|
private
|
167
177
|
class AssetHelper
|
168
178
|
attr_accessor :visitor
|
data/app/models/user.rb
CHANGED
data/app/models/version.rb
CHANGED
@@ -70,7 +70,13 @@ class Version < ActiveRecord::Base
|
|
70
70
|
def set_defaults
|
71
71
|
# set author
|
72
72
|
self[:user_id] = visitor.id
|
73
|
-
|
73
|
+
if lang.blank? || !lang_changed?
|
74
|
+
if node && node.vclass.monolingual?
|
75
|
+
self[:lang] = current_site.default_lang
|
76
|
+
else
|
77
|
+
self[:lang] = visitor.lang
|
78
|
+
end
|
79
|
+
end
|
74
80
|
self[:site_id] = current_site.id
|
75
81
|
end
|
76
82
|
|
data/app/models/virtual_class.rb
CHANGED
@@ -34,7 +34,7 @@ class VirtualClass < Role
|
|
34
34
|
attr_accessor :export_attributes
|
35
35
|
end
|
36
36
|
|
37
|
-
self.export_attributes = %w{auto_create_discussion icon}
|
37
|
+
self.export_attributes = %w{auto_create_discussion icon monolingual}
|
38
38
|
|
39
39
|
attr_accessor :import_result
|
40
40
|
belongs_to :create_group, :class_name => 'Group', :foreign_key => 'create_group_id'
|
@@ -51,12 +51,15 @@ class VirtualClass < Role
|
|
51
51
|
include Zena::Use::PropEval::VirtualClassMethods
|
52
52
|
include Zena::Use::ScopeIndex::VirtualClassMethods
|
53
53
|
|
54
|
+
property.boolean 'monolingual'
|
55
|
+
safe_method :monolingual? => Boolean
|
54
56
|
safe_method :roles => {:class => ['Role'], :method => 'sorted_roles'}
|
55
57
|
safe_method :relations => {:class => ['RelationProxy'], :method => 'all_relations'}
|
56
58
|
safe_method [:relations, String] => {:class => ['RelationProxy'], :method => 'filtered_relations'}
|
57
59
|
# All columns defined for a VirtualClass (kpath based).
|
58
60
|
safe_method :all_columns => {:class => ['Column'], :method => 'safe_columns'}
|
59
61
|
|
62
|
+
|
60
63
|
class Cache
|
61
64
|
def initialize
|
62
65
|
clear_cache!
|
@@ -165,6 +168,9 @@ class VirtualClass < Role
|
|
165
168
|
vclass.include_role real_class.schema
|
166
169
|
vclass.instance_variable_set(:@is_real_class, true)
|
167
170
|
vclass.site_id = current_site.id
|
171
|
+
if real_class <= TextDocument
|
172
|
+
vclass.monolingual = true
|
173
|
+
end
|
168
174
|
vclass
|
169
175
|
end
|
170
176
|
|
@@ -5,7 +5,16 @@
|
|
5
5
|
<%= text_field 'node', 'tag_list', :size=>nil, :class => 'full_width' %>
|
6
6
|
|
7
7
|
<label for='v_lang'><%= _("language") %></label>
|
8
|
-
|
8
|
+
<% if @node.vclass.monolingual?
|
9
|
+
if @node.new_record?
|
10
|
+
selected = current_site.default_lang
|
11
|
+
else
|
12
|
+
selected = @node.v_lang == visitor.lang ? @node.v_lang : current_site.default_lang
|
13
|
+
end
|
14
|
+
else
|
15
|
+
selected = visitor.lang
|
16
|
+
end -%>
|
17
|
+
<%= select 'node', 'v_lang', current_site.lang_list.map {|l| [_(l), l]}, :selected => selected %>
|
9
18
|
|
10
19
|
<label><%= _('publication date') %></label>
|
11
20
|
<%= date_box(@node, 'v_publish_from') %>
|
@@ -41,6 +41,7 @@
|
|
41
41
|
|
42
42
|
<tr><td class='label'><%= _('create group')%></td><td><%= select('virtual_class', 'create_group_id', visitor.all_groups.map{|g| [g.name, g.id]} ) %></td></tr>
|
43
43
|
<tr><td class='label'><%= _('auto create discussion')%></td><td><%= check_box('virtual_class', 'auto_create_discussion') %></td></tr>
|
44
|
+
<tr><td class='label'><%= _('monolingual')%></td><td><%= check_box('virtual_class', 'monolingual') %></td></tr>
|
44
45
|
<% end -%>
|
45
46
|
<tr><td class='label'><%= _('icon')%> </td><td><%= text_field('virtual_class', 'icon', :size=>15 ) %></td></tr>
|
46
47
|
<tr><td colspan='2'><p class='btn_validate'><input type='submit' value='<%= _('validate') %>'/></p></td></tr>
|
data/lib/zena/info.rb
CHANGED
data/lib/zena/use/i18n.rb
CHANGED
@@ -136,9 +136,6 @@ module Zena
|
|
136
136
|
chosen_lang = nil
|
137
137
|
[
|
138
138
|
params[:lang],
|
139
|
-
# FIXME: This is good to protect templates and other documents but is *NOT* nice when translating a website !!
|
140
|
-
# What should we do ?
|
141
|
-
params[:node] ? params[:node][:v_lang] : nil,
|
142
139
|
# Avoid redirects for static assets (cached documents).
|
143
140
|
request.format == Mime::HTML ? params[:prefix] : nil,
|
144
141
|
visitor.is_anon? ? session[:lang] : visitor.lang,
|
data/lib/zena/use/rendering.rb
CHANGED
@@ -115,6 +115,9 @@ module Zena
|
|
115
115
|
end
|
116
116
|
|
117
117
|
def render_and_cache(options={})
|
118
|
+
# FIXME: maybe we can remove this.
|
119
|
+
@title_for_layout = title_for_layout
|
120
|
+
|
118
121
|
opts = {:skin => @node[:skin], :cache => true}.merge(options)
|
119
122
|
opts[:mode ] ||= params[:mode]
|
120
123
|
opts[:format] ||= params[:format].blank? ? 'html' : params[:format]
|
@@ -299,7 +302,7 @@ module Zena
|
|
299
302
|
out "<% set_headers(#{headers.join(', ')}) %>"
|
300
303
|
end
|
301
304
|
end
|
302
|
-
|
305
|
+
|
303
306
|
def r_style
|
304
307
|
@markup.tag = 'style'
|
305
308
|
expand_with
|
@@ -47,9 +47,9 @@ module Zena
|
|
47
47
|
end
|
48
48
|
|
49
49
|
module ModelMethods
|
50
|
-
def version
|
50
|
+
def version(lang = nil)
|
51
51
|
@version ||= begin
|
52
|
-
if v_id = version_id
|
52
|
+
if v_id = version_id(lang)
|
53
53
|
version = ::Version.find(v_id)
|
54
54
|
else
|
55
55
|
version = ::Version.new
|
@@ -59,9 +59,10 @@ module Zena
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
def version_id
|
62
|
+
def version_id(lang = nil)
|
63
|
+
lang ||= visitor.lang
|
63
64
|
access = can_see_redactions? ? vhash['w'] : vhash['r']
|
64
|
-
access[
|
65
|
+
access[lang] || access[self[:ref_lang]] || access.values.first
|
65
66
|
end
|
66
67
|
|
67
68
|
# Return the list of versions that are stored in the vhash and could be loaded depending
|
Binary file
|
data/locale/de/zena.po
CHANGED
@@ -711,7 +711,7 @@ msgstr "persönliche Informationen ändern"
|
|
711
711
|
|
712
712
|
#: app/views/relations/_form.erb:17 app/views/nodes/_parent.rhtml:7
|
713
713
|
msgid "class"
|
714
|
-
msgstr "
|
714
|
+
msgstr "Klasse"
|
715
715
|
|
716
716
|
#: app/views/templates/document_create_tabs/_import.rhtml:7
|
717
717
|
msgid "class of first element"
|
@@ -162,4 +162,44 @@ class CachedPageTest < Zena::Unit::TestCase
|
|
162
162
|
end
|
163
163
|
end
|
164
164
|
end
|
165
|
+
|
166
|
+
def test_no_expire_in_dev
|
167
|
+
without_files('test.host/zafu') do
|
168
|
+
preserving_files('/test.host/data') do
|
169
|
+
login(:lion)
|
170
|
+
visitor.dev_skin_id = nodes_id(:default)
|
171
|
+
assert visitor.dev_mode?
|
172
|
+
template_ids = [nodes_id(:Node_index_zafu), nodes_id(:Project_zafu), nodes_id(:Node_zafu), nodes_id(:notes_zafu)]
|
173
|
+
path = SITES_ROOT + visitor.site.zafu_path + "/default/Node_index.html/en/main.erb"
|
174
|
+
dev_path = SITES_ROOT + visitor.site.zafu_path + "/default/Node_index.html/dev_en/main.erb"
|
175
|
+
|
176
|
+
assert !File.exists?(path), "No cached file yet"
|
177
|
+
cache = secure!(CachedPage) { CachedPage.create(
|
178
|
+
:path => (visitor.site.zafu_path + "/default/Node_index.html/en/main.erb"),
|
179
|
+
:expire_after => nil,
|
180
|
+
:expire_with_ids => template_ids,
|
181
|
+
:content_data => "public cache") }
|
182
|
+
|
183
|
+
cache = secure!(CachedPage) { CachedPage.create(
|
184
|
+
:path => (visitor.site.zafu_path + "/default/Node_index.html/dev_en/main.erb"),
|
185
|
+
:expire_after => nil,
|
186
|
+
:expire_with_ids => template_ids,
|
187
|
+
:content_data => "dev cache") }
|
188
|
+
assert File.exists?(path), "Cache file created"
|
189
|
+
assert File.exists?(dev_path), "Cache file created"
|
190
|
+
|
191
|
+
# test expire
|
192
|
+
node = secure!(Node) { nodes(:Node_zafu) }
|
193
|
+
assert node.update_attributes(:title=>'hey'), "Can save"
|
194
|
+
assert File.exists?(path), "Public cache not removed"
|
195
|
+
assert !File.exists?(dev_path), "Dev cache removed"
|
196
|
+
|
197
|
+
# expire all
|
198
|
+
assert current_site.update_attributes(:expire_in_dev => true)
|
199
|
+
node = secure!(Node) { nodes(:Node_zafu) }
|
200
|
+
assert node.update_attributes(:title=>'hey boy'), "Can save"
|
201
|
+
assert !File.exists?(path), "Public cache removed"
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
165
205
|
end
|
data/test/unit/site_test.rb
CHANGED
@@ -172,6 +172,10 @@ class SiteTest < Zena::Unit::TestCase
|
|
172
172
|
assert_kind_of User, subject.any_admin
|
173
173
|
assert_equal users(:lion), subject.any_admin
|
174
174
|
end
|
175
|
+
|
176
|
+
should 'respond to expire_in_dev' do
|
177
|
+
assert !subject.expire_in_dev?
|
178
|
+
end
|
175
179
|
end # A site
|
176
180
|
|
177
181
|
|
@@ -350,7 +354,7 @@ class SiteTest < Zena::Unit::TestCase
|
|
350
354
|
end
|
351
355
|
end
|
352
356
|
|
353
|
-
|
357
|
+
|
354
358
|
private
|
355
359
|
def fullpath(*args)
|
356
360
|
args.map {|sym| nodes_zip(sym).to_s}.join('/')
|
@@ -647,6 +647,12 @@ class VirtualClassTest < Zena::Unit::TestCase
|
|
647
647
|
should 'return real_class name on get_real_class' do
|
648
648
|
assert_equal 'Page', subject.send(:get_real_class, subject)
|
649
649
|
end
|
650
|
+
|
651
|
+
should 'respond to monolingual' do
|
652
|
+
assert_nothing_raised do
|
653
|
+
assert_nil subject.monolingual
|
654
|
+
end
|
655
|
+
end
|
650
656
|
|
651
657
|
context 'that is a Node' do
|
652
658
|
subject do
|
data/test/unit/workflow_test.rb
CHANGED
@@ -398,6 +398,21 @@ class WorkflowTest < Zena::Unit::TestCase
|
|
398
398
|
assert_equal 'de', subject.version.lang
|
399
399
|
end
|
400
400
|
|
401
|
+
context 'with a text document' do
|
402
|
+
subject do
|
403
|
+
secure(Node) { nodes(:Node_zafu) }
|
404
|
+
end
|
405
|
+
|
406
|
+
should 'create versions in the default language' do
|
407
|
+
visitor.lang = 'de'
|
408
|
+
assert subject.vclass.monolingual?
|
409
|
+
assert_difference('Version.count', 1) do
|
410
|
+
subject.update_attributes('text' => 'Die Antwoord')
|
411
|
+
assert_equal 'en', subject.version.lang
|
412
|
+
end
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
401
416
|
should 'not be allowed to propose' do
|
402
417
|
assert !subject.can_propose?
|
403
418
|
assert !subject.propose # does nothing
|
@@ -623,25 +638,25 @@ class WorkflowTest < Zena::Unit::TestCase
|
|
623
638
|
end
|
624
639
|
end # setting v_status to autopublish
|
625
640
|
end # that she owns
|
626
|
-
|
641
|
+
|
627
642
|
# Basic tests for property integration in Node.
|
628
643
|
context 'changing attributes' do
|
629
644
|
should 'mark version as edited' do
|
630
645
|
subject.attributes = {'title' => 'foo'}
|
631
646
|
assert subject.version.edited?
|
632
647
|
end
|
633
|
-
|
648
|
+
|
634
649
|
should 'mark properties as changed' do
|
635
650
|
subject.attributes = {'title' => 'foo'}
|
636
651
|
assert subject.prop.changed?
|
637
652
|
end
|
638
|
-
|
653
|
+
|
639
654
|
should 'show property changes on chages' do
|
640
655
|
subject.attributes = {'title' => 'foo'}
|
641
656
|
assert_equal Hash['title'=> ['status title', 'foo']], subject.changes
|
642
657
|
end
|
643
658
|
end # changing attributes
|
644
|
-
|
659
|
+
|
645
660
|
end # A visitor with drive access on a publication
|
646
661
|
|
647
662
|
|
data/zena.gemspec
CHANGED
metadata
CHANGED