I've been working with translations and menus packages and I want to share my thoughts.
1. ../translations/strings.py/LangStrings.get_strings
Here's this method
Syntax: Select all
def get_strings(self, key, **tokens):
"""Return a TranslationStrings object with updated tokens."""
strings = self[key]
strings.tokens.update(tokens)
return strings
I don't quite understand its purpose. It updates TranslationStrings's tokens, but does it in place.
Say we have the following plugin
popuptest/my_strings.ini
Code: Select all
[title]
en="Popup Title :) "
[option]
en="Option ${num}!"
popuptest.py
Syntax: Select all
from filters.players import PlayerIter
from menus import PagedMenu, PagedOption
from translations.strings import LangStrings
my_strings = LangStrings("popuptest/my_strings")
def popup_callback(popup, player_index, option):
pass
popup = PagedMenu(select_callback=popup_callback,
title=my_strings['title'])
for i in range(15):
option = PagedOption(text=my_strings.get_strings('option', num=i))
popup.append(option)
def load():
popup.send(*[player.index for player in PlayerIter('human')])
Here I'm playing with popup (note that there's issue #107 is up, but it's doesn't fit this particular case) and I'm using the same exact translation string for each option, but want to pass to them different tokens. If .get_string() created a new TranslationStrings instance and modified its tokens instead of updating them in the original instance, we would get something beautiful:
1. Option 0!
2. Option 1!
3. Option 2!
...
Instead we're getting
1. Option 14!
2. Option 14!
3. Option 14!
...
I don't understand why we touch original TranslationStrings instance (the one that is stored in LangStrings)
If we instead created a shallow copy of the original TranslationStrings instance this way:
Syntax: Select all
def get_strings(self, key, **tokens):
"""Return a TranslationStrings object with updated tokens."""
strings = TranslationStrings(self[key])
strings.tokens.update(tokens)
return strings
and made TranslationStrings act like a real dict (currently it does not accept no args no kwargs - I want it to accept everything and pass to an internal dict):
Syntax: Select all
class TranslationStrings(dict):
"""Stores and get language strings for a particular string."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.tokens = {}
then we would get the wanted result, the beautiful one.
2. ../translations/strings.py/TranslationStrings.get_string
I want it to accept other TranslationStrings instances as tokens values. Example:
Code: Select all
[team alpha]
en="Alpha"
ru="?????"
[your_team_is]
en="Your current team is $team"
Syntax: Select all
SayText2(message=my_strings['your_team_is']).send(player_index, team=my_strings['team alpha'])
This can be achieved by adding a few lines to get_string and making it recursive:
Syntax: Select all
def get_string(self, language=None, **tokens):
for token_name, token in tokens.items():
if isinstance(token, TranslationStrings):
new_tokens = tokens.copy()
del new_tokens[token_name] # To avoid infinite recursion
token = token.get_string(language, **new_tokens)
tokens[token_name] = token
# rest of the code...
What do you guys think?
Edit: after a second thought... We could possibly do a shallow copy with .copy method, but I'm unsure if that method would return an instance of the same class or a regular Python dict.