ટ્રાન્સલેશન સિસ્ટમ: ત્રણ-ટેક્નોલોજી હાઇબ્રિડ અભિગમ
આ લેખ અમારી ટ્રાન્સલેશન સિસ્ટમ સમજાવે છે જે ત્રણ ટેક્નોલોજીને જોડે છે—ટેમ્પલેટ માટે Flask-Babel, ફ્રેઝ ટેબલ માટે TranslationManager, અને કન્ટેન્ટ ટ્રાન્સલેશન માટે DeepSeek AI—વ્યાપક બહુભાષી સપોર્ટ પ્રદાન કરવા માટે.
સમસ્યા: જટિલ વેબસાઇટનું ભાષાંતર
અમારી વેબસાઇટમાં બહુવિધ પ્રકારનું કન્ટેન્ટ છે જેનું ભાષાંતર કરવાની જરૂર છે:
-
સ્થિર ટેમ્પલેટ: નેવિગેશન, બટનો, લેબલો (500+ સ્ટ્રિંગ્સ)
-
ડાયનેમિક કન્ટેન્ટ: પ્રોડક્ટ નામો, વર્ણનો, ફીચર્સ (10,000+ સ્ટ્રિંગ્સ)
-
યુઝર-જનરેટેડ કન્ટેન્ટ: રિવ્યુઝ, કોમેન્ટ્સ, સપોર્ટ ટિકિટ્સ
-
ટેક્નિકલ ટર્મ્સ: બ્રાન્ડ નામો, SKUs, URLs (ભાષાંતર કરવું જ નહીં)
એક જ ભાષાંતર અભિગમ કામ કરતો નથી:
-
મશીન ભાષાંતર: ઝડપી પરંતુ ટેક્નિકલ ટર્મ્સ માટે અચૂક નથી
-
મેન્યુઅલ ભાષાંતર: ચોક્કસ પરંતુ ધીમું અને ખર્ચાળ
-
ફક્ત ટેમ્પલેટ: ડાયનેમિક કન્ટેન્ટ હેન્ડલ કરતું નથી
આપણે એક હાઇબ્રિડ અભિગમની જરૂર છે જે ત્રણેયના શ્રેષ્ઠને જોડે.
ટ્રાન્સલેશન આર્કિટેક્ચર
graph TD
Request[વપરાશકર્તા રિક્વેસ્ટ
lang=hi]
subgraph Templates
Babel[Flask-Babel
.po ફાઇલો]
Static[સ્થિર સ્ટ્રિંગ્સ
બટનો, લેબલો]
end
subgraph Dynamic
TM[TranslationManager
ફ્રેઝ ટેબલ]
Phrases[પ્રોડક્ટ નામો
ફીચર્સ, ટર્મ્સ]
end
subgraph AI
DS[DeepSeek API
AI ભાષાંતર]
Content[વર્ણનો
લેખો, લાંબુ ટેક્સ્ટ]
end
Request --> Babel
Request --> TM
Request --> DS
Babel --> Static
TM --> Phrases
DS --> Content
Static --> Response[ભાષાંતરિત પેજ]
Phrases --> Response
Content --> Responseત્રણ ટેક્નોલોજી
1. Flask-Babel: ટેમ્પલેટ ટ્રાન્સલેશન
Flask-Babel gettext .po ફાઇલોનો ઉપયોગ કરીને સ્થિર ટેમ્પલેટ સ્ટ્રિંગ્સ હેન્ડલ કરે છે.
-
ઉપયોગ કેસ: નેવિગેશન, બટનો, લેબલો, એરર મેસેજીસ
-
ઉદાહરણ:
# ટેમ્પલેટ
{{ _('Add to Cart') }}
# .po ફાઇલ (હિન્દી)
msgid "Add to Cart"
msgstr "કાર્ટમાં ઉમેરો"
લાભો:
-
✅ સ્ટાન્ડર્ડ i18n અભિગમ
-
✅ ટ્રાન્સલેશન ટૂલ્સ સપોર્ટ (Poedit, Weblate)
-
✅ કમ્પાઇલ-ટાઇમ વેલિડેશન
-
✅ ફાસ્ટ લુકઅપ (કમ્પાઇલ્ડ .mo ફાઇલો)
મર્યાદાઓ:
-
❌ ફક્ત સ્થિર સ્ટ્રિંગ્સ માટે કામ કરે છે
-
❌ નવી સ્ટ્રિંગ્સ ઉમેરવા માટે કોડ ફેરફારની જરૂર છે
-
❌ ડાયનેમિક કન્ટેન્ટ સપોર્ટ નથી
2. TranslationManager: ફ્રેઝ ટેબલ
અમારું કસ્ટમ TranslationManager ક્લાસ JSON ફ્રેઝ ટેબલનો ઉપયોગ કરીને ડાયનેમિક કન્ટેન્ટ હેન્ડલ કરે છે.
-
ઉપયોગ કેસ: પ્રોડક્ટ નામો, ફીચર્સ, સ્પેસિફિકેશન્સ, વર્ણનો
-
ઉદાહરણ:
{
"Mini PC": "મિની પીસી",
"Intel N100": "Intel N100",
"8GB RAM": "8GB RAM",
"256GB SSD": "256GB SSD"
}
લાભો:
-
✅ ડાયનેમિક કન્ટેન્ટ સપોર્ટ
-
✅ રનટાઇમ અપડેટ્સ (રીસ્ટાર્ટની જરૂર નથી)
-
✅ પ્રિઝર્વેશન નિયમો (બ્રાન્ડ નામો, SKUs)
-
✅ રીજનલ ફોર્મેટિંગ (દશાંશ સેપરેટર)
-
✅ ટ્રાન્સલેશન કતાર (ગુમ થયેલ સ્ટ્રિંગ્સ)
મર્યાદાઓ:
-
❌ મેન્યુઅલ ફ્રેઝ મેનેજમેન્ટ
-
❌ ભાષાંતરકો માટે કોન્ટેક્સ્ટ નથી
-
❌ પ્રારંભિક ભાષાંતરની જરૂર છે
3. DeepSeek AI: કન્ટેન્ટ ટ્રાન્સલેશન
DeepSeek AI મોડલ લાંબા ફોર્મના કન્ટેન્ટ ભાષાંતર હેન્ડલ કરે છે.
-
ઉપયોગ કેસ: બ્લોગ લેખો, પ્રોડક્ટ વર્ણનો, માર્કેટિંગ કોપી
-
ઉદાહરણ:
prompt = f"Translate to {lang}: {text}"
response = deepseek.generate(prompt)
લાભો:
-
✅ લાંબા કન્ટેન્ટ હેન્ડલ કરે છે (1000+ શબ્દો)
-
✅ કોન્ટેક્સ્ટ-એવેર ટ્રાન્સલેશન
-
✅ નેચરલ લેંગ્વેજ આઉટપુટ
-
✅ બેચ પ્રોસેસિંગ
મર્યાદાઓ:
-
❌ ટ્રાન્સલેશન દીઠ API કિંમત
-
❌ ઇન્ટરનેટ કનેક્શનની જરૂર છે
-
❌ ટેક્નિકલ ટર્મ્સ ખોટી રીતે ભાષાંતર કરી શકે છે
TranslationManager આર્કિટેક્ચર
ફ્રેઝ ટેબલ સ્ટ્રક્ચર
ફ્રેઝ ટેબલ ભાષા દીઠ JSON ફાઇલો તરીકે સ્ટોર થાય છે:
app/shared/translation/phrase_tables/
દરેક ફાઇલ અંગ્રેજી ફ્રેઝને ભાષાંતરો સાથે મેપ કરે છે:
{
"Mini PC": "મિની પીસી",
"Thin Client": "થિન ક્લાયંટ",
"Industrial PC": "ઔદ્યોગિક પીસી",
"All-in-One": "ઑલ-ઇન-વન"
}
ટ્રાન્સલેશન લુકઅપ
get() મેથડ મલ્ટિ-ટાયર લુકઅપ કરે છે:
1. પ્રિઝર્વેશન ચેક:
if self._should_skip_translation(text, lang):
return text # બ્રાન્ડ નામો, SKUs, URLs ભાષાંતર ન કરો
2. કોમા સ્પ્લિટિંગ (લાંબી સ્ટ્રિંગ્સ માટે):
if len(text) > 150 and "," in text:
parts = text.split(",")
return ", ".join(self.get(p, lang) for p in parts)
3. ફ્રેઝ ટેબલ લુકઅપ:
if text in self.phrase_tables[lang]:
return self.phrase_tables[lang][text]
4. લેગસી કેશ પ્રોમોશન:
if text_hash in self.legacy_caches[lang]:
translation = self.legacy_caches[lang][text_hash]
self.set(text, lang, translation) # ફ્રેઝ ટેબલમાં પ્રોમોટ કરો
return translation
5. ગુમ થયેલ હોય તો કતારમાં મૂકો:
if queue_if_missing:
self.add_to_queue(text, lang)
return None # ભાષાંતર મળ્યું નથી
પ્રિઝર્વેશન નિયમો
અમે ચોક્કસ કન્ટેન્ટ પ્રકારોને સાચવીએ છીએ:
બ્રાન્ડ નામો:
BRAND_NAMES_PRESERVE = [
"Thinvent", "Intel", "AMD", "Microsoft", "Ubuntu",
"Windows", "Linux", "WiFi", "Bluetooth"
]
ટેક્નિકલ ટર્મ્સ:
TECHNICAL_TERMS_PRESERVE = [
"HDMI", "DisplayPort", "VGA", "USB", "Ethernet",
"DDR4", "SSD", "NVMe", "PCIe", "SATA"
]
SKUs (પેટર્ન-આધારિત):
if not " " in text and text.count("-") >= 2:
return True # "Treo-N100-8-256-2H-W6-11P" સાચવો
URLs:
if text.startswith(("/", "http://", "https://")):
return True
રીજનલ ફોર્મેટિંગ
યુરોપિયન લોકેલ્સ (જર્મન, ફ્રેન્ચ, સ્પેનિશ) માટે, અમે રીજનલ ફોર્મેટિંગ લાગુ કરીએ છીએ:
દશાંશ સેપરેટર:
# અંગ્રેજી: 34.00
# જર્મન: 34,00
text = text.replace(".", ",")
વોલ્ટેજ/એમ્પેરેજ:
# અંગ્રેજી: 12.5V
# જર્મન: 12,5V
text = re.sub(r"(\d+)\.(\d+)V", r"\1,\2V", text)
આ ખાતરી કરે છે કે નંબરો દરેક લોકેલ માટે યોગ્ય રીતે દેખાય છે.
ટ્રાન્સલેશન કતાર
ગુમ થયેલ ભાષાંતરો બેચ પ્રોસેસિંગ માટે કતારમાં મૂકવામાં આવે છે:
[
{
"text": "Compact Desktop",
"lang": "hi",
"hash": "a1b2c3d4e5f6"
},
{
"text": "Fanless Design",
"lang": "hi",
"hash": "f6e5d4c3b2a1"
}
]
બેકગ્રાઉન્ડ સ્ક્રિપ્ટ DeepSeek AI નો ઉપયોગ કરીને કતાર પ્રોસેસ કરે છે:
for item in queue:
translation = deepseek.translate(item["text"], item["lang"])
translation_manager.set(item["text"], item["lang"], translation)
ફાઇલ લોકિંગ
અમે કન્કરન્ટ રાઇટ્સને રોકવા માટે fcntl ફાઇલ લોકિંગનો ઉપયોગ કરીએ છીએ:
```python with open(lock_path, "w") as lock_file: fcntl.flock(lock_file, fcntl.LOCK_EX) try: # ફ્રેઝ ટેબલ વાંચો, સંશોધિત કરો, લખો with open(table_path, "r+") as f: data = json.load(f) data.update(new_translations) f.seek(0) json.dump(data, f)