accessing a javascript variable in handlebars template - javascript

I am getting a php varible in javascript as
window.apiUserId = '<?php echo Yii::$app->user->id ?>';
And I have a handlebar template as
<script type="text/x-handlebars">
{{log apiUserId}}
{{outlet}}
</script>
But the console displays "undefined"
How to log javascript variables in handlebars ?

From the documentation:
var context = {title: "My New Post", body: "This is my first post!"}
var html = template(context);
Therefore:
var context = {apiUserId: window.apiUserId};
var html = template(context);
I suppose you might manage to make:
var html = template(window);
… work, but splurging that much arbitrary data into the function is a good recipe for unexpected results.

Related

JavaScript script won't load contents of a JSON file to process

I am trying to load a JSON file into a JavaScript script for use in a Mustache script on a webpage. The JSON in a string loads correctly, but the same JSON in a file does not.
This works:
function renderHello() {
var json = JSON.parse('{"cloudy": "This applies to Snowflake.","classic": "This applies to SQL Server."}');
var template = document.getElementById("template").innerHTML;
var rendered = Mustache.render(template, json);
document.getElementById("target").innerHTML = rendered;
}
This does not work:
function renderHello() {
var json = JSON.parse('./abc.json');
var template = document.getElementById("template").innerHTML;
var rendered = Mustache.render(template, json);
document.getElementById("target").innerHTML = rendered;
}
Variations I've tried in abc.json:
{
"cloudy": "This applies to Snowflake.",
"classic": "This applies to SQL Server."
}
{"cloudy": "This applies to Snowflake.","classic": "This applies to SQL Server."}
I've unsuccessfully tried
var json = './abc.json';
var json = JSON.parse('./abc.json');
var json = JSON.stringify('./abc.json');
var json = JSON.parse(JSON.parse('./abc.json'));
var json = JSON.parse(JSON.stringify('./abc.json'));
Frequently an error like this is returned in the Chrome Developer Tools:
VM223:1 Uncaught SyntaxError: Unexpected token . in JSON at position 0
at JSON.parse (<anonymous>)
at renderHello (render.js:2)
at onload (docs.html:91)
I added these lines in the script to reveal the location of the website file that includes the Mustache template, so I knew where to locate abc.json:
var loc = window.location.pathname;
var dir = loc.substring(0, loc.lastIndexOf('/'));
console.log(dir)
And the file structure is now this:
directory
--file-with-mustache-script.html
--abc.json
This may not be relevant, but this is the Mustache script, which of course already works with the JSON as a string.
<body onload="renderHello()">
<div id="target">Loading...</div>
<script id="template" type="x-tmpl-mustache">
Hello {{ cloudy }}, {{ classic }}!
</script>
</body>
The website build tool I'm using does not support Node or Handlebars.
If it is relevant at all, the goal is to populate values from a JSON file in a product documentation website page to indicate which paragraphs apply to which product version.
You need to load the content of the file via "AJAX". You can't get the content like you are trying to do.
Something like this would do the job:
function renderHello() {
fetch('https://jsonplaceholder.typicode.com/users/3').then(r=>r.json())
.then(json=>{
// var template = document.getElementById("template").innerHTML;
// var rendered = Mustache.render(template, json);
document.getElementById("target").innerHTML = JSON.stringify(json,null,2);
})
}
renderHello();
<pre id="target"></pre>
As I don't have access to your abc.json file I used a publicly resource at http://typicode.com.

can't select specific elements from data contained in <?!=JSON.stringify(dataFromServerTemplate) ?>

I have a problem with JSON format. I'm new at this kind of stuff so I can't figure out which is the problem. In google app script I have this get function
function doGet() {
var htmlTemplate = HtmlService.createTemplateFromFile('html');
var ss = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1_cj_HO2oN6CYe_Pb7Cy8S3yVtwKW8Efr-Sdyf1Sk8Ts/edit#gid=2009573145");
htmlTemplate.dataFromServerTemplate = makeJSON(getRowsData_(ss.getSheetByName("Foglio8"),getExportOptions()),getExportOptions());
var htmlOutput = htmlTemplate.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME)
.setTitle('sample');
return htmlOutput;
}
Now, here is the part of the HTML which isn't working
<div>
<p id="tx"></p>
</div>
<script type="text/javascript">
var data = <?!=JSON.stringify(dataFromServerTemplate) ?>;
function caric(){
document.getElementById("tx").innerText= data.saldo;}
</script>
</body>
Function caric() runs onload of the page. "saldo" is actually contained in this JSON.
If I use data.saldoI receives undefined but if I only use data it works and prints everything that is contained in the JSON.
Do you know what I'm doing wrong?
Thanks
JSON.stringify produces a string not an object. In your server code you should do something like this.
var obj = { name: "me", gender: "male", eyes: "blue" };
htmlTemplate.dataFromServerTemplate = JSON.stringify(obj);
And on the client side this
var data = JSON.parse(<?= dataFromServerTemplate ?>);
(function caric(){
document.getElementById("tx").innerText= data.name;}());

