Replies: 40 comments 118 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.
-
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.
-
New updates. All commits are listed here.
I believe as for now, most of the translation keys are marked and exported. Next I will get to other projects to see how they manage translation keys and try if there's a better solution for our project. Once that's ready, I could start working on the Lokalise integration and the CI/CD pipeline. P.S. I think I found some typos during the process of adding translation keys to the HTML files. Not sure if they are intentional or not, so I'll list them here for your reference:
|
Beta Was this translation helpful? Give feedback.
-
Apologies for my inactivity in the past month first - I was caught up with some personal matters and couldn't allocate time to work on the project. I'm back now and ready to continue the work 🚀 After digging into some other projects, I found that although the current solution is not perfect, it's still a good start. Other projects either keep the i18n workflow simple and manual (with potential human errors) or to some extent use scripts and integrations which are similar to what we have done. I believe manually editing translation files and keeping them in sync with the source code would be of much more burden than the current solution - there will be no spelling errors or misplaced quotation marks in the automatically generated files, and accordingly, the effort of review and correction spent on such low-level errors could be transferred to maintaining high-level translation pipelines, which in my opinion is more valuable and meaningful. Besides, although building the translation process can be relatively cumbersome, once configured, there is almost no need to make modifications to the infrastructure itself. So in this comparison, I think it's worth it. Let's re-list out what changes will be introduced if we adopt the current solution:
Throughout the process, the only manual work about i18n is to mark strings in the source code, which is inevitable and necessary. The rest of the process is one-time work, which later can be automated by a single command or a single click. The process is also transparent and traceable with logs and commit history. P.S. This demo by Lokalise could be a reference on how to bi-directionally pull/push translations between Lokalise and GitHub using only cli and actions. This is just my personal opinion and I'm open to any suggestions or comments on this. Let me know if you have any concerns or ideas :) |
Beta Was this translation helpful? Give feedback.
-
Some progressCheck commits here:
Further thoughts about the i18n workflowDuring the process of adding the ci script above, I found that the process proposed three days ago still has room for improvement and further automation. Below is a more detailed and refined workflow, based on branching and actions:
Some notes:
This is more detailed and seemingly more complicated than the previous one, but I believe it's more robust and automated. I'd like to hear your thoughts on this and whether it's feasible to implement this. Once we reach a final consensus, I'll summarize it into documentation and guidelines for future reference just as you suggested. |
Beta Was this translation helpful? Give feedback.
-
Finally, I am glad to announce that the Lokalise integration is now ready! Check here to see all changes 🚀 I have tried to use rebase to remove the modifications that I introduced but later removed, in order to make the commit history appear cleaner. However, there might still be some commits that are not well-organized, so I might suggest you to directly check the "Files Changed" tab in the compare view of the commits to get a clearer view. If any confusion arise, my apologies for that 😥 Some notable changes📚 Docs
⚙ CI
I've created a demo repo and a demo project on Lokalise to show how the i18n workflow works. Feel free to check them out (like the PRs, actions) and let me know if you have any questions or suggestions. P.S. The |
Beta Was this translation helpful? Give feedback.
-
So below is the trimmed list of tasks that haven't been done yet:
The topic about hash and cache was postponed before and here I'd like to hear your thoughts on this and whether it's necessary to implement this feature. The rest of the tasks are relatively minor and could be done in a short time. I'm looking forward to your ideas and suggestions on this. |
Beta Was this translation helpful? Give feedback.
-
I want to elaborate about keeping keys in sync, as mentioned before.
For example, consider this scenario: Let's assume that this code has been already translated to different languages. <div class="description" data-i18n="deploy.create.desc" data-i18n-prop="innerHTML">
A new <strong>public</strong> repo will be created. The result page will be pushed to <span class="code">gh-pages</span> branch.
</div> and then a maintainer changes it to that <div class="description" data-i18n="deploy.create.desc" data-i18n-prop="innerHTML">
Deploy to <a href="...">Netlify</a>.
</div> The English translation will indeed be changed after running Do we need to change the key every time we change the text? This is a bit cumbersome and error-prone. What if we forget? |
Beta Was this translation helpful? Give feedback.
-
After production build, file hashes are added to all files in This assumes that all files to be hashed are in that directory (without nesting), and that they are referenced in code like that const mod = await import(baseUrl + '{{hash:file-name.js}}'); Then, these files are aggressively cached (for 1 year). So, any file that has not changed will continue to be served from cach even for later releases. Based on this, if we do not apply hashing for translation files, the old files will continue to be served from cache and updates will not be visible even across releases. I can think of 3 options:
I'm fine with the 3 options. You choose what you think works best and is more maintainable. |
Beta Was this translation helpful? Give feedback.
-
By the way, I come up with a workaround for the Lokalise badge this afternoon. Basically it just uses Github Actions to fetch the project status from Lokalise and generate a P.S. To perform this you might want to register a special bot account on Lokalise. Its API token might also be used for CI actions in the i18n workflow. |
Beta Was this translation helpful? Give feedback.
-
Another small suggestion: I think it would be more clear if we change the auto-generation notice to something like // ATTENTION: This file is auto-generated from source code. Do not edit manually! Someone might understand the current message that the ts file is generated from the json file, since it doesn't have this notice. // ATTENTION: This is an auto-generated file. Do not edit this file manually. Also, I'm thinking about adding an entry at the top of the json file like this: {
"// ____ATTENTION____": "This file is auto-generated from source code. Do not edit manually!",
...
} But obviously, we do not want this entry to be propagated to other translations. what do you think? |
Beta Was this translation helpful? Give feedback.
-
After a silent period of three weeks, I'm glad to announce my return with the news that the Simplified Chinese translation is now ready! Check Lokalise project page to have an overview and here to see all commits and changes since last update. Here are some screenshots: Generally speaking, most of source texts should be correctly marked out and translated. However, there are still some exceptions (and basically they are all related to hard-coded texts):
Other similar issues might also exist. Because I didn't know what impact it would have, I just left them as they are. Any suggestions on how to deal with them? |
Beta Was this translation helpful? Give feedback.
-
After some thinking regarding enabling i18n in embeds: We do not want to increase bundle size for embedded playgrounds by loading the i18n module, specially that most users will use the English language and most of translations affect modal screens while most of them are not enabled in embeds anyways. However, still some screen are available (e.g. external resources). Also tools pane. It might be nice if we allow site owners to explicitly enable i18n in embedded playgrounds by setting I have opened a PR with the suggested changes. |
Beta Was this translation helpful? Give feedback.
-
Hi @zyf722 There is a new PR that makes some major changes to UI. Would you please check if this will cause significant merge conflicts on your side? Just to check what is the best way to merge both and in what order. Thank you. |
Beta Was this translation helpful? Give feedback.
-
Added some missing translations and updated on Lokalise (commits here). I18n now should be consistent with recent changes in upstream repo. Besides, I found that Another minor display issue (not related to i18n) found during my local test is that when hovering on the I believe it has something to do with the multi-column layout and the |
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