Translation in JavaScript like gettext in PHP? - javascript

I am using gettext in my PHP code, but I have a big problem. All my JavaScript files are not affected by the translation, can somebody tell me an easy way to get the translations in the chosen language into JavaScript as well.

The easiest way is having a PHP file write the translations from gettext into JavaScript variables.
js_lang.php:
word_hello = "<?php echo gettext("hello"); ?>"
word_world = "<?php echo gettext("world"); ?>"
word_how_are_you = "<?php echo gettext("how_are_you"); ?>"
and then include it:
<script type="text/javascript" src="js_lang.php"></script>
I would also recommend this method in conjunction with the translation plugins S.Mark mentions (which are very interesting!).
You can define the dictionary in the current page's header, too, without including an external file, but that way, you would have to look up and send the data on every page load - quite unnecessary, as a dictionary tends to change very rarely.

I generally export the translations in a JavaScript structure:
var app = {};
var app.translations = {
en: {
hello: "Hello, World!",
bye: "Goodbye!"
},
nl: {
hello: "Hallo, Wereld!",
bye: "Tot ziens!"
}
};
The current language of the page texts can be defined using: <html xml:lang="en" lang="nl">
This can be read in JavaScript:
var currentLanguage = document.documentElement.lang || "en";
app.lang = app.translations[ currentLanguage ] || app.translations.en;
And then you can write code like this:
alert( app.lang.hello );
Optionally, a i18n() or gettext() function can bring some intelligence, to return the default text if the key does not exist). For example:
function gettext( key )
{
return app.lang[ key ] || app.translations.en[ key ] || "{translation key not found: " + key + "}";
}

Try, jQuery i18n or jQuery localisation
An example for jQuery i18n, and of course you need to generate JSON based dictionary from language file from php
var my_dictionary = {
"some text" : "a translation",
"some more text" : "another translation"
}
$.i18n.setDictionary(my_dictionary);
$('div#example').text($.i18n._('some text'));

JSGettext (archived link) is best implementation of GNU gettext spec.
First download JSGETTEXT package and include in your page
/js/Gettext.js
<?php
$locale = "ja_JP.utf8";
if(isSet($_GET["locale"]))$locale = $_GET["locale"];
?>
<html>
<head>
<link rel="gettext" type="application/x-po" href="/locale/<?php echo $locale ?>/LC_MESSAGES/messages.po" />
<script type="text/javascript" src="/js/Gettext.js"></script>
<script type="text/javascript" src="/js/test.js"></script>
</head>
<body>
Test!
</body>
</html>
javascript code for example
window.onload = function init(){
var gt = new Gettext({ 'domain' : 'messages' });
alert(gt.gettext('Hello world'));
}
For reference find below link. It's working fine without converting .js file to .php.
Click here

You can make your life much easier if you get rid of bad habit to use string literals in your code. That is, instead of
alert("Some message")
use
alert($("#some_message_id").text())
where "#some_message_id" is a hidden div or span generated on the server side.

As a further hint there's a perl script called po2json which will generate json from a .po file.

For JavaScript implementation of GNU gettext API these links can be also useful:
http://tnga.github.io/lib.ijs
http://tnga.github.io/lib.ijs/docs/iJS.Gettext.html
//set the locale in which the messages will be translated
iJS.i18n.setlocale("fr_FR.utf8") ;
//add domain where to find messages data. can also be in .json or .mo
iJS.i18n.bindtextdomain("domain_po", "./path_to_locale", "po") ;
//Always do this after a `setlocale` or a `bindtextdomain` call.
iJS.i18n.try_load_lang() ; //will load and parse messages data from the setting catalog.
//now print your messages
alert( iJS.i18n.gettext("messages to be translated") ) ;
//or use the common way to print your messages
alert( iJS._("another way to get translated messages") ) ;

This library seems the best implementation of getText in javascript:
http://messageformat.github.io/Jed/
https://github.com/messageformat/Jed
example from the documentation:
<script src="jed.js"></script>
<script>
var i18n = new Jed({
// Generally output by a .po file conversion
locale_data : {
"messages" : {
"" : {
"domain" : "messages",
"lang" : "en",
"plural_forms" : "nplurals=2; plural=(n != 1);"
},
"some key" : [ "some value"]
}
},
"domain" : "messages"
});
alert( i18n.gettext( "some key" ) ); // alerts "some value"
</script>

Related

How to use explode function to delimit and display different values

