JSON भाषा फ़ाइल का अनुवाद कैसे करें बिना कुंजियाँ या प्लेसहोल्डर तोड़े
देखें कि en.json फ़ाइल में कौन से मान अनुवादित होते हैं, फ़ाइल अनुवादक क्या बदलता है (टिप्पणियाँ, कुंजी क्रम, बड़े ID), और मुफ़्त स्क्रिप्ट और परीक्षण फ़ाइल से प्लेसहोल्डर, ICU बहुवचन और कुंजियों की जाँच कैसे करें।

en.json जैसी JSON भाषा फ़ाइल का अनुवाद करने के लिए, पूरी फ़ाइल ऐसे अनुवादक को दें जो JSON समझता हो। कच्चा टेक्स्ट चैट विंडो या वेब अनुवादक में पेस्ट करना जोखिम भरा तरीका है। JSON-सचेत अनुवादक फ़ाइल पढ़ता है, केवल टेक्स्ट मानों का अनुवाद करता है, और वही कुंजियाँ वापस लिखता है, ताकि आपका ऐप फ़ाइल लोड कर सके। कॉपी-पेस्ट से कुंजी का अनुवाद हो सकता है, उद्धरण चिह्न बदल सकता है, या ब्रेस हट सकता है। इनमें से कोई भी फ़ाइल को तोड़ देता है।
कुंजियाँ बनाए रखना आसान हिस्सा है। ज़्यादातर परेशानी बाद में आती है: {name} प्लेसहोल्डर जो {nom} के रूप में लौटता है, ICU बहुवचन जो अपना other केस खो देता है, एक URL जो किसी अन्य टेक्स्ट की तरह अनुवाद के लिए भेजा जाता है, और अनुवादक द्वारा फ़ाइल में ही किए गए कुछ बदलाव। यही इस गाइड में शामिल है।
हमने इन सभी मामलों के साथ एक परीक्षण फ़ाइल बनाई और एक मुफ़्त चेकर लिखा जो स्रोत फ़ाइल की उसके अनुवाद से तुलना करता है। हमने परीक्षण फ़ाइल को BookTranslator द्वारा उपयोग किए जाने वाले JSON पार्सिंग और राइटिंग कोड की स्थानीय प्रति से भी चलाया, मॉडल के स्थान पर एक मार्कर के साथ, ताकि आप ठीक-ठीक देख सकें कि कौन से मान भेजे जाते हैं और फ़ाइल कैसे वापस आती है।
संक्षिप्त उत्तर: फ़ाइल के प्रत्येक भाग का क्या होता है
| फ़ाइल का भाग | हमारे परीक्षण से उदाहरण | BookTranslator क्या करता है | क्या जाँचें |
|---|---|---|---|
| कुंजियाँ | "greeting", "error" | जैसी हैं वैसी ही रखी जाती हैं | कुछ नहीं |
| सादे टेक्स्ट मान | "Reading list" | अनुवादित | अर्थ, स्क्रीन पर लंबाई |
| प्लेसहोल्डर वाले मान | "Welcome back, {name}!", "Saved %s of %d chapters" | अनुवादित, भेजे गए टेक्स्ट में प्लेसहोल्डर शामिल | प्लेसहोल्डर नाम और गणनाएँ (चेकर यह करता है) |
| ICU बहुवचन संदेश | "{count, plural, one {# book} other {# books}}" | एक स्ट्रिंग के रूप में भेजा जाता है | other केस, और लक्ष्य भाषा के लिए बहुवचन श्रेणियाँ |
| इनलाइन HTML | "accept the <b>Terms</b>." | अनुवादित; अनुवाद के बाद टैग की गिनती जाँची जाती है | टैग नाम और गिनती (चेकर यह करता है) |
| टेक्स्ट के रूप में संग्रहीत URL | "https://example.com/help" | अनुवाद के लिए भेजा गया | कि यह अपरिवर्तित वापस आया |
| बिना अक्षरों वाले मान | "2.4.1", "—", "" | जैसे थे वैसे ही छोड़ दिए गए | कुछ नहीं |
संख्याएँ, true/false, null | 20, true | जैसे थे वैसे ही छोड़ दिए गए | बहुत बड़ी ID (नीचे देखें) |
| स्ट्रिंग्स की सरणियाँ | ["Open", "Save", "Export as EPUB"] | अनुवादित फ़ाइल में अनुवादित; द्विभाषी फ़ाइल में अनुवादित नहीं छोड़ा गया | द्विभाषी फ़ाइल, यदि आप इसका उपयोग करते हैं |
| टिप्पणियाँ (JSONC) | // Shown on the home screen | हटा दी गईं। यदि किसी मान में // भी है, तो फ़ाइल लोड होने में विफल हो सकती है | अपलोड करने से पहले टिप्पणियाँ हटाएँ |
इस गाइड का शेष भाग दिखाता है कि प्रत्येक पंक्ति कहाँ से आती है और इसके बारे में क्या करना है।
चरण 1: अपलोड करने से पहले स्रोत फ़ाइल जाँचें
जिस फ़ाइल का आप अनुवाद करने की योजना बना रहे हैं, उस पर चेकर चलाएँ। इसके लिए Python 3 चाहिए और कुछ नहीं:
python3 check_i18n_json.py en.json
हमारी परीक्षण फ़ाइल पर इसने प्रिंट किया:
WARN limits.projectId: 9007199254740993 is above 2^53 and can change in a JavaScript round trip; store IDs as strings
WARN error.network: a flat key with dots and a nested key resolve to the same dot path; tools that address strings by dot path can mix them up
INFO (root): 3 keys look like integers; JavaScript sorts those first and in numeric order when it rewrites the object
INFO source: 17 strings, 2 numbers
दो चेतावनियाँ और पूर्णांक-जैसी कुंजियों के बारे में नोट, प्रत्येक उस परिवर्तन से मेल खाते हैं जो हमने तब देखा जब हमारी परीक्षण फ़ाइल अनुवादक के माध्यम से गई। यदि आपकी फ़ाइल में इनमें से कोई भी नहीं आता है, तो आप चरण 3 पर जा सकते हैं।
चेकर ऐसी फ़ाइल को भी अस्वीकार कर देता है जो सख्त JSON नहीं है, जैसे कि टिप्पणियों या अनुगामी अल्पविराम वाली, क्योंकि वह अगली समस्या है।
हमारी परीक्षण फ़ाइल से क्या वापस आया
परीक्षण 2 नवंबर, 2026 को BookTranslator के बैकएंड में वर्तमान JSON हैंडलिंग के विरुद्ध चलाया गया था। किसी मॉडल को कॉल करने के बजाय, परीक्षण ने अनुवाद के लिए भेजे जाने वाले प्रत्येक मान को [ZH] और मूल पाठ से बदल दिया। इससे परिणाम पूर्वानुमेय रहता है: जिसके आगे [ZH] है वह भेजा गया, जिसके आगे नहीं है वह नहीं भेजा गया। दोनों आउटपुट प्रकाशित हैं: अनुवादित फ़ाइल और द्विभाषी फ़ाइल।
अनुवादित फ़ाइल
हर कुंजी बिना बदले वापस आई, और फ़ाइल अभी भी पार्स हुई। अक्षरों वाले मान भेजे गए, जिनमें {name}, %s, ICU संदेश, <b> टैग और सहायता URL शामिल हैं। संस्करण स्ट्रिंग "2.4.1", डैश और खाली स्ट्रिंग नहीं भेजे गए, क्योंकि उनमें कोई अक्षर नहीं है। संख्याएँ और बूलियन अछूते रहे।
चार अन्य चीज़ें बदलीं:
- एक स्ट्रिंग गलत कुंजी में चली गई। हमारे परीक्षण में, हमारी फ़ाइल में एक सपाट कुंजी
"error.network"थी जिसमें पाठ "Check your connection." था, और एक नेस्टेड"error": { "network": "Network error" }भी था। अनुवादक प्रत्येक स्ट्रिंग को भागों के बीच बिंदुओं के साथ उसके पथ से पहचानता है, इसलिए दोनों स्ट्रिंग्स का पता एक ही था,error.network। आउटपुट में, दोनों कुंजियों में "Network error" का अनुवाद था। "Check your connection." गायब हो गया। इसके लिए एक ही फ़ाइल में दोनों शैलियों की आवश्यकता होती है, जो दुर्लभ है, लेकिन यह चुपचाप विफल हो जाता है। चेकर आपके अपलोड करने से पहले इसके बारे में चेतावनी देता है। - पूर्णांक-जैसी कुंजियाँ पुनः क्रमित हो गईं।
"steps": { "10": ..., "2": ..., "1": ... }वापस"1","2","10"के रूप में आया। जब JavaScript किसी ऑब्जेक्ट को पुनर्निर्मित करता है, तो वह हमेशा पूर्णांक-जैसी कुंजियों को पहले, संख्यात्मक क्रम में सूचीबद्ध करता है। कुंजियाँ और मान अभी भी मेल खाते हैं, इसलिए आपका ऐप ठीक है, लेकिन स्रोत फ़ाइल के विरुद्ध डिफ़ शोरगुल वाला होगा। - एक बड़ी ID ने सटीकता खो दी।
9007199254740993वापस9007199254740992के रूप में आया। JavaScript संख्याओं को 64-बिट फ़्लोटिंग पॉइंट के रूप में संग्रहीत करता है, और 2^53 से ऊपर के पूर्णांकों को सभी को सटीक रूप से प्रदर्शित नहीं किया जा सकता (MDN परNumber.MAX_SAFE_INTEGER)। लंबी ID को स्ट्रिंग के रूप में संग्रहीत करें, या उन्हें भाषा फ़ाइल से बाहर रखें। - फ़ॉर्मेटिंग फिर से लिखी गई। आउटपुट दो-स्थान इंडेंटेशन का उपयोग करता है और न्यूलाइन के साथ समाप्त होता है। यदि आपके स्रोत ने टैब या चार स्थानों का उपयोग किया है, तो डिफ़ में व्हाइटस्पेस परिवर्तनों की अपेक्षा करें।
हमारी परीक्षण फ़ाइल में कोई डुप्लिकेट कुंजी नहीं थी, लेकिन उनके बारे में जानना उपयोगी है: JavaScript का JSON पार्सर एक बार-बार आने वाली कुंजी के लिए केवल अंतिम मान रखता है, इसलिए पहले वाला पाठ कभी अनुवादित नहीं होता। आपका ऐप वही अंतिम मान लोड करेगा, इसलिए दिखने में कुछ नहीं टूटता, लेकिन चेकर डुप्लिकेट कुंजियों को सूचीबद्ध करता है ताकि आप उन्हें साफ कर सकें।
द्विभाषी फ़ाइल
द्विभाषी फ़ाइल प्रत्येक मूल मान को रखती है और अंत में _translated के साथ एक सहोदर कुंजी जोड़ती है:
"greeting": "Welcome back, {name}!",
"greeting_translated": "[ZH] Welcome back, {name}!",
यह समीक्षा के लिए अच्छी तरह से काम करता है, क्योंकि स्रोत और अनुवाद साथ-साथ होते हैं। यह ऐसी फ़ाइल नहीं है जिसे आपका ऐप लोड कर सके, क्योंकि अब प्रत्येक कुंजी का एक जुड़वाँ है। अपने ऐप में अनुवादित फ़ाइल का उपयोग करें।
एक कमी: सरणियों के अंदर की स्ट्रिंग्स को कोई _translated सहोदर नहीं मिलता, क्योंकि सरणी आइटम में जोड़ने के लिए कोई कुंजी नहीं होती। हमारे परीक्षण में, "menu": ["Open", "Save", "Export as EPUB"] द्विभाषी फ़ाइल में अंग्रेज़ी में वापस आया, लेकिन अनुवादित फ़ाइल में अनुवादित हुआ। यदि आप द्विभाषी फ़ाइल से समीक्षा करते हैं, तो अनुवादित फ़ाइल में सरणियों की जाँच करें।
टिप्पणियों वाली फ़ाइलें
कई प्रोजेक्ट अपनी भाषा फ़ाइलों में टिप्पणियाँ रखते हैं (JSONC), जिसकी सख्त JSON अनुमति नहीं देता। अनुवादक पहले सख्त JSON का प्रयास करता है। यदि वह विफल हो जाता है, तो यह टिप्पणियों और अनुगामी अल्पविरामों को हटाता है और फिर से प्रयास करता है। टिप्पणियों को हटाने का अर्थ है किसी पंक्ति पर // के बाद सब कुछ हटाना, और इसमें https:// में // भी शामिल है।
हमारी टिप्पणी और URL वाली फ़ाइल बिल्कुल लोड नहीं हुई; पहली टिप्पणी पर पार्सिंग विफल रही। टिप्पणियों वाली लेकिन किसी भी मान में // के बिना एक फ़ाइल ठीक से लोड हुई, और आउटपुट से टिप्पणियाँ हटा दी गईं।
तो: यदि आपकी फ़ाइल में टिप्पणियाँ हैं, तो अपलोड करने से पहले उन्हें हटा दें, या टिप्पणियों के साथ एक प्रति रखें और स्वीकार करें कि अनुवाद में वे नहीं होंगी।
चरण 2: फ़ाइल तैयार करें
आप अनुवाद करने से पहले इनमें से अधिकांश समस्याओं को ठीक कर सकते हैं:
- इसे सख्त JSON बनाएं। टिप्पणियाँ और अनुगामी अल्पविराम हटा दें। यदि आपका बिल्ड टूल JSONC पढ़ता है, तो टिप्पणी वाली फ़ाइल को अपने स्रोत के रूप में रखें और अनुवाद के लिए एक साफ प्रति निर्यात करें।
- एक कुंजी शैली का उपयोग करें। या तो कुंजियों को नेस्ट करें या उन्हें बिंदुओं के साथ समतल करें, एक फ़ाइल में दोनों नहीं। यदि आप i18next का उपयोग करते हैं, तो इसका
keySeparatorविकल्प नियंत्रित करता है कि कुंजियों में बिंदुओं को कैसे पढ़ा जाता है, इसलिए कुछ भी समतल करने से पहले उस सेटिंग की जाँच करें। - गैर-पाठ डेटा को बाहर निकालें। ID, URL, फ़ीचर फ़्लैग और सीमाएँ कॉन्फ़िग में होनी चाहिए, भाषा फ़ाइल में नहीं। यदि कोई URL रहना ही चाहिए, तो उसे रखें, लेकिन अनुवाद के बाद उसे जाँचने की अपेक्षा करें। हमारी अनुवाद न करने की मार्गदर्शिका में बताया गया है कि और क्या मूल भाषा में रहना चाहिए।
- प्लेसहोल्डर हर जगह एक ही तरह से लिखें। एक शैली, जैसे
{name},{name},{{name}}और%sके मिश्रण की तुलना में जाँचना आसान है।
चरण 3: पूरी फ़ाइल का अनुवाद करें
साफ की गई फ़ाइल को BookTranslator के दस्तावेज़ अनुवादक पर अपलोड करें, जो अन्य स्थानीयकरण और संरचित-पाठ प्रारूपों के साथ .json को सूचीबद्ध करता है जिन्हें वह स्वीकार करता है। चेकआउट से पहले मूल्य दिखाया जाता है। जब कार्य पूरा हो जाता है, तो आपका इतिहास पृष्ठ अनुवादित फ़ाइल और द्विभाषी फ़ाइल को अलग-अलग डाउनलोड के रूप में प्रदान करता है।
पाठ का अनुवाद कैसे होता है, यह दो बातों से परिणाम को प्रभावित करता है:
- मॉडल आपकी कुंजियाँ नहीं देखता। प्रत्येक मान को एक क्रमांकित खंड के रूप में भेजा जाता है, कुंजी के नाम के बिना। यदि
"button.open"और"status.open"दोनों में "Open" लिखा है, तो मॉडल के पास यह जानने का कोई तरीका नहीं है कि एक क्रिया है और दूसरा विशेषण। छोटी, अस्पष्ट स्ट्रिंग्स को हाथ से जाँचना चाहिए। - प्रत्येक मान का अनुवाद अलग-अलग होता है। दो कुंजियों को कुछ भी नहीं जोड़ता, इसलिए दो स्थानों पर एक ही शब्द दो अलग-अलग रूपों में वापस आ सकता है, और जिस शब्द के दो अलग-अलग अनुवाद चाहिए वह एक ही रूप में वापस आ सकता है। BookTranslator की वैकल्पिक ऑटो ग्लॉसरी नाम, स्थान और विशेष शब्दों को एकत्र करती है और उन्हें सुसंगत रखती है, लेकिन आप इसे अपने स्वयं के निश्चित अनुवाद नहीं दे सकते। जिन शब्दों का अनुवाद एक ही सटीक तरीके से होना चाहिए, उनके लिए एक शब्द सूची रखें और अनुवाद के बाद उन स्ट्रिंग्स को जाँचें; हमारी ग्लॉसरी गाइड बताती है कि एक की योजना कैसे बनाएँ।
इनलाइन HTML टैग्स को अनुवाद के बाद गिना जाता है, और जिस खंड के टैग मेल नहीं खाते उसे फिर से आज़माया जाता है। कर्ली-ब्रेस प्लेसहोल्डर्स, %s-शैली के प्लेसहोल्डर्स, और ICU सिंटैक्स को पाठ के भाग के रूप में भेजा जाता है लेकिन उसी तरह जाँचा नहीं जाता। प्रत्येक अनुवाद पर चरण 4 चलाएँ।
यदि आप चैट मॉडल या स्थानीय मॉडल से अनुवाद करना पसंद करते हैं, तो केवल मान भेजें, कभी भी कच्ची फ़ाइल नहीं, और उन्हें स्क्रिप्ट से कुंजी के अनुसार वापस रखें। नीचे दी गई जाँचें दोनों ही स्थितियों में लागू होती हैं।
चरण 4: अनुवादित फ़ाइल की जाँच करें
अनुवाद की स्रोत से तुलना करें:
python3 check_i18n_json.py en.json fr.json
यह क्या पकड़ता है, यह दिखाने के लिए हमने जानबूझकर त्रुटियों वाली एक फ़्रेंच फ़ाइल बनाई। यह हाथ से बनाई गई है, मॉडल आउटपुट नहीं। चरण 1 की तरह ही स्रोत चेतावनियों के बाद, चेकर ने प्रिंट किया:
ERROR app.greeting: placeholders differ; lost ['name'] extra ['nom']
ERROR app.help_url: urls differ; lost ['https://example.com/help'] extra ['https://example.com/aide']
ERROR app.items: ICU message has no 'other' case
ERROR app.legacy: placeholders differ; lost ['%d'] extra []
ERROR limits.maxFiles: type changed from int to str
ERROR limits.projectId: non-text value changed: 9007199254740993 -> 9007199254740992
INFO menu[1]: identical to source: 'Save'
INFO compared 20 source values, 1 unchanged strings
इनमें से प्रत्येक ऐप में बग के रूप में दिखाई देगा: एक खाली नाम, एक टूटा हुआ लिंक, बहुवचन प्रस्तुत होने पर क्रैश या कच्चा संदेश, एक गायब अध्याय संख्या, पाठ के रूप में तुलना की गई एक सीमा। INFO पंक्ति उन स्ट्रिंग्स को सूचीबद्ध करती है जो अपरिवर्तित वापस आईं। कुछ ठीक हैं, जैसे ब्रांड नाम; फ़्रेंच मेनू में "Save" नहीं है।
चेकर कुंजियों, मान प्रकारों, गैर-पाठ मानों, प्लेसहोल्डर्स ({name}, {{name}}, %s, %1$s, %@), ICU तर्क नामों, HTML टैग्स और URL की तुलना करता है। यह अनुवाद का स्वयं मूल्यांकन नहीं करता।
बहुवचन मामले बदलने चाहिए
एक ICU बहुवचन प्रत्येक बहुवचन श्रेणी के लिए एक संदेश सूचीबद्ध करता है। अंग्रेज़ी में दो श्रेणियाँ हैं, one और other, लेकिन कई भाषाओं में एक अलग सेट होता है। हमारे items संदेश का एक अच्छा रूसी अनुवाद सामान्यतः one, few, many, और other का उपयोग करेगा, और जापानी अनुवाद केवल other का। इसलिए यहाँ एक बेमेल हमेशा त्रुटि नहीं होती।
श्रेणियाँ Unicode CLDR बहुवचन नियमों से आती हैं, और other वह है जो हर भाषा में होती है। ये CLDR 48 के साथ Node.js में Intl.PluralRules द्वारा रिपोर्ट की गई मूल श्रेणियाँ हैं:
| भाषा | बहुवचन श्रेणियाँ |
|---|---|
| अंग्रेज़ी, जर्मन | one, other |
| फ़्रेंच, स्पेनिश, पुर्तगाली | one, many, other |
| रूसी, पोलिश | one, few, many, other |
| अरबी | zero, one, two, few, many, other |
| जापानी, चीनी, कोरियाई | अन्य |
फ़्रेंच, स्पेनिश और पुर्तगाली में many का उपयोग केवल बहुत बड़ी पूर्ण संख्याओं के लिए होता है, जैसे दस लाख, इसलिए छोटी गिनती के लिए संदेश में आमतौर पर इसकी आवश्यकता नहीं होती। चेकर other के अनुपस्थित होने को त्रुटि के रूप में रिपोर्ट करता है, और श्रेणियों में किसी अन्य परिवर्तन को इस तालिका से तुलना करने के लिए चेतावनी के रूप में बताता है। आप किसी भी भाषा के लिए सूची स्वयं प्रिंट कर सकते हैं:
node -e 'console.log(new Intl.PluralRules("ru").resolvedOptions().pluralCategories)'
अनुवादक को अंग्रेज़ी केस दिए जाते हैं, इसलिए जाँचें कि क्या वापस आया है। यदि रूसी या अरबी संदेश में अभी भी केवल one और other हैं, तो गायब केस हाथ से जोड़ें, या किसी अनुवादक से ऐसा करवाएँ।
फिर इसे ऐप में लोड करें
चेकर यह साबित करता है कि फ़ाइल लोड करने के लिए सुरक्षित है, यह नहीं कि वह अच्छी तरह पढ़ी जाती है। ऐप को नई भाषा में स्विच करें और स्क्रीन देखें: जर्मन या फ़िनिश में लंबे शब्द जो बटन से बाहर निकल जाते हैं, अरबी या हिब्रू में दाएँ-से-बाएँ पाठ, और तिथियाँ या संख्याएँ जिन्हें आपका कोड भाषा फ़ाइल से अलग से फ़ॉर्मेट करता है। हमारी अनुवाद बनाम स्थानीयकरण की गाइड में बताया गया है कि शब्दों के अलावा बाज़ारों के बीच और क्या बदलता है।
सामान्य समस्याएँ
अनुवादित फ़ाइल मेरे ऐप में लोड नहीं होगी। उस पर चेकर चलाएँ। यदि चेकर इसे पार्स नहीं कर सकता, तो फ़ाइल अनुवाद के बाद संपादित की गई थी या शुरू से ही मान्य नहीं थी। यदि यह पार्स हो जाती है, तो कुंजियों या प्रकारों के बारे में ERROR पंक्तियाँ देखें।
एक स्ट्रिंग कच्चे ICU संदेश के रूप में दिखाई देती है, जैसे {count, plural, ...}। अनुवाद में ICU सिंटैक्स टूट गया, आमतौर पर एक गायब ब्रेस या गायब other केस। स्रोत से संरचना कॉपी करें और केवल प्रत्येक केस के अंदर के शब्दों का अनुवाद करें।
मेरी फ़ाइल YAML, .po फ़ाइल, या Markdown है। BookTranslator इन्हें भी स्वीकार करता है, लेकिन प्रत्येक प्रारूप के अपने नियम हैं। दस्तावेज़ीकरण के लिए, हमारी Markdown अनुवाद गाइड देखें; वेब पेजों के लिए, HTML फ़ाइल गाइड देखें।
क्या मैं केवल नई कुंजियों का अनुवाद कर सकता हूँ? एक अपलोड के अंदर नहीं; पूरी फ़ाइल का अनुवाद होता है। नई कुंजियों को एक अलग फ़ाइल में रखें, उसका अनुवाद करें, और परिणाम को कुंजी के आधार पर मर्ज करें। चेकर पुष्टि करेगा कि मर्ज की गई फ़ाइल में हर कुंजी है।
क्या मुझे कुंजियों का अनुवाद करना चाहिए? नहीं। कुंजियाँ पहचानकर्ता हैं जिन्हें आपका कोड खोजता है। केवल मान ही लोगों के पढ़ने के लिए पाठ हैं।
संबंधित लेख





