Skip to content

Instantly share code, notes, and snippets.

@erenmustafaozdal
Last active July 10, 2023 16:06
Show Gist options
  • Save erenmustafaozdal/8700a83e675697ae46f9fe2c9efa919d to your computer and use it in GitHub Desktop.
Save erenmustafaozdal/8700a83e675697ae46f9fe2c9efa919d to your computer and use it in GitHub Desktop.
A class that handles translations and provides translation functionality.
import json
import random
from typing import Union
class TranslationHandler:
"""
A class that handles translations and provides translation functionality.
Attributes:
TRANSLATIONS (dict): A dictionary that holds loaded translations.
ROOT (str): The root directory path where the translations are stored.
"""
TRANSLATIONS = {}
ROOT = "./translations"
def get(self, key: str, **kwargs) -> str:
"""
Retrieves the translated value for the given key.
Args:
key (str): The translation key in the format 'path.to.translation::key'.
Returns:
str: The translated value for the key, with optional placeholders replaced.
Example:
translation_handler.get('common.error_message::not_found', name='Eren')
"""
keys, path = self._parse_key(key)
self._load_translation(path)
value = self._get_value(keys, path)
# If the translation text is a list, meaning that you have multiple
# alternative translations for a specific event, it selects one randomly.
if isinstance(value, list):
value = random.choice(value)
value = self._replace_placeholders(value, kwargs)
return value
def _parse_key(self, key: str) -> tuple[list, str]:
"""
Parses the translation key into path and key parts.
Args:
key (str): The translation key.
Returns:
tuple: A tuple containing a list of key parts and the translation file path.
Example:
keys, path = self._parse_key('common.error_message::not_found')
"""
path_parts, key_parts = key.split("::")
paths = path_parts.split(".")
path = f"{self.ROOT}/{'/'.join(paths[:-1])}/{paths[-1]}.json"
keys = key_parts.split(".")
return keys, path
def _load_translation(self, path):
"""
Loads the translation from the given path if it hasn't been loaded already.
Args:
path (str): The path of the translation file.
Example:
self._load_translation('./translations/common/error_message.json')
"""
if path not in self.TRANSLATIONS:
with open(path, "r", encoding="utf-8") as f:
self.TRANSLATIONS[path] = json.load(f)
def _get_value(self, keys: list, path: str) -> Union[str, list]:
"""
Retrieves the translation value for the given keys.
Args:
keys (list): A list of key parts.
path (str): The path of the translation file.
Returns:
Union[str, list]: The translation value.
Example:
value = self._get_value(['not_found'], './translations/common/error_message.json')
"""
value = self.TRANSLATIONS[path]
for key in keys:
value = value[key]
return value
def _replace_placeholders(self, value: str, placeholders: dict) -> str:
"""
Replaces placeholders in the translation value with the provided values.
Args:
value (str): The translation value.
placeholders (dict): A dictionary containing placeholder-value pairs.
Returns:
str: The translated value with placeholders replaced.
Example:
value = self._replace_placeholders('User :name not found', {'name': 'Eren'})
"""
for ph in placeholders.keys():
value = value.replace(f":{ph}", str(placeholders[ph]))
return value
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment