zena 1.1.2 → 1.1.3

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/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ == 1.1.3 2011-11-09
2
+
3
+ * Major changes
4
+ * Does not expire compiled templates when working in dev mode by default.
5
+ * Added 'monolingual' option for virtual classes. All TextDocuments are monolingual
6
+ by default.
7
+
1
8
  == 1.1.2 2011-11-09
2
9
 
3
10
  * Minor changes
@@ -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'
@@ -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, node_ids = nil)
72
- if node_ids && node_ids != []
73
- direct_pages = CachedPage.find(:all, :conditions => "node_id IN (#{node_ids.join(',')})")
71
+ def expire_with(node, opts = {})
72
+ if opts
73
+ expire(node.cached_pages.find(:all, opts))
74
74
  else
75
- direct_pages = []
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
- attr_accessible :usr_prototype_attributes
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
@@ -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
@@ -342,6 +342,10 @@ class User < ActiveRecord::Base
342
342
  end
343
343
  end
344
344
 
345
+ def dev_mode?
346
+ !dev_skin_id.blank?
347
+ end
348
+
345
349
  private
346
350
 
347
351
  def user_site
@@ -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
- self[:lang] = visitor.lang unless lang_changed?
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
 
@@ -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
- <%= select 'node', 'v_lang', current_site.lang_list.map {|l| [_(l), l]} %>
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>
@@ -1,5 +1,5 @@
1
1
  # Settings specified here will take precedence over those in config/environment.rb
2
- config.log_level = :info
2
+ config.log_level = :debug
3
3
 
4
4
  # The production environment is meant for finished, "live" apps.
5
5
  # Code is not reloaded between requests
data/lib/zena/info.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Zena
2
- VERSION = '1.1.2'
2
+ VERSION = '1.1.3'
3
3
  ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
4
4
  end
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,
@@ -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[visitor.lang] || access[self[:ref_lang]] || access.values.first
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
@@ -336,7 +336,7 @@ module Zena
336
336
 
337
337
  # Return true if the current rendering should include a dev box.
338
338
  def dev_mode?
339
- !visitor.dev_skin_id.blank?
339
+ visitor.dev_mode?
340
340
  end
341
341
 
342
342
  # Return true if we should display the dev box
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 "<img src='/images/lock.png' title='Klasse'/>"
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
@@ -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
@@ -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
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{zena}
8
- s.version = "1.1.2"
8
+ s.version = "1.1.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Gaspard Bucher"]
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zena
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 1
9
- - 2
10
- version: 1.1.2
9
+ - 3
10
+ version: 1.1.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Gaspard Bucher