Mustache.to_html() returning an empty string

This question was asked before but didn't get an answer. I have a php file which sends a json object to a javascript file which is supposed to render it with a template and display it on a div. The problem is, the function Mustache.to_html() returns empty. can anyone tell me what I am doing wrong. here's my code.
{
$(":button").click(function(){
var cat = $(this).attr("name");
$.get("trier.php",{input: cat}, function(data){
alert(data);
var template = $('#templabel').html();
console.log(template);
var html = Mustache.to_html(template, data);
console.log(html);
$('#feedback2').html(data);
});
});
}
The javascript sends the data to this php file which sends back a json object
{
if(isset($_GET['input'])){
$catt = $_GET['input'];
$info = "SELECT * FROM books WHERE (Category = '$catt')";
$information = mysqli_query($conn,$info);
$arraay = array();
while($r = mysqli_fetch_assoc($information)){
$arraay[] = $r;
}
$jason = json_encode($arraay);
$jason = '{"arraay":'.$jason."}";
echo $jason;
}
}
The javascript file will then send the json object rendered with the mustache template to the html file, to the tag with the id = "feedback2". But the display is raw json, not templated. and the second console.log after I apply the Mustache.to_html function returns an empty string. What am I doing wrong?
The output of the console.log for the template is
{{#arraay}}
<div>
<h2> {{Title}}</h2>
<p>{{Course}}</p>
<p>{{Category}}</p>
</div>
{{/arraay}}
and the alert for the data is
{"arraay":[{"Title":"Algorithms","Course":"CSI241","Category":"science"},{"Title":"Fluid dynamics","Course":"PHY345","Category":"science"}]}
Works for me:
var data = {"arraay":[{"Title":"Algorithms","Course":"CSI241","Category":"science"},{"Title":"Fluid dynamics","Course":"PHY345","Category":"science"}]};
var template = document.getElementById('template').innerHTML;
var html = Mustache.to_html(template, data);
document.getElementById('render').innerHTML = html;
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.2.0/mustache.min.js"></script>
<template id="template">
{{#arraay}}
<div>
<h2> {{Title}}</h2>
<p>{{Course}}</p>
<p>{{Category}}</p>
</div>
{{/arraay}}
</template>
<div id="render">
</div>

Unable to access array of entities passed through twig in javascript

I am currently working on a symfony2.0 project. At the moment I am stuck at some point where I want to use some simple javascript within my twig file.
From my controller I pass an array of entities called Machine to the twig file like this:
...
return $this->render('PRwissHostsBundle:mini:editLocation.html.twig',
array(
'form' => $form->createView(), 'id' => $id, 'machines' => $machinesInLoc,
));
My form inside the twig file easily cann acces the machines array. What I now need is to access this array within javascript.
Currently I m doing this like follwing:
<script type="text/javascript">
...
var mach_array = {{machines|json_encode|raw}};
var machine = mach_array[0];
alert(machine.name);
....
</script>
Somehow if I alert the mach_array it says that it is an object. Same result when I alert the machine. What is not possible is to access the machines id or name or whatevers property of it.
I have searched a couple of other questions like this but unfortunatly they were not helpfull regarding an array of entities.
Any help is highly appreciated.
In general, you shouldn't let Twig handle the data formatting unless it's absolutely necessary, for example as a response from a AJAX call.
With that said, your issue lies with how you declare the mach_array.
var mach_array = {{machines|json_encode|raw}};
should be
var mach_array = '{{machines|json_encode|raw}}';
By not wrapping the call to twig, Javascript will make mach_array a Object, its the same as
var mach_array = {"foo" : "bar"}
which resolves to a Object.
So I just solved my problem with the help of Nihilnovi. The problemw as not an empty array like gregory supposed, I just did not realy figure out how to properly use javascript and twig entities. The working code now looks like following:
<script type="text/javascript">
function report(period){
var e = document.getElementById("form_machines");
var selectValue = e.options[e.selectedIndex].value;
var selectText = e.options[e.selectedIndex].text;
if (selectValue != ""){
var table = document.getElementById("uebersicht");
var row = table.insertRow(-1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
cell1.innerHTML = "<b>Name:</b>";
var mach_array = {{machinesAvailable|json_encode|raw}};
{% for machine in machinesAvailable %}
if ({{machine.name|json_encode|raw}} == selectText){
cell2.innerHTML = "<a href='{{ url('PRwissHostsBundle_det_machine', { 'id':machine.id }) }}'> {{machine.name}} </a>";
}
{% endfor %}
cell3.setAttribute('align', 'right');
cell3.innerHTML = "<input type='checkbox' id=machine.id >";
}
}
</script>
Hope this helps some who steps into the same issue!

Translation in JavaScript like gettext in PHP?

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>

Categories