kete_translatable_content 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. data/.document +5 -0
  2. data/.gitignore +23 -0
  3. data/LICENSE +295 -0
  4. data/README.rdoc +80 -0
  5. data/README.rdoc.orig +72 -0
  6. data/Rakefile +53 -0
  7. data/VERSION +1 -0
  8. data/app/views/active_scaffold_overrides/_show.html.erb +8 -0
  9. data/app/views/active_scaffold_overrides/_update_form.html.erb +8 -0
  10. data/app/views/active_scaffold_overrides/list.html.erb +5 -0
  11. data/app/views/baskets/_additional_footer_content_fields.html.erb +33 -0
  12. data/app/views/baskets/_rss_feed.html.erb +42 -0
  13. data/app/views/baskets/_side_bar_html.html.erb +19 -0
  14. data/app/views/configure/section.rhtml +36 -0
  15. data/app/views/layouts/translations.html.erb +1 -0
  16. data/app/views/topics/_content_wrapper_start.rhtml +26 -0
  17. data/app/views/translations/_form.html.erb +54 -0
  18. data/app/views/translations/_translatable_value.html.erb +36 -0
  19. data/app/views/translations/_translation_field_input.html.erb +61 -0
  20. data/app/views/translations/show.html.erb +12 -0
  21. data/app/views/translations/versioned_edit.html.erb +9 -0
  22. data/config/locales/en.yml +51 -0
  23. data/config/routes.rb +11 -0
  24. data/config/translatables.yml +65 -0
  25. data/generators/kete_translatable_content_migration/USAGE +2 -0
  26. data/generators/kete_translatable_content_migration/kete_translatable_content_migration_generator.rb +7 -0
  27. data/generators/kete_translatable_content_migration/templates/migration.rb +82 -0
  28. data/generators/kete_translatable_content_tests/USAGE +2 -0
  29. data/generators/kete_translatable_content_tests/kete_translatable_content_tests_generator.rb +38 -0
  30. data/generators/kete_translatable_content_tests/templates/configure_kete_content_translation_controller_and_routes_test.rb +48 -0
  31. data/generators/kete_translatable_content_tests/templates/configure_kete_content_translation_test.rb +47 -0
  32. data/generators/kete_translatable_content_tests/templates/kete_translatable_content_helper_test.rb +19 -0
  33. data/generators/kete_translatable_content_tests/templates/kete_translatable_content_migration_test.rb +45 -0
  34. data/generators/kete_translatable_content_tests/templates/kete_translatable_content_oai_dc_helpers_test.rb +66 -0
  35. data/generators/kete_translatable_content_tests/templates/kete_translatable_content_translations_test.rb +23 -0
  36. data/generators/kete_translatable_content_tests/templates/kete_translations_test.rb +57 -0
  37. data/generators/kete_translatable_content_tests/templates/mongo_factories.rb +6 -0
  38. data/generators/kete_translatable_content_tests/templates/mongo_test_helper.rb +37 -0
  39. data/generators/kete_translatable_content_tests/templates/mongo_translatable_test.rb +262 -0
  40. data/lib/kete_translatable_content.rb +54 -0
  41. data/lib/kete_translatable_content/extensions/controllers/application_controller.rb +202 -0
  42. data/lib/kete_translatable_content/extensions/controllers/audio_controller.rb +7 -0
  43. data/lib/kete_translatable_content/extensions/controllers/baskets_controller.rb +3 -0
  44. data/lib/kete_translatable_content/extensions/controllers/documents_controller.rb +7 -0
  45. data/lib/kete_translatable_content/extensions/controllers/images_controller.rb +7 -0
  46. data/lib/kete_translatable_content/extensions/controllers/topics_controller.rb +7 -0
  47. data/lib/kete_translatable_content/extensions/controllers/translations_controller.rb +209 -0
  48. data/lib/kete_translatable_content/extensions/controllers/video_controller.rb +7 -0
  49. data/lib/kete_translatable_content/extensions/controllers/web_links_controller.rb +7 -0
  50. data/lib/kete_translatable_content/extensions/extended_content_translation.rb +54 -0
  51. data/lib/kete_translatable_content/extensions/helpers/application_helper.rb +156 -0
  52. data/lib/kete_translatable_content/extensions/helpers/extended_fields_helper.rb +17 -0
  53. data/lib/kete_translatable_content/extensions/helpers/search_helper.rb +5 -0
  54. data/lib/kete_translatable_content/extensions/helpers/translations_helper.rb +72 -0
  55. data/lib/kete_translatable_content/extensions/models/audio_recording.rb +12 -0
  56. data/lib/kete_translatable_content/extensions/models/basket.rb +34 -0
  57. data/lib/kete_translatable_content/extensions/models/comment.rb +12 -0
  58. data/lib/kete_translatable_content/extensions/models/document.rb +12 -0
  59. data/lib/kete_translatable_content/extensions/models/still_image.rb +12 -0
  60. data/lib/kete_translatable_content/extensions/models/system_setting.rb +13 -0
  61. data/lib/kete_translatable_content/extensions/models/tag.rb +37 -0
  62. data/lib/kete_translatable_content/extensions/models/topic.rb +12 -0
  63. data/lib/kete_translatable_content/extensions/models/user.rb +36 -0
  64. data/lib/kete_translatable_content/extensions/models/video.rb +12 -0
  65. data/lib/kete_translatable_content/extensions/models/web_link.rb +12 -0
  66. data/lib/kete_translatable_content/extensions/oai_dc_helpers_overrides.rb +99 -0
  67. data/lib/kete_translatable_content/extensions/tagging_controller_overrides.rb +21 -0
  68. data/lib/kete_translatable_content/extensions/tagging_overrides.rb +27 -0
  69. data/lib/kete_translatable_content/extensions/tinymce_controller_valid_action_override.rb +16 -0
  70. data/lib/kete_translatable_content/extensions/translation_from_version.rb +105 -0
  71. data/lib/kete_translatable_content/kete.rb +25 -0
  72. data/lib/kete_translatable_content/overwrites/oai_dc_helpers_test.rb +6 -0
  73. data/rails/init.rb +110 -0
  74. metadata +156 -0
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+
3
+ # test that the translations for each model are available (so when
4
+ # new translatable fields are added, it doesn't have missing strings)
5
+ class KeteTranslatableContentTranslationsTest < ActiveSupport::TestCase
6
+
7
+ Kete.translatables.each do |name, attributes|
8
+
9
+ context "The #{name.humanize} translatable" do
10
+
11
+ attributes['translatable_attributes'].each do |attr|
12
+
13
+ should "have a translation for #{attr}" do
14
+ assert I18n.t("#{name.pluralize}.form.#{attr}") !~ /translation missing/
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,57 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.dirname(__FILE__) + '/integration_test_helper'
3
+
4
+ def translate_for_locales(record, *locales)
5
+ locales.each do |locale|
6
+ visit "/en/site/#{record.class.name.pluralize.downcase}/#{record.id}/translations/new?to_locale=#{locale}"
7
+ click_button 'Create'
8
+ assert_contain 'Translation was successfully created.'
9
+ end
10
+ end
11
+
12
+ # simulate languages available without actually making them
13
+ def I18n.available_locales_with_labels; { 'en' => 'English', 'fr' => 'Français', 'zh' => '中文' }; end
14
+ TranslationsHelper.available_locales = I18n.available_locales_with_labels
15
+ def I18n.available_locales; I18n.available_locales_with_labels.keys; end
16
+ RoutingFilter::Locale.locales = I18n.available_locales
17
+
18
+ class KeteTranslationsTest < ActionController::IntegrationTest
19
+
20
+ context "A translatable basket" do
21
+
22
+ include Webrat::HaveTagMatcher
23
+
24
+ setup do
25
+ add_admin_as_super_user
26
+ login_as('admin')
27
+
28
+ # create_new_basket is a method in Kete's integration helpers to create
29
+ # the basket, and remove it when tests are run (so each test has a clean
30
+ # environment)
31
+ @basket = create_new_basket :name => 'Translatable Basket'
32
+ end
33
+
34
+ should "have links to locales needing translation on its show page" do
35
+ visit "/en/#{@basket.urlified_name}/baskets/edit/#{@basket.id}"
36
+ assert_contain "Needs translating to"
37
+ assert_have_tag "a", :href => "/en/#{@basket.urlified_name}/baskets/#{@basket.id}/translations/new?to_locale=zh", :content => "中文"
38
+ end
39
+
40
+ context "that has been previously translated" do
41
+
42
+ setup do
43
+ translate_for_locales(@basket, :zh)
44
+ end
45
+
46
+ should "have locales that have been translated on its show page" do
47
+ url_stub = "#{@basket.urlified_name}/baskets/edit/#{@basket.id}"
48
+ visit "/en/#{url_stub}"
49
+ assert_have_tag "li", :content => "Français"
50
+ assert_have_tag "a", :href => "/zh/#{url_stub}", :content => "中文"
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,6 @@
1
+ #Usings topic types because they are translatable and have multiple fields
2
+ Factory.define :topic_type do |t|
3
+ #make the name random. should install faker, but only need this one.
4
+ t.sequence(:name){ |n| "name#{n}"}
5
+ t.description 'spam'
6
+ end
@@ -0,0 +1,37 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/mongo_factories")
2
+
3
+
4
+ LOCALE_LABELS = { :en => "a label",
5
+ :ar => "Ar_lable",
6
+ :fi => "fi_lable",
7
+ :fr => "fr_label",
8
+ :zh => "zh_label"}
9
+
10
+ ALL_TRANSLATION_LOCALE_KEYS_EXCEPT_EN = LOCALE_LABELS.keys - [:en]
11
+
12
+ MongoMapper.database = 'test'
13
+
14
+ def translate_topic_type_for_locales(topic_type, locales)
15
+ create_translations_for(topic_type, [:name], locales)
16
+ end
17
+
18
+ def create_translations_for(item, attrs_to_mock = [:title], locales = nil)
19
+ original_locale = I18n.locale
20
+
21
+ locales ||= ALL_TRANSLATION_LOCALE_KEYS_EXCEPT_EN
22
+ locales = [locales] unless locales.is_a?(Array)
23
+ locales.each do |locale|
24
+ I18n.locale = locale
25
+
26
+ attrs = Hash.new
27
+ attrs_to_mock.each do |attr_sym|
28
+ attrs[attr_sym] = LOCALE_LABELS[locale]
29
+ end
30
+
31
+ item.translate(attrs).save
32
+ end
33
+
34
+ I18n.locale = original_locale
35
+ end
36
+
37
+
@@ -0,0 +1,262 @@
1
+ # -*- coding: utf-8 -*-
2
+ require 'test_helper'
3
+ require 'mongo_test_helper'
4
+
5
+ class MongodbTranslatableTest < ActiveSupport::TestCase
6
+ context "A translation" do
7
+ setup do
8
+ I18n.locale = I18n.default_locale
9
+
10
+ @topic_type = Factory.create(:topic_type)
11
+
12
+ topic_type_hash = Hash.new
13
+ topic_type_hash[:name] = @topic_type.attributes['name']
14
+ topic_type_hash[:locale] = :fr
15
+ topic_type_hash[@topic_type.class.as_foreign_key_sym] = @topic_type.id
16
+ @translation = @topic_type.class::Translation.create(topic_type_hash)
17
+ end
18
+
19
+ should "have a locale" do
20
+ if assert(@translation.respond_to?(:locale))
21
+ assert @translation.locale
22
+ end
23
+ end
24
+
25
+ should "have a translated object's translated attributes" do
26
+ assert @translation.attributes[TopicType.translatable_attributes.first]
27
+ end
28
+
29
+ should "be accessable from its topic_type" do
30
+ if assert(@topic_type.respond_to?(:translations))
31
+ assert @topic_type.translation_for(I18n.locale)
32
+ end
33
+ end
34
+
35
+ should "be able to retrieve just the translated attribute" do
36
+ if assert(@topic_type.respond_to?(:translations) && @topic_type.respond_to?(:name_translation_for))
37
+ assert @topic_type.name_translation_for(I18n.locale)
38
+ end
39
+ end
40
+
41
+ should "be able to retrieve its topic_type from the topic_type's persistence" do
42
+ assert @translation.translatable
43
+ end
44
+ end
45
+
46
+ context "When there is an TopicType needing translating" do
47
+ setup do
48
+ @topic_type = Factory.create(:topic_type, { :name => LOCALE_LABELS[:en] })
49
+ end
50
+
51
+ #Create id 1
52
+ should "create translation" do
53
+ translate_topic_type_for_locales(@topic_type, :zh)
54
+ assert @topic_type.translations.count == 1
55
+ end
56
+
57
+ should "not create translation if no translated text submitted" do
58
+ # arabic
59
+ I18n.locale = :ar
60
+ @topic_type.translate
61
+ assert @topic_type.translations.count == 0
62
+ end
63
+
64
+ should "not create translation if topic_type's original_locale is same as translation locale" do
65
+ I18n.locale = :en
66
+ @topic_type.translate(:name => LOCALE_LABELS[:en])
67
+ assert @topic_type.translations.count == 0
68
+ end
69
+
70
+ should "create translation and it should reflect current locale" do
71
+ # french
72
+ translate_topic_type_for_locales(@topic_type, :fr)
73
+ assert @topic_type.translation_for(:fr)
74
+ end
75
+
76
+ should "find topic_type with the proper translation for current locale" do
77
+ translate_topic_type_for_locales(@topic_type, :fi)
78
+
79
+ I18n.locale = :fi
80
+ # reloading topic_type should detect current locale and pass back translated version of object
81
+ @topic_type = TopicType.find(@topic_type.id)
82
+
83
+ assert_equal @topic_type.name, LOCALE_LABELS[:fi]
84
+ end
85
+
86
+ should "find topic_type with the proper translation for current locale and fallback to original's description for translatable attribute that hasn't been translated" do
87
+ translate_topic_type_for_locales(@topic_type, :fi)
88
+
89
+ original_description = @topic_type.description
90
+
91
+ I18n.locale = :fi
92
+ # reloading topic_type should detect current locale and pass back translated version of object
93
+ @topic_type = TopicType.find(@topic_type.id)
94
+
95
+ assert_equal @topic_type.name, LOCALE_LABELS[:fi]
96
+ assert_equal original_description, @topic_type.description
97
+ end
98
+
99
+ should "find topic_type with the proper translation for current locale when there is more than one translation" do
100
+ # add a couple translations
101
+ translate_topic_type_for_locales(@topic_type, [:fi, :fr])
102
+
103
+ # then back to finnish
104
+ I18n.locale = :fi
105
+
106
+ # reloading topic_type should detect current locale and pass back translated version of object
107
+ @topic_type = TopicType.find(@topic_type.id)
108
+
109
+ assert_equal @topic_type.name, LOCALE_LABELS[:fi]
110
+ end
111
+
112
+ # test dynamic finder
113
+ should "find topic_type with the proper translation for current locale when there is more than one translation and finding using dynamic finder" do
114
+ @topic_type = Factory.create(:topic_type, {:description => "a description"})
115
+
116
+ # add a couple translations
117
+ translate_topic_type_for_locales(@topic_type, [:fi, :fr])
118
+
119
+ # then back to finnish
120
+ I18n.locale = :fi
121
+
122
+ # reloading topic_type should detect current locale and pass back translated version of object
123
+ @topic_type = TopicType.find_by_description(@topic_type.description)
124
+
125
+ assert_equal @topic_type.name, LOCALE_LABELS[:fi]
126
+ end
127
+
128
+ should "after creating translations, if the topic_type is destroyed, the translations are destroyed" do
129
+ # add a couple translations
130
+ translate_topic_type_for_locales(@topic_type, [:fi, :fr])
131
+
132
+ translations_ids = @topic_type.translations.collect { |translation| translation.id }
133
+
134
+ @topic_type.destroy
135
+
136
+ remaining_translations = TopicType::Translation.find(translations_ids)
137
+
138
+ assert_equal 0, remaining_translations.size
139
+ end
140
+
141
+ should "when the topic_type is destroyed, when it has no translations, it should succeed in being destroyed" do
142
+ assert_equal 0, @topic_type.translations.size
143
+ assert @topic_type.destroy
144
+ end
145
+
146
+ teardown do
147
+ I18n.locale = @original_locale
148
+ @topic_type.destroy if @topic_type
149
+ end
150
+ end
151
+
152
+ context "When there are many topic_types being translated" do
153
+ setup do
154
+ # TODO: pull out this locale, not sure why before_save filter is not being called
155
+ @original_locale = I18n.locale
156
+ end
157
+
158
+ should "find topic_types with the proper translation for current locale" do
159
+ ids = many_setup
160
+
161
+ # reloading topic_type should detect current locale and pass back translated version of object
162
+ @topic_types = TopicType.find(ids)
163
+
164
+ many_tests
165
+ end
166
+
167
+ should "find topic_types with the proper translation for current locale using dynamic finder" do
168
+ description = "a description"
169
+ many_setup({:description => description})
170
+
171
+ # reloading topic_type should detect current locale and pass back translated version of object
172
+ @topic_types = TopicType.find_all_by_description(description)
173
+
174
+ many_tests(:fi => 10)
175
+ end
176
+
177
+ teardown do
178
+ I18n.locale = @original_locale
179
+ @topic_type.destroy if @topic_type
180
+ end
181
+ end
182
+
183
+ context "translations for an topic_type" do
184
+ setup do
185
+ I18n.locale = I18n.default_locale
186
+ @topic_type = Factory.create(:topic_type)
187
+ @translation_keys = LOCALE_LABELS.keys - [:en]
188
+ translate_topic_type_for_locales(@topic_type, @translation_keys)
189
+ end
190
+
191
+ should "be retrievable from translations method" do
192
+ assert_equal @translation_keys.size, @topic_type.translations.size
193
+ end
194
+
195
+ should "hae just locales be retrievable from translations_locales method" do
196
+ # these should be partial objects and not have any descriptions for other attributes
197
+ locale_keys = @topic_type.translations_locales.collect { |translation| translation.locale.to_sym if translation.name.nil? }.compact
198
+
199
+ assert_equal 0, (@translation_keys - locale_keys).size
200
+ end
201
+
202
+ should "have translation locales plus original local be retrievable as available_in_these_locales" do
203
+ locale_keys = @topic_type.available_in_these_locales.collect { |locale| locale.to_sym }
204
+
205
+ assert_equal 0, ( ([:en] + @translation_keys) - locale_keys ).size
206
+ end
207
+
208
+ should "have needed_in_these_locales method that returns locales that haven't been translated yet" do
209
+ TopicType::Translation.first(:topic_type_id => @topic_type.id, :locale => "zh").destroy
210
+ assert_equal [:zh], @topic_type.needed_in_these_locales.collect { |locale| locale.to_sym }
211
+ end
212
+
213
+ teardown do
214
+ I18n.locale = @original_locale
215
+ @topic_type.destroy if @topic_type
216
+ end
217
+ end
218
+
219
+
220
+
221
+ private
222
+
223
+ # see many_tests for what it expects
224
+ def many_setup(topic_type_spec = nil)
225
+ ids = Array.new
226
+ 5.times do
227
+ I18n.locale = @original_locale
228
+ topic_type = topic_type_spec ? Factory.create(:topic_type, topic_type_spec) : Factory.create(:topic_type)
229
+ translate_topic_type_for_locales(topic_type, [:ar, :fr])
230
+ ids << topic_type.id
231
+ end
232
+
233
+ 5.times do
234
+ I18n.locale = @original_locale
235
+ topic_type = topic_type_spec ? Factory.create(:topic_type, topic_type_spec) : Factory.create(:topic_type)
236
+ translate_topic_type_for_locales(topic_type, [:zh, :fi])
237
+ ids << topic_type.id
238
+ end
239
+
240
+ # excluding these from ids searched
241
+ 5.times do
242
+ I18n.locale = @original_locale
243
+ topic_type = topic_type_spec ? Factory.create(:topic_type, topic_type_spec) : Factory.create(:topic_type)
244
+ translate_topic_type_for_locales(topic_type, [:fr, :fi])
245
+ end
246
+
247
+ I18n.locale = :fi
248
+ ids
249
+ end
250
+
251
+ # expect 5 en, 5 finnish, and none in french, chinese, or arabic
252
+ def many_tests(passed_amounts = { })
253
+ results_number_for = { :fi => 5, :en => 5, :fr => 0, :ar => 0, :zh => 0}
254
+ results_number_for.merge!(passed_amounts)
255
+
256
+ assert_equal results_number_for[:fi], @topic_types.select { |i| i.locale.to_sym == :fi }.size
257
+ assert_equal results_number_for[:en], @topic_types.select { |i| i.locale.to_sym == :en }.size
258
+ assert_equal results_number_for[:fr], @topic_types.select { |i| i.locale.to_sym == :fr }.size
259
+ assert_equal results_number_for[:ar], @topic_types.select { |i| i.locale.to_sym == :ar }.size
260
+ assert_equal results_number_for[:zh], @topic_types.select { |i| i.locale.to_sym == :zh }.size
261
+ end
262
+ end
@@ -0,0 +1,54 @@
1
+ # Keep this file are bare as possible as it is used in migrations and routes
2
+ # and does not need to pull in mongo libs or adjust view paths. Such code
3
+ # should be done in ../rails/init.rb
4
+
5
+ require 'kete_translatable_content/kete'
6
+
7
+ Kete.define_reader_method_as('translatables',
8
+ YAML.load(IO.read(File.join(File.dirname(__FILE__), '../config/translatables.yml'))))
9
+
10
+ Kete.define_reader_method_as('translatable_system_settings', ['Pretty Site Name',
11
+ 'Flagging Tags',
12
+ 'Download Warning',
13
+ 'Blank Title',
14
+ 'Pending Flag',
15
+ 'Rejected Flag',
16
+ 'Blank Flag',
17
+ 'Reviewed Flag',
18
+ 'No Public Version Title',
19
+ 'No Public Version Description',
20
+ 'Government Website',
21
+ 'Default Page Keywords',
22
+ 'Default Page Description',
23
+ 'Additional Credits HTML',
24
+ 'Restricted Flag'
25
+ ])
26
+
27
+ Kete.define_reader_method_as('translatable_configurable_settings',
28
+ ['additional_footer_content'])
29
+
30
+ Kete.define_reader_method_as('translatable_tiny_mce_options', {
31
+ :width => '390',
32
+ :theme => 'advanced',
33
+ :theme_advanced_toolbar_location => "top",
34
+ :theme_advanced_toolbar_align => "left",
35
+ :theme_advanced_statusbar_location => "bottom",
36
+ :theme_advanced_buttons1 => %w{ bold italic underline strikethrough separator justifyleft justifycenter justifyright justifyfull separator indent outdent separator bullist numlist separator link unlink image },
37
+ :theme_advanced_buttons2 => %w{ formatselect fontselect fontsizeselect separator forecolor backcolor separator undo redo },
38
+ :theme_advanced_buttons3 => %w{ tablecontrols separator fullscreen separator code },
39
+ :theme_advanced_resizing => true,
40
+ :theme_advanced_resize_horizontal => false,
41
+ :convert_urls => false,
42
+ :content_css => "/stylesheets/base.css",
43
+ :plugins => %w{ table fullscreen paste }
44
+ })
45
+
46
+ def kete_translatable_content_ready?
47
+ kete_translatable_content_ready = true
48
+ Kete.translatables.keys.each do |name|
49
+ translatable = name.camelize.constantize.send(:new) rescue false
50
+ kete_translatable_content_ready = translatable && translatable.respond_to?(:original_locale)
51
+ break if kete_translatable_content_ready == false
52
+ end
53
+ kete_translatable_content_ready
54
+ end
@@ -0,0 +1,202 @@
1
+ ApplicationController.class_eval do
2
+
3
+ def kete_translatable_content?
4
+ controller, controller_as_key, action = params[:controller], params[:controller].singularize, params[:action]
5
+
6
+ translatable = Kete.translatables[controller_as_key]
7
+ return true if translatable && (translatable['views'] || []).include?(action)
8
+
9
+ # for some translatables, the controller is different than (or in addition to) its key.pluralized
10
+ !!Kete.translatables.find { |t|
11
+ (t.last['controllers'] || []).include?(controller) && (t.last['views'] || []).include?(action)
12
+ }
13
+ end
14
+ helper_method :kete_translatable_content?
15
+
16
+ def current_translatable_record
17
+ key = case params[:controller]
18
+ when 'images'
19
+ 'still_image'
20
+ when 'audio'
21
+ 'audio_recording'
22
+ else
23
+ params[:controller].singularize
24
+ end
25
+
26
+ instance_variable_get('@' + key) || @item || @record || key.camelize.constantize.find(params[:id])
27
+ end
28
+ helper_method :current_translatable_record
29
+
30
+ before_filter :reload_standard_baskets
31
+ def reload_standard_baskets
32
+ Rails.logger.debug "[Kete Translatable Content]: Reloading Standard Baskets to be locale aware"
33
+ [@site_basket, @help_basket, @about_basket, @documentation_basket].each { |b| b.reload }
34
+ end
35
+
36
+ before_filter :redirect_unless_editing_original_locale, :only => ['edit', 'section', 'appearance', 'homepage_options']
37
+ def redirect_unless_editing_original_locale
38
+ action = params[:action]
39
+ editing_actions = ['edit', 'section', 'appearance', 'homepage_options']
40
+ if kete_translatable_content? && editing_actions.include?(action)
41
+ # check to see if we are in the special case for system settings
42
+ if action == 'section' && I18n.locale.to_sym != I18n.default_locale.to_sym
43
+ flash[:error] = I18n.t('kete_translatable.only_edit_original_locale')
44
+ I18n.locale = I18n.default_locale
45
+ return true
46
+ elsif action != 'section'
47
+ # handle everything else
48
+ translated = current_translatable_record
49
+ if I18n.locale.to_sym != translated.original_locale.to_sym
50
+ flash[:error] = I18n.t('kete_translatable.only_edit_original_locale')
51
+ redirect_to params.merge(:locale => translated.original_locale)
52
+ return false
53
+ end
54
+ end
55
+ end
56
+ true
57
+ end
58
+
59
+ # override mongo_translatable's target_locale locally
60
+ # because we only allow editing of the original locale (see redirect_unless_editing_original_locale)
61
+ # make sure we redirect to a locale the user has access to after translations are created or saved
62
+ def target_locale(options = {})
63
+ translation = options.delete(:translation) || @translation
64
+ translated = @translated || @translatable
65
+ override_locale = translated.original_locale if translated
66
+ override_locale || options.delete(:locale) || (translation.locale if translation) || I18n.locale
67
+ end
68
+
69
+ # override mongo_translatable's target_controller locally
70
+ # some kete translatables don't fall back under their own controller
71
+ def target_controller(options = {})
72
+ controller = options.delete(:controller)
73
+ if controller.nil?
74
+ key = options.delete(:translatable_params_name) || @translatable_params_name
75
+ if Kete.translatables[key] && Kete.translatables[key]['controllers'].present?
76
+ controller = Kete.translatables[key]['controllers'].first
77
+ else
78
+ controller = key.pluralize
79
+ end
80
+ end
81
+
82
+ if controller == 'tags'
83
+ if session[:original_item_return_to] && params[:action] == 'create'
84
+ url_parts = session[:original_item_return_to].split('/')
85
+ matching_parts = url_parts.select { |part| item_controllers.include?(part) }
86
+ controller = matching_parts.first
87
+ end
88
+ end
89
+
90
+ controller
91
+ end
92
+
93
+ # override mongo_translatable's target_action locally
94
+ # some kete translatables don't fall back under their own action
95
+ def target_action(options = {})
96
+ translated = options.delete(:translated) || @translated || options.delete(:translatable) || @translatable
97
+
98
+ case translated.class.name
99
+ when 'SystemSetting' then 'index'
100
+ when 'Feed' then 'homepage_options'
101
+ when 'ConfigurableSetting'
102
+ case translated.configurable_type
103
+ when 'Basket'
104
+ 'appearance'
105
+ end
106
+ else
107
+ key = translated.class.name.tableize.singularize
108
+ if Kete.translatables[key] && Kete.translatables[key]['views'].present?
109
+ Kete.translatables[key]['views'].first
110
+ else
111
+ options.delete(:action) || params[:action]
112
+ end
113
+ end
114
+ end
115
+
116
+ # override mongo_translatable's target_id locally
117
+ # some kete translatables don't fall back under their own id
118
+ def target_id(options = {})
119
+ translated = options.delete(:translated) || @translated || options.delete(:translatable) || @translatable
120
+
121
+ case translated.class.name
122
+ when 'SystemSetting' then nil
123
+ when 'Feed' then translated.basket_id
124
+ when 'ConfigurableSetting' then translated.configurable_id
125
+ when 'Tag'
126
+ if session[:original_item_return_to] && params[:action] == 'create'
127
+ id_segment = session[:original_item_return_to].split('/').last
128
+ id = id_segment.include?('?') ? id_segment.split('?').first : id_segment
129
+ else
130
+ options.delete(:id) || translated
131
+ end
132
+ else
133
+ options.delete(:id) || translated
134
+ end
135
+ end
136
+
137
+ alias_method(:oai_dc_first_element_for_orig, :oai_dc_first_element_for) unless self.new.respond_to?(:oai_dc_first_element_for_orig)
138
+ # we override to get the current locale's specific field value
139
+ # if available
140
+ def oai_dc_first_element_for(field_name, oai_dc)
141
+ first_field_element = oai_dc.xpath(".//dc:#{field_name}[@xml:lang=\"#{I18n.locale}\"]",
142
+ "xmlns:dc" => "http://purl.org/dc/elements/1.1/").first
143
+
144
+ # we have a match for the locale, we're done
145
+ return first_field_element if first_field_element.present?
146
+
147
+ # no match, return first match without lang specified
148
+ oai_dc.xpath(".//dc:#{field_name}",
149
+ "xmlns:dc" => "http://purl.org/dc/elements/1.1/").first
150
+ end
151
+
152
+ before_filter :set_original_item_return_to, :only => :show
153
+ def set_original_item_return_to
154
+ if item_controllers.include?(params[:controller])
155
+ session[:original_item_return_to] = request.request_uri
156
+ end
157
+ end
158
+
159
+ before_filter :add_locale_to_attributes_in_params, :only => [:create, :update]
160
+
161
+ def add_locale_to_attributes_in_params
162
+ # only relevant to Kete.translatables
163
+ # return true if not Kete.translatables
164
+ params_attributes_key = nil
165
+ Kete.translatables.keys.each do |key|
166
+ if params.keys.include?(key)
167
+ params_attributes_key = key.to_sym
168
+ break
169
+ end
170
+ end
171
+
172
+ return true unless params_attributes_key
173
+
174
+ if params[params_attributes_key].present? &&
175
+ params[params_attributes_key][:locale].blank?
176
+ params[params_attributes_key][:locale] = I18n.locale
177
+ end
178
+ true
179
+ end
180
+
181
+ private :add_locale_to_attributes_in_params
182
+
183
+ # modified to delete all locales' caches
184
+ def expire_fragment_for_all_versions(item, name = {})
185
+ name = name.merge(:id => item.id)
186
+ file_path = "#{RAILS_ROOT}/tmp/cache/#{fragment_cache_key(name).gsub(/(\?|:)/, '.')}.cache"
187
+
188
+ possible_locales = item.respond_to?(:available_in_these_locales) ? item.available_in_these_locales : TranslationsHelper::available_locales.keys
189
+
190
+ starting_locale = possible_locales.select { |locale| file_path.include?("\/#{locale}\/") }.first
191
+
192
+ possible_locales.each do |locale|
193
+ with_locale_file_path = file_path
194
+
195
+ with_locale_file_path = file_path.sub("\/#{starting_locale}\/", "\/#{locale}\/") unless starting_locale == locale
196
+
197
+ File.delete(with_locale_file_path) if File.exists?(with_locale_file_path)
198
+ end
199
+
200
+ end
201
+
202
+ end