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,7 @@
1
+ require File.join(File.dirname(__FILE__), '../tinymce_controller_valid_action_override')
2
+ require File.join(File.dirname(__FILE__), '../tagging_controller_overrides')
3
+
4
+ AudioController.class_eval do
5
+ include TinymceControllerValidActionOverride
6
+ include TaggingControllerOverrides
7
+ end
@@ -0,0 +1,3 @@
1
+ BasketsController.class_eval do
2
+ uses_tiny_mce :options => Kete.translatable_tiny_mce_options, :only => %w{ edit appearance }
3
+ end
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), '../tinymce_controller_valid_action_override')
2
+ require File.join(File.dirname(__FILE__), '../tagging_controller_overrides')
3
+
4
+ DocumentsController.class_eval do
5
+ include TinymceControllerValidActionOverride
6
+ include TaggingControllerOverrides
7
+ end
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), '../tinymce_controller_valid_action_override')
2
+ require File.join(File.dirname(__FILE__), '../tagging_controller_overrides')
3
+
4
+ ImagesController.class_eval do
5
+ include TinymceControllerValidActionOverride
6
+ include TaggingControllerOverrides
7
+ end
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), '../tinymce_controller_valid_action_override')
2
+ require File.join(File.dirname(__FILE__), '../tagging_controller_overrides')
3
+
4
+ TopicsController.class_eval do
5
+ include TinymceControllerValidActionOverride
6
+ include TaggingControllerOverrides
7
+ end
@@ -0,0 +1,209 @@
1
+ TranslationsController.class_eval do
2
+ uses_tiny_mce :options => Kete.translatable_tiny_mce_options, :only => %w{ new edit }
3
+
4
+ include WorkerControllerHelpers
5
+
6
+ before_filter :params_version_to_latest_if_necessary, :only => :new
7
+
8
+ after_filter :expire_locale_cache, :only => [:create, :update]
9
+ after_filter :update_zoom_record_if_applicable, :only => [:create, :update]
10
+
11
+ def edit
12
+ @translation = @translated.translation_for(params[:id]) || @translatable_class::Translation.find(params[:id])
13
+ if @translated.respond_to?("version")
14
+ @translation = @translated.translate(:locale => (params[:to_locale] || I18n.locale.to_s)) unless @translation.version.to_i == @translated.version.to_i
15
+ end
16
+
17
+ render :template => "translations/versioned_edit"
18
+ end
19
+
20
+ # POST /translations
21
+ # POST /translations.xml
22
+ def create
23
+ translation_params = params[:translation] || params[@translatable_params_name + '_translation']
24
+ params[:version] ||= params[@translatable_key][:version] if params[@translatable_key]
25
+ translation_params[:version] = params[:version].to_i if params[:version]
26
+ @translation = @translatable.translate(translation_params)
27
+
28
+ respond_to do |format|
29
+ if @translation.save
30
+ flash[:notice] = t('translations.controllers.created')
31
+ # we redirect to translated object in the new translated version
32
+ # assumes controller name is tableized version of class
33
+ format.html { redirect_to url_for_translated(:locale => I18n.locale) }
34
+ # TODO: adjust :location accordingly for being a nested route
35
+ format.xml { render :xml => @translation, :status => :created, :location => @translation }
36
+ else
37
+ format.html { render :action => "new" }
38
+ format.xml { render :xml => @translation.errors, :status => :unprocessable_entity }
39
+ end
40
+ end
41
+ end
42
+
43
+ # PUT /translations/1
44
+ # PUT /translations/1.xml
45
+ def update
46
+ respond_to do |format|
47
+ translation_params = params[:translation] || params[@translatable_params_name + '_translation']
48
+ params[:version] ||= params[@translatable_key][:version] if params[@translatable_key]
49
+ translation_params[:version] = params[:version].to_i if params[:version]
50
+ if @translation.update_attributes(translation_params)
51
+ flash[:notice] = t('translations.controllers.updated')
52
+ format.html { redirect_to url_for_translated(:locale => I18n.locale) }
53
+ format.xml { head :ok }
54
+ else
55
+ format.html { render :action => "edit" }
56
+ format.xml { render :xml => @translation.errors, :status => :unprocessable_entity }
57
+ end
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ def get_translation
64
+ @translation = @translated.translation_for(params[:id]) || @translatable_class::Translation.find(params[:id])
65
+ if @translated.respond_to?("version")
66
+ @translation = @translated.translate(:locale => (params[:to_locale] || I18n.locale.to_s)) unless @translation.version.to_i == @translated.version.to_i
67
+ end
68
+ end
69
+
70
+ %w{translatable translated}.each do |term|
71
+ define_method("get_" + term) do
72
+ params[:version] ||= params[@translatable_key][:version] if params[@translatable_key]
73
+
74
+ value = @translatable_class.find(params[@translatable_key])
75
+
76
+ value.revert_to(params[:version].to_i) if params[:version]
77
+
78
+ # handle case of editing translation from another locale than original
79
+ # unfortunately requires reloading of object
80
+ if value.locale != value.original_locale &&
81
+ params[:controller] == 'translations' &&
82
+ params[:action] == 'edit'
83
+
84
+ starting_locale = I18n.locale
85
+ I18n.locale = value.original_locale
86
+
87
+ if params[:version]
88
+ value.revert_to(params[:version].to_i)
89
+ else
90
+ value.reload
91
+ end
92
+
93
+ I18n.locale = starting_locale
94
+ end
95
+
96
+ instance_variable_set("@" + term, value)
97
+ end
98
+ end
99
+
100
+ #Expire the cache of documents related to this record works on
101
+ #a wider scale if the record is relevant to the global UI.
102
+ def expire_locale_cache
103
+ #Kete items to be cleared individually
104
+ @translatable = @translation.respond_to?("translatable") ? @translation.translatable : @translation
105
+ if ITEM_CLASSES.include?(@translatable_class.to_s)
106
+ expire_show_caches_for(@translatable)
107
+
108
+ #Clear out the available for_list which may be updated
109
+ clear_header_fragments_for(@translated)
110
+ @translatable.translations.each do |translation|
111
+ clear_header_fragments_for(translation.translatable)
112
+ end
113
+
114
+ return true
115
+ elsif @translatable.is_a?(Tag)
116
+ # we need to expire the tag part
117
+ # for everything with that tag
118
+ @translatable.taggings.each do |tagging|
119
+ item = tagging.taggable
120
+
121
+ # sort of redundent, but achieves what we want
122
+ item.locale = @translatable.locale
123
+
124
+ controller = zoom_class_controller(item.class.name)
125
+ part = 'secondary_content_tags_[privacy]'
126
+ resulting_part = cache_name_for(part, 'public')
127
+ expire_fragment_for_all_versions_and_locale(item, { :controller => controller, :action => 'show', :id => item, :part => resulting_part })
128
+ resulting_part = cache_name_for(part, 'private')
129
+ expire_fragment_for_all_versions_and_locale(item, { :controller => controller, :action => 'show', :id => item, :part => resulting_part })
130
+ end
131
+ elsif @translatable.is_a?(Feed)
132
+ @translatable.clear_caches
133
+ else
134
+ expire_all_locale_caches
135
+ end
136
+ end
137
+
138
+ def clear_header_fragments_for(item)
139
+ item_class = item.class.name
140
+ controller = zoom_class_controller(item_class)
141
+ @privacy_type ||= (item.private? ? "private" : "public")
142
+ return unless ITEM_CLASSES.include?(item_class)
143
+ part = 'details_first_[privacy]'
144
+ resulting_part = cache_name_for(part, @privacy_type)
145
+ expire_fragment_for_all_versions_and_locale(item, { :controller => controller, :action => 'show', :id => item, :part => resulting_part })
146
+ end
147
+
148
+ def expire_fragment_for_all_versions_and_locale(item, name = {})
149
+ #blank title or url_for comes up with something it shouldn't
150
+ name[:id].title = "" if name[:id].title
151
+
152
+ name = name.merge(:id => item.id)
153
+
154
+ file_path = "#{RAILS_ROOT}/tmp/cache/#{fragment_cache_key(name).gsub(/(\?|:)/, '.')}.cache"
155
+ file_path.sub!("\/#{@translatable.locale}\/", "\/#{item.locale}\/")
156
+ File.delete(file_path) if File.exists?(file_path)
157
+ end
158
+
159
+ def expire_all_locale_caches
160
+ # this is the big hammer for translation clearing # it does the entire locale's cache if a translation changes
161
+ # only use on UI element related models
162
+ # Kete items (i.e. user generated content) should be done on an item by item basis
163
+ expire_locale = @translatable.locale
164
+ method_name = "clear_locale_cache"
165
+ options = { :locale_to_clear => expire_locale }
166
+
167
+ worker_type = :generic_muted_worker
168
+ worker_key = worker_key_for("generic_muted_worker_#{method_name}_#{expire_locale}")
169
+
170
+ # only allow a single cache clearing to happen at once
171
+ MiddleMan.new_worker( :worker => worker_type,
172
+ :worker_key => worker_key )
173
+
174
+ MiddleMan.worker(worker_type, worker_key).async_do_work( :arg => { :method_name => method_name, :options => options } )
175
+ true
176
+ end
177
+
178
+ # filter that will trigger zoom record rebuild for translatable
179
+ # if translatable.class is in ITEM_CLASSES
180
+ def update_zoom_record_if_applicable
181
+ @translatable = @translation.respond_to?("translatable") ? @translation.translatable : @translation
182
+ if ITEM_CLASSES.include?(@translatable.class.name)
183
+ rebuild_zoom_for_translatable
184
+ end
185
+ end
186
+
187
+ def rebuild_zoom_for_translatable
188
+ method_name = "rebuild_zoom_record_for"
189
+ options = { :item => @translatable }
190
+
191
+ worker_type = :generic_muted_worker
192
+ worker_key = worker_key_for("generic_muted_worker_#{method_name}_#{@translatable_class.to_s}_#{@translatable.id}")
193
+
194
+ # only allow a single cache clearing to happen at once
195
+ MiddleMan.new_worker( :worker => worker_type,
196
+ :worker_key => worker_key )
197
+
198
+ MiddleMan.worker(worker_type, worker_key).async_do_work( :arg => { :method_name => method_name, :options => options } )
199
+ true
200
+ end
201
+
202
+ # default to latest version, unless it is passed in
203
+ # private versions should pass version
204
+ def params_version_to_latest_if_necessary
205
+ if params[:version].blank? && @translatable.respond_to?(:version)
206
+ params[:version] = @translatable.version
207
+ end
208
+ end
209
+ end
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), '../tinymce_controller_valid_action_override')
2
+ require File.join(File.dirname(__FILE__), '../tagging_controller_overrides')
3
+
4
+ VideoController.class_eval do
5
+ include TinymceControllerValidActionOverride
6
+ include TaggingControllerOverrides
7
+ end
@@ -0,0 +1,7 @@
1
+ require File.join(File.dirname(__FILE__), '../tinymce_controller_valid_action_override')
2
+ require File.join(File.dirname(__FILE__), '../tagging_controller_overrides')
3
+
4
+ WebLinksController.class_eval do
5
+ include TinymceControllerValidActionOverride
6
+ include TaggingControllerOverrides
7
+ end
@@ -0,0 +1,54 @@
1
+ # for ZOOM_CLASSES, extended_content is translatable_attribute
2
+ # however, in mongodb we store indivdual values for the extended fields
3
+ # and then we swap in actual translatable extended field values via individual
4
+ # extended field setter methods (method missing methods)
5
+ # the advantage is that we only have to tell mongo_translatable that extended_content
6
+ # is translatable at the time of system startup
7
+ # and we can go on declaring new extended fields dynamically
8
+ module ExtendedContentTranslation
9
+ unless included_modules.include? ExtendedContentTranslation
10
+ def self.included(base)
11
+
12
+ #Send define method because scopes are not playing nicely together
13
+ base.send(:define_method, :translatable_attributes) do
14
+ return @translatable_attributes if @translatable_attributes.present?
15
+
16
+ # klass is ::Version classes parent namespace wise
17
+ klass = self.class
18
+
19
+ type = klass == Topic ? topic_type : ContentType.find_by_class_name(klass.name)
20
+
21
+ if type
22
+ # fields = type.mapped_fields.select { |f| ['text', 'textarea', 'choice', 'autocomplete'].include?(f.ftype) }
23
+ fields = type.mapped_fields.select { |f| ['text', 'textarea',].include?(f.ftype) }
24
+
25
+ type_translatable_attributes = fields.collect do |f|
26
+ unless f.multiple
27
+ f.label_for_params.to_sym
28
+ else
29
+ [f.label_for_params.to_sym, Array]
30
+ end
31
+ end
32
+
33
+ klass::Translation.update_keys_if_necessary_with(type_translatable_attributes)
34
+
35
+ update_translation_for_methods_if_necessary_with(type_translatable_attributes)
36
+
37
+ type_translatable_attribute_keys_only = type_translatable_attributes.collect do |a|
38
+ if a.is_a?(Array)
39
+ a[0]
40
+ else
41
+ a
42
+ end
43
+ end
44
+
45
+ @translatable_attributes = self.class.translatable_attributes + type_translatable_attribute_keys_only
46
+ else
47
+ @translatable_attributes = self.class.translatable_attributes
48
+ end
49
+ @translatable_attributes
50
+ end
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,156 @@
1
+ ApplicationHelper.module_eval do
2
+ # lighboxes only used when user is logged in
3
+ def lightbox?
4
+ logged_in?
5
+ end
6
+
7
+ def tags_for(item)
8
+ html_string = String.new
9
+
10
+ return html_string if item.tags.blank?
11
+
12
+ html_string = "<p>#{t('application_helper.tags_for.tags')} "
13
+ item_tags = item.tags
14
+
15
+ item_tags.each_with_index do |tag,index|
16
+ html_string += link_to_tagged(tag, item.class.name)
17
+
18
+ # since tags-list is cached,
19
+ # we have to assume the user is logged out, use false for lightbox
20
+
21
+ # all we need to know is whether this tag is in the I18n.locale
22
+ # if not, provide translate link
23
+ unless tag.locale == I18n.locale
24
+ html_string += '<sup class="badge">' +
25
+ translate_link(tag,
26
+ :lightbox => false,
27
+ :action => 'new') +
28
+ '</sup>'
29
+ end
30
+
31
+ html_string += ", " unless item_tags.size == (index + 1)
32
+ end
33
+ html_string += "</p>"
34
+
35
+ html_string
36
+ end
37
+
38
+ def display_label_for(field_or_choice)
39
+ field_or_choice.label_translation_for(I18n.locale) || field_or_choice.label
40
+ end
41
+
42
+ def combined_tranlation_links
43
+ version = (current_translatable_record.respond_to?(:version) && current_translatable_record.version)
44
+ html = ''
45
+ html += '<div class="content-wrapper-submenu" id="translations">' + I18n.t('translations.available_in')
46
+ html += '<ul class="horizontal-list">'
47
+
48
+ available_locale_links = raw_available_in_locales_links(current_translatable_record, :params => {:version => version })
49
+
50
+ available_locales = available_locale_links.collect { |link| link[:locale].to_s }
51
+
52
+ available_locale_links.each_with_index do |link, i|
53
+ html += "<li#{' class="first"' if i == 0 }>"
54
+ html += link[:link]
55
+
56
+ unless link[:locale] == current_translatable_record.original_locale
57
+ record_translation_for_locale = current_translatable_record.translation_for(link[:locale])
58
+
59
+ if record_translation_for_locale &&
60
+ current_translatable_record.version.to_i > record_translation_for_locale.version.to_i
61
+ html += '<sup class="badge">' + I18n.t('translations.old') + '</sup>'
62
+ # drop locale from available_locales, so we get the translate link
63
+ available_locales.delete(link[:locale].to_s)
64
+ end
65
+ end
66
+
67
+ html += '</li>'
68
+ end
69
+
70
+ translate_link_version = nil
71
+
72
+ if version &&
73
+ current_translatable_record.respond_to?(:private?) &&
74
+ current_translatable_record.private?
75
+
76
+ translate_link_version = version
77
+ end
78
+
79
+ if current_translatable_record.original_locale != I18n.locale &&
80
+ !available_locales.include?(I18n.locale.to_s)
81
+ html += '<li id="translate">' + translate_link(current_translatable_record,
82
+ :lightbox => lightbox?,
83
+ :action => 'new',
84
+ :params => {:version => translate_link_version}) + '</li>'
85
+ elsif current_translatable_record.original_locale == I18n.locale && available_locales.size == 1
86
+ other_locales = TranslationsHelper::available_locales.keys - [current_translatable_record.original_locale]
87
+
88
+ html += '<li id="translate">' + translate_link(current_translatable_record,
89
+ :lightbox => lightbox?,
90
+ :action => 'new',
91
+ :params => {:version => translate_link_version,
92
+ :to_locale => other_locales.first}) + '</li>'
93
+ end
94
+
95
+ translations_params = Hash.new
96
+ params.each do |k,v|
97
+ translations_params[k] = v unless %w(action controller id).include?(k.to_s)
98
+ end
99
+
100
+ manage_links = manage_translations_links_for(current_translatable_record,
101
+ available_locales - [current_translatable_record.original_locale],
102
+ { :params => translations_params })
103
+
104
+
105
+ if manage_links.present? && logged_in?
106
+ # drop the 'delete' link unless a moderator or above
107
+ # a little brittle, as it relies on knowledge that ( edit | delete ) html
108
+ # as returned by helper method has | when (edit | delete) rather than manage
109
+ unless @at_least_a_moderator && manage_links.include?('|')
110
+
111
+ # only moderators and above can have access to 'delete'
112
+ manage_links = ' ' + manage_links.split('|')[0]
113
+ end
114
+
115
+ html += '<li id="manage-translations">(' + manage_links + ')</li>'
116
+ end
117
+
118
+ html += '</ul>
119
+ </div>'
120
+
121
+ translatable_lightbox_js_and_css
122
+
123
+ html
124
+ end
125
+
126
+ def add_ons_item_form_beginning(form=nil)
127
+ return unless form
128
+ locale_dropdown(form, :default => I18n.locale)
129
+ end
130
+
131
+ # redefining, because under certain circumstances
132
+ # user should get a confirm dialog before going to edit page
133
+ def link_to_edit_for(item)
134
+ t_key = t("topics.actions_menu.edit")
135
+
136
+
137
+ args = ["<span class=\"edit-link\">#{t_key}</span>",
138
+ { :action => :edit,
139
+ :id => item,
140
+ :private => params[:private]}]
141
+
142
+ additional_options = { :tabindex => '1' }
143
+
144
+ # translation for this locale exists,
145
+ # but it isn't the original locale
146
+ if item.original_locale != I18n.locale &&
147
+ item.available_in_these_locales.include?(I18n.locale)
148
+
149
+ additional_options[:confirm] = t('translations.are_you_sure_for_item_edit')
150
+ end
151
+
152
+ args << additional_options
153
+
154
+ link_to(*args)
155
+ end
156
+ end