I’m making a random sentence generator for my English class. I’m close but because of my limited php and javascript knowledge I need to ask for help. I’m not bad at reading the code, I just get stuck writing it.
I want to use explode to break up a string of comma seperated values. The string is a mix of English and Spanish, on the .txt file they would seperated like:
The book, El libro
The man, El hombre
The woman, La mujer
etc.
I would like to break these two values into an array and display them in separate places on my web page.
I`m going to use a random text generator script that I found, it’s working great with no problems. I just need to modify it using explode to read, separate the values into an array, and be able to display the separate values of the array.
<?php
/* File, where the random text/quotes are stored one per line */
$settings['text_from_file'] = 'quotes.txt';
/*
How to display the text?
0 = raw mode: print the text as it is, when using RanTex as an include
1 = Javascript mode: when using Javascript to display the quote
*/
$settings['display_type'] = 1;
/* Allow on-the-fly settings override? 0 = NO, 1 = YES */
$settings['allow_otf'] = 1;
// Override type?
if ($settings['allow_otf'] && isset($_GET['type']))
{
$type = intval($_GET['type']);
}
else
{
$type = $settings['display_type'];
}
// Get a list of all text options
if ($settings['text_from_file'])
{
$settings['quotes'] = file($settings['text_from_file']);
}
// If we have any text choose a random one, otherwise show 'No text to choose from'
if (count($settings['quotes']))
{
$txt = $settings['quotes'][array_rand($settings['quotes'])];
}
else
{
$txt = 'No text to choose from';
}
// Output the image according to the selected type
if ($type)
{
// New lines will break Javascript, remove any and replace them with <br />
$txt = nl2br(trim($txt));
$txt = str_replace(array("\n","\r"),'',$txt);
// Set the correct MIME type
header("Content-type: text/javascript");
// Print the Javascript code
echo 'document.write(\''.addslashes($txt).'\')';
}
else
{
echo $txt;
}
?>
The script that displays the result:
<script type="text/javascript" src="rantex.php?type=1"></script>
Can someone please help me modify the rantex.php file so that I can use explode to separate the different comma separated values, and use a different script to call them in different places on my web page?
Thank you, and please excuse my noobness.
The following seems unnecessary, since file() will have already removed new line characters:
// New lines will break Javascript, remove any and replace them with <br />
$txt = nl2br(trim($txt));
$txt = str_replace(array("\n","\r"),'',$txt);
To break your line, you may instead use:
list($english, $spanish) = explode(', ', trim($txt));
It seems you are trying to use PHP to serve a static page with some random sentences, right? So why not use PHP to serve valid JSON, and handle to display logic on the client?
Heres a quick implementation.
// Get the data from the text file
$source = file_get_contents('./quotes.txt', true);
// Build an array (break on every line break)
$sentences = explode("\n", $source);
// Filter out empty values (if there is any)
$filtered = array_filter($sentences, function($item) {
return $item !== "";
});
// Build a hashmap of the array
$pairs = array_map(function($item) {
return ['sentence' => $item];
}, $filtered);
// Encode the hashmap to JSON, and return this to the client.
$json = json_encode($pairs);
Now you can let the client handle the rest, with some basic JavaScript.
// Return a random sentence from your list.
var random = sentences[Math.floor(Math.random() * sentences.length)];
// Finally display it
random.sentence
[edit]
You can get the JSON data to client in many ways, but if you don't want to use something like Ajax, you could simply just dump the contents on your webpage, then use JavaScript to update the random sentence, from the global window object.
// Inside your php page
<p>English: <span id="english"></span></p>
<p>Spanish: <span id="spanish"></span></p>
<script>
var sentences = <?= json_encode($pairs); ?>;
var random = sentences[Math.floor(Math.random() * sentences.length)];
var elspa = document.getElementById('spanish');
var eleng = document.getElementById('english');
elspa.innerText = random.sentence.split(',')[1];
eleng.innerText = random.sentence.split(',')[0];
</script>
Ok, so I have this figured out, I take 0 credit because I paid someone to do it. Special thanks to #stormpat for sending me in the right direction, if not for him I wouldn't have looked at this from a JSON point of view.
The .PHP file is like so:
<?php
$f_contents = file('quotes.txt');
$line = trim($f_contents[rand(0, count($f_contents) - 1)]);
$data = explode(',', $line);
$data['eng'] = $data[0];
$data['esp'] = $data[1];
echo json_encode($data);
?>
On the .HTML page in the header:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
(function ($) {
$(function()
{
function load_random_data() {
$.get('random_line.php', function(data) {
var data = $.parseJSON(data);
$('#random_english').text(data.eng);
$('#random_spanish').text(data.esp);
});
}
load_random_data();
$('#get_random').click(function(e){
e.preventDefault();
load_random_data();
});
});
})(jQuery);
</script>
This splits the different variables into classes, so to call them into my html page I call them by their class, for instance I wanted to drop the variable into a table cell so I gave the individual td cell a class:
<td id="random_spanish"></td>
<td id="random_english"></td>
Plus as a bonus the coder threw in a nifty button to refresh the json classes:
<input type="button" value="Get random" id="get_random" />
So now I don`t have to have my students refresh the whole web page, they can just hit the button and refresh the random variables.
Thanks again everyone!

