Emre's Blog

Flask-Babel ile Çok Dilli Uygulamalar: i18n (Uluslararasılaşma) ve l10n (Yerelleştirme)

download(3)

Giriş

Farklı uluslardan kullanıcılara hizmet vermek, günümüz uygulamalarında önemli bir gereklilik haline gelmiştir. Bu süreç, temelde ikiye ayrılır: i18n (Uluslararasılaşma) ve l10n (Yerelleştirme). i18n, uygulamanızın birden fazla dili ve kültürü destekleyecek şekilde tasarlanmasıdır. l10n ise bu genel yapıyı, belirli bir dildeki veya bölgedeki kullanıcıya özel hale getirmeyi amaçlar. Örneğin, bir kullanıcının diline uygun metinler veya yerel tarih saat formatları sağlamak gibi.

Bu yazıda, daha çok dil için yerelleştirme kısmına odaklanacağız. Flask uygulamanızda, farklı uluslardan gelen kullanıcılarınıza kendi dillerine uygun yanıtlar sunabilmek için kullanabileceğiniz araçlardan biri de Flask-Babel'dir. Flask-Babel, bu amaç doğrultusunda kullanabileceğiniz uygulaması kolay, basit ve anlaşılır araçların başında gelir.

Kurulum ve Temel Yapılandırma

İlk olarak Flask-Babel için gerekli paketleri yükleyelim. requirements.txt dosyanız var ise ona da eklemeyi unutmayın.

$ pip install flask-babel

Ardından uygulama konfigürasyonlarımızı yapalım.

from flask import Flask
from flask_babel import Babel

app = Flask(__name__)
app.config['BABEL_DEFAULT_LOCALE'] = 'en'
app.config['BABEL_SUPPORTED_LOCALES'] = ['en', 'tr']

babel = Babel(app, locale_selector=get_locale)

Dil Tespiti (get_locale)

Locale Selector ne olaki demiş olabilirsiniz. Locale Selector uygulamanıza gelen HTTP isteğinin Accept-Language başlığından (header) istemcinin (client) tercih ettiği dil bilgisini alır. Babel, bu sayede hangi çeviri dosyasını kullanacağını belirler. Flask-Babel'in eski sürümlerinde @babel.localeselector dekoratörü doğrudan get_locale fonksiyonu üzerinde kullanılarak locale_selector tanımlanıyordu. Ancak yeni versiyonlarda uygulama konfigürasyonunda (app.config) Babel başlatıcısına bir parametre olarak verilmesi gerekiyor.

from flask import request, current_app

def get_locale():
    return request.accept_languages.best_match(current_app.config['BABEL_SUPPORTED_LOCALES'])

Desteklenen dilleri doğrudan bir liste olarak da verebilirsiniz ya da yukardaki gibi app.config'den çekebilirsiniz.

Genel Kullanım

Sırada çevirilerin uygulanmasını istediğiniz kısımları belirtmek var. Bu adım için gettext fonksiyonu kullanılır.

from flask_babel import gettext
@app.route('/')
def index():
    message = gettext("hello_world")
    return message

Çeviri Dosyaları (Translation Files)

Sırada çeviri dosyalarımızı oluşturmak ve konfigüre etmek var.

Öncelikle babele kullandığımız gettext vb. fonksiyonları nerede araması gerektiğini söylemeliyiz.

babel.cfg dosyasını oluşturup içerisine:

[python: **.py]
[jinja2: **/templates/**.html]

yazdığımızda bu bize babelin .py uzantılı dosyalarımız ve jinja templatelerimizin tümünde arama yapacağını belirtmektedir.

Ardından arama işlemini başlatmak var.

$ pybabel extract -F babel.cfg -o messages.pot .

Kodunu terminalde çalıştırdığımızda bize messages.pot adlı bir dosya oluşturacaktır. İçerisinde bir nevi harita denebilecek bir içerik barındırır. Uygulamanızda babel fonksiyonlarınızı nerede, kaç kez kullandığınız ve id leri alıp size bir liste gibi sıralar. Örneğin:

# Translations template for PROJECT.
# Copyright (C) 2024 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2024.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-12-18 10:49+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 2.16.0\n"

#: app.py:19
msgid "hello_world"
msgstr ""

Bu içerikte gördüğünüz msgid çevirinin id'si, boş olan msgstr ise bunun çevirisi olacaktır. Fakat bu dosya üzerinde çeviri işlemlerini yapmıyoruz. Bunu çeviri dosyalarınızı oluşturmak için kullanacağınz bir template gibi düşünebilirsiniz.

Sırada messages.pot dosyasını kullanarak her dil için ayrı çeviri dosyalarını oluşturmak var.

$ pybabel init -i messages.pot -d translations -l en
$ pybabel init -i messages.pot -d translations -l tr

Bu kod blokları uygulamanızın ana dizininde translations dosyası altında 2 adet klasör oluşturacaktır. en ve tr isimli. İçerisinde messages.po dosyalarını göreceksiniz. Bu dosyalar sizin çeviriler için oynayıp değiştireceğiniz dosyalar.

Örneğin tr klasöründeki messages.po dosyanızı açtığınızda:

msgid "hello_world"
msgstr ""

gibi bir kullanım göreceksiniz. Burda yapmanız gereken msgstr kısmındaki tırnaklar içerisine hello_world id'li stringin tr çevirisini yazmak olacak. Örneğin:

msgid "hello_world"
msgstr "Merhaba Dünya!"

Bu şekilde tüm msgstr'leri doldurduktan sonra sırada messages.po dosyalarınızı compile etmek var.

$ pybabel compile -d translations

Bu işlemden sonra messages.mo dosyalarının oluştuğunu göreceksiniz.

Sonuncu adımı da tamamladığımıza göre çeviriler için her şey hazır.

Sonuç

Özetle Babel, Flask uygulamalarınızda kullanıcılarınızın dillerine göre yanıt dönmek için kullanabileceğiniz basit ve performanslı araçlardan biri.


Emre Basiboyuk | Backend Developer

Bloguma e-posta ile abone olun.

İletişim için: contact@emrebasiboyuk.com

#flask #flask-babel #i18n-l10 #yerelleştirme