From 9c6a7c4db1533424780538a8252c9e8f3c07c938 Mon Sep 17 00:00:00 2001 From: Nat Date: Thu, 13 Feb 2025 23:15:00 +0800 Subject: [PATCH 1/5] DEV: Use backend plugin api instead of frontend apis to override cooked and translate --- .../extend-for-translate-button.js | 19 ------- plugin.rb | 32 ++++++++--- .../basic_topic_serializer_spec.rb | 53 +++++++++++++++++++ spec/serializers/post_serializer_spec.rb | 15 +++--- .../serializers/topic_view_serializer_spec.rb | 18 +++---- 5 files changed, 95 insertions(+), 42 deletions(-) create mode 100644 spec/serializers/basic_topic_serializer_spec.rb diff --git a/assets/javascripts/discourse/initializers/extend-for-translate-button.js b/assets/javascripts/discourse/initializers/extend-for-translate-button.js index 518377be..182c9c21 100644 --- a/assets/javascripts/discourse/initializers/extend-for-translate-button.js +++ b/assets/javascripts/discourse/initializers/extend-for-translate-button.js @@ -29,25 +29,6 @@ function initializeTranslation(api) { (currentUser || siteSettings.experimental_anon_language_switcher) ) { api.renderInOutlet("topic-navigation", ShowOriginalContent); - api.decorateCookedElement((cookedElement, helper) => { - if (helper) { - const translatedCooked = helper.getModel().get("translated_cooked"); - if (translatedCooked) { - cookedElement.innerHTML = translatedCooked; - } else { - // this experimental feature does not yet support - // translating individual untranslated posts - } - } - }); - - api.registerModelTransformer("topic", (topics) => { - topics.forEach((topic) => { - if (topic.translated_title) { - topic.set("fancy_title", topic.translated_title); - } - }); - }); } if (!siteSettings.experimental_topic_translation) { diff --git a/plugin.rb b/plugin.rb index 9fead2d9..43497386 100644 --- a/plugin.rb +++ b/plugin.rb @@ -42,17 +42,33 @@ module ::DiscourseTranslator scope.can_translate?(object) end - add_to_serializer :post, :translated_cooked do - if !SiteSetting.experimental_topic_translation || scope.request.params["show"] == "original" - return nil + register_modifier(:basic_post_serializer_cooked) do |cooked, serializer| + if !SiteSetting.experimental_topic_translation || + serializer.scope.request.params["show"] == "original" + cooked + else + translation = serializer.object.translation_for(I18n.locale) + translation if translation.present? end - object.translation_for(I18n.locale) || nil end - add_to_serializer :topic_view, :translated_title do - if !SiteSetting.experimental_topic_translation || scope.request.params["show"] == "original" - return nil + register_modifier(:topic_serializer_fancy_title) do |fancy_title, serializer| + if !SiteSetting.experimental_topic_translation || + serializer.scope.request.params["show"] == "original" + fancy_title + else + translation = serializer.object.translation_for(I18n.locale) + translation if translation.present? + end + end + + register_modifier(:topic_view_serializer_fancy_title) do |fancy_title, serializer| + if !SiteSetting.experimental_topic_translation || + serializer.scope.request.params["show"] == "original" + fancy_title + else + translation = serializer.object.topic.translation_for(I18n.locale) + translation if translation.present? end - object.topic.translation_for(I18n.locale) || nil end end diff --git a/spec/serializers/basic_topic_serializer_spec.rb b/spec/serializers/basic_topic_serializer_spec.rb new file mode 100644 index 00000000..ffb7bfce --- /dev/null +++ b/spec/serializers/basic_topic_serializer_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +require "rails_helper" + +describe BasicTopicSerializer do + fab!(:user) { Fabricate(:user, locale: "ja") } + fab!(:topic) + + before do + SiteSetting.translator_enabled = true + SiteSetting.experimental_topic_translation = true + end + + describe "#fancy_title" do + let!(:guardian) { Guardian.new(user) } + let!(:original_title) { "FUS ROH DAAHHH" } + let!(:jap_title) { "フス・ロ・ダ・ア" } + + before do + topic.title = original_title + SiteSetting.experimental_topic_translation = true + I18n.locale = "ja" + end + + def serialize_topic(guardian_user: user, params: {}) + env = { "action_dispatch.request.parameters" => params, "REQUEST_METHOD" => "GET" } + request = ActionDispatch::Request.new(env) + guardian = Guardian.new(guardian_user, request) + BasicTopicSerializer.new(topic, scope: guardian) + end + + it "does not replace fancy_title with translation when experimental_topic_translation is disabled" do + SiteSetting.experimental_topic_translation = false + topic.set_translation("ja", jap_title) + + expect(serialize_topic.fancy_title).to eq(topic.fancy_title) + end + + it "does not replace fancy_title with translation when show_original param is present" do + topic.set_translation("ja", jap_title) + expect(serialize_topic(params: { "show" => "original" }).fancy_title).to eq(topic.fancy_title) + end + + it "does not replace fancy_title with translation when no translation exists" do + expect(serialize_topic.fancy_title).to eq(topic.fancy_title) + end + + it "returns translated title in fancy_title when translation exists for current locale" do + topic.set_translation("ja", jap_title) + expect(serialize_topic.fancy_title).to eq(jap_title) + end + end +end diff --git a/spec/serializers/post_serializer_spec.rb b/spec/serializers/post_serializer_spec.rb index c935d248..9a463e40 100644 --- a/spec/serializers/post_serializer_spec.rb +++ b/spec/serializers/post_serializer_spec.rb @@ -88,31 +88,34 @@ def serialize_post(guardian_user: user, params: {}) PostSerializer.new(post, scope: guardian) end - before { SiteSetting.experimental_topic_translation = true } + before do + SiteSetting.translator_enabled = true + SiteSetting.experimental_topic_translation = true + end it "does not return translated_cooked when experimental_topic_translation is disabled" do SiteSetting.experimental_topic_translation = false - expect(serialize_post.translated_cooked).to eq(nil) + expect(serialize_post.cooked).to eq(post.cooked) end it "does not return translated_cooked when show=original param is present" do I18n.locale = "ja" post.set_translation("ja", "こんにちは") - expect(serialize_post(params: { "show" => "original" }).translated_cooked).to eq(nil) - expect(serialize_post(params: { "show" => "derp" }).translated_cooked).to eq("こんにちは") + expect(serialize_post(params: { "show" => "original" }).cooked).to eq(post.cooked) + expect(serialize_post(params: { "show" => "derp" }).cooked).to eq("こんにちは") end it "returns translated content based on locale" do I18n.locale = "ja" post.set_translation("ja", "こんにちは") post.set_translation("es", "Hola") - expect(serialize_post.translated_cooked).to eq("こんにちは") + expect(serialize_post.cooked).to eq("こんにちは") end it "does not return translated_cooked when plugin is disabled" do SiteSetting.translator_enabled = false - expect(serialize_post.translated_cooked).to eq(nil) + expect(serialize_post.cooked).to eq(post.cooked) end end end diff --git a/spec/serializers/topic_view_serializer_spec.rb b/spec/serializers/topic_view_serializer_spec.rb index 641efb16..fc19c353 100644 --- a/spec/serializers/topic_view_serializer_spec.rb +++ b/spec/serializers/topic_view_serializer_spec.rb @@ -31,7 +31,7 @@ expect(topic_view.posts.first.association(:content_locale)).to be_loaded end - describe "#translated_title" do + describe "#fancy_title" do fab!(:user) { Fabricate(:user, locale: "ja") } fab!(:topic) @@ -52,25 +52,25 @@ def serialize_topic(guardian_user: user, params: {}) TopicViewSerializer.new(TopicView.new(topic), scope: guardian) end - it "does not return translated_title when experimental_topic_translation is disabled" do + it "does not replace fancy_title with translation when experimental_topic_translation is disabled" do SiteSetting.experimental_topic_translation = false topic.set_translation("ja", jap_title) - expect(serialize_topic.translated_title).to eq(nil) + expect(serialize_topic.fancy_title).to eq(topic.fancy_title) end - it "does not return translated_title when show_original param is present" do + it "does not replace fancy_title with translation when show_original param is present" do topic.set_translation("ja", jap_title) - expect(serialize_topic(params: { "show" => "original" }).translated_title).to eq(nil) + expect(serialize_topic(params: { "show" => "original" }).fancy_title).to eq(topic.fancy_title) end - it "does not return translated_title when no translation exists" do - expect(serialize_topic.translated_title).to eq(nil) + it "does not replace fancy_title with translation when no translation exists" do + expect(serialize_topic.fancy_title).to eq(topic.fancy_title) end - it "returns translated title when translation exists for current locale" do + it "returns translated title in fancy_title when translation exists for current locale" do topic.set_translation("ja", jap_title) - expect(serialize_topic.translated_title).to eq(jap_title) + expect(serialize_topic.fancy_title).to eq(jap_title) end end end From 0cb4015ac046e3faacc471e1c73e7d0b51795fcf Mon Sep 17 00:00:00 2001 From: Nat Date: Fri, 14 Feb 2025 00:10:04 +0800 Subject: [PATCH 2/5] Do not load translation for posts already in correct locale --- plugin.rb | 3 ++- spec/serializers/post_serializer_spec.rb | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/plugin.rb b/plugin.rb index 43497386..48cd7975 100644 --- a/plugin.rb +++ b/plugin.rb @@ -44,7 +44,8 @@ module ::DiscourseTranslator register_modifier(:basic_post_serializer_cooked) do |cooked, serializer| if !SiteSetting.experimental_topic_translation || - serializer.scope.request.params["show"] == "original" + serializer.scope.request.params["show"] == "original" || + serializer.object.detected_locale == I18n.locale.to_s.gsub("_", "-") cooked else translation = serializer.object.translation_for(I18n.locale) diff --git a/spec/serializers/post_serializer_spec.rb b/spec/serializers/post_serializer_spec.rb index 9a463e40..65f18094 100644 --- a/spec/serializers/post_serializer_spec.rb +++ b/spec/serializers/post_serializer_spec.rb @@ -106,6 +106,14 @@ def serialize_post(guardian_user: user, params: {}) expect(serialize_post(params: { "show" => "derp" }).cooked).to eq("こんにちは") end + it "does not return translated_cooked when post is already in correct locale" do + I18n.locale = "ja" + post.set_detected_locale("ja") + post.set_translation("ja", "こんにちは") + + expect(serialize_post.cooked).to eq(post.cooked) + end + it "returns translated content based on locale" do I18n.locale = "ja" post.set_translation("ja", "こんにちは") From 2266d9d64f1355c81f19c25b3278c675fa54076c Mon Sep 17 00:00:00 2001 From: Nat Date: Fri, 14 Feb 2025 00:13:50 +0800 Subject: [PATCH 3/5] Extend to other serializers --- plugin.rb | 6 ++++-- spec/serializers/basic_topic_serializer_spec.rb | 8 ++++++++ spec/serializers/topic_view_serializer_spec.rb | 8 ++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/plugin.rb b/plugin.rb index 48cd7975..79157e7d 100644 --- a/plugin.rb +++ b/plugin.rb @@ -55,7 +55,8 @@ module ::DiscourseTranslator register_modifier(:topic_serializer_fancy_title) do |fancy_title, serializer| if !SiteSetting.experimental_topic_translation || - serializer.scope.request.params["show"] == "original" + serializer.scope.request.params["show"] == "original" || + serializer.object.detected_locale == I18n.locale.to_s.gsub("_", "-") fancy_title else translation = serializer.object.translation_for(I18n.locale) @@ -65,7 +66,8 @@ module ::DiscourseTranslator register_modifier(:topic_view_serializer_fancy_title) do |fancy_title, serializer| if !SiteSetting.experimental_topic_translation || - serializer.scope.request.params["show"] == "original" + serializer.scope.request.params["show"] == "original" || + serializer.object.topic.detected_locale == I18n.locale.to_s.gsub("_", "-") fancy_title else translation = serializer.object.topic.translation_for(I18n.locale) diff --git a/spec/serializers/basic_topic_serializer_spec.rb b/spec/serializers/basic_topic_serializer_spec.rb index ffb7bfce..a880e3d6 100644 --- a/spec/serializers/basic_topic_serializer_spec.rb +++ b/spec/serializers/basic_topic_serializer_spec.rb @@ -45,6 +45,14 @@ def serialize_topic(guardian_user: user, params: {}) expect(serialize_topic.fancy_title).to eq(topic.fancy_title) end + it "does not replace fancy_title when topic is already in correct locale" do + I18n.locale = "ja" + topic.set_detected_locale("ja") + topic.set_translation("ja", jap_title) + + expect(serialize_topic.fancy_title).to eq(topic.fancy_title) + end + it "returns translated title in fancy_title when translation exists for current locale" do topic.set_translation("ja", jap_title) expect(serialize_topic.fancy_title).to eq(jap_title) diff --git a/spec/serializers/topic_view_serializer_spec.rb b/spec/serializers/topic_view_serializer_spec.rb index fc19c353..c60f0407 100644 --- a/spec/serializers/topic_view_serializer_spec.rb +++ b/spec/serializers/topic_view_serializer_spec.rb @@ -68,6 +68,14 @@ def serialize_topic(guardian_user: user, params: {}) expect(serialize_topic.fancy_title).to eq(topic.fancy_title) end + it "does not replace fancy_title when topic is already in correct locale" do + I18n.locale = "ja" + topic.set_detected_locale("ja") + topic.set_translation("ja", jap_title) + + expect(serialize_topic.fancy_title).to eq(topic.fancy_title) + end + it "returns translated title in fancy_title when translation exists for current locale" do topic.set_translation("ja", jap_title) expect(serialize_topic.fancy_title).to eq(jap_title) From 2c1f1ab4ddd0a093774aae2c158f7ecdeafd2fe9 Mon Sep 17 00:00:00 2001 From: Nat Date: Fri, 14 Feb 2025 11:15:44 +0800 Subject: [PATCH 4/5] Update discourse-compat --- .discourse-compatibility | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.discourse-compatibility b/.discourse-compatibility index 1fbb7354..66102f45 100644 --- a/.discourse-compatibility +++ b/.discourse-compatibility @@ -1,4 +1,4 @@ -< 3.5.0.beta1-dev: f7d6ca6b32c0cff27422dd9f7583f41b203c0c57 +< 3.5.0.beta1-dev: 65d7ea2dbc9e7bf276e5ac3f9e23c2111e64e278 < 3.4.0.beta3-dev: b4cf3a065884816fa3f770248c2bf908ba65d8ac < 3.4.0.beta1-dev: 5346b4bafba2c2fb817f030a473b7bbca97b909c < 3.3.0.beta1-dev: 6750e10a6d9dfd3fc2c9a0cac5a83aca1a8ee401 From 629853978a73565d805564786bf28e21117d0fc7 Mon Sep 17 00:00:00 2001 From: Nat Date: Fri, 14 Feb 2025 11:46:07 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=8F=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- plugin.rb | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/plugin.rb b/plugin.rb index 79157e7d..5b79592d 100644 --- a/plugin.rb +++ b/plugin.rb @@ -48,8 +48,7 @@ module ::DiscourseTranslator serializer.object.detected_locale == I18n.locale.to_s.gsub("_", "-") cooked else - translation = serializer.object.translation_for(I18n.locale) - translation if translation.present? + serializer.object.translation_for(I18n.locale).presence end end @@ -59,8 +58,7 @@ module ::DiscourseTranslator serializer.object.detected_locale == I18n.locale.to_s.gsub("_", "-") fancy_title else - translation = serializer.object.translation_for(I18n.locale) - translation if translation.present? + serializer.object.translation_for(I18n.locale).presence end end @@ -70,8 +68,7 @@ module ::DiscourseTranslator serializer.object.topic.detected_locale == I18n.locale.to_s.gsub("_", "-") fancy_title else - translation = serializer.object.topic.translation_for(I18n.locale) - translation if translation.present? + serializer.object.topic.translation_for(I18n.locale).presence end end end