zena 1.0.0.rc2 → 1.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +23 -0
- data/README.rdoc +1 -1
- data/app/controllers/columns_controller.rb +3 -31
- data/app/controllers/comments_controller.rb +8 -3
- data/app/controllers/data_entries_controller.rb +1 -1
- data/app/controllers/documents_controller.rb +2 -2
- data/app/controllers/nodes_controller.rb +29 -12
- data/app/controllers/relations_controller.rb +2 -2
- data/app/controllers/sites_controller.rb +1 -1
- data/app/controllers/user_sessions_controller.rb +6 -3
- data/app/controllers/users_controller.rb +18 -16
- data/app/controllers/versions_controller.rb +20 -18
- data/app/controllers/virtual_classes_controller.rb +103 -17
- data/app/helpers/users_helper.rb +1 -1
- data/app/models/column.rb +19 -50
- data/app/models/comment.rb +2 -1
- data/app/models/node.rb +45 -22
- data/app/models/relation.rb +13 -0
- data/app/models/relation_proxy.rb +3 -2
- data/app/models/role.rb +213 -4
- data/app/models/site.rb +18 -11
- data/app/models/template.rb +37 -35
- data/app/models/version.rb +1 -1
- data/app/models/virtual_class.rb +154 -86
- data/app/views/columns/_li.html.erb +1 -1
- data/app/views/columns/index.html.erb +1 -9
- data/app/views/comments/index.rhtml +10 -8
- data/app/views/documents/_crop.rhtml +5 -6
- data/app/views/documents/crop_form.rjs +3 -2
- data/app/views/groups/index.rhtml +1 -1
- data/app/views/iformats/index.rhtml +1 -1
- data/app/views/nodes/_import_results.rhtml +1 -1
- data/app/views/nodes/_parent.rhtml +1 -2
- data/app/views/nodes/update.rjs +3 -4
- data/app/views/relations/index.erb +1 -1
- data/app/views/sites/index.erb +1 -1
- data/app/views/templates/drive_tabs/_drive.rhtml +0 -2
- data/app/views/templates/edit_tabs/_image.rhtml +1 -1
- data/app/views/templates/edit_tabs/_title.rhtml +0 -6
- data/app/views/users/index.rhtml +1 -1
- data/app/views/users/preferences.html.erb +2 -2
- data/app/views/versions/backup.rjs +1 -1
- data/app/views/versions/custom_tab.rhtml +9 -4
- data/app/views/versions/destroy.rjs +2 -2
- data/app/views/versions/update.rjs +2 -9
- data/app/views/virtual_classes/_form.erb +3 -2
- data/app/views/virtual_classes/import_prepare.html.erb +13 -0
- data/app/views/virtual_classes/index.erb +28 -8
- data/app/views/zafu/default/Node-+adminLayout.zafu +1 -13
- data/app/views/zafu/default/Node-+login.zafu +1 -0
- data/app/views/zafu/default/Node-+notFound.zafu +1 -1
- data/app/views/zafu/default/Node-+popupLayout.zafu +1 -2
- data/app/views/zafu/default/Node-+search.zafu +1 -1
- data/app/views/zafu/default/Node-admin.zafu +205 -0
- data/app/views/zafu/default/Node.zafu +11 -11
- data/bricks/captcha/lib/bricks/captcha.rb +3 -2
- data/bricks/mongrel/zena/init.rb +2 -1
- data/bricks/pdf/README +5 -5
- data/bricks/pdf/lib/bricks/pdf/engine/prince.rb +2 -2
- data/bricks/pdf/lib/bricks/pdf/engine/xhtml2pdf.rb +2 -2
- data/bricks/pdf/lib/bricks/pdf/install.rb +5 -5
- data/bricks/pdf/lib/bricks/pdf.rb +11 -11
- data/bricks/pdf/test/engines/test_prince.rb +4 -4
- data/bricks/pdf/test/engines/test_xhtml2pdf.rb +4 -4
- data/bricks/pdf/test/shoulda_macros/shoulda_pdf.rb +2 -2
- data/bricks/pdf/zena/init.rb +2 -2
- data/bricks/pdf/zena/tasks.rb +2 -2
- data/bricks/sphinx/lib/bricks/sphinx.rb +6 -2
- data/bricks/sphinx/zena/{sphinx.yml → sphinx.yml.erb} +2 -2
- data/bricks/sphinx/zena/tasks.rb +28 -2
- data/bricks/tags/lib/bricks/tags.rb +16 -1
- data/bricks/tags/zena/test/unit/tags_test.rb +15 -0
- data/bricks/tags/zena/test/zafu/tags.yml +5 -1
- data/bricks/worker/lib/bricks/worker.rb +39 -0
- data/bricks/worker/zena/deploy.rb +0 -2
- data/bricks/worker/zena/init.rb +1 -0
- data/bricks/worker/zena/test/sites/zena/delayed_jobs.yml +16 -0
- data/bricks/worker/zena/test/zafu/worker.yml +8 -0
- data/bricks/zena/zena/migrate/01_base.rb +36 -60
- data/bricks/zena/zena/migrate/02_zerox1_schema.rb +388 -0
- data/bricks/zena/zena/migrate/03_zerox1_data.rb +380 -0
- data/bricks/zena/zena/migrate/20110315161158_add_reverse_scope_to_roles.rb +9 -0
- data/config/database_example.yml +1 -1
- data/config/environment.rb +1 -1
- data/config/gems.yml +17 -14
- data/db/init/base/skins/default/Node-+index.zafu +8 -1
- data/db/init/base/skins/default/Node-+login.zafu +1 -0
- data/db/init/base/skins/default/Node-+popupLayout.zafu +1 -2
- data/db/init/base/skins/default/Node-+search.zafu +2 -2
- data/db/init/base/skins/default/Node.zafu +9 -9
- data/db/init/base/skins/default/{favicon.png → img/favicon.png} +0 -0
- data/db/init/base/skins/default/{style.css → img/style.css} +0 -0
- data/db/init/base/skins/default/img/translations.yml +11 -0
- data/db/init/base/skins/default/notes.zafu +7 -9
- data/doc/zafu_changes.yml +12 -0
- data/lib/bricks/loader.rb +38 -15
- data/lib/tasks/zena.rake +74 -24
- data/lib/zena/acts/enrollable.rb +4 -1
- data/lib/zena/acts/secure.rb +2 -48
- data/lib/zena/acts/serializable.rb +13 -1
- data/lib/zena/app.rb +9 -0
- data/lib/zena/code_syntax.rb +154 -151
- data/lib/zena/console.rb +141 -0
- data/lib/zena/controller/test_case.rb +1 -1
- data/lib/zena/db_helper/abstract_db.rb +17 -5
- data/lib/zena/db_helper/mysql.rb +14 -12
- data/lib/zena/db_helper/postgresql.rb +1 -2
- data/lib/zena/db_helper/sqlite3.rb +6 -6
- data/lib/zena/deploy/awstats.conf.rhtml +1 -1
- data/lib/zena/deploy/httpd.rhtml +6 -1
- data/lib/zena/deploy/vhost.rhtml +9 -1
- data/lib/zena/deploy.rb +12 -7
- data/lib/zena/foxy_parser.rb +3 -1
- data/lib/zena/info.rb +1 -1
- data/lib/zena/parser/zafu_tags.rb +1 -0
- data/lib/zena/parser/zazen_rules.rb +1 -1
- data/lib/zena/remote/node.rb +15 -3
- data/lib/zena/remote/serializable_array.rb +19 -0
- data/lib/zena/remote.rb +1 -0
- data/lib/zena/routes.rb +7 -2
- data/lib/zena/site_worker.rb +11 -1
- data/lib/zena/unit/test_case.rb +68 -0
- data/lib/zena/use/action.rb +6 -2
- data/lib/zena/use/ajax.rb +127 -53
- data/lib/zena/use/ancestry.rb +11 -8
- data/lib/zena/use/calendar.rb +265 -129
- data/lib/zena/use/conditional.rb +1 -1
- data/lib/zena/use/context.rb +5 -5
- data/lib/zena/use/dates.rb +172 -60
- data/lib/zena/use/display.rb +70 -39
- data/lib/zena/use/error_rendering.rb +1 -3
- data/lib/zena/use/field_index.rb +4 -1
- data/lib/zena/use/forms.rb +94 -72
- data/lib/zena/use/fulltext.rb +16 -24
- data/lib/zena/use/html_tags.rb +20 -12
- data/lib/zena/use/i18n.rb +37 -37
- data/lib/zena/use/image_builder.rb +8 -1
- data/lib/zena/use/ml_index.rb +16 -16
- data/lib/zena/use/prop_eval.rb +10 -5
- data/lib/zena/use/query_builder.rb +55 -23
- data/lib/zena/use/query_node.rb +51 -25
- data/lib/zena/use/refactor.rb +2 -28
- data/lib/zena/use/relations.rb +1 -1
- data/lib/zena/use/rendering.rb +29 -0
- data/lib/zena/use/scope_index.rb +75 -14
- data/lib/zena/use/search.rb +5 -10
- data/lib/zena/use/test_helper.rb +2 -2
- data/lib/zena/use/urls.rb +125 -104
- data/lib/zena/use/workflow.rb +2 -1
- data/lib/zena/use/zafu_attributes.rb +2 -2
- data/lib/zena/use/zafu_safe_definitions.rb +20 -0
- data/lib/zena/use/zafu_templates.rb +20 -6
- data/lib/zena/use/zazen.rb +31 -20
- data/lib/zena/view/test_case.rb +5 -0
- data/lib/zena/zafu_compiler.rb +24 -2
- data/lib/zena.rb +12 -6
- data/locale/de/LC_MESSAGES/zena.mo +0 -0
- data/locale/de/zena.po +1345 -1164
- data/locale/en/LC_MESSAGES/zena.mo +0 -0
- data/locale/en/zena.po +1275 -1129
- data/locale/fr/LC_MESSAGES/zena.mo +0 -0
- data/locale/fr/zena.mo +0 -0
- data/locale/fr/zena.po +1617 -1441
- data/locale/log.txt +9 -0
- data/locale/zena.pot +957 -748
- data/public/javascripts/prototype.js +1 -1
- data/public/javascripts/zena.js +99 -44
- data/public/stylesheets/admin.css +6 -4
- data/public/stylesheets/backend.css +71 -0
- data/public/stylesheets/calendar.css +24 -25
- data/public/stylesheets/code.css +11 -6
- data/public/stylesheets/comment.css +2 -1
- data/public/stylesheets/popup.css +7 -8
- data/test/custom_queries/complex.host.yml +15 -1
- data/test/fixtures/files/Node-test.zafu +29 -28
- data/test/fixtures/files/translations_de.yml +12 -1
- data/test/fixtures/files/translations_fr.yml +12 -1
- data/test/functional/comments_controller_test.rb +9 -0
- data/test/functional/iformats_controller_test.rb +1 -1
- data/test/functional/nodes_controller_test.rb +124 -35
- data/test/functional/users_controller_test.rb +132 -3
- data/test/functional/virtual_classes_controller_test.rb +75 -4
- data/test/integration/navigation_test.rb +51 -9
- data/test/integration/query_node/basic.yml +19 -7
- data/test/integration/query_node/complex.yml +1 -1
- data/test/integration/query_node/dates.yml +27 -1
- data/test/integration/query_node/filters.yml +1 -1
- data/test/integration/query_node/relations.yml +13 -4
- data/test/integration/query_node_test.rb +4 -0
- data/test/integration/xml_api_test.rb +6 -1
- data/test/integration/zafu_compiler/action.yml +3 -3
- data/test/integration/zafu_compiler/ajax.yml +103 -22
- data/test/integration/zafu_compiler/basic.yml +0 -52
- data/test/integration/zafu_compiler/calendar.yml +44 -20
- data/test/integration/zafu_compiler/comments.yml +53 -0
- data/test/integration/zafu_compiler/complex.yml +11 -11
- data/test/integration/zafu_compiler/complex_ok.yml +16 -3
- data/test/integration/zafu_compiler/conditional.yml +15 -5
- data/test/integration/zafu_compiler/context.yml +9 -0
- data/test/integration/zafu_compiler/dates.yml +43 -15
- data/test/integration/zafu_compiler/display.yml +60 -6
- data/test/integration/zafu_compiler/errors.yml +6 -2
- data/test/integration/zafu_compiler/forms.yml +45 -6
- data/test/integration/zafu_compiler/i18n.yml +8 -1
- data/test/integration/zafu_compiler/meta.yml +38 -0
- data/test/integration/zafu_compiler/query.yml +43 -4
- data/test/integration/zafu_compiler/relations.yml +26 -33
- data/test/integration/zafu_compiler/rubyless.yml +10 -0
- data/test/integration/zafu_compiler/safe_definitions.yml +21 -1
- data/test/integration/zafu_compiler/urls.yml +75 -5
- data/test/integration/zafu_compiler/version.yml +2 -2
- data/test/integration/zafu_compiler/zafu_attributes.yml +5 -1
- data/test/integration/zafu_compiler/zazen.yml +14 -6
- data/test/integration/zafu_compiler_test.rb +5 -1
- data/test/sites/complex/columns.yml +5 -0
- data/test/sites/complex/roles.yml +4 -0
- data/test/sites/zena/nodes.yml +13 -2
- data/test/sites/zena/roles.yml +13 -5
- data/test/sites/zena/versions.yml +27 -9
- data/test/unit/column_test.rb +51 -5
- data/test/unit/iformat_test.rb +2 -2
- data/test/unit/node_test.rb +29 -17
- data/test/unit/note_test.rb +1 -1
- data/test/unit/relation_proxy_test.rb +4 -5
- data/test/unit/relation_test.rb +16 -0
- data/test/unit/remote_test.rb +2 -2
- data/test/unit/role_test.rb +292 -4
- data/test/unit/site_test.rb +12 -0
- data/test/unit/template_test.rb +1 -1
- data/test/unit/text_document_test.rb +1 -1
- data/test/unit/virtual_class_test.rb +200 -83
- data/test/unit/zena/acts/enrollable_test.rb +26 -31
- data/test/unit/zena/use/calendar_test.rb +90 -37
- data/test/unit/zena/use/field_index_test.rb +28 -0
- data/test/unit/zena/use/html_tags_test.rb +7 -3
- data/test/unit/zena/use/ml_index_test.rb +2 -16
- data/test/unit/zena/use/nested_attributes_alias_view_test.rb +2 -2
- data/test/unit/zena/use/prop_eval_test.rb +50 -8
- data/test/unit/zena/use/query_node_test.rb +11 -0
- data/test/unit/zena/use/rendering_test.rb +72 -0
- data/test/unit/zena/use/scope_index_test.rb +37 -2
- data/test/unit/zena/use/urls_test.rb +10 -0
- data/test/unit/zena/use/zazen_test.rb +3 -3
- data/vendor/plugins/gettext_i18n_rails/Gemfile +11 -0
- data/vendor/plugins/gettext_i18n_rails/Gemfile.lock +92 -0
- data/vendor/plugins/gettext_i18n_rails/Rakefile +12 -17
- data/vendor/plugins/gettext_i18n_rails/Readme.md +215 -0
- data/vendor/plugins/gettext_i18n_rails/VERSION +1 -1
- data/vendor/plugins/gettext_i18n_rails/gettext_i18n_rails.gemspec +38 -34
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/active_record.rb +1 -1
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/backend.rb +30 -14
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/haml_parser.rb +1 -1
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/html_safe_translations.rb +29 -0
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/i18n_hacks.rb +29 -1
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/model_attributes_finder.rb +7 -1
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/railtie.rb +10 -0
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/ruby_gettext_extractor.rb +6 -2
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/string_interpolate_fix.rb +20 -0
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails/tasks.rb +120 -0
- data/vendor/plugins/gettext_i18n_rails/lib/gettext_i18n_rails.rb +10 -3
- data/vendor/plugins/gettext_i18n_rails/lib/tasks/gettext_rails_i18n.rake +1 -74
- data/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/active_record_spec.rb +51 -20
- data/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/backend_spec.rb +12 -7
- data/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails/string_interpolate_fix_spec.rb +32 -0
- data/vendor/plugins/gettext_i18n_rails/spec/gettext_i18n_rails_spec.rb +38 -1
- data/vendor/plugins/gettext_i18n_rails/spec/rails2/Gemfile +11 -0
- data/vendor/plugins/gettext_i18n_rails/spec/spec_helper.rb +1 -8
- data/zena.gemspec +2241 -2217
- metadata +123 -83
- data/.gitignore +0 -36
- data/app/views/nodes/_dates.rhtml +0 -13
- data/db/init/base/skins/default/Node-+adminLayout.zafu +0 -46
- data/db/init/base/skins/default/Node-tree.zafu +0 -19
- data/vendor/plugins/gettext_i18n_rails/README.markdown +0 -143
data/lib/zena/deploy/vhost.rhtml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# zena apache2 vhost for <%= config[:host] %>
|
2
2
|
# automatically generated file
|
3
3
|
|
4
|
-
<VirtualHost
|
4
|
+
<VirtualHost *<%= config[:ssl] ? ':443' : '' %>>
|
5
5
|
ServerName <%= config[:host] %>
|
6
6
|
|
7
7
|
DocumentRoot <%= config[:sites_root] %>/<%= config[:host] %>/public
|
@@ -95,4 +95,12 @@
|
|
95
95
|
LogFormat '"%r" %{output_info}n/%{input_info}n (%{ratio_info}n%%)' deflate
|
96
96
|
CustomLog <%= config[:sites_root] %>/<%= config[:host] %>/log/deflate.log deflate
|
97
97
|
<% end %>
|
98
|
+
|
99
|
+
<% if config[:ssl] %>
|
100
|
+
SSLEngine on
|
101
|
+
SSLCertificateFile /etc/ssl/<%= config[:host] %>.crt
|
102
|
+
SSLCertificateKeyFile /etc/ssl/<%= config[:host] %>.key
|
103
|
+
SSLCACertificateFile /etc/ssl/<%= config[:ssl_pem] %>
|
104
|
+
SSLVerifyClient None
|
105
|
+
<% end %>
|
98
106
|
</VirtualHost>
|
data/lib/zena/deploy.rb
CHANGED
@@ -149,7 +149,7 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
149
149
|
#========================== MANAGE HOST =========================#
|
150
150
|
desc "create a new site [-s host='...' -s pass='...' -s lang='...']"
|
151
151
|
task :mksite, :roles => :app do
|
152
|
-
run "#{in_current} rake zena:mksite HOST='#{self[:host]}' PASSWORD='#{self[:pass]}' RAILS_ENV='production'
|
152
|
+
run "#{in_current} rake zena:mksite HOST='#{self[:host]}' PASSWORD='#{self[:pass]}' RAILS_ENV='production' HOST_LANG='#{self[:lang] || 'en'}'"
|
153
153
|
create_vhost
|
154
154
|
create_awstats
|
155
155
|
logrotate
|
@@ -307,12 +307,17 @@ Capistrano::Configuration.instance(:must_exist).load do
|
|
307
307
|
end
|
308
308
|
|
309
309
|
run "test -e /etc/apache2/sites-enabled/000-default && a2dissite default || echo 'default already disabled'"
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
310
|
+
|
311
|
+
modules = %w{rewrite deflate proxy_balancer proxy proxy_http expires}
|
312
|
+
if self[:ssl]
|
313
|
+
modules << 'ssl'
|
314
|
+
# Default in debian: no need to change ports.
|
315
|
+
# /etc/apache2/ports.conf:
|
316
|
+
# Listen 443
|
317
|
+
end
|
318
|
+
modules.each do |mod|
|
319
|
+
run "test -e /etc/apache2/mods-enabled/#{mod}.load || a2enmod #{mod}"
|
320
|
+
end
|
316
321
|
run "/etc/init.d/apache2 force-reload"
|
317
322
|
end
|
318
323
|
|
data/lib/zena/foxy_parser.rb
CHANGED
@@ -411,7 +411,7 @@ module Zena
|
|
411
411
|
records = [
|
412
412
|
{ 'id' => Zena::FoxyParser::id(site, "#{name}_#{node['v_lang'] || node['ref_lang']}"),
|
413
413
|
'publish_from' => node['v_publish_from'],
|
414
|
-
'status' => Zena::Status[node['v_status'].to_sym],
|
414
|
+
'status' => Zena::Status[(node['v_status'] || 'pub').to_sym],
|
415
415
|
'lang' => node['v_lang'] || node['ref_lang']
|
416
416
|
}
|
417
417
|
]
|
@@ -602,6 +602,7 @@ module Zena
|
|
602
602
|
version['lang'] ||= node['ref_lang']
|
603
603
|
version['user_id'] ||= Zena::FoxyParser::multi_site_id(node['user'])
|
604
604
|
if prop = version.delete('prop')
|
605
|
+
version['idx_text_high'] = prop['title']
|
605
606
|
version['properties'] = make_prop(prop) unless prop.blank?
|
606
607
|
end
|
607
608
|
|
@@ -642,6 +643,7 @@ module Zena
|
|
642
643
|
version['prop']['title'] ||= version['node']
|
643
644
|
|
644
645
|
if prop = version.delete('prop')
|
646
|
+
version['idx_text_high'] = prop['title']
|
645
647
|
version['properties'] = make_prop(prop) unless prop.blank?
|
646
648
|
end
|
647
649
|
|
data/lib/zena/info.rb
CHANGED
@@ -203,7 +203,7 @@ module Zena
|
|
203
203
|
store "\"#{title}\":#{id}"
|
204
204
|
else
|
205
205
|
id = "#{node.zip}#{mode_format}"
|
206
|
-
if format == '.data'
|
206
|
+
if format == '.data' && node.kind_of?(Document)
|
207
207
|
title = "#{node.fullpath_as_title.join('/')}#{mode}.#{node.ext}#{dash}"
|
208
208
|
else
|
209
209
|
title = "#{node.fullpath_as_title.join('/')}#{mode_format}"
|
data/lib/zena/remote/node.rb
CHANGED
@@ -13,7 +13,10 @@ module Zena
|
|
13
13
|
def attributes=(new_attributes)
|
14
14
|
raise Exception.new("Invalid attributes. Expecting a hash, found #{new_attributes.inspect}") unless new_attributes.kind_of?(Hash)
|
15
15
|
new_attributes.stringify_keys.each do |key, value|
|
16
|
-
|
16
|
+
writer = "#{key}=".to_sym
|
17
|
+
if self.respond_to?(writer)
|
18
|
+
self.send(writer, value)
|
19
|
+
elsif value.kind_of?(Array)
|
17
20
|
# setting multiple ids
|
18
21
|
key = "#{key}_ids" unless key =~ /_ids$/
|
19
22
|
@attributes[key] = value.map do |elem|
|
@@ -34,6 +37,10 @@ module Zena
|
|
34
37
|
end
|
35
38
|
end
|
36
39
|
|
40
|
+
def tag_names=(list)
|
41
|
+
@attributes['tag_names'] = SerializableArray.new('tag_names', 'tag', list)
|
42
|
+
end
|
43
|
+
|
37
44
|
def id
|
38
45
|
@attributes['id']
|
39
46
|
end
|
@@ -48,8 +55,13 @@ module Zena
|
|
48
55
|
@attributes[key] = elem.id
|
49
56
|
elsif elem.kind_of?(Array)
|
50
57
|
key = "#{key}_ids" unless key =~ /_ids?$/
|
51
|
-
|
52
|
-
|
58
|
+
if elem == []
|
59
|
+
# Fix for strange handling of empty array by to_xml and such.
|
60
|
+
@attributes[key] = nil
|
61
|
+
else
|
62
|
+
@attributes[key] = elem.map do |value|
|
63
|
+
value.kind_of?(Remote::Node) ? value.id : value
|
64
|
+
end
|
53
65
|
end
|
54
66
|
else
|
55
67
|
@attributes[$1] = elem
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Zena
|
2
|
+
module Remote
|
3
|
+
class SerializableArray < Array
|
4
|
+
def initialize(name, elem_name, elements)
|
5
|
+
@name, @elem_name = name, elem_name
|
6
|
+
replace(elements)
|
7
|
+
end
|
8
|
+
|
9
|
+
def to_xml(opts)
|
10
|
+
builder = opts[:builder]
|
11
|
+
builder.tag!(@name, :type => :array) do
|
12
|
+
each do |elem|
|
13
|
+
builder.tag!(@elem_name, elem.to_s, :type => :string)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end # Remote
|
19
|
+
end # Zena
|
data/lib/zena/remote.rb
CHANGED
data/lib/zena/routes.rb
CHANGED
@@ -56,8 +56,13 @@ module Zena
|
|
56
56
|
:member => { :crop_form => :get }
|
57
57
|
|
58
58
|
resources :relations
|
59
|
-
resources :virtual_classes, :collection => {
|
60
|
-
|
59
|
+
resources :virtual_classes, :collection => {
|
60
|
+
:import_prepare => :post,
|
61
|
+
:import => :post,
|
62
|
+
:export => :get,
|
63
|
+
}
|
64
|
+
|
65
|
+
resources :columns
|
61
66
|
|
62
67
|
resources :sites,
|
63
68
|
:member => { :clear_cache => :post }
|
data/lib/zena/site_worker.rb
CHANGED
@@ -19,7 +19,7 @@ module Zena
|
|
19
19
|
def perform(site = nil)
|
20
20
|
if site.nil?
|
21
21
|
site ||= Site.find(site_id)
|
22
|
-
Thread.current[:visitor] = site.
|
22
|
+
Thread.current[:visitor] = site.any_admin
|
23
23
|
end
|
24
24
|
|
25
25
|
if nodes = get_nodes
|
@@ -44,5 +44,15 @@ module Zena
|
|
44
44
|
def page_count
|
45
45
|
(Node.count(:conditions => ['site_id = ?', site_id]) / CHUNK_SIZE) + 1
|
46
46
|
end
|
47
|
+
|
48
|
+
# Return a textual description of the operation.
|
49
|
+
def info
|
50
|
+
if site_id == current_site.id
|
51
|
+
"#{action}, #{_('page')} #{page}/#{page_count}"
|
52
|
+
else
|
53
|
+
# Do not show jobs from other sites
|
54
|
+
"-"
|
55
|
+
end
|
56
|
+
end
|
47
57
|
end
|
48
58
|
end # Zena
|
data/lib/zena/unit/test_case.rb
CHANGED
@@ -17,6 +17,74 @@ module Zena
|
|
17
17
|
# Ignore since we include helpers in the TestCase itself
|
18
18
|
end
|
19
19
|
|
20
|
+
# Specific helpers to validate model relations and queries with SQLiss
|
21
|
+
def main_date
|
22
|
+
raise "The test uses 'validate_query' without defining @main_date" unless @main_date
|
23
|
+
return @main_date.strftime("'%Y-%m-%d'")
|
24
|
+
end
|
25
|
+
|
26
|
+
# Test a query (useful with complex custom queries). Usage:
|
27
|
+
#
|
28
|
+
# validate_query "emp_comp_dates where log_at is not null", [
|
29
|
+
# { :title => 'Creativity',
|
30
|
+
# :priority => '5',
|
31
|
+
# :log_at => '2010-06-01',
|
32
|
+
# :event_at => '2011-06-01',
|
33
|
+
# },
|
34
|
+
# { :title => 'Leadership',
|
35
|
+
# :priority => '5',
|
36
|
+
# :log_at => '2003-01-01',
|
37
|
+
# :event_at => nil, # forever
|
38
|
+
# },
|
39
|
+
# ]
|
40
|
+
#
|
41
|
+
def validate_query(query, expected_list)
|
42
|
+
list = subject.find(:all, query.gsub('<', '<').gsub('>', '>'), :errors => true)
|
43
|
+
if expected_list.nil? || expected_list.empty?
|
44
|
+
assert_equal nil, list
|
45
|
+
elsif expected_list.first.kind_of?(String)
|
46
|
+
assert_equal expected_list, list.map(&:title)
|
47
|
+
elsif list.nil?
|
48
|
+
assert_equal expected_list, list
|
49
|
+
elsif list.kind_of?(::QueryBuilder::Error)
|
50
|
+
assert_equal expected_list, list.to_s
|
51
|
+
else
|
52
|
+
proto = expected_list.first.keys
|
53
|
+
sz = [expected_list.size, list.size].max
|
54
|
+
|
55
|
+
(0..(sz-1)).to_a.each do |i|
|
56
|
+
record = list[i]
|
57
|
+
expected = expected_list[i]
|
58
|
+
if not record
|
59
|
+
assert_equal expected[:title], nil
|
60
|
+
elsif not expected
|
61
|
+
assert_equal nil, map_to_proto(proto, record)
|
62
|
+
else
|
63
|
+
if expected[:title] != record.title
|
64
|
+
assert_equal expected[:title], map_to_proto(proto, record)
|
65
|
+
else
|
66
|
+
expected.keys.each do |key|
|
67
|
+
value = format_date(record[key] || record.send(key))
|
68
|
+
assert_equal expected[key], value, "(#{record.title} #{key} expected to be #{expected[key].inspect} but was #{value.inspect}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
def format_date(date)
|
78
|
+
if date.respond_to?(:strftime)
|
79
|
+
date.strftime('%Y-%m-%d')
|
80
|
+
else
|
81
|
+
date
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def map_to_proto(proto, record)
|
86
|
+
Hash[*proto.map{|k| [k, format_date(record[k] || record.send(k))]}.flatten]
|
87
|
+
end
|
20
88
|
end
|
21
89
|
end
|
22
90
|
end
|
data/lib/zena/use/action.rb
CHANGED
@@ -27,12 +27,16 @@ module Zena
|
|
27
27
|
tag = "<a href='#{url}' target='_blank' title='#{title}' onclick=\"Zena.open_window('#{url}', '#{id}', event);return false;\">"
|
28
28
|
else
|
29
29
|
query = query.empty? ? '' : "?#{query.join('&')}"
|
30
|
-
tag = "<a href='/nodes/#{node_zip}/versions/0/#{action}#{query}' onclick='Zena.
|
30
|
+
tag = "<a href='/nodes/#{node_zip}/versions/0/#{action}#{query}' onclick='Zena.m(this, \"put\");return false;' title ='#{title}'>"
|
31
31
|
end
|
32
32
|
"#{tag}#{text}</a>"
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
module ControllerMethods
|
37
|
+
include Common
|
38
|
+
end
|
39
|
+
|
36
40
|
module ViewMethods
|
37
41
|
include Common
|
38
42
|
include RubyLess
|
@@ -270,7 +274,6 @@ class #{node.klass}: #{Array(node.klass).first.columns.keys.join(', ')}
|
|
270
274
|
end
|
271
275
|
elsif block = (ancestor('block') || ancestor('each'))
|
272
276
|
# ancestor: ok
|
273
|
-
block = self
|
274
277
|
elsif parent && block = parent.descendant('block')
|
275
278
|
# sibling: ok
|
276
279
|
upd_both = ''
|
@@ -285,6 +288,7 @@ class #{node.klass}: #{Array(node.klass).first.columns.keys.join(', ')}
|
|
285
288
|
out make_link(:update => block, :action => 'update', :query_params => query_params, :method => :put)
|
286
289
|
end
|
287
290
|
end # ZafuMethods
|
291
|
+
|
288
292
|
end # Action
|
289
293
|
end # Use
|
290
294
|
end # Zena
|
data/lib/zena/use/ajax.rb
CHANGED
@@ -2,24 +2,29 @@ module Zena
|
|
2
2
|
module Use
|
3
3
|
module Ajax
|
4
4
|
module ViewMethods
|
5
|
+
include RubyLess
|
6
|
+
safe_method :ajax? => {:class => Boolean, :method => 'params[:s]'}
|
7
|
+
|
5
8
|
# Return the DOM id for a node. We had to name this method 'ndom_id' because we want
|
6
9
|
# to avoid the clash with Rails' dom_id method.
|
7
10
|
def ndom_id(node)
|
8
|
-
if node.
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
if node.kind_of?(Node)
|
12
|
+
if node.new_record?
|
13
|
+
return "#{params[:dom_id]}_form"
|
14
|
+
elsif params[:action] == 'create' && !params[:udom_id]
|
15
|
+
return "#{params[:dom_id]}_#{node.zip}"
|
16
|
+
end
|
14
17
|
end
|
18
|
+
|
19
|
+
@dom_id || params[:udom_id] || params[:dom_id]
|
15
20
|
end
|
16
21
|
|
17
22
|
# RJS to update a page after create/update/destroy
|
18
23
|
def update_page_content(page, obj)
|
19
24
|
unless params[:dom_id]
|
20
25
|
# simply reply with failure or success
|
21
|
-
if
|
22
|
-
page << "alert(#{
|
26
|
+
if !obj.errors.empty?
|
27
|
+
page << "alert(#{obj.errors.first.join(': ')});"
|
23
28
|
page << "return false;" # How to avoid 'onSuccess' ?
|
24
29
|
elsif params[:udom_id] == '_page'
|
25
30
|
# reload page
|
@@ -30,8 +35,8 @@ module Zena
|
|
30
35
|
return
|
31
36
|
end
|
32
37
|
|
33
|
-
if params[:t_id] &&
|
34
|
-
|
38
|
+
if params[:t_id] && obj.errors.empty?
|
39
|
+
obj = secure(Node) { Node.find_by_zip(params[:t_id])}
|
35
40
|
end
|
36
41
|
|
37
42
|
base_class = obj.kind_of?(Node) ? Node : obj.class
|
@@ -84,14 +89,13 @@ module Zena
|
|
84
89
|
case params[:action]
|
85
90
|
when 'edit'
|
86
91
|
page.replace params[:dom_id], :file => template_path_from_template_url + ".erb"
|
87
|
-
puts "$('#{params[:dom_id]}_form_t').focusFirstElement();"
|
88
92
|
page << "$('#{params[:dom_id]}_form_t').focusFirstElement();"
|
89
93
|
when 'create'
|
90
94
|
pos = params[:position] || :before
|
91
95
|
ref = params[:reference] || "#{params[:dom_id]}_add"
|
92
96
|
page.insert_html pos.to_sym, ref, :file => template_path_from_template_url + ".erb"
|
93
97
|
if obj.kind_of?(Node)
|
94
|
-
@node =
|
98
|
+
@node = obj.parent.new_child(:class => obj.class)
|
95
99
|
else
|
96
100
|
instance_variable_set("@#{base_class.to_s.underscore}", obj.clone)
|
97
101
|
end
|
@@ -115,7 +119,11 @@ module Zena
|
|
115
119
|
end
|
116
120
|
page.replace params[:dom_id], :file => template_path_from_template_url + ".erb"
|
117
121
|
else
|
118
|
-
|
122
|
+
if position = params[:insert]
|
123
|
+
page.call 'Zena.insert_inner', params[:dom_id], position, render(:file => template_path_from_template_url + ".erb")
|
124
|
+
else
|
125
|
+
page.replace params[:dom_id], :file => template_path_from_template_url + ".erb"
|
126
|
+
end
|
119
127
|
end
|
120
128
|
end
|
121
129
|
page << render_js(false)
|
@@ -179,43 +187,46 @@ module Zena
|
|
179
187
|
|
180
188
|
module ZafuMethods
|
181
189
|
def self.included(base)
|
182
|
-
# TODO: move
|
190
|
+
# TODO: move process_toggle in 'before_wrap' callback so that 'node' is properly set.
|
183
191
|
base.before_process :process_drag, :process_toggle
|
184
192
|
base.before_wrap :wrap_with_drag
|
185
193
|
end
|
186
194
|
|
187
|
-
def
|
188
|
-
|
189
|
-
@wrap_with_drag.wrap(text)
|
190
|
-
else
|
191
|
-
text
|
192
|
-
end
|
195
|
+
def process_drag
|
196
|
+
@drag_param = @params.delete(:draggable)
|
193
197
|
end
|
194
198
|
|
195
199
|
# Force an id on the current tag and record the DOM_ID to make the element draggable.
|
196
|
-
def
|
197
|
-
|
200
|
+
def wrap_with_drag(text)
|
201
|
+
# do not render drag in make_form
|
202
|
+
return text unless @drag_param && !@context[:make_form]
|
203
|
+
drag = @drag_param
|
198
204
|
|
199
|
-
if @markup.params[:id]
|
200
|
-
# we do not mess with
|
201
|
-
markup = @
|
205
|
+
if @markup.params[:id] || (@markup.done && @method == 'link') # hack to rewrap link...
|
206
|
+
# we do not mess with the original but use our own markup
|
207
|
+
markup = @wrap_markup = Zafu::Markup.new('span')
|
202
208
|
else
|
203
209
|
markup = @markup
|
204
210
|
end
|
205
211
|
|
206
212
|
markup.tag ||= 'div'
|
207
213
|
|
208
|
-
node = pre_filter_node
|
209
|
-
|
210
214
|
if @name.blank?
|
211
215
|
# make sure we have a scope
|
212
|
-
|
216
|
+
node.dom_prefix = dom_name
|
213
217
|
end
|
214
218
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
+
if erb_dom_id = markup.dyn_params[:id]
|
220
|
+
# id set, get erb id
|
221
|
+
else
|
222
|
+
# We do not want to use the same id as the 'each' loop but we also want to
|
223
|
+
# avoid changing the node context
|
224
|
+
@drag_prefix ||= root.get_unique_name('drag', true).gsub(/[^\d\w\/]/,'_')
|
225
|
+
erb_dom_id = node.dom_id(:dom_prefix => @drag_prefix)
|
226
|
+
markup.set_id(erb_dom_id)
|
227
|
+
end
|
228
|
+
|
229
|
+
dom_id = erb_dom_id[/<%=\s*(.*?)\s*%>/,1]
|
219
230
|
|
220
231
|
markup.append_param(:class, 'drag')
|
221
232
|
|
@@ -234,7 +245,13 @@ module Zena
|
|
234
245
|
js_options << (%w{true false}.include?(revert) ? revert : revert.inspect)
|
235
246
|
end
|
236
247
|
|
237
|
-
markup.pre_wrap[:drag] = "#{handle}<% add_drag_id(
|
248
|
+
markup.pre_wrap[:drag] = "#{handle}<% add_drag_id(#{dom_id}, #{js_options.join(', ').inspect}) %>"
|
249
|
+
|
250
|
+
if @markup == markup
|
251
|
+
text
|
252
|
+
else
|
253
|
+
markup.wrap(text)
|
254
|
+
end
|
238
255
|
end
|
239
256
|
|
240
257
|
# Display an input field to filter a remote block
|
@@ -243,13 +260,24 @@ module Zena
|
|
243
260
|
return unless block = find_target(upd)
|
244
261
|
else
|
245
262
|
return parser_error("missing 'block' in same parent") unless parent && block = parent.descendant('block')
|
263
|
+
if block.name.blank?
|
264
|
+
block.name ||= unique_name
|
265
|
+
end
|
266
|
+
upd = block.name
|
246
267
|
end
|
247
268
|
|
248
269
|
return parser_error("cannot use 's' as key (used by start_node)") if @params[:key] == 's'
|
249
270
|
|
271
|
+
# Move up in case we are in a list.
|
272
|
+
if self.node.list_context?
|
273
|
+
node = self.node.up(Node)
|
274
|
+
else
|
275
|
+
node = self.node
|
276
|
+
end
|
277
|
+
node.dom_prefix = dom_name
|
250
278
|
dom_id = node.dom_id(:erb => false)
|
251
279
|
|
252
|
-
out %Q{<%= form_remote_tag(:url => zafu_node_path(#{node}
|
280
|
+
out %Q{<%= form_remote_tag(:url => zafu_node_path(#{node}), :method => :get, :html => {:id => \"#{dom_id}_f\"}) %>
|
253
281
|
<div class='hidden'>
|
254
282
|
<input type='hidden' name='t_url' value='#{template_url(upd)}'/>
|
255
283
|
<input type='hidden' name='dom_id' value='#{upd}'/>
|
@@ -271,25 +299,22 @@ module Zena
|
|
271
299
|
def r_drop
|
272
300
|
if parent.method == 'each' && @method == parent.single_child_method
|
273
301
|
# We reuse the 'each' block.
|
274
|
-
|
275
|
-
# Make sure the parent has a proper dom_prefix.
|
276
|
-
parent.set_dom_prefix
|
302
|
+
target = parent
|
277
303
|
else
|
278
|
-
|
279
|
-
|
304
|
+
node.dom_prefix = dom_name
|
305
|
+
target = self
|
280
306
|
end
|
281
307
|
|
308
|
+
# Make sure the target has a proper dom_prefix.
|
309
|
+
# FIXME: Test without, not sure this is needed anymore
|
310
|
+
#target.node.dom_prefix = target.dom_name
|
311
|
+
|
312
|
+
node = target.node
|
313
|
+
markup = target.markup
|
314
|
+
|
282
315
|
markup.tag ||= 'div'
|
283
316
|
|
284
|
-
|
285
|
-
if dom_id = markup.dyn_params[:id]
|
286
|
-
if dom_id =~ /<%= %Q\{(.*)\} %>/
|
287
|
-
dom_id = $1
|
288
|
-
end
|
289
|
-
else
|
290
|
-
dom_id = node.dom_id(:list => false, :erb => false)
|
291
|
-
markup.set_id(node.dom_id(:list => false))
|
292
|
-
end
|
317
|
+
dom_id, dom_prefix = get_dom_id(target)
|
293
318
|
|
294
319
|
markup.append_param(:class, 'drop') unless markup.params[:class] =~ /drop/
|
295
320
|
|
@@ -300,11 +325,11 @@ module Zena
|
|
300
325
|
end
|
301
326
|
|
302
327
|
if role = @params.delete(:set) || @params.delete(:add)
|
303
|
-
@params["node[#{role}_id]"] = '
|
328
|
+
@params["node[#{role}_id]"] = '\\#{id}'
|
304
329
|
end
|
305
330
|
|
306
|
-
query_params << ", :url => #{make_href(
|
307
|
-
markup.pre_wrap[:drop] = "<% add_drop_id(
|
331
|
+
query_params << ", :url => #{make_href(target, :action => 'drop')}"
|
332
|
+
markup.pre_wrap[:drop] = "<% add_drop_id(#{dom_id}#{query_params}) %>"
|
308
333
|
r_block
|
309
334
|
end
|
310
335
|
|
@@ -316,7 +341,7 @@ module Zena
|
|
316
341
|
finder = RubyLess.translate(self, finder)
|
317
342
|
return parser_error("Invalid class 'for' parameter: #{finder.klass}") unless finder.klass <= Node
|
318
343
|
|
319
|
-
|
344
|
+
node.dom_prefix = dom_name
|
320
345
|
dom_id = node.dom_id(:erb => false)
|
321
346
|
markup.set_id(node.dom_id)
|
322
347
|
markup.append_param(:class, 'toggle')
|
@@ -342,7 +367,7 @@ module Zena
|
|
342
367
|
if dom_id = @markup.params[:id]
|
343
368
|
# we do not mess with it
|
344
369
|
else
|
345
|
-
|
370
|
+
node.dom_prefix = dom_name
|
346
371
|
markup.set_id(node.dom_id)
|
347
372
|
dom_id = node.dom_id(:erb => false)
|
348
373
|
end
|
@@ -403,6 +428,22 @@ module Zena
|
|
403
428
|
#end
|
404
429
|
end
|
405
430
|
|
431
|
+
# Add some js at end of document/partial
|
432
|
+
def r_js
|
433
|
+
if @blocks.detect {|b| !b.kind_of?(String)}
|
434
|
+
out "<% js_data << capture do %>"
|
435
|
+
out expand_with
|
436
|
+
out "<% end %>"
|
437
|
+
else
|
438
|
+
txt = @blocks.join('')
|
439
|
+
out "<% js_data << #{txt.inspect} %>"
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
def r_ajax?
|
444
|
+
r_if(RubyLess.translate(self, 'ajax?'))
|
445
|
+
end
|
446
|
+
|
406
447
|
protected
|
407
448
|
|
408
449
|
def need_ajax?(each_block)
|
@@ -413,6 +454,39 @@ module Zena
|
|
413
454
|
each_block.descendant('unlink')
|
414
455
|
end
|
415
456
|
|
457
|
+
# Returns ruby for dom_id.
|
458
|
+
#
|
459
|
+
# FIXME: HACK
|
460
|
+
# This dom_id detection code is crap but it fixes the drop in each bug.
|
461
|
+
def get_dom_id(target)
|
462
|
+
if dom_id = target.markup.dyn_params[:id] || target.markup.params[:id]
|
463
|
+
if dom_id =~ /^<%=\s+(.*?)\s+%>$/
|
464
|
+
dom_id = $1
|
465
|
+
else
|
466
|
+
dom_id = "%Q{#{dom_id}}"
|
467
|
+
end
|
468
|
+
|
469
|
+
elsif target.context
|
470
|
+
# @context set, so node is available
|
471
|
+
dom_id = "%Q{#{target.node.dom_id(
|
472
|
+
:list => target.method == 'each',
|
473
|
+
:erb => false
|
474
|
+
)}}"
|
475
|
+
|
476
|
+
target.markup.set_id(node.dom_id(
|
477
|
+
:list => target.method == 'each'
|
478
|
+
))
|
479
|
+
else
|
480
|
+
# Has not been rendered yet, does not have a dom_prefix set.
|
481
|
+
dom_id = "%Q{#{target.dom_name}}"
|
482
|
+
|
483
|
+
target.markup.set_id(node.dom_id(
|
484
|
+
:list => target.method == 'each'
|
485
|
+
))
|
486
|
+
end
|
487
|
+
|
488
|
+
return [dom_id, target.context ? target.node.dom_prefix : target.dom_name]
|
489
|
+
end
|
416
490
|
end
|
417
491
|
end # Ajax
|
418
492
|
end # Use
|