Get servlet context in javascript

In my jsp I use <%String base = (String)application.getAttribute("base");%>
I tried to use 'base' in javascript but not work. Below is my javascript:
<script>
var newBase = <%=base%>;
</script>
Can anyone help me to solve this?Thanks
This is the eplanation www.w3schools.com give for location object property pathname:
pathname: Sets or returns the path name of a URL
In our case the javascript file wich is in your context.
The first element is that pathname is the context
So you split the attribute (see the split method in javascript String) and return it.
This should do.
<script language='javascript'>
function servletContext() {
var sc = window.location.pathname.split( '/' );
return "/"+sc[1];
}
</script>
You can rather try it out like this ,
set the value to the hidden field ,
input type="hidden" id="hidVal" name="txt2" value="${base}"/>
And in your java script ,
<script>
var x = document.getElementById('hidVal').value;
alert(x);
</script>
Update :
var newBase = '<%=base%>';
You are missing the quotes to treat the value as string .
Hope this helps !!

How can I create a custom function in PHP for HTML tags?

Last time I asked for help in PHP and I got great response. Thanks to all of you for that. Now I am learning and creating website using MVC PHP. I want to ask you that can I create a custom function to use html tags? I am trying to remember that where I saw an example of it. Actually I've seen it before in and open source project.
It was like something this:
htmltag(script(src=address, type=javascript))
Its output was in html like:
<script src="address" type="javascript"></script>
So can I create something like this? I am trying to do this way:
public function script($var1, $var2){
$var1 = array(
'type'=>'',
'charset' => '',
'src' => ''
);
$var2 = false;
print("<script $var1>$var2</script>");
}
So can anyone guide me with this? Do I need to create class first? I will be waiting for your reply friends.
Javascript works with DOM, see the reference
function htmltag(name,atts) {
var tag = document.createElement(name);
for(var i in atts) tag.setAttribute(i, atts[i]);
return tag;
}
var img = htmltag("img", {
src: "https://kevcom.com/images/linux/linux.logo.2gp.jpg",
alt: "linux logo"
});
document.body.appendChild(img);
Note that img here is object (XML Node), not just plain text, so you can attach events on it etc. If you want to extract just the plain html code from it, use img.outerHTML. Test it on the fiddle.
Note: print is the equivalent of Ctrl+P in the browser :-) it is not the print equivalent in PHP.
In PHP you can use DOM::createElement and other methods from DOM which are quite similar to those from javascript. Personaly I prefer something more simple:
function tag($name,$atts="",$content="") {
$str_atts = "";
if(is_array($atts)) {
foreach($atts as $key=>$val) if(!($val===null || $val===false)) $str_atts.= " $key=\"$val\"";
} else $str_atts = " ".preg_replace("/=(?!\")(\S+)/m","=\"\\1\"",$atts);
if($name=="img" && !strpos($str_atts,"alt=")) $str_atts.= " alt=\"\"";
if(in_array($name,array("input","img","col","br","hr","meta"))) $name.= "/";
if(substr($name,-1)=="/") { $name = substr($name,0,-1); return "<{$name}{$str_atts}/>"; }
else return "<{$name}{$str_atts}>$content</$name>";
}
Examples
echo tag("p","class=foo id=bar1","hello");
echo tag("p",'class="foo" id="bar2"',"hey");
echo tag("p",array("class"=>"foo","id"=>"bar3"),"heya");
echo tag("img","src=https://kevcom.com/images/linux/linux.logo.2gp.jpg");

Parse JavaScript with jsoup

