Localization
Sciter › Forums › General discussion › Localization
Tagged: i18n, localization, translation
- This topic has 20 replies, 9 voices, and was last updated 2 weeks, 3 days ago by Andrew.
-
AuthorPosts
-
-
March 16, 2016 at 2:42 am #44971SjsciterParticipant
Hi,
I have been working on a assignment which has to be published in different languages. What could be the proper approach to follow so that every html page need not to be repeated for every language.
-
March 16, 2016 at 3:55 am #44973
-
March 16, 2016 at 4:34 am #44974ShrekParticipant
\Sciter\samples\i18n also.
-
March 16, 2016 at 10:32 am #44982AndrewKeymaster
That depends on what is really needed.
1. Static localization using SGML entities.
“Static” here means that you know your UI language upfront and will not change it at runtime.
Let’s say you have the following document:
<html> <head> <include src="lang:words.htm"/> </head> <body> <p>&hello; &world; !</p> </body> </html>And two entity table files, words-en.htm :
<!ENTITY hello "Hello"> <!ENTITY world "World">and words-ru.htm :
<!ENTITY hello "Привет"> <!ENTITY world "Мир">then while loading that main HTML document you will receive SCN_LOAD_DATA request with the URL “lang:words.htm” (see
<include>above).
In response of that request your application will supply content of either “words-en.htm” or “words-ru.htm”.2. Static localization using inclusions.
Let’s consider the following document:
<html> <body> <p> <include src="lang:fragment:hello-world">Hello World</include> </p> </body> </html>It uses
<include>to request partial markup. Normally you will see just “Hello World” there. But if your
application, on SCN_LOAD_DATA / “lang:fragment:hello-world” request, will supply other content then it will be included instead of markup inside that<include>...</include>.3. Dynamic localization using CSS
“Dynamic” here means that translation can be done on loaded UI – as a runtime switch.
Let’s consider the following document:
<html lang="ru"> <head> <style> @import url(lang.css); </style> </head> <body> <p> <span class="hello-world">Hello World</span> </p> </body> </html>and following content of that lang.css
span.hello-world:lang(en) { content:"Hello World"; } ... span.hello-world:lang(ru) { content:"Привет Мир"; } ...So when you will switch value of lang attribute in
<html lang=...>(at load time or at runtime) you will see content of thatspan.hello-worldin different languages.4. Dynamic localization using script
One of possible approaches is outlined in sdk/samples/+lang/ . It relies on CSS aspect feature – declarative binding of script code with particular DOM elements.
Beside of simple text translation and substitution it supports intelligent language sensitive formatting and pluralization.
5. Preprocessors
In principle you can use combination of all methods outlined above.
Yet, in some cases you can consider use of either native or script preprocessor.
For example, this document:
<html> <body> <p>%HELLO% %WORLD% !</p> </body> </html>can be trivially preprocessed by native code before supplying it to the engine – just a matter of finding tokens like
%HELLO%and replacing them by something else.In script you can use built-in preprocessor feature and write something like this:
<html> <body> <p><% =words.hello %> <% =words.world %> !</p> </body> </html>Common problem with preprocessing: when used all html content that you supply to the engine needs to be passed through such preprocessors. If in your code you have content population/update by HTML then you will need to pass resulting code to the preprocessor to translate. While with entities (first approach) you can do simply this:
el.html = "&hello; &world";and it will be handled universally.
Afterwords
What to choose is up to you. First and second approach are most effective and usually combined together.
Places where you will need pluralization and other dynamic formatting are usually not so widespread and so can be handled by special and specific functions. -
March 16, 2016 at 4:17 pm #44991MikanoshiParticipant
Also you can always register a native function and translate in runtime:
var lines = $$(div[text], label, button, speedbutton > span); for (var line in lines) line.html = GetTranslation(line.html);-
March 16, 2016 at 4:57 pm #44992AndrewKeymaster
I think you understand that this does for each element the following: a) serialization to html, b) call of the function and c) html parsing to set it back. So you have as many update transactions as many elements involved.
While case #1 does this once and inside one parsing/dom-building transaction.Problem is that each call of
line.html = ...shall leave the DOM in consistent state so there is some overhead.Usually that is made once on loading so it is OK in general. But if frequently, on each update, then it makes sense to consider other options.
-
March 16, 2016 at 5:08 pm #44993MikanoshiParticipant
So you have as many update transactions as many elements involved.
or combine everything into array and send in one transaction.
If lang change is required without reloading the document then all the default texts could be stored in some custom tag attribute, it will exclude serialization to html.
-
-
-
March 17, 2016 at 6:58 am #44999learnsciterParticipant
Hi,
I tried the very first type of localization i.e. static method.
I have created normal html named as demo.htm and words.htm also.
demo.htm:
<html> <head> <include src="lang:words.htm"/> </head> <body> <p>&hello; &world; !</p> </body> </html>words.htm:
<!ENTITY hello "Hello"> <!ENTITY world "World">The expected output is not reflecting. Do we have any dependency on lang file or so.
Could you please explain what exactly “lang:” means.
-
March 17, 2016 at 9:24 am #45004AndrewKeymaster
For the testing purposes, instead of
<include src="lang:words.htm"/>
use this:
<include src="words.htm"/>“lang:” is a custom protocol as Mikanoshi said above…
-
March 27, 2016 at 5:03 pm #45156midiModerator
I would not recommend Static localization as a first option because you will probably have localized strings in script, say:
view.msgbox(#information, "Name of the collection: <br><input !text>", "Add new collection") -
March 19, 2019 at 8:01 am #60371Tom_ClanceParticipant
Hello!
Can I use static localization – dynamically? 🙂
The task is just to get localization in runtime.for example
<!ENTITY hello “Hello”>
<!ENTITY world “World”><script>
var hello = &hello;
var world = &world;
</script><html>
<head>
<include src=”lang:words.htm”/>
</head>
<body>
<div #hello></div>
<div #world></div>
</body>
</html>Is there any way for this implementation?
Thanks! -
March 19, 2019 at 9:26 am #60375AndrewKeymaster
If you have these entity declarations in entity table:
<!ENTITY hello "Hello"> <!ENTITY world "World">then this code:
$(div#hello).html = "&hello;"; $(div#world).html = "&world;";will lead to this DOM
<div #hello>Hello</div> <div #world>World</div>Is this what you mean?
(please use [code] button to wrap your code snippets on the forum)
-
March 20, 2019 at 5:20 am #60384Tom_ClanceParticipant
Thanks! It works.
It didnt works, because i tried to do like this:
$(div#hello).value= "&hello;";$(div#world).text= "&world;";Can you explain, why i cant do like this?
I am confused that anything can be passed to the tag .htmlI didn’t check, but it seems to me that something like this might work for example:
$(div#world).html= "<script> view.msgbox(#inforamtion, script)</script>";Thank you!
- This reply was modified 6 years, 9 months ago by Tom_Clance.
-
March 20, 2019 at 9:23 am #60387AndrewKeymaster
This:
<!ENTITY hello "Hello">is an instruction to HTML parser to replace
& hello;byHello.For ordinary elements (with no special behaviors attached) this:
$(div#hello).value="...";
is exactly this
$(div#hello).text="...";
Which is essentially
$(div#hello).append(Node.createText("..."))
As you see HTML parser is not involved into this operation and so no entity translations are happening there.In principle I can provide some method like
$(div#hello).value = self.entitify("& hello;"); // will do $(div#hello).value = "Hello";But you will need to call it explicitly, will it work for you?
-
-
December 13, 2025 at 11:23 am #89658DesktopPaintsParticipant
What is the best way to implement dynamic localization in 2025?
The sdk/samples/+lang folder was removed from the latest SDK build. I downloaded it from GitHub, but the samples don't work in the inspector and automatic translation map generation doesn't work in my app...
-
December 13, 2025 at 1:42 pm #89659AndrewKeymaster
sdk/samples.sciter/i18n
sdk/samples.sciter/i18n-reactor -
December 14, 2025 at 5:58 am #89662DesktopPaintsParticipant
Does generate-translation-table.htm work only with JavaScript? It doesn't extract strings from HTML like the +lang samples do, does it?
-
December 14, 2025 at 12:13 pm #89667AndrewKeymaster
It doesn't extract strings from HTML like the +lang samples do
Where do they do that ?
-
December 14, 2025 at 12:40 pm #89668DesktopPaintsParticipant
Where do they do that ?
I mean "+lang samples did." Now it doesn't work apparently, but this is described in the "Automatic translation map generation and maintenance" section of the redmee
-
December 15, 2025 at 11:47 am #89672AndrewKeymaster
This example:
https://gitlab.com/sciter-engine/sciter-js-sdk/-/tree/main/samples.sciter/i18n/basicis a prototype of translation mechanism that is used in +lang.
lang.js there defines aspect function translate()
By default it is applied to any element having class
.x:<span.x>yes</span> <span.x>no</span>You can extend this to match
+langdeclarations :.x { aspect: translate url(lang.js) } label, dfn { aspect: translate url(lang.js) }And in general, +lang/lang.tis is trivially portable to js. Use lang.js as a prototype.
- This reply was modified 2 weeks, 3 days ago by Andrew.
-
-
-
-
AuthorPosts
- You must be logged in to reply to this topic.