dynamic translation/translation with variable with i18next - javascript

How come I can't translate dynamically resp. using a variable with i18next?
For example in my JS-file I got this:
Here I use a variable and assign it to the i18n function and it doesn't work:
//this does not work:
var dynamicTranslation = "myText.toBetranslated";
console.log("translation dynamic ", !{JSON.stringify(t(dynamicTranslation))});
Here I hardcoded the string from above directly into the i18n function and it does work:
//inserted string is the same string as in dynamic translation but this does work:
console.log("translation static ", !{JSON.stringify(t("myText.toBetranslated"))});
As a result I get:
translation dynamic
translation static correct Translation
In order to solve it, I tried to solve it by playing around with setTimeout:
setTimeout(function() {console.log("time out translation: " + !{JSON.stringify(t(dynamicTranslation))})}, 2000);
But it would still show an empty result:
time out translation:

It's jade syntax. The first code didn't work because it is rendered with jade at the back end site. At that point jade doesn't take the JS part into consideration but only renders it and pushes the result (along with the untouched JS code) to the front end. Therefore the part with the variable inside the t()-function is not translated, because it doesn't take the JS code into consideration.

Related

Globally show numbers to be localized formatted

It's nice to change one place that reflects everywhere in Angular app it gives you a good feeling on having control on your app.
I have to change format of numbers to be in DE format for everywhere in an Angular13 app,
Say I have this in the TS file:
const number = 42342.42;
then in the HTML template file:
instead of having {{number}} I change it to {{number.toLocaleString('de')}}
but we have "tons" of this line in the whole app, is there a way to change the template rendering of numbers to be by default formatted with .toLocaleString('de') or with any other way of formatting so there's no need to do hundreds of lines of changes in Angular app?
The closest thing to a global solution for your problem would be creating a prototype format for number. But you'd still have to call a method.
Number.prototype.format = function() {
return this.valueOf().toLocaleString('de')
}
const number = 42342.42;
console.log(number.format())

Exectuing JS script from file containing c# variables

I'm creating a software using CefSharp and needs to executes some JS code. What I'm doing for now is to write the script using only one line, but it's not convenient and it makes it hard to apply modifications.
Here is the JS script from file that I tried to execute :
console.log(size) //size.Text is the variable defined in C#
But as the size variable is defined in c#, the output I get is undefined.
Here is the code I use to load the file :
string size = "XL";
string testJs = Path.Combine(Environment.CurrentDirectory, #"Data\", "test.js");
string test = File.ReadAllText(testJs);
browser.ExecuteScriptAsyncWhenPageLoaded(test);
And the one that would work (the one-lined one) :
browser.ExecuteScriptAsyncWhenPageLoaded("console.log(" + size + ");")
So the main problem is to pass the variable to have XL as an output in the console of the browser.
Considering that size is passed from C# code, what you need in the js file is a placeholder which later can be replaced.
One possible solution might be -
JS File
console.log('#{SIZE}#');// you can use any formatting for your placeholder
C# Code
string size = "XL";
string testJs = Path.Combine(Environment.CurrentDirectory, #"Data\", "test.js");
string test = File.ReadAllText(testJs).Replace("#{SIZE}#", size);
browser.ExecuteScriptAsyncWhenPageLoaded(test);
This approach will allow you to use as many placeholders as you want in your js file and as many number of places you want to use them.
Are you passing a view model to a Razor template? If so, you can use razor syntax within script tags:
<script>
console.log(#Model.size);
</script>

how to render JavaScript using pug/jade

For example, I pass a user variable to this pug file, and I want to run some js code after dom has loaded.
script.
document.addEventListener("DOMContentLoaded", function(event) {
console.log(#{user.name});//log the user's name
});
Is it possible to do so?
First, you're trying to use a string interpolation #{user.name} outside of a string. Use !{user.name} instead for unescaped code interpolation. If you need this to be in a string you'll need to surround the variable in quotes as well.
console.log('!{user.name}');

How do you display translated strings using i18next on js alerts?

We're developing an app that utilizes html/css/js, and it uses i18next to display translated strings.
In order to display translations, I embed an attribute within a tag. For example:
利用規約<label for="checkbox2" data-i18n="text_agree">に同意する</label>
In addition to this, the app uses a javascript file to replace strings with translations. For instance, the above code corresponds with:
en: { translation: {
text_agreement: 'Agree to EULA'
} }
This method of translation works for HTML tags. What I don't know is how to translate strings within js code. For instance, how would I display translated strings for this?
element.alert('なまえを記入してください。');
Help would be very much appreciated.
The initialization function gives you a function to translate your strings. ;)
You can 'put' this function to the window object, so you can use it everywhere in your code.
i18n.init(function(t) {
window.t = t("Your string here");
});
// ... more code
// Now you can use window.t to translate
element.alert(window.t('Your string'));
But note that it's asynchronous (!), so it could happen that the console says, that t() is undefined.
So first initialize i18next and then use window.t();
Also have a look at the documentation: http://jamuhl.github.io/i18next/pages/doc_init.html

How can I insert JSON into a script tage in a zope chameleon template?

I am building a pyramid/python app where my view callable for a certain template passes in a value called data. This variable is an array in the form of [[[x1,y1,z1,],...],[[v1,v2,v3],...]]
in my viewcallable I have
import json
jsdata = json.dumps(data)
I want to put it into a javascript script tag section of my template so:
<script>
data=${jsdata}
</script>
but i'm pretty sure that syntax is incorrect. How can I do this?
Edit: from this: http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/templates.html it seems that Genshi style replacements are the way to go, which I take to mean that what I have above is correct. I am still unsure however, about whether this should be treated differently because it is going inside a javascript tag. Is this true?
You want to insert a JavaScript array, not a Python list.
The easiest way to convert between Python and JavaScript formats is to use the json module. JSON is a JavaScript subset for data after all:
import json
jsdata = (json.dumps(data)
.replace(u'<', u'\\u003c')
.replace(u'>', u'\\u003e')
.replace(u'&', u'\\u0026')
.replace(u"'", u'\\u0027'))
then pass jsdata to your template instead. The str.replace() calls ensure that the data remains HTML safe.
In the template, interpolate this without escaping:
<script>
var data = ${structure:jsdata};
</script>
I'm not sure about Chameleon, but "classical" Zope Page Templates did not allow to do anything inside script tags - if you don't see your variables interpolated it is likely that Chameleon behaves the same. The reason for this, as I understand, is to avoid exactly this type of code generation (you're generating JavaScript from Python via the template). Also, ZPT is an XML-based templating language and the content of <script> tags does not have to be a valid XML.
To work around the problem, you could do something like
jsdata = '<script type="text/javascript">var data = ' + json.dumps(data) + ';</script>'
and in your template insert the whole thing:
<tal:myscript replace="structure jsdata" />
Alternatively, you could do something like
<tal:lt replace="string:<" />script>
var data = <tal:script replace="structure jsdata" />;
<tal:lt replace="string:<" />/script>
which would hide the script tags from Chameleon.
It would be a good practice to try to keep the amount of generated JavaScript in your pages as minimal as possible.

Categories

Resources