In an HTML page, I want to pick the value of a javascript variable.
Below is the snippet of HTML page:
<input id="hidval" value="" type="hidden">
<form method="post" style="padding: 0px;margin: 0px;" name="profile" autocomplete="off">
<input name="pqRjnA" id="pqRjnA" value="" type="hidden">
<script type="text/javascript">
key="pqRjnA";
</script>
My aim is to read the value of variable key from this page using jsoup.
Is it possible with jsoup? If yes then how?
Since jsoup isn't a javascript library you have two ways to solve this:
A. Use a javascript library
Pro:
Full Javascript support
Con:
Additional libraray / dependencies
B. Use Jsoup + manual parsing
Pro:
No extra libraries required
Enough for simple tasks
Con:
Not as flexible as a javascript library
Here's an example how to get the key with jsoupand some "manual" code:
Document doc = ...
Element script = doc.select("script").first(); // Get the script part
Pattern p = Pattern.compile("(?is)key=\"(.+?)\""); // Regex for the value of the key
Matcher m = p.matcher(script.html()); // you have to use html here and NOT text! Text will drop the 'key' part
while( m.find() )
{
System.out.println(m.group()); // the whole key ('key = value')
System.out.println(m.group(1)); // value only
}
Output (using your html part):
key="pqRjnA"
pqRjnA
The Kotlin question is marked as duplicate and is directed to this question.
So, here is how I did that with Kotlin:
val (key, value) = document
.select("script")
.map(Element::data)
.first { "key" in it } // OR single { "key" in it }
.split("=")
.map(String::trim)
val pureValue = value.replace(Regex("""["';]"""), "")
println("$key::$pureValue") // key::pqRjnA
Another version:
val (key, value) = document
.select("script")
.first { Regex("""key\s*=\s*["'].*["'];""") in it.data() }
.data()
.split("=")
.map { it.replace(Regex("""[\s"';]"""), "") }
println("$key::$value") // key::pqRjnA
Footnote
To get the document you can do this:
From a file:
val input = File("my-document.html")
val document = Jsoup.parse(input, "UTF-8")
From a server:
val document = Jsoup.connect("the/target/url")
.userAgent("Mozilla")
.get()

a more graceful multi-line javascript string method

The only way I know how to print a huge string without using += is to use \ backslashes. ugly!
<div id="foo"></div>
<script type="text/javascript">
var longString = '<div id="lol">\
<div id="otherstuff">\
test content. maybe some code\
</div>\
</div>';
document.getElementById('foo').innerHTML = longString;
</script>
is there any way to do this where the longString is untainted? php has $foo = ''' long multiline string '''; I want this in javascript!
Anyone know of a better method for printing long, multi-line strings in javascript?
In general, the answer is: not in the language syntax. Though as Ken pointed out in his answer there are many work-arounds (my personal method is to load a file via AJAX). In your specific case though, I'd prefer creating a HTML constructor function so you can then define the HTML structure using javascript object literals. Something like:
var longString = makeHTML([{
div : {
id : "lol",
children : [{
div : {
id : "otherstuff",
children : [{
text : "test content. maybe some code"
}]
}]
}]
which I find to be much easier to handle. Plus, you this would allow you to use real function literals when you need it to avoid string quoting hell:
makeHTML([{
span : {
onclick : function (event) {/* do something */}
}
}]);
note: the implementation of makeHTML is left as exercise for the reader
Additional answer:
Found some old code after a quick scan through my hard disk. It's a bit different from what I suggested above so I thought I'd share it to illustrate one of the many ways you can write functions like this. Javascript is a very flexible language and there is not much that forces you to write code one way or another. Choose the API you feel most natural and comfortable and write code to implement it.
Here's the code:
function makeElement (tag, spec, children) {
var el = document.createElement(tag);
for (var n in spec) {
if (n == 'style') {
setStyle(el,spec[n]);
}
else {
el[n] = spec[n];
}
}
if (children && children.length) {
for (var i=0; i<children.length; i++) {
el.appendChild(children[i]);
}
}
return el;
}
/* implementation of setStyle is
* left as exercise for the reader
*/
Using it would be something like:
document.getElementById('foo').appendChild(
makeElement(div,{id:"lol"},[
makeElement(div,{id:"otherstuff"},[
makeText("test content. maybe some code")
])
])
);
/* implementation of makeText is
* left as exercise for the reader
*/
One technique if you have a big block is a <script> tag with an invalid type. It will be ignored by browsers.
<script type="text/x-my-stuff" id="longString">
<div id="lol">
<div id="otherstuff">
test content. maybe some code
</div>
</div>
</script>
<script type="text/javascript">
var longString = document.getElementById("longString").text;
document.getElementById('foo').innerHTML = longString;
</script>
A few somewhat unattractive options are discussed in the answers to this question.
You really could minimize this ugliness by creating your <div id="lol"> as HTML, and set its content with .innerHTML = "test content. maybe some code"
I don't like creating HTML in Javascript because of this exact issue, and instead use "template" elements which i simply clone then manipulate.
var lol = document.getElementById("template_lol").clone();
lol.firstChild.innerHTML = "code and stuff";
foo.appendChild(lol);
And this is the HTML:
<body>
<div>normal stuff</div>
<div style="display:none" id="templateBucket">
<div id="template_lol"><div class="otherstuff"></div></div>
</div>
</body>
This works too :
var longString =
'<div id="lol">' +
'<div id="otherstuff">' +
'test content. maybe some code' +
'</div>' +
'</div>';

Categories