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,17 @@
1
+ # we only override specific extended field uses for translation
2
+ # rather than overriding find
3
+ ExtendedFieldsHelper.module_eval do
4
+ def label_show_column(extended_field)
5
+ translated_label = extended_field.label_translation_for(I18n.locale) || extended_field.label
6
+ h(translated_label)
7
+ end
8
+
9
+ def example_show_column(extended_field)
10
+ translated_example = extended_field.example_translation_for(I18n.locale) || extended_field.example
11
+ h(translated_example)
12
+ end
13
+
14
+ def extended_field_example(extended_field)
15
+ example_show_column(extended_field)
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ SearchHelper.module_eval do
2
+ def tag_show_link_options(tag)
3
+ { :title => t('search_helper.tag_show_link_options.title_with_translations', :tag_name => tag.name) }
4
+ end
5
+ end
@@ -0,0 +1,72 @@
1
+ TranslationsHelper.module_eval do
2
+ def modify_translation_value(value, original_object)
3
+ if original_object.class == ConfigurableSetting
4
+ YAML.load(value)
5
+ else
6
+ value
7
+ end
8
+ end
9
+
10
+ def localized_label_for(attribute_key)
11
+ @localized_labels ||= Hash.new
12
+ return @localized_labels[attribute_key] if @localized_labels[attribute_key].present?
13
+
14
+ extended_content_keys = nil
15
+ if @original.respond_to?('extended_content_pairs')
16
+ extended_content_keys = @original.extended_content_pairs.collect { |p| p[0] }
17
+ end
18
+
19
+ if extended_content_keys &&
20
+ (extended_content_keys.include?(attribute_key.to_s) ||
21
+ extended_content_keys.include?(attribute_key.to_s + '_multiple'))
22
+
23
+ ef = ExtendedField.find(:first,
24
+ :conditions => ExtendedField.clauses_for_has_label_that_matches(attribute_key))
25
+
26
+ @localized_labels[attribute_key] = display_label_for(ef)
27
+ else
28
+ form_key = '.' + 'form' + '.'
29
+
30
+ if ITEM_CLASSES.include?(@translatable_class.name)
31
+ form_key = 'topics' + form_key
32
+ else
33
+ form_key = @translatable_class.name.tableize + form_key
34
+ end
35
+
36
+ @localized_labels[attribute_key] = t(form_key + attribute_key.to_s)
37
+ end
38
+
39
+ @localized_labels[attribute_key]
40
+ end
41
+
42
+ %w{untranslated translated}.each do |term|
43
+ name = term + '_values_with_localized_labels'
44
+ define_method(name) do
45
+ set_original
46
+ raise "No object supplied to translate." if @original.blank?
47
+ raise "No matching translation available." if term == 'translated' && @translation.blank?
48
+
49
+ existing_value = instance_variable_get('@' + name)
50
+ return existing_value if existing_value.present?
51
+
52
+ new_value = @original.translatable_attributes.collect do |attribute_key|
53
+ attribute_key = check_for_value_hash(attribute_key)
54
+ value = (term == 'untranslated') ? @original.send(attribute_key) : @translation[attribute_key]
55
+ { :attribute_key => attribute_key,
56
+ :localized_label => localized_label_for(attribute_key),
57
+ :value => modify_translation_value(value, @original) }
58
+ end
59
+
60
+ instance_variable_set('@' + name, new_value)
61
+ end
62
+ end
63
+
64
+ def check_for_value_hash(value)
65
+ if value.is_a?(Hash) && value.keys.include?('value') && value.keys.include?('label')
66
+ value["label"]
67
+ else
68
+ value
69
+ end
70
+ end
71
+
72
+ end
@@ -0,0 +1,12 @@
1
+ # extensions to the kete audio recording model
2
+
3
+ # instantiate the model in Kete before reopening it below
4
+ AudioRecording
5
+
6
+ require File.join(File.dirname(__FILE__), '../tagging_overrides')
7
+ require File.join(File.dirname(__FILE__), '../oai_dc_helpers_overrides')
8
+
9
+ class AudioRecording
10
+ include TaggingOverrides
11
+ include OaiDcHelpersOverrides
12
+ end
@@ -0,0 +1,34 @@
1
+ # extensions to the kete basket model
2
+
3
+ # require the model in Kete before reopening it below
4
+ Basket
5
+
6
+ class Basket
7
+ def self.list_as_names_and_urlified_names
8
+ basket_list = Array.new
9
+ all(:select => 'id, name, urlified_name, locale, original_locale').each do |basket|
10
+ translated_name = basket.name_translation_for(I18n.locale) || basket.name
11
+ basket_list << [translated_name, basket.urlified_name]
12
+ end
13
+ basket_list
14
+ end
15
+
16
+ def additional_footer_content_with_inheritance
17
+ value = parsed_value_from(self._configurable_settings.find_by_name('additional_footer_content'))
18
+ value ||= parsed_value_from(self.site_basket._configurable_settings.find_by_name('additional_footer_content'))
19
+ value
20
+ end
21
+
22
+ private
23
+
24
+ def parsed_value_from(setting)
25
+ if setting
26
+ # Original translation values will come back as YAML, but translations are just strings
27
+ value = (setting.original_locale == setting.locale) ? YAML.load(setting.value) : setting.value
28
+ # If the value is blank, return nil, else return the value
29
+ value.to_s.squish.present? ? value : nil
30
+ else
31
+ nil
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,12 @@
1
+ # extensions to the kete comment model
2
+
3
+ # require the model in Kete before reopening it below
4
+ Comment
5
+
6
+ require File.join(File.dirname(__FILE__), '../tagging_overrides')
7
+ require File.join(File.dirname(__FILE__), '../oai_dc_helpers_overrides')
8
+
9
+ class Comment
10
+ include TaggingOverrides
11
+ include OaiDcHelpersOverrides
12
+ end
@@ -0,0 +1,12 @@
1
+ # extensions to the kete document model
2
+
3
+ # require the model in Kete before reopening it below
4
+ Document
5
+
6
+ require File.join(File.dirname(__FILE__), '../tagging_overrides')
7
+ require File.join(File.dirname(__FILE__), '../oai_dc_helpers_overrides')
8
+
9
+ class Document
10
+ include TaggingOverrides
11
+ include OaiDcHelpersOverrides
12
+ end
@@ -0,0 +1,12 @@
1
+ # extensions to the kete still image model
2
+
3
+ # require the model in Kete before reopening it below
4
+ StillImage
5
+
6
+ require File.join(File.dirname(__FILE__), '../tagging_overrides')
7
+ require File.join(File.dirname(__FILE__), '../oai_dc_helpers_overrides')
8
+
9
+ class StillImage
10
+ include TaggingOverrides
11
+ include OaiDcHelpersOverrides
12
+ end
@@ -0,0 +1,13 @@
1
+ # convenience methods for setting translatable system settings
2
+
3
+ # require the model in Kete before reopening it below
4
+ SystemSetting
5
+
6
+ class SystemSetting
7
+ def self.update_translatables
8
+ Kete.translatable_system_settings.each { |name| SystemSetting.find_by_name(name).make_translatable }
9
+ end
10
+ def make_translatable
11
+ update_attributes!(:takes_translations => true)
12
+ end
13
+ end
@@ -0,0 +1,37 @@
1
+ # extensions to the kete tag model
2
+
3
+ # require the model in Kete before reopening it below
4
+ Tag
5
+
6
+ class Tag
7
+ # When creating a tag, check both the tags model, and tag translations
8
+ # This is done so that for each tag we don't end up with additiona Tag
9
+ # objects, but rather, the original tag object with multiple translations
10
+ #
11
+ # Example Usage:
12
+ #
13
+ # >> I18n.locale = :en
14
+ # >> t = Tag.find_or_create_with_like_by_name('Welcome')
15
+ # => #<Tag id: 1, name: "Welcome", locale: "en", original_locale: "en">
16
+ # >> t.translate(:name => 'Accueil', :locale => :fr)
17
+ # => #<Tag::Translation name: "Accueil", tag_id: 1, _id: ObjectID('4bfb1a87f42ce12372000002'), locale: "fr", translatable_locale: "en">
18
+ #
19
+ # >> I18n.locale = :fr
20
+ # >> Tag.find_or_create_with_like_by_name('Accueil')
21
+ # => #<Tag id: 1, name: "Accueil", locale: "fr", original_locale: "en">
22
+
23
+ # redefine so if no tag is found initially, we look for translations too
24
+ # this method is used by acts-as-taggable-on for all creations of tags
25
+ def self.find_or_create_with_like_by_name(name)
26
+ # first, see if any tags exist with this name
27
+ existing_tag = first(:conditions => ["name LIKE ?", name])
28
+
29
+ # if no tag exists, look through tag translations for the current locale
30
+ if !existing_tag && existing_tag = Tag::Translation.first(:name => name, :locale => I18n.locale)
31
+ # if a translation is found, return the original Tag object, but with the values of the locale
32
+ existing_tag = Tag.swap_in_translation_for_single(existing_tag.translatable)
33
+ end
34
+
35
+ existing_tag || create(:name => name, :locale => I18n.locale)
36
+ end
37
+ end
@@ -0,0 +1,12 @@
1
+ # extensions to the kete topic model
2
+
3
+ # require the model in Kete before reopening it below
4
+ Topic
5
+
6
+ require File.join(File.dirname(__FILE__), '../tagging_overrides')
7
+ require File.join(File.dirname(__FILE__), '../oai_dc_helpers_overrides')
8
+
9
+ class Topic
10
+ include TaggingOverrides
11
+ include OaiDcHelpersOverrides
12
+ end
@@ -0,0 +1,36 @@
1
+ # extensions to the kete user model
2
+
3
+ # require the model in Kete before reopening it below
4
+ User
5
+
6
+ class User
7
+ def basket_permissions
8
+ select = "roles.id AS role_id, roles.name AS role_name, baskets.id AS basket_id, baskets.urlified_name AS basket_urlified_name, baskets.name AS basket_name"
9
+ join = "INNER JOIN baskets on roles.authorizable_id = baskets.id"
10
+ permissions = roles.find_all_by_authorizable_type('Basket', :select => select, :joins => join)
11
+
12
+ # query for matching translations for the baskets in one go
13
+ basket_ids = permissions.collect { |p| p.basket_id.to_i }
14
+ translations = Basket::Translation.all(:basket_id => basket_ids, :locale => I18n.locale.to_s)
15
+
16
+ logger.debug("what is locale: " + I18n.locale.inspect )
17
+ logger.debug("what are translations: " + translations.inspect )
18
+
19
+ permissions_hash = Hash.new
20
+ permissions.each do |permission|
21
+ p = permission.attributes
22
+
23
+ # grab the appropriate name for the basket based on locale
24
+ translation = translations.select { |t| t.basket_id == p['basket_id'].to_i }.first
25
+ p['basket_name'] = translation ? translation.name : p['basket_name']
26
+
27
+ permissions_hash[p['basket_urlified_name'].to_sym] = {
28
+ :id => p['basket_id'].to_i,
29
+ :role_id => p['role_id'].to_i,
30
+ :role_name => p['role_name'],
31
+ :basket_name => p['basket_name']
32
+ }
33
+ end
34
+ permissions_hash
35
+ end
36
+ end
@@ -0,0 +1,12 @@
1
+ # extensions to the kete video model
2
+
3
+ # require the model in Kete before reopening it below
4
+ Video
5
+
6
+ require File.join(File.dirname(__FILE__), '../tagging_overrides')
7
+ require File.join(File.dirname(__FILE__), '../oai_dc_helpers_overrides')
8
+
9
+ class Video
10
+ include TaggingOverrides
11
+ include OaiDcHelpersOverrides
12
+ end
@@ -0,0 +1,12 @@
1
+ # extensions to the kete web link model
2
+
3
+ # require the model in Kete before reopening it below
4
+ WebLink
5
+
6
+ require File.join(File.dirname(__FILE__), '../tagging_overrides')
7
+ require File.join(File.dirname(__FILE__), '../oai_dc_helpers_overrides')
8
+
9
+ class WebLink
10
+ include TaggingOverrides
11
+ include OaiDcHelpersOverrides
12
+ end
@@ -0,0 +1,99 @@
1
+ # redefine helpers to include translated versions
2
+ module OaiDcHelpersOverrides
3
+ unless included_modules.include? OaiDcHelpersOverrides
4
+ def self.included(klass)
5
+ klass.class_eval do
6
+
7
+ if self.new.respond_to?(:oai_dc_xml_dc_title)
8
+ alias_method(:oai_dc_xml_dc_title_orig, :oai_dc_xml_dc_title) unless self.new.respond_to?(:oai_dc_xml_dc_title_orig)
9
+
10
+ def oai_dc_xml_dc_title(xml, options = {})
11
+ is_translatable = Kete.translatables.keys.include?(self.class.name.tableize.singularize)
12
+
13
+ # handle original title
14
+ options = options.merge({ "xml:lang" => locale }) if is_translatable
15
+ oai_dc_xml_dc_title_orig(xml, options)
16
+
17
+ original_title = title
18
+
19
+ return unless is_translatable
20
+
21
+ @translations_for_this_version ||= self.class::Translation.all(self.class.as_foreign_key_sym => id,
22
+ :version => version.to_s)
23
+ @translations_for_this_version.each do |t|
24
+ if t.title.present?
25
+ self.title = t.title
26
+ options = options.merge({ "xml:lang" => t.locale })
27
+ oai_dc_xml_dc_title_orig(xml, options)
28
+ end
29
+ end
30
+ self.title = original_title
31
+ end
32
+ end
33
+
34
+ if self.new.respond_to?(:oai_dc_xml_dc_description)
35
+ alias_method(:oai_dc_xml_dc_description_orig, :oai_dc_xml_dc_description) unless self.new.respond_to?(:oai_dc_xml_dc_description_orig)
36
+
37
+ def oai_dc_xml_dc_description(xml, passed_description = nil, options = {})
38
+ unless passed_description.blank?
39
+ oai_dc_xml_dc_description_orig(xml, passed_description, options)
40
+ else
41
+ class_name = self.class.name
42
+ is_translatable = Kete.translatables.keys.include?(class_name.tableize.singularize)
43
+ has_short_summary = [Topic, Document].include?(self.class)
44
+
45
+ options = options.merge({ "xml:lang" => locale }) if is_translatable
46
+
47
+ # topic/document specific
48
+ # order is important, first description will be used as blurb
49
+ # in result list
50
+ if has_short_summary && short_summary.present?
51
+ oai_dc_xml_dc_description(xml, short_summary, options)
52
+ end
53
+
54
+ oai_dc_xml_dc_description(xml, description, options) if description.present?
55
+
56
+ return unless is_translatable
57
+
58
+ @translations_for_this_version ||= self.class::Translation.all(self.class.as_foreign_key_sym => id,
59
+ :version => version.to_s)
60
+ @translations_for_this_version.each do |t|
61
+ options = options.merge({ "xml:lang" => t.locale })
62
+
63
+ if has_short_summary && t.short_summary.present?
64
+ oai_dc_xml_dc_description(xml, t.short_summary, options)
65
+ end
66
+
67
+ if t.description.present?
68
+ options = options.merge({ "xml:lang" => t.locale })
69
+ oai_dc_xml_dc_description(xml, t.description, options)
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+
76
+ if self.new.respond_to?(:oai_dc_xml_tags_to_dc_subjects)
77
+ alias_method(:oai_dc_xml_tags_to_dc_subjects_orig, :oai_dc_xml_tags_to_dc_subjects) unless self.new.respond_to?(:oai_dc_xml_tags_to_dc_subjects_orig)
78
+
79
+ def oai_dc_xml_tags_to_dc_subjects(xml)
80
+ tags.each do |tag|
81
+ # handle original
82
+ xml.send("dc:subject", "xml:lang" => tag.original_locale) {
83
+ xml.cdata tag.name
84
+ }
85
+
86
+ # do each translation of tag
87
+ tag.translations.each do |t|
88
+ xml.send("dc:subject", "xml:lang" => t.locale) {
89
+ xml.cdata t.name
90
+ }
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,21 @@
1
+ # for ITEM_CLASSES
2
+ # when new version is created to just add tags
3
+ # we want to update the version attribute of translations
4
+ # that matched previous version
5
+ # to new version number
6
+ module TaggingControllerOverrides
7
+ unless included_modules.include? TaggingControllerOverrides
8
+ # method that add-ons can define to do something after tags added
9
+ def after_tags_added(options)
10
+ logger.debug("what are after_tags added options: " + options.inspect)
11
+ # get translations matching starting version
12
+ translations = @item.class::Translation.all(@item.class.as_foreign_key_sym => @item.id,
13
+ :version => options[:starting_version].to_s)
14
+
15
+ translations.each do |t|
16
+ t.version = options[:ending_version].to_s
17
+ t.save!
18
+ end
19
+ end
20
+ end
21
+ end