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
@@ -6,6 +6,18 @@ class PropEvalTest < Zena::Unit::TestCase
|
|
6
6
|
set_table_name :nodes_roles
|
7
7
|
end
|
8
8
|
|
9
|
+
def idx_ml_value(obj_id, key, lang=visitor.lang)
|
10
|
+
IdxNodesMlString.find(:first,
|
11
|
+
:conditions => {:node_id => obj_id, :lang => lang, :key => key}
|
12
|
+
).value
|
13
|
+
end
|
14
|
+
|
15
|
+
def idx_value(obj_id, key)
|
16
|
+
IdxNodesString.find(:first,
|
17
|
+
:conditions => {:node_id => obj_id, :key => key}
|
18
|
+
).value
|
19
|
+
end
|
20
|
+
|
9
21
|
context 'A visitor with admin rights' do
|
10
22
|
setup do
|
11
23
|
login(:lion)
|
@@ -98,21 +110,35 @@ class PropEvalTest < Zena::Unit::TestCase
|
|
98
110
|
end
|
99
111
|
|
100
112
|
should 'use evaluated prop in ml prop indices' do
|
101
|
-
|
102
|
-
:conditions => {:node_id => subject.id, :lang => visitor.lang, :key => 'search'}
|
103
|
-
)
|
104
|
-
assert_equal 'zena enhancements paper:Origami', idx.value
|
113
|
+
assert_equal 'zena enhancements paper:Origami', idx_ml_value(subject.id, 'search')
|
105
114
|
end
|
106
115
|
|
107
116
|
should 'use evaluated prop in prop indices' do
|
108
|
-
|
109
|
-
:conditions => {:node_id => subject.id, :key => 'search_mono'}
|
110
|
-
)
|
111
|
-
assert_equal 'Origami mono', idx.value
|
117
|
+
assert_equal 'Origami mono', idx_value(subject.id, 'search_mono')
|
112
118
|
end
|
113
119
|
end # with property indices
|
114
120
|
|
115
121
|
end # updating attributes
|
122
|
+
|
123
|
+
context 'rebuilding index' do
|
124
|
+
setup do
|
125
|
+
login(:lion)
|
126
|
+
vclass = secure(Role) { roles(:Contact) }
|
127
|
+
# changed prop_eval
|
128
|
+
assert vclass.update_attributes(:prop_eval => %q[{'title' => "LAST:#{name} FIRST:#{first_name}"}])
|
129
|
+
end
|
130
|
+
|
131
|
+
subject do
|
132
|
+
secure(Node) { nodes(:ant) }
|
133
|
+
end
|
134
|
+
|
135
|
+
should 'evaluate prop' do
|
136
|
+
subject.rebuild_index!
|
137
|
+
assert_equal 'LAST:Invicta FIRST:Solenopsis', idx_ml_value(subject.id, 'title')
|
138
|
+
assert_equal 'LAST:Invicta FIRST:Solenopsis', nodes(:ant).title
|
139
|
+
end
|
140
|
+
end # rebuilding index
|
141
|
+
|
116
142
|
end # from a class with evaluated properties
|
117
143
|
|
118
144
|
context 'from a class with prop eval used as default' do
|
@@ -163,8 +189,24 @@ class PropEvalTest < Zena::Unit::TestCase
|
|
163
189
|
end
|
164
190
|
assert_equal 'Hyperion', subject.title
|
165
191
|
end
|
192
|
+
|
193
|
+
should 'rebuild prop_eval on klass change' do
|
194
|
+
assert subject.update_attributes(:klass => 'Letter')
|
195
|
+
node = secure(Node) { Node.find(subject.id)}
|
196
|
+
assert_equal 'projects list paper:', node.search
|
197
|
+
end
|
166
198
|
end # from a native class
|
167
199
|
|
168
200
|
end # on a node
|
169
201
|
end # A visitor with write access
|
202
|
+
|
203
|
+
context 'The VirtualClass class' do
|
204
|
+
subject do
|
205
|
+
VirtualClass
|
206
|
+
end
|
207
|
+
|
208
|
+
should 'contain prop_eval in export attributes' do
|
209
|
+
assert subject.export_attributes.include?('prop_eval')
|
210
|
+
end
|
211
|
+
end # A VirtualClass
|
170
212
|
end
|
@@ -89,6 +89,17 @@ class QueryNodeTest < Zena::Unit::TestCase
|
|
89
89
|
should 'set main_class' do
|
90
90
|
assert_equal VirtualClass['Document'], subject.main_class
|
91
91
|
end
|
92
|
+
|
93
|
+
context 'with core context' do
|
94
|
+
subject do
|
95
|
+
Node.build_query(:all, 'project')
|
96
|
+
end
|
97
|
+
|
98
|
+
should 'set main_class' do
|
99
|
+
assert_equal VirtualClass['Project'], subject.main_class
|
100
|
+
end
|
101
|
+
end # with core context
|
102
|
+
|
92
103
|
end # with a real class filter
|
93
104
|
|
94
105
|
context 'with root' do
|
@@ -41,6 +41,12 @@ class RenderingInControllerTest < Zena::Controller::TestCase
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
def make_template(zafu, mode = 'special')
|
45
|
+
login(:lion)
|
46
|
+
# create template for 'special' mode
|
47
|
+
secure(Template) { Template.create(:parent_id => nodes_id(:default), :title => "Node-#{mode}.zafu", :text => zafu, :v_status => Zena::Status[:pub]) }
|
48
|
+
end
|
49
|
+
|
44
50
|
context 'A custom rendering engine' do
|
45
51
|
setup do
|
46
52
|
login(:anon)
|
@@ -102,6 +108,72 @@ class RenderingInControllerTest < Zena::Controller::TestCase
|
|
102
108
|
end
|
103
109
|
end # Custom rendering options
|
104
110
|
|
111
|
+
context 'special rendering zafu' do
|
112
|
+
subject do
|
113
|
+
{:action => 'show', :controller => 'nodes', :path => ["section#{nodes_zip(:people)}_#{@mode}.html"], :prefix => 'en'}
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'to raise not found' do
|
117
|
+
setup do
|
118
|
+
@mode = 'nf'
|
119
|
+
make_template "<r:not_found/>", @mode
|
120
|
+
login(:anon)
|
121
|
+
end
|
122
|
+
|
123
|
+
should 'raise not found' do
|
124
|
+
# Stupid tests. Raises ActionView::TemplateError during testing and
|
125
|
+
# ActiveRecord::RecordNotFound in production.
|
126
|
+
assert_raise(ActionView::TemplateError) { get_subject }
|
127
|
+
end # Not found rendering
|
128
|
+
end # to raise not found
|
129
|
+
|
130
|
+
# Not working yet...
|
131
|
+
# context 'to redirect' do
|
132
|
+
# setup do
|
133
|
+
# @mode = 'redir'
|
134
|
+
# make_template "<r:redirect url='http://feature-space.com'/>", @mode
|
135
|
+
# login(:anon)
|
136
|
+
# end
|
137
|
+
#
|
138
|
+
# should 'redirect' do
|
139
|
+
# get_subject
|
140
|
+
# assert_redirected_to 'http://feature-space.com'
|
141
|
+
# end
|
142
|
+
# end # to redirect
|
143
|
+
|
144
|
+
context 'to update' do
|
145
|
+
setup do
|
146
|
+
@mode = 'ins'
|
147
|
+
make_template "<div id='foo' do='block'>hello <r:title/></div>", @mode
|
148
|
+
login(:anon)
|
149
|
+
# render page to build template
|
150
|
+
get 'show', :path => ["section#{nodes_zip(:people)}_#{@mode}.html"], :prefix => 'en'
|
151
|
+
assert_equal "<div id='foo'>hello people</div>", @response.body
|
152
|
+
end
|
153
|
+
|
154
|
+
should 'execute Element update' do
|
155
|
+
get 'zafu', {
|
156
|
+
:id => nodes_zip(:people),
|
157
|
+
:t_url => 'Default skin/Node-ins/foo',
|
158
|
+
:dom_id => 'foo',
|
159
|
+
}
|
160
|
+
assert_equal %Q{Element.replace("foo", "\\u003Cdiv id='foo'\\u003Ehello people\\u003C/div\\u003E");\n}, @response.body
|
161
|
+
end
|
162
|
+
|
163
|
+
context 'with insert' do
|
164
|
+
should 'execute Zena insert_inner' do
|
165
|
+
get 'zafu', {
|
166
|
+
:id => nodes_zip(:people),
|
167
|
+
:t_url => 'Default skin/Node-ins/foo',
|
168
|
+
:dom_id => 'foo',
|
169
|
+
:insert => 'bottom',
|
170
|
+
}
|
171
|
+
assert_equal %Q{Zena.insert_inner("foo", "bottom", "\\u003Cdiv id='foo'\\u003Ehello people\\u003C/div\\u003E");\n}, @response.body
|
172
|
+
end
|
173
|
+
end # with insert
|
174
|
+
end # to update
|
175
|
+
end # special rendering zafu
|
176
|
+
|
105
177
|
context 'Custom rendering options on html' do
|
106
178
|
subject do
|
107
179
|
login(:lion)
|
@@ -76,6 +76,29 @@ class ScopeIndexTest < Zena::Unit::TestCase
|
|
76
76
|
end
|
77
77
|
end # creating a sub node
|
78
78
|
|
79
|
+
context 'deleting a sub node' do
|
80
|
+
setup do
|
81
|
+
secure(Node) { Node.create_node(:klass => 'Contact', :name => 'Life threat', :first_name => 'Earthquake', :parent_id => @project.zip, :v_status => Zena::Status[:pub])
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
subject do
|
86
|
+
secure(Node) { Node.create_node(:klass => 'Contact', :name => 'Life threat', :first_name => 'Fukushima', :parent_id => @project.zip, :v_status => Zena::Status[:pub])
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
should 'rebuild target indexes' do
|
91
|
+
assert_equal 'Earthquake', IdxProject.find(@project.scope_index).contact_first_name
|
92
|
+
subject
|
93
|
+
assert_equal 'Fukushima', IdxProject.find(@project.scope_index).contact_first_name
|
94
|
+
assert_difference('IdxProject.count', 0) do
|
95
|
+
subject.destroy
|
96
|
+
idx = IdxProject.find(@project.scope_index)
|
97
|
+
assert_equal 'Earthquake', idx.contact_first_name
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end # deleting a sub node
|
101
|
+
|
79
102
|
context 'moving a sub node' do
|
80
103
|
subject do
|
81
104
|
secure(Node) { VirtualClass['Contact'].create_instance(:first_name => 'Friedrich', :name => 'Hölderlin', :parent_id => nodes_id(:zena), :v_status => Zena::Status[:pub]) }
|
@@ -412,7 +435,7 @@ class ScopeIndexTest < Zena::Unit::TestCase
|
|
412
435
|
vclass = VirtualClass.create(subject)
|
413
436
|
assert_equal "Invalid entry: keys should be a String and query should be a String or an Array of strings (1 => \"project\")", vclass.errors[:idx_scope]
|
414
437
|
end
|
415
|
-
|
438
|
+
|
416
439
|
context 'with array keys' do
|
417
440
|
subject do
|
418
441
|
{:name => 'Song', :superclass => 'Post', :idx_scope => "{%w{self project} => 'project'}", :create_group_id => groups_id(:public) }
|
@@ -423,7 +446,7 @@ class ScopeIndexTest < Zena::Unit::TestCase
|
|
423
446
|
assert_equal "Invalid rubyless: Invalid key type for hash (should be a literal value, was :array)", vclass.errors[:idx_scope]
|
424
447
|
end
|
425
448
|
end # with array keys
|
426
|
-
|
449
|
+
|
427
450
|
end # with an invalid idx_scope
|
428
451
|
|
429
452
|
context 'with an invalid idx_scope type' do
|
@@ -460,5 +483,17 @@ class ScopeIndexTest < Zena::Unit::TestCase
|
|
460
483
|
end
|
461
484
|
end # with an invalid query in idx_scope
|
462
485
|
end # Creating a virtual class
|
486
|
+
|
487
|
+
context 'The VirtualClass class' do
|
488
|
+
subject do
|
489
|
+
VirtualClass
|
490
|
+
end
|
463
491
|
|
492
|
+
should 'contain scopes in export attributes' do
|
493
|
+
assert subject.export_attributes.include?('idx_class')
|
494
|
+
assert subject.export_attributes.include?('idx_scope')
|
495
|
+
assert subject.export_attributes.include?('idx_reverse_scope')
|
496
|
+
end
|
497
|
+
end # A VirtualClass
|
498
|
+
|
464
499
|
end
|
@@ -27,6 +27,16 @@ class UrlsTest < Zena::View::TestCase
|
|
27
27
|
assert_equal '/en/projects-list/Clean-Water-project/page22_test.html', zen_path(node, :mode=>'test')
|
28
28
|
end
|
29
29
|
|
30
|
+
def test_zen_path_custom_base_with_accents
|
31
|
+
# See also test in NodesController
|
32
|
+
login(:lion)
|
33
|
+
node = secure!(Node) { nodes(:cleanWater) }
|
34
|
+
node.update_attributes(:title => 'Lignes aériennes')
|
35
|
+
assert_equal '/oo/projects-list/Lignes-a%C3%A9riennes', zen_path(node)
|
36
|
+
# Make sure this is parsed back correctly
|
37
|
+
assert_match Zena::Use::Urls::ALLOWED_REGEXP, zen_path(node).split('/').last
|
38
|
+
end
|
39
|
+
|
30
40
|
def test_zen_path_query_params
|
31
41
|
login(:anon)
|
32
42
|
node = secure!(Node) { nodes(:status) }
|
@@ -137,7 +137,7 @@ class ZazenTest < Zena::View::TestCase
|
|
137
137
|
end
|
138
138
|
|
139
139
|
def test_pseudo_id
|
140
|
-
assert_zazen_match "a[@href='/en/contact15.html'][text()='people/Panthera Leo Verneyi']", 'This is a "link"::
|
140
|
+
assert_zazen_match "a[@href='/en/contact15.html'][text()='people/Panthera Leo Verneyi']", 'This is a "link"::Leo.'
|
141
141
|
assert_zazen_match "a[@href='/en/image30_pv.jpg?967816914293'][text()='projects list/a wiki with Zena/bird_pv.jpg']", 'This is a "link"::bir_pv.data.'
|
142
142
|
end
|
143
143
|
|
@@ -229,10 +229,10 @@ class ZazenTest < Zena::View::TestCase
|
|
229
229
|
projects = secure!(Node) { nodes(:projects) }
|
230
230
|
zena = secure!(Node) { nodes(:zena) }
|
231
231
|
assert_equal "This \"is\":33 \"a\":#{nodes_zip(:wiki)} !#{nodes_zip(:bird_jpg)}! \"link\":#{nodes_zip(:lion)}.",
|
232
|
-
zazen('This "is":33 "a":(projects list/a wiki with Zena) !(projects list/a wiki with Zena/bird)! "link"::
|
232
|
+
zazen('This "is":33 "a":(projects list/a wiki with Zena) !(projects list/a wiki with Zena/bird)! "link"::Leo.', :translate_ids => :zip, :node => zena)
|
233
233
|
|
234
234
|
assert_equal 'This "is":(../Collections/Art) "a":(a wiki with Zena) !(a wiki with Zena/bird)! !{(a wiki with Zena/bird)}! ![(a wiki with Zena/bird)]! "link":(../people/Panthera Leo Verneyi).',
|
235
|
-
zazen('This "is":33 "a":(/projects list/a wiki with Zena) !30! !{30}! ![30]! "link"::
|
235
|
+
zazen('This "is":33 "a":(/projects list/a wiki with Zena) !30! !{30}! ![30]! "link"::Leo.', :translate_ids => :relative_path, :node => projects)
|
236
236
|
|
237
237
|
assert_equal "This \"is\":33 \"a\":#{nodes_zip(:wiki)} !#{nodes_zip(:bird_jpg)}! \"link\":#{nodes_zip(:lion)}.",
|
238
238
|
zazen('This "is":(../Collections/Art) "a":(a wiki with Zena) !(a wiki with Zena/bird)! "link":(../people/Panthera Leo Verneyi).', :translate_ids => :zip, :node => projects)
|
@@ -0,0 +1,92 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
abstract (1.0.0)
|
5
|
+
actionmailer (3.0.4)
|
6
|
+
actionpack (= 3.0.4)
|
7
|
+
mail (~> 2.2.15)
|
8
|
+
actionpack (3.0.4)
|
9
|
+
activemodel (= 3.0.4)
|
10
|
+
activesupport (= 3.0.4)
|
11
|
+
builder (~> 2.1.2)
|
12
|
+
erubis (~> 2.6.6)
|
13
|
+
i18n (~> 0.4)
|
14
|
+
rack (~> 1.2.1)
|
15
|
+
rack-mount (~> 0.6.13)
|
16
|
+
rack-test (~> 0.5.7)
|
17
|
+
tzinfo (~> 0.3.23)
|
18
|
+
activemodel (3.0.4)
|
19
|
+
activesupport (= 3.0.4)
|
20
|
+
builder (~> 2.1.2)
|
21
|
+
i18n (~> 0.4)
|
22
|
+
activerecord (3.0.4)
|
23
|
+
activemodel (= 3.0.4)
|
24
|
+
activesupport (= 3.0.4)
|
25
|
+
arel (~> 2.0.2)
|
26
|
+
tzinfo (~> 0.3.23)
|
27
|
+
activeresource (3.0.4)
|
28
|
+
activemodel (= 3.0.4)
|
29
|
+
activesupport (= 3.0.4)
|
30
|
+
activesupport (3.0.4)
|
31
|
+
arel (2.0.8)
|
32
|
+
builder (2.1.2)
|
33
|
+
diff-lcs (1.1.2)
|
34
|
+
erubis (2.6.6)
|
35
|
+
abstract (>= 1.0.0)
|
36
|
+
fast_gettext (0.5.10)
|
37
|
+
git (1.2.5)
|
38
|
+
i18n (0.5.0)
|
39
|
+
jeweler (1.5.2)
|
40
|
+
bundler (~> 1.0.0)
|
41
|
+
git (>= 1.2.5)
|
42
|
+
rake
|
43
|
+
mail (2.2.15)
|
44
|
+
activesupport (>= 2.3.6)
|
45
|
+
i18n (>= 0.4.0)
|
46
|
+
mime-types (~> 1.16)
|
47
|
+
treetop (~> 1.4.8)
|
48
|
+
mime-types (1.16)
|
49
|
+
polyglot (0.3.1)
|
50
|
+
rack (1.2.1)
|
51
|
+
rack-mount (0.6.13)
|
52
|
+
rack (>= 1.0.0)
|
53
|
+
rack-test (0.5.7)
|
54
|
+
rack (>= 1.0)
|
55
|
+
rails (3.0.4)
|
56
|
+
actionmailer (= 3.0.4)
|
57
|
+
actionpack (= 3.0.4)
|
58
|
+
activerecord (= 3.0.4)
|
59
|
+
activeresource (= 3.0.4)
|
60
|
+
activesupport (= 3.0.4)
|
61
|
+
bundler (~> 1.0)
|
62
|
+
railties (= 3.0.4)
|
63
|
+
railties (3.0.4)
|
64
|
+
actionpack (= 3.0.4)
|
65
|
+
activesupport (= 3.0.4)
|
66
|
+
rake (>= 0.8.7)
|
67
|
+
thor (~> 0.14.4)
|
68
|
+
rake (0.8.7)
|
69
|
+
rspec (2.5.0)
|
70
|
+
rspec-core (~> 2.5.0)
|
71
|
+
rspec-expectations (~> 2.5.0)
|
72
|
+
rspec-mocks (~> 2.5.0)
|
73
|
+
rspec-core (2.5.1)
|
74
|
+
rspec-expectations (2.5.0)
|
75
|
+
diff-lcs (~> 1.1.2)
|
76
|
+
rspec-mocks (2.5.0)
|
77
|
+
sqlite3 (1.3.3)
|
78
|
+
thor (0.14.6)
|
79
|
+
treetop (1.4.9)
|
80
|
+
polyglot (>= 0.3.1)
|
81
|
+
tzinfo (0.3.24)
|
82
|
+
|
83
|
+
PLATFORMS
|
84
|
+
ruby
|
85
|
+
|
86
|
+
DEPENDENCIES
|
87
|
+
fast_gettext
|
88
|
+
jeweler
|
89
|
+
rails (~> 3)
|
90
|
+
rake
|
91
|
+
rspec (~> 2)
|
92
|
+
sqlite3
|
@@ -1,32 +1,27 @@
|
|
1
|
-
require
|
2
|
-
|
1
|
+
require "rspec/core/rake_task"
|
2
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
3
|
+
t.rspec_opts = '--backtrace --color'
|
4
|
+
end
|
3
5
|
|
4
|
-
task :
|
5
|
-
|
6
|
-
|
6
|
+
task :rails2 do
|
7
|
+
sh "cd spec/rails2 && RAILS=rails rspec ../../spec"
|
8
|
+
end
|
7
9
|
|
8
|
-
|
9
|
-
|
10
|
-
if ActiveRecord::VERSION::MAJOR >= 3
|
11
|
-
puts `rake spec RSPEC_COLOR=1`
|
12
|
-
else
|
13
|
-
'install rails 3 to get full test coverage...'
|
14
|
-
end
|
10
|
+
task :default do
|
11
|
+
sh "rake spec && rake rails2"
|
15
12
|
end
|
16
13
|
|
17
14
|
begin
|
18
15
|
require 'jeweler'
|
19
|
-
project_name = 'gettext_i18n_rails'
|
20
16
|
Jeweler::Tasks.new do |gem|
|
21
|
-
gem.name =
|
17
|
+
gem.name = 'gettext_i18n_rails'
|
22
18
|
gem.summary = "Simple FastGettext Rails integration."
|
23
19
|
gem.email = "grosser.michael@gmail.com"
|
24
|
-
gem.homepage = "http://github.com/grosser/#{
|
20
|
+
gem.homepage = "http://github.com/grosser/#{gem.name}"
|
25
21
|
gem.authors = ["Michael Grosser"]
|
26
|
-
gem.add_dependency 'fast_gettext'
|
27
22
|
end
|
28
23
|
|
29
24
|
Jeweler::GemcutterTasks.new
|
30
25
|
rescue LoadError
|
31
26
|
puts "Jeweler, or one of its dependencies, is not available. Install it with: sudo gem install jeweler"
|
32
|
-
end
|
27
|
+
end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
[FastGettext](http://github.com/grosser/fast_gettext) / Rails integration.
|
2
|
+
|
3
|
+
Translate via FastGettext, use any other I18n backend as extension/fallback.
|
4
|
+
|
5
|
+
Rails does: `I18n.t('syntax.with.lots.of.dots')` with nested yml files
|
6
|
+
We do: `_('Just translate my damn text!')` with simple, flat mo/po/yml files or directly from db
|
7
|
+
To use I18n calls add a `syntax.with.lots.of.dots` translation.
|
8
|
+
|
9
|
+
[See it working in the example application.](https://github.com/grosser/gettext_i18n_rails_example)
|
10
|
+
|
11
|
+
Setup
|
12
|
+
=====
|
13
|
+
### Installation
|
14
|
+
|
15
|
+
#### Rails 3
|
16
|
+
|
17
|
+
##### As plugin:
|
18
|
+
|
19
|
+
rails plugin install git://github.com/grosser/gettext_i18n_rails.git
|
20
|
+
|
21
|
+
# Gemfile
|
22
|
+
gem 'fast_gettext', '>=0.4.8'
|
23
|
+
|
24
|
+
##### As gem:
|
25
|
+
|
26
|
+
# Gemfile
|
27
|
+
gem 'gettext_i18n_rails'
|
28
|
+
|
29
|
+
##### Optional:
|
30
|
+
If you want to find translations or build .mo files
|
31
|
+
# Gemfile
|
32
|
+
gem 'gettext', '>=1.9.3', :require => false, :group => :development
|
33
|
+
|
34
|
+
#### Rails 2
|
35
|
+
|
36
|
+
##### As plugin:
|
37
|
+
|
38
|
+
script/plugin install git://github.com/grosser/gettext_i18n_rails.git
|
39
|
+
sudo gem install fast_gettext
|
40
|
+
|
41
|
+
# config/environment.rb
|
42
|
+
config.gem "fast_gettext", :version => '>=0.4.8'
|
43
|
+
|
44
|
+
##### As gem:
|
45
|
+
|
46
|
+
gem install gettext_i18n_rails
|
47
|
+
|
48
|
+
# config/environment.rb
|
49
|
+
config.gem 'gettext_i18n_rails'
|
50
|
+
|
51
|
+
#Rakefile
|
52
|
+
begin
|
53
|
+
require "gettext_i18n_rails/tasks"
|
54
|
+
rescue LoadError
|
55
|
+
puts "gettext_i18n_rails is not installed, you probably should run 'rake gems:install' or 'bundle install'."
|
56
|
+
end
|
57
|
+
|
58
|
+
##### Optional:
|
59
|
+
If you want to find translations or build .mo files
|
60
|
+
# config/environments/development.rb
|
61
|
+
config.gem "gettext", :version => '>=1.9.3', :lib => false
|
62
|
+
|
63
|
+
### Locales & initialisation
|
64
|
+
Copy default locales with dates/sentence-connectors/AR-errors you want from e.g.
|
65
|
+
[rails i18n](http://github.com/svenfuchs/rails-i18n/tree/master/rails/locale/) into 'config/locales'
|
66
|
+
|
67
|
+
To initialize:
|
68
|
+
|
69
|
+
# config/initializers/fast_gettext.rb
|
70
|
+
FastGettext.add_text_domain 'app', :path => 'locale', :type => :po
|
71
|
+
FastGettext.default_available_locales = ['en','de'] #all you want to allow
|
72
|
+
FastGettext.default_text_domain = 'app'
|
73
|
+
|
74
|
+
And in your application:
|
75
|
+
|
76
|
+
# app/controllers/application_controller.rb
|
77
|
+
class ApplicationController < ...
|
78
|
+
before_filter :set_gettext_locale
|
79
|
+
|
80
|
+
Translating
|
81
|
+
===========
|
82
|
+
Performance is almost the same for all backends since translations are cached after first use.
|
83
|
+
|
84
|
+
### Option A: .po files
|
85
|
+
|
86
|
+
FastGettext.add_text_domain 'app', :path => 'locale', :type => :po
|
87
|
+
|
88
|
+
- use some _('translations')
|
89
|
+
- run `rake gettext:find`, to let GetText find all translations used
|
90
|
+
- (optional) run `rake gettext:store_model_attributes`, to parse the database for columns that can be translated
|
91
|
+
- if this is your first translation: `cp locale/app.pot locale/de/app.po` for every locale you want to use
|
92
|
+
- translate messages in 'locale/de/app.po' (leave msgstr blank and msgstr == msgid)
|
93
|
+
|
94
|
+
New translations will be marked "fuzzy", search for this and remove it, so that they will be used.
|
95
|
+
Obsolete translations are marked with ~#, they usually can be removed since they are no longer needed
|
96
|
+
|
97
|
+
#### Unfound translations with rake gettext:find
|
98
|
+
Dynamic translations like `_("x"+"u")` cannot be fond. You have 4 options:
|
99
|
+
|
100
|
+
- add `N_('xu')` somewhere else in the code, so the parser sees it
|
101
|
+
- add `N_('xu')` in a totally separate file like `locale/unfound_translations.rb`, so the parser sees it
|
102
|
+
- use the [gettext_test_log rails plugin ](http://github.com/grosser/gettext_test_log) to find all translations that where used while testing
|
103
|
+
- add a Logger to a translation Chain, so every unfound translations is logged ([example]((http://github.com/grosser/fast_gettext)))
|
104
|
+
|
105
|
+
### Option B: Traditional .po/.mo files
|
106
|
+
|
107
|
+
FastGettext.add_text_domain 'app', :path => 'locale'
|
108
|
+
|
109
|
+
- follow Option A
|
110
|
+
- run `rake gettext:pack` to write binary GetText .mo files
|
111
|
+
|
112
|
+
### Option C: Database
|
113
|
+
Most scalable method, all translators can work simultaneously and online.
|
114
|
+
|
115
|
+
Easiest to use with the [translation database Rails engine](http://github.com/grosser/translation_db_engine).
|
116
|
+
Translations can be edited under `/translation_keys`
|
117
|
+
|
118
|
+
FastGettext::TranslationRepository::Db.require_models
|
119
|
+
FastGettext.add_text_domain 'app', :type => :db, :model => TranslationKey
|
120
|
+
|
121
|
+
I18n
|
122
|
+
====
|
123
|
+
I18n.locale <==> FastGettext.locale.to_sym
|
124
|
+
I18n.locale = :de <==> FastGettext.locale = 'de'
|
125
|
+
|
126
|
+
Any call to I18n that matches a gettext key will be translated through FastGettext.
|
127
|
+
|
128
|
+
Namespaces
|
129
|
+
==========
|
130
|
+
Car|Model means Model in namespace Car.
|
131
|
+
You do not have to translate this into english "Model", if you use the
|
132
|
+
namespace-aware translation
|
133
|
+
s_('Car|Model') == 'Model' #when no translation was found
|
134
|
+
|
135
|
+
XSS / html_safe
|
136
|
+
===============
|
137
|
+
If you trust your translators and all your usages of % on translations:<br/>
|
138
|
+
# config/environment.rb
|
139
|
+
GettextI18nRails.translations_are_html_safe = true
|
140
|
+
|
141
|
+
String % vs html_safe is buggy (can be used for XSS on 1.8 and is always non-safe in 1.9)<br/>
|
142
|
+
My recommended fix is: `require 'gettext_i18n_rails/string_interpolate_fix'`
|
143
|
+
|
144
|
+
- safe stays safe (escape added strings)
|
145
|
+
- unsafe stays unsafe (do not escape added strings)
|
146
|
+
|
147
|
+
ActiveRecord - error messages
|
148
|
+
=============================
|
149
|
+
ActiveRecord error messages are translated through Rails::I18n, but
|
150
|
+
model names and model attributes are translated through FastGettext.
|
151
|
+
Therefore a validation error on a BigCar's wheels_size needs `_('big car')` and `_('BigCar|Wheels size')`
|
152
|
+
to display localized.
|
153
|
+
|
154
|
+
The model/attribute translations can be found through `rake gettext:store_model_attributes`,
|
155
|
+
(which ignores some commonly untranslated columns like id,type,xxx_count,...).
|
156
|
+
|
157
|
+
Error messages can be translated through FastGettext, if the ':message' is a translation-id or the matching Rails I18n key is translated.
|
158
|
+
|
159
|
+
####Option A:
|
160
|
+
Define a translation for "I need my rating!" and use it as message.
|
161
|
+
validates_inclusion_of :rating, :in=>1..5, :message=>N_('I need my rating!')
|
162
|
+
|
163
|
+
####Option B:
|
164
|
+
validates_inclusion_of :rating, :in=>1..5
|
165
|
+
Make a translation for the I18n key: `activerecord.errors.models.rating.attributes.rating.inclusion`
|
166
|
+
|
167
|
+
####Option C:
|
168
|
+
Add a translation to each config/locales/*.yml files
|
169
|
+
en:
|
170
|
+
activerecord:
|
171
|
+
errors:
|
172
|
+
models:
|
173
|
+
rating:
|
174
|
+
attributes:
|
175
|
+
rating:
|
176
|
+
inclusion: " -- please choose!"
|
177
|
+
The [rails I18n guide](http://guides.rubyonrails.org/i18n.html) can help with Option B and C.
|
178
|
+
|
179
|
+
Plurals
|
180
|
+
=======
|
181
|
+
FastGettext supports pluralization
|
182
|
+
n_('Apple','Apples',3) == 'Apples'
|
183
|
+
|
184
|
+
Abnormal plurals like e.g. Polish that has 4 different can also be addressed, see [FastGettext Readme](http://github.com/grosser/fast_gettext)
|
185
|
+
|
186
|
+
Customizing list of translatable files
|
187
|
+
======================================
|
188
|
+
When you run
|
189
|
+
|
190
|
+
rake gettext:find
|
191
|
+
|
192
|
+
by default the following files are going to be scanned for translations: {app,lib,config,locale}/**/*.{rb,erb,haml}. If
|
193
|
+
you want to specify a different list, you can redefine files_to_translate in the gettext namespace in a file like
|
194
|
+
lib/tasks/gettext.rake:
|
195
|
+
|
196
|
+
namespace :gettext do
|
197
|
+
def files_to_translate
|
198
|
+
Dir.glob("{app,lib,config,locale}/**/*.{rb,erb,haml,rhtml}")
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
[Contributors](http://github.com/grosser/gettext_i18n_rails/contributors)
|
203
|
+
======
|
204
|
+
- [ruby gettext extractor](http://github.com/retoo/ruby_gettext_extractor/tree/master) from [retoo](http://github.com/retoo)
|
205
|
+
- [Paul McMahon](http://github.com/pwim)
|
206
|
+
- [Duncan Mac-Vicar P](http://duncan.mac-vicar.com/blog)
|
207
|
+
- [Ramihajamalala Hery](http://my.rails-royce.org)
|
208
|
+
- [J. Pablo Fernández](http://pupeno.com)
|
209
|
+
- [Anh Hai Trinh](http://blog.onideas.ws)
|
210
|
+
- [ed0h](http://github.com/ed0h)
|
211
|
+
- [Nikos Dimitrakopoulos](http://blog.nikosd.com)
|
212
|
+
|
213
|
+
[Michael Grosser](http://grosser.it)<br/>
|
214
|
+
grosser.michael@gmail.com<br/>
|
215
|
+
Hereby placed under public domain, do what you want, just do not hold me accountable...
|
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.19
|