Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request for Adding Support for Localized Key References #10

Closed
zyf722 opened this issue Jul 25, 2023 · 8 comments
Closed

Request for Adding Support for Localized Key References #10

zyf722 opened this issue Jul 25, 2023 · 8 comments
Labels
enhancement New feature or request

Comments

@zyf722
Copy link

zyf722 commented Jul 25, 2023

Appreciation

First, I want to thank you first for taking on the maintenance of the original python-i18n package and add more functionality to it.
This simple, lightweight, and user-friendly i18n tool saves me a lot of time. Salute.

Feature Request

Here I'd like to request a feature addition to enhance the package's capabilities. Specifically, the support for localized key references.

An example written in JSON is provided as follows:

{
    "en": {
        "DUMMY_1": "dummy1",
        "DUMMY_2": "dummy2",
        "MENU_A_DUMMY": "${DUMMY_1} and ${DUMMY_2}",
        "MENU_B_DUMMY": "${DUMMY_1}"
    }
}

And the corresponding expected result will be:

i18n.t("MENU_A_DUMMY") # Output: dummy1 and dummy2

With a special syntax (${} here, could be replaced with any other delimiters), it would be possible to reference existing localized keys within other translations.

The proposed approach offers two significant advantages: interface flexibility through referencing multiple localized keys within a single translation, allowing diverse interfaces that are easily modifiable in the future, and translation reusability, minimizing redundancy and improving maintenance efficiency.

I believe adding support for localized key references would improve the package's utility, especially for projects with complex translation requirements.

Thank you for considering this enhancement request.

@zyf722
Copy link
Author

zyf722 commented Jul 26, 2023

I have created a simple wrapper class to address this issue.

import i18n
from string import Template

i18n.set('file_format', 'json')
i18n.set('filename_format', '{locale}.{format}')
i18n.load_path.append('./i18n/')

class KeyRefFormatter(Template):
    delimiter = "$"
    
    def __init__(self, template, **kwargs):
        template = i18n.t(template, **kwargs)
        super().__init__(template)
        self.kwargs = kwargs
    
    # From https://github.com/python/cpython/issues/90465
    # For Python 3.11+, use library method string.Template.get_identifiers() instead
    def get_identifiers(self):
        return list(
            set(
                filter(
                    lambda v: v is not None,
                    (mo.group('named') or mo.group('braced') 
                     for mo in self.pattern.finditer(self.template))
                )
            )
        )
        
    def format(self):
        sub_dict = { key: i18n.t(key, **self.kwargs) for key in self.get_identifiers() }
        return self.safe_substitute(sub_dict)

def _(key, **kwargs):
    return KeyRefFormatter(key, **kwargs).format()

print(_('MENU_A_DUMMY', placeholder_1="def", placeholder_2="abc"))
# Output: dummy1 with def, and dummy2 with abc

The corresponding en.json file is as follows:

{
    "en": {
        "DUMMY_1": "dummy1 with %{placeholder_1}",
        "DUMMY_2": "dummy2",
        "MENU_A_DUMMY": "${DUMMY_1}, and ${DUMMY_2} with %{placeholder_2}",
        "MENU_B_DUMMY": "${DUMMY_1}"
    }
}

This is a workaround and a temporary solution. Perhaps it can be further integrated into this project in the future?

@solaluset solaluset added the enhancement New feature or request label Jul 27, 2023
@solaluset
Copy link
Owner

Thanks for opening the issue. I agree that this can be a useful feature.

@solaluset
Copy link
Owner

You can take a look at my pull request and share your thoughts.

@zyf722
Copy link
Author

zyf722 commented Jul 29, 2023

Looks good and thanks for your work!

Let me confirm, so the static reference feature and placeholder feature share the delimiter %, right?

Additionally, could you explain the behavior of the feature when the referenced value contains a placeholder?

For instance, in my example above, MENU_A_DUMMY includes the placeholder %{placeholder_2} and also references DUMMY_1, which itself contains the placeholder %{placeholder_1}. In this case, would i18n.t('MENU_A_DUMMY', placeholder_1="def", placeholder_2="abc") work as expected? Perhaps this could be added as a test case.

@solaluset
Copy link
Owner

It's already covered by tests and described in the readme. You probably got confused because the library uses placeholder delimiter (defaults to %) for placeholders (and now static refs) and namespace delimiter (defaults to .) for keys.

To create a static reference, you put it as key prefixed with namespace delimiter ("%{.DUMMY_1}, and %{.DUMMY_2} with %{placeholder_2}" in your case)

Let me know if you have any suggestions for description improvement, because I'm kind of bad when it comes to explaining things ;)

@zyf722
Copy link
Author

zyf722 commented Jul 29, 2023

Oh, I figure it out now. It would be great if everything works just as expected! 👏
The description is just fine and thank you for the update. Looking forward to the new version being released on PyPI!

@solaluset
Copy link
Owner

I'll keep this open until the new release is published

@solaluset
Copy link
Owner

New version is released 🎉
Thanks for your input. In case if something doesn't work as intended, please open a new issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants