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
Allow translations of BTCPay Server Backend by admins #5662
base: master
Are you sure you want to change the base?
Conversation
Great work @NicolasDorier Thanks for picking up my (very old) work. Some things I'd still like to see are:
|
The choice of a single language is because the goal of this PR is to improve local adoption in Bitcoin. The expectation is that a Bitcoin ambassador onboard local businesses or friends on their local instance, and set the proper language for them so their first time experience with BTCPay is less intimidating. We aren't attempting to improve the life of a "international" host. Secondly, I am also not comfortable to put translations in merchant level, because at some place, we will want to allow HTML injection. (For example if the string to translate contains bold letters in some part) This mean that there would be a need for different screen to update the "User level strings" and the "Server level strings". This makes things more complicated for everyone. It makes also make things weird, as then the Server Level strings may be in one language, but the user level one in another language. This will result in screens mixing two languages.
For the
So if you are using English it's already the case. In other language it's more difficult, as we shouldn't override something that the user edited. If we did this, this would give us some serious UX dilemna in the following case:
|
Makes sense. Just consider if we have an easy upgrade path after this, or if it would be major refactoring down the line? If the latter, might make sense to have basic structure already in place. At the bare minimum, I think we need to add a dropdown to indicate which language is entered in the textarea. If we don't know the language, we cannot upgrade later to multi-language because we won't know what was entered.
If we bundle 1 language (i.e. Spanish) + provide a way to load others, it wouldn't be intimidating at all.
The way I solve this typically, is by allowing some tags + escape everything else. Example: the translated output is escaped, except for An alternative solution is to allow markdown in some places. Markdown is highly predictable and can be done safely.
Why can't all translations be in 1 place, only accessible by the admin? The merchant is just a user and has to use the translations set by the admin.
This is not an issue at all if we consider the bundled translations as defaults + use the textarea as a means to override specific lines. Most people don't want to bother with translations and will just use whatever is bundled or contibute via Transiflex. If a translation is missing or particulaly troublesome, they can override. |
If you feel bundling translations is risky, we can always make it "opt-in", so nobody is forced into this... |
b0bd0f4
to
7f76afc
Compare
7f76afc
to
8bc7600
Compare
Abstract
Sourced from #5468
To achieve our goal of widespread adoption of BTCPay Server by local communities, it is crucial to focus efforts on translating BTCPay. As it stands, only the checkout pages are translated, implying that BTCPay merchants must know English. This requirement significantly hinders local adoption.
The proposed solution should possess these characteristics:
IStringLocalizer
,IHtmlLocalizer
, or annotations for implementation.We can reasonably presume that the backend operates in a specific language, which can be designated in the server's policies.
Translations should be stored in the database and loaded into memory during runtime.
UX
This PR introduces backend translation capability in BTCPay Server for administrators. A new tab in server settings presents a large text field for updating translations, formatted as
[English] => [Translation]
. The simplicity of this UI facilitates easy modification and sharing of translations. A dedicated GitHub repository will host all translations, linked directly from this page.Translatable strings are primarily located under
Server Settings -> Translations
.Administrators can effortlessly import translations from other people into the text area and share their translations.
I plan to add a link to a github repository later so the community can share translations.
Prior to major release, we should probably show case a few languages translated through ChatGPT in such repository.
Localizable content
Developers have multiple options for making page content translatable:
<label asp-for="Property">
in views are automatically translatable if the target property has a[Display]
or[DisplayName]
attribute.text-translate="true"
tag helper in views marks tag content as translatable. This content should be text-only, as HTML is not currently supported.ViewLocalizer
object is injected for use asViewLocalizer["My sentence"]
.IStringLocalizer
,ViewLocalizer
, orIHtmlLocalizer
.Implementation
The system employs standard MVC interfaces like
IStringLocalizer
,ViewLocalizer
, andIHtmlLocalizer
, customized to meet the abstract's outlined requirements. Translations differing from default English versions are stored in the database, ensuring immediate reflection of localized string updates for English-speaking administrators (unless overridden).A
translations
table has been added withkey
andvalue
columns.Default translations
Ensuring discoverability of translatable strings is vital. These strings are predefined in
Translations.Default.cs
.To ease maintenance, a
UpdateDefaultTranslations
script functions similarly toPullTransifexTranslations
. This script, which requires periodic execution, updates hardcoded assets by scanning *.cs files for Display and DisplayName usage, and .cshtml files forViewLocalizer
ortext-translate
tag helper use. Detected translations are then incorporated intoTranslations.Default.cs
.It is possible for developer to manually edit
Translations.Default.cs
to add more strings.Out of scope
Translations.Default
could be modularized into a plugin format. This would enhance the discoverability of translations for plugins.text-translate
should be used in other parts of the source code, however, we can do this gradually rather than everything in this PRtooltip=
), we should probably do this later too.