Replies: 27 comments 39 replies
-
Thank you, @zyf722 for the suggestion. This is also related to providing a RTL layout, since a significant percentage of LiveCodes users have Arabic as their first language. |
Beta Was this translation helpful? Give feedback.
-
I have opened an issue for this here: |
Beta Was this translation helpful? Give feedback.
-
Glad to see this is being considered. If possible, I would like to have a try to work on this. I think i18next could be a good choice for i18n library based on following reasons:
I might take some time to get familiar with the codebase and other current existing i18n implementations, then try to make a demo to validate the feasibility of this proposal. |
Beta Was this translation helpful? Give feedback.
-
After some research, I believe the hardest part of this challenge is to find out all hard-coded UI strings out of other string literals. String concatenation shall also be considered since it is indeed a common way to dynamically generate strings. Frustatingly, there seems to be no easy way to do this. Existing tools either are not designed to handle this task (instead, they basically extract keys like The only choice left is to manually search for hard-coded strings. But ahead of that, it is necessary to understand where to look for. After a quick look at the codebase, I wonder if all we have to check is @hatemhosny Any idea if this is the right approach? If so, I will start working on it. Otherwise, please let me know what you think. Thanks! |
Beta Was this translation helpful? Give feedback.
-
yes, @zyf722 , I see what you mean. i18n was not put in mind when developing LiveCodes, so no effort was made to isolate user-facing text.
exactly as you say, most UI strings can be found in those 2 folders. html files in Other much fewer strings will be elsewhere, like tool names: https://github.com/live-codes/livecodes/blob/develop/src/livecodes/toolspane/tools.ts#L29C1-L42C5 If you start, I can help or guide for the rest. Please note that I would prefer lazy-loading language resources for the selected language only. Thanks a lot for willing to help. |
Beta Was this translation helpful? Give feedback.
-
Here's some progress about infrastructure and HTML-related work. All changes could be checked here in my fork. Infrastructure
HTML
As for static HTML, I checked Current workaround is to add Then, these elements will be processed in their container's corresponding handler in To preview, you may want to change That's all for now. Please let me know if you have any suggestions or questions. By the way, is it still available to assign the issue by commenting |
Beta Was this translation helpful? Give feedback.
-
@zyf722 I have some comments:
Let me know what you think. edit: Of course, I would be happy to assign you to this issue. Just add a comment there so that I can assign you. |
Beta Was this translation helpful? Give feedback.
-
After checking bundle size, I found that the app minified bundle size increased from 313kb to 385kb after adding the i18n dependencies. The variable A helper function The type I have opened a PR in your repo with these changes |
Beta Was this translation helpful? Give feedback.
-
All changes look great to me. I only have one question about language detection in core.ts when no language is explicitly set. This seems to do the same thing as the language detector plugin (which has more ways to detect the language besides Another thing to mention is that i18next offers namespace support which allows to further separate translations into different files. How many localized strings do you roughly estimate in the application? Should separate files be considered for better maintainability? If there's no other major changes, I shall merge the PR and continue to work on the next steps once we reach a consensus on the above points. |
Beta Was this translation helpful? Give feedback.
-
I agree on removing language detection plugin. Other ways for language detection are either not needed or already provided by the app. Something else we need to consider. Currently the I think keeping each translation in a single file will be easier to manage and easier for contributors to provide more translations. However, the language-info file is quite large. Can we keep this file in a separate namespace for lazy-loading and have everything else together? |
Beta Was this translation helpful? Give feedback.
-
We may use Weblate to allow contributions for translation to different languages. This is a demo for the-algorithms.com: https://github.com/TheAlgorithms/website?tab=readme-ov-file#translating-the-website We should consider this after extracting text to be translated. |
Beta Was this translation helpful? Give feedback.
-
New progress here. Features discussed before have now been implemented, and some new features have been added. Changes
CommentsType-safe translationsThis is a feature that I come up with when implementing other changes. Please let me know if you have any thoughts on this. Pre-replaced values in HTML tagsAs for HTML tag support, I now find another thing to think about. Take the about message for example, it contains multiple HTML tags with pre-replaced values like Abstract tags proposalBesides, containing a large <a> element like For example, we use This is just a thought, and I'm not sure if it's a good idea because more efforts to parse HTML and replace tags are needed. |
Beta Was this translation helpful? Give feedback.
-
Great work @zyf722 . Thank you. I like the type-safe solution. I have started another PR with the following changes:
const translation = {
welcome: 'Welcome',
hello: { textContent: 'Hello', title: 'Hello' }
}
Regarding your question, I like your proposal ( |
Beta Was this translation helpful? Give feedback.
-
Done with abstract tags and intellisense enhancement. Please check commits for details.
I believe i18n integration is now functional enough for use. Please let me know if you have any suggestions or questions on above changes. If there is no further feature planned, I will mainly focus on marking elements that need to be translated in HTML files next. |
Beta Was this translation helpful? Give feedback.
-
wow! this is impressive. some minor comments:
Nice 👍
This is fine. You may want to update the comment here to use the new type
Beautiful 😍 You may actually add I think the regex used here is too specific and can easily break with minor code change (e.g. if we later use
I like this indeed 👍 const replaceElement = (node: HTMLElement) => {
if (node.nodeType === Node.ELEMENT_NODE) {
node.childNodes.forEach((child) => {
replaceElement(child as HTMLElement);
});
const name = node.tagName.toLowerCase();
if (name !== 'body') {
// implementation
}
}
}; I usually do this: const replaceElement = (node: HTMLElement) => {
if (node.nodeType !== Node.ELEMENT_NODE) return;
node.childNodes.forEach((child) => {
replaceElement(child as HTMLElement);
});
const name = node.tagName.toLowerCase();
if (name === 'body') return;
// implementation
}; also, instead of: const attributes =
(node.attributes.length > 0) ?
Array.from(node.attributes).reduce((acc, attr) => {
acc[attr.name] = attr.value;
return acc;
}, {} as Record<string, string>) : undefined; I would reverse the condition to deal with the short path ( const attributes =
node.attributes.length === 0
? undefined
: Array.from(node.attributes).reduce(
(acc, attr) => {
acc[attr.name] = attr.value;
return acc;
},
{} as Record<string, string>,
); just to keep the same style with the rest of the codebase.
Very nice 💯 In my local setup, I have prettier configured to run on-save. I noticed some formatting changes (mostly whitspace formatting). Apart from these minor comments, I think we are ready. Please go ahead. |
Beta Was this translation helpful? Give feedback.
-
TODO: we need later on to add some e2e tests for significant cases. e.g.:
etc. Also, whenever you see suitable, you may start a [WIP] PR, so that we can run all CI checks early and fix anything that fails. And then you can keep pushing more changes. |
Beta Was this translation helpful? Give feedback.
-
We will also need to add something in the docs. A point for thought: May be add another screen for global app settings. |
Beta Was this translation helpful? Give feedback.
-
I think some changes here are worth discussion. Further type-safety and nested keysType-safety and intellisense of
Translation processDuring add keys and translations for I also take collaboration and online translation platform into consideration. The main problem here is that I think it'd be much better if translators can see the actual HTML elements for abstract tags in the form of context, description or etc. (as shown in the screenshot) However, i18next's key-translation JSON schema doesn't support this kind of comment information, which then drives me to come up with the following localization process:
Even myself must admit that I seem to have made this too complicated. However, there seems to be no better way to add context information except manually maintaining it as we use a custom format for translation files to have better type-safety and developing experience - we either have to give up providing context information for translators or make the process more complicated. Any ideas or suggestions shall be greatly appreciated. PS: After doing some research, I believe Crowdin has been a little bit too strict for open-source projects, so I then turn to Lokalise. |
Beta Was this translation helpful? Give feedback.
-
@zyf722 So I have to admit, this is impressive. However, it is getting quite complex. I like that contributors to translations can have much simpler workflow using Lokalise while having context, without having to mess with code. I also like the proposed GitHub actions workflow to automate incorporating the translations back into the code base. If there is no simpler way, we may just accept that, and clearly document the workflow in contribution docs here, and refer to it under "Specific topics" here. In this documentation we need to explain the full workflow (including when running scripts are required), with guides for:
I also have some comments for specific topics:
This is great in principle. However, I see we are not making use of this since we are just looping through the keys in
This is nice. const type = namespace === 'translation' ? 'I18nTranslationTemplate' : 'I18nTranslationTemplate'; Also I think this is error-prone: const definition = JSON.stringify(trans[namespace], null, 2)
.replace(/"([^"]+)":/g, '$1:')
// .replace(/"(.*)\/\* COMMENTS \*\/(.*)"(,?)/g, "'$1'$3 // $2")
.replace(/"/g, "'"); These are examples for how this can break: https://livecodes.io/?x=id/rxmym34u9va This type does not allow a tranlation file to be missing top-level keys while the translation is still in progress: type UnAsConst<T> = {
readonly [K in keyof T]: T[K] extends I18nAttributes | I18nTranslationTemplate
? RequireAtLeastOne<UnAsConst<T[K]>>
: string;
}; consider wrapping it with This is indeed becoming a big project. However, I'm really grateful for you making this effort. |
Beta Was this translation helpful? Give feedback.
-
We need to think of a way to keep the translations in sync. Consider the case when some text in HTML is changed. We need a check that detects that this key in all translations is no longer valid, so it should not be used and defaults to the text in HTML till the translations are updated. May be add a checksum for the source string with translation key. This check can only run with production build. The build should fail if this is the case till we mark that this key should be ignored, so that we are aware of this situation. Specially that maintainers may not be able to read different translations or update them on their own. |
Beta Was this translation helpful? Give feedback.
-
FYI |
Beta Was this translation helpful? Give feedback.
-
These days I fixed few typo alongside small mistakes, and more importantly, briefly reviewed the entire thread and now have a to-do list below (ones with higher priority are listed first):
Here are some comments on part of the tasks and need your help to clarify them: Solution for
|
Beta Was this translation helpful? Give feedback.
-
Got a response from Lokalise support team. There are a couple of questions that need to be clarified before they can approve the open-source plan:
They also points out that it will be appreciated if we could spread the word about Lokalise on X and other media. |
Beta Was this translation helpful? Give feedback.
-
No, LiveCodes is fully open-source under MIT license.
LiveCodes has a sponsorship program to support its development: https://livecodes.io/docs/sponsor
I'm happy to add a logo with a link to Lokalise in the credits section in GitHub readme and the docs website. |
Beta Was this translation helpful? Give feedback.
-
Hmm. Found something tricky to deal with. Some values of attributes in those dynamically-added elements are only determined at runtime (like here), which means that there is no simple way to extract their default value through a static analysis. This makes it hard to integrate with current Moreover, our current i18n mechanism is element-level (using PS. The work on Lokalise is progressing smoothly. I turned abstract tags in |
Beta Was this translation helpful? Give feedback.
-
New progress in these days. Check here to see all changes. String-level translationAdded the string-level translation and enhance its intellisense and static checking with type-safety (Reused some code from Now we can use window.deps.translateString('namespace:file.key1.subkey1', 'default <strong>value</strong>, {{interpol}}', {
isHTML: true,
interpol: "abc"
}) The function is completely type-safe:
To provide better readability and maintainability, only string-level translation will be used in Marked all strings in
|
Beta Was this translation helpful? Give feedback.
-
wow! I like the added type-safety and extracting data from ts files (using babel!). Impressive. I reviewed the changes and have some comments:
I have no problem with the namings of the keys. Actually, I find them descriptive. The big concern I'm having now is that I'm starting to feel overwhelmed with this feature. I'm not 100% sure I know what is going on where.
I want to know your thoughts. |
Beta Was this translation helpful? Give feedback.
-
I'm working on a project that requires me to allow users to edit and run code in multiple languages in the browser. Then I found this project and it works perfectly for my needs.
I notice that currently all messages and texts are hardcoded in the source code. I think it would be better if we can move all these texts to a separate file so that it's easier to maintain and translate. Any plans or thoughts on this i18n feature?
Beta Was this translation helpful? Give feedback.
All reactions