[TikiWiki-commits] [Git][tikiwiki/tiki][master] [FIX] Interactive translation: Ensure placeholder variables (%0, %1, etc.) are...

"luci \(@luciash\) via TikiWiki-cvs" <[email protected]>
Newsgroups gmane.comp.cms.tiki.cvs
Message-ID <690c862a2303_2ce2734300b6@gitlab-sidekiq-low-urgency-cpu-bound-v2-67b7b754dd-jskkb.mail>

luci pushed to branch master at Tiki Wiki CMS Groupware / Tiki


Commits:
b74af08e by Landry Bitege at 2025-11-06T11:19:33+00:00
[FIX] Interactive translation: Ensure placeholder variables (%0, %1, etc.) are preserved in suggested translations during interactive translation
---
* [FIX] Interactive translation: Ensure placeholder variables (%0, %1, etc.) are preserved in suggested translations during interactive translation

See merge request tikiwiki/tiki!8882

- - - - -


2 changed files:

- lib/language/LanguageTranslator.php
- lib/language/js/interactive_translation.js


Changes:

=====================================
lib/language/LanguageTranslator.php
=====================================
@@ -65,7 +65,7 @@ class LanguageTranslator
         list($content, $out, $wasTranslated) = $this->traImpl($content, $this->lang, $args);
         $out = typography($out, $this->lang, true);
 
-        $this->populateCollectedTranslations($content, $out, $wasTranslated);
+        $this->populateCollectedTranslations($content, $out, $wasTranslated, $args);
         return $out;
     }
 
@@ -235,10 +235,10 @@ class LanguageTranslator
      * @param $printed
      * @param $isTranslated
      */
-    private function populateCollectedTranslations($original, $printed, $isTranslated)
+    private function populateCollectedTranslations($original, $printed, $isTranslated, $args = [])
     {
         if (self::inInteractiveMode()) {
-            $this->interactiveCollectedStrings[md5($original . '___' . $printed)] = [$original, html_entity_decode($printed), $isTranslated];
+            $this->interactiveCollectedStrings[md5($original . '___' . $printed)] = [$original, html_entity_decode($printed), $isTranslated, $args];
         }
     }
 


=====================================
lib/language/js/interactive_translation.js
=====================================
@@ -253,7 +253,7 @@ function findTextToTranslate(text, val, alt, title) {
                 }
                 r.find(':hidden').val(this[0]);
                 r.find(':text').val(this[1]);
-                r.find('textarea').val(this[1]);
+                r.find('textarea').val(reverseArgReplace(this[1], this[3]));
                 return r[0];
             }));
     } else {
@@ -268,4 +268,68 @@ function findTextToTranslate(text, val, alt, title) {
 
     $('#intertrans-modal').modal('show').on("keydown", function (e) {
     }).find("input").first().trigger("focus");
+}
+
+/**
+ * Replace argument values in the content with their placeholders.
+ *
+ * @param {string} content Text with argument values
+ * @param {string[]} args Array of argument values
+ * @returns {string} Text with arguments replaced by their placeholders
+ */
+function reverseArgReplace(content, args) {
+    if (!args || args.length === 0 || !content) return content;
+
+    const matches = [];
+
+    args.forEach((val, i) => {
+        if (!val) return;
+        let offset = 0;
+        while (true) {
+            const pos = content.indexOf(val, offset);
+            if (pos === -1) break;
+            matches.push({
+                start: pos,
+                length: val.length,
+                arg: i
+            });
+            offset = pos + 1;
+        }
+    });
+
+    if (matches.length === 0) return content;
+
+    matches.sort((a, b) => b.length - a.length || a.start - b.start);
+
+    const selected = [];
+    matches.forEach(m => {
+        const s = m.start;
+        const e = s + m.length;
+        let overlap = selected.some(sel => !(e <= sel.start || s >= sel.start + sel.length));
+        if (!overlap) selected.push(m);
+    });
+
+    if (selected.length === 0) return content;
+
+    selected.sort((a, b) => a.start - b.start);
+    let out = '';
+    let cursor = 0;
+    selected.forEach(m => {
+        const start = m.start;
+        const len = m.length;
+        const argIndex = m.arg;
+
+        if (cursor < start) {
+            out += content.slice(cursor, start);
+        }
+
+        out += `%${argIndex}`;
+        cursor = start + len;
+    });
+
+    if (cursor < content.length) {
+        out += content.slice(cursor);
+    }
+
+    return out;
 }
\ No newline at end of file



View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/b74af08ef6e9a02d56ba2a94a5c9704b4fdcc632

-- 
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/b74af08ef6e9a02d56ba2a94a5c9704b4fdcc632
You're receiving this email because of your account on gitlab.com.

_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.