A lightweight Python package designed to facilitate seamless translation for multilingual websites.
Project description
Transify: A Multi-Language Translator for Web Applications
Transify is a Python library designed for easy integration of multi-language translation functionality in web applications. It allows you to use custom translation files (in JSON format) for various languages and locales. This tool is ideal for web frameworks like FastAPI, Flask, or any other platform where dynamic translations are necessary.
Features
- Multiple Language Support: Add and manage different languages by simply providing JSON files for each language.
- Dynamic Replacements: Supports dynamic replacements like variable insertion into translated strings.
- Nested Translation Keys: Allows translation via nested keys (e.g., captions.hello).
- Locale Switching: Switch between different locales on-the-fly.
- Works with Jinja2 Templates: Easily integrate with Jinja2 templates for real-time translations in your web pages.
Installation
You can install transify via pip or poetry:
Using pip:
pip install transify
Using poetry:
poetry add transify
Setting Up Translations
-
Create Language Folders: In your project, create a folder named lang to hold your translation files.
-
Add Translation Files: Inside the lang folder, create subdirectories for each language (e.g., en, fa) and add the respective translation JSON files.
Example structure:
lang/
en/
captions.json
messages.json
validations.json
fa/
captions.json
messages.json
validations.json
...
Example JSON Files
Below are examples of the translation files in JSON format:
captions.json
{
"name": "Azadjalal",
"first_name": "First name",
"hello": "Hello",
"goodbye": "Goodbye",
"username": "username",
"good_score": "Good score"
}
messages.json
{
"welcome": "Welcome, :name to my website :website.",
"errors": {
"create": "Create item failed.",
"user": {
"not_found": "The user not found."
}
}
}
validations.json
{
"required": "The :attr is required.",
"between": "The :attr must be between :min and :max values."
}
Using Transify in a Project
Here’s an example of how you can integrate transify into a FastAPI project:
import pathlib
import uvicorn
from fastapi import FastAPI
from fastapi.requests import Request
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from transify import *
app = FastAPI(title='transify', version='1.0.0')
# Mount static resources
app.mount(
'/resources',
StaticFiles(directory=f'{pathlib.Path(__file__).resolve().parent}/resources', html=False),
name='static'
)
# Jinja2 template setup
templates = Jinja2Templates(
directory=f'{pathlib.Path(__file__).resolve().parent}/resources'
)
# Update the template environment with the trans function
templates.env.globals.update(trans=trans)
def startup():
load_languages(path='tests/lang', default_fallback='en')
app.add_event_handler('startup', startup)
@app.get('/', response_class=HTMLResponse)
async def get_home(request: Request):
return templates.TemplateResponse('home.html', {'request': request, 'lang': get_locale()})
if __name__ == '__main__':
uvicorn.run('test_webapp:app', host='localhost', port=8000, reload=True)
Then in your Jinja2 templates, you can use the translations like this:
<!DOCTYPE html>
<html lang={{ lang }}>
<head>
<title>Transify Example</title>
</head>
<body>
<!-- Example: Display translation for 'hello' -->
<span>{{ trans('captions.hello') }}</span> <!-- Outputs: Hello -->
</body>
<footer>
<!-- Example: Display translation for 'welcome' -->
{{ trans('messages.welcome', 'name:Azadjalal|website:azadjalal.ir') }} <!-- Outputs: Welcome, Azadjalal to my website azadjalal.ir -->
</footer>
</html>
Functions and Methods
load_languages(path: str = 'lang', default_fallback: str = 'en')
oads translation files from the given path and sets up the languages. If a language file is missing, it falls back to the default_fallback language (usually 'en').
set_locale(locale: str)
Sets the active locale to the desired language. For example, you can switch between "en" (English) and "fa" (Farsi) by calling:
set_locale('fa')
get_locale()
Returns the current active locale.
trans(key: str, value: str = None)
This is the core translation function. It takes the key (e.g., captions.hello) and looks up the corresponding translation in the active language files. If a value is provided, it performs dynamic replacements.
- For simple translation:
trans('captions.hello') # Output: "Hello"
- For translations with dynamic replacements (using : syntax):
trans('messages.welcome', value='name:Azadjalal|website:azadjalal.ir')
# Output: "Welcome, Azadjalal to my website azadjalal.ir."
Testing the Library
We have included a test_transify.py file to help you verify the functionality of the library. It uses Python’s unittest framework and covers various scenarios such as loading languages, setting locales, basic translations, dynamic replacements, and nested keys.
python test_transify.py
Sample Test Cases in test_transify.py
- Load Languages Test if the languages are correctly loaded:
self.assertIn('en', lang.languages)
self.assertIn('fa', lang.languages)
- Set Locale Test switching between locales:
set_locale('fa')
self.assertEqual(get_locale(), 'fa')
set_locale('en')
- Basic Translation Test basic translations:
self.assertEqual(trans('captions.hello'), 'Hello')
- Dynamic Replacements Test translations with dynamic replacements:
self.assertEqual(
trans('validations.between', value='score|min:1|max:20'),
'The score must be between 1 and 20 values.'
)
- Nested Keys Test translations with nested keys:
self.assertEqual(trans('messages.errors.user.not_found'), 'The user not found.')
- Locale-Specific Translations Test translations in different locales:
set_locale('fa')
self.assertEqual(trans('captions.hello'), 'سلام')
Error Handling
If a key is missing or there’s an error during the translation process, the library will log an error and return the original key as a fallback. For example:
trans('messages.nonexistent') # Returns 'messages.nonexistent'
Customization
You can customize the load_languages function to load translations from any directory structure or path you prefer. This makes it easy to fit into different project setups.
Conclusion
With transify, you can easily manage multi-language support in your web application, with simple setup, dynamic translations, and seamless integration into Jinja2 templates. Whether you’re working with FastAPI or another web framework, this library provides everything you need for language management.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file transify-1.0.0.tar.gz.
File metadata
- Download URL: transify-1.0.0.tar.gz
- Upload date:
- Size: 6.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc42778fc5f8f76c401a0e2c27b0f68be45961c2cb9c4942a2e9e6ab043fcaea
|
|
| MD5 |
ab224c40e6150a191837f76eda7d44f6
|
|
| BLAKE2b-256 |
f42e992b0a466038d00f2f3fdef1803f674576f9b77ba801d88408033333cd8c
|
File details
Details for the file transify-1.0.0-py3-none-any.whl.
File metadata
- Download URL: transify-1.0.0-py3-none-any.whl
- Upload date:
- Size: 6.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.20
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
00efcf205b77070670541c5504c27e63e7f35dc8364ebc44bb714ba72acda05a
|
|
| MD5 |
29669c33d8c1ff29a3e6e9bce40e6518
|
|
| BLAKE2b-256 |
ec18c14e860123ad4d77ca7c04347917d8a4802273f11c1ac93e64242932d65a
|