kete_translatable_content 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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