Skip to content

Commit c5b08d4

Browse files
committed
FEATURE: Translate all new posts automatically
Adds a new site setting 'translate_posts_to_languages'
1 parent fb5af06 commit c5b08d4

File tree

7 files changed

+101
-11
lines changed

7 files changed

+101
-11
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# frozen_string_literal: true
2+
3+
module Jobs
4+
class TranslateTranslatable < ::Jobs::Base
5+
def execute(args)
6+
return unless SiteSetting.translator_enabled
7+
return if SiteSetting.automatic_translation_target_languages.blank?
8+
9+
translatable = args[:type].constantize.find_by(id: args[:translatable_id])
10+
return if translatable.blank?
11+
12+
target_locales = SiteSetting.automatic_translation_target_languages.split("|")
13+
target_locales.each do |target_locale|
14+
"DiscourseTranslator::#{SiteSetting.translator}".constantize.translate(
15+
translatable,
16+
target_locale.to_sym,
17+
)
18+
topic_id = translatable.is_a?(Post) ? translatable.topic.id : translatable.id
19+
post_id = translatable.is_a?(Post) ? translatable.id : 1
20+
MessageBus.publish("/topic/#{topic_id}", type: :revised, id: post_id)
21+
end
22+
end
23+
end
24+
end
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# frozen_string_literal: true
2+
3+
module Jobs
4+
class AutomaticTranslationBackfill < ::Jobs::Scheduled
5+
every 5.minutes
6+
7+
def execute(args = nil)
8+
return unless SiteSetting.translator_enabled
9+
return if SiteSetting.automatic_translation_target_languages.blank?
10+
return if SiteSetting.automatic_translation_backfill_maximum_posts_per_hour == 0
11+
12+
batch_size = SiteSetting.automatic_translation_backfill_maximum_posts_per_hour / 12
13+
target_locales = SiteSetting.automatic_translation_target_languages.split("|")
14+
15+
Topic
16+
.where.not(
17+
id: DiscourseTranslator::TopicTranslation.select(:topic_id).where(locale: target_locales),
18+
)
19+
.order(id: :desc)
20+
.limit(batch_size)
21+
.each do |topic|
22+
Jobs.enqueue(:translate, translatable_type: "Topic", translatable_id: topic.id)
23+
end
24+
25+
# Handle Posts
26+
Post
27+
.where.not(
28+
id: DiscourseTranslator::PostTranslation.select(:post_id).where(locale: target_locales),
29+
)
30+
.order(id: :desc)
31+
.limit(batch_size)
32+
.each do |post|
33+
Jobs.enqueue(:translate, translatable_type: "Post", translatable_id: post.id)
34+
end
35+
end
36+
end
37+
end

assets/javascripts/discourse/initializers/extend-for-translate-button.js

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,6 @@ function initializeTranslation(api) {
2929
(currentUser || siteSettings.experimental_anon_language_switcher)
3030
) {
3131
api.renderInOutlet("topic-navigation", ShowOriginalContent);
32-
api.decorateCookedElement((cookedElement, helper) => {
33-
if (helper) {
34-
const translatedCooked = helper.getModel().get("translated_cooked");
35-
if (translatedCooked) {
36-
cookedElement.innerHTML = translatedCooked;
37-
} else {
38-
// this experimental feature does not yet support
39-
// translating individual untranslated posts
40-
}
41-
}
42-
});
4332

4433
api.registerModelTransformer("topic", (topics) => {
4534
topics.forEach((topic) => {
@@ -48,6 +37,12 @@ function initializeTranslation(api) {
4837
}
4938
});
5039
});
40+
41+
api.registerModelTransformer("post", (post) => {
42+
if (post.translated_cooked) {
43+
post.set("cooked", post.translated_cooked);
44+
}
45+
});
5146
}
5247

5348
if (!siteSettings.experimental_topic_translation) {

config/locales/server.en.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ en:
1818
restrict_translation_by_group: "Only allowed groups can translate"
1919
restrict_translation_by_poster_group: "Only allow translation of posts made by users in allowed groups. If empty, allow translations of posts from all users."
2020
experimental_anon_language_switcher: "Enable experimental language switcher for anonymous users. This will allow anonymous users to switch between translated versions of Discourse and user-contributed content in topics."
21+
translate_posts_to_languages: "Translate posts to languages"
2122
errors:
2223
set_locale_cookie_requirements: "The experimental language switcher for anonymous users requires the `set locale from cookie` site setting to be enabled."
2324
experimental_topic_translation: "Enable experimental topic translation feature. This replaces existing post in-line translation with a button that allows users to translate the entire topic."

config/settings.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,12 @@ discourse_translator:
109109
experimental_topic_translation:
110110
default: false
111111
client: true
112+
automatic_translation_target_languages:
113+
default: ""
114+
type: list
115+
list_type: named
116+
choices: "DiscourseTranslator::TranslatableLanguagesSetting.values"
117+
allow_any: false
118+
automatic_translation_backfill_maximum_posts_per_hour:
119+
default: 0
120+
client: false
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# frozen_string_literal: true
2+
3+
module DiscourseTranslator
4+
class TranslatableLanguagesSetting < LocaleSiteSetting
5+
def self.printable_values
6+
values.map { |v| v[:value] }
7+
end
8+
9+
@lock = Mutex.new
10+
end
11+
end

plugin.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,19 @@ module ::DiscourseTranslator
3838
end
3939
end
4040

41+
on(:post_process_cooked) do |_, post|
42+
return if SiteSetting.automatic_translation_target_languages.blank?
43+
Jobs.enqueue(:translate_translatable, type: Post, translatable_id: post.id)
44+
end
45+
46+
on(:topic_created) do |topic|
47+
Jobs.enqueue(:translate_translatable, type: Topic, translatable_id: topic.id)
48+
end
49+
50+
on(:topic_edited) do |topic|
51+
Jobs.enqueue(:translate_translatable, type: Topic, translatable_id: topic.id)
52+
end
53+
4154
add_to_serializer :post, :can_translate do
4255
scope.can_translate?(object)
4356
end

0 commit comments

Comments
 (0)