Passing variable to HTML output and then into a scriptlet - html

Code.gs
function doPost(e) {
...
template.data += getCustomerData + "<br>";
}
return template.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME);
index.html
...
<?= data ?>
The code shown does display the correct values. However, it doesn't translate <br> into HTML. I'm not sure why it isn't working since template.evaluate() is supposed to return an HtmlOutput object.

By default the strings are sanitized, converting special characters to their HTML encoded equivalents (such as < becoming <).
When outputting HTML you must use <?!= to avoid sanitizing the data.
<?!= data ?>
See the details on standard & force-printing scriptlets here:
https://developers.google.com/apps-script/guides/html/templates#standard_scriptlets

Related

Line breaks in templated HTML scriptlets

If I have an HTML file test.html:
<p><?= str ?></p>
And a script function:
var t = HtmlService.createTemplateFromFile("test.html");
t.str = "test\nstring";
var content = t.evaluate().setSandboxMode(...).getContent();
Logger.log(content);
Is there any way to safely replace the newline with an HTML line break? I can use String.prototype.replace() to replace \n with <br/>, but then I'd have to use <?!= to disable the HTML templating engine's contextual escaping. I'm dealing with untrusted input and so I need both escaping and smart handling of line breaks. Having it contextually would be nice. As things stand, I wrote my own escaper, but it is only good for one context.
I see two options for your scenario, the simple one is to forget the substitution entirely and use a <pre> tag, which will render your line breaks (and other formatting chars)
<pre> <?= str ?> </pre>
The second is to perform the substitution and sanitize your input with a custom function, so that you can safely use the force print scriptlet.
In your html:
<?!= sanitize(str); ?>
and in your .gs:
function sanitize(val){
var vals = val.split('\n'); //split string into an array on newlines
for(var i in vals){
vals[i] = Encoder.htmlEncode(vals[i]); //sanitize each element in the array
}
return vals.join('<br />'); //join the elements as a string, with <br /> as glue.
}
Note, in my example I'm using the library located here to sanitize the strings: http://www.strictly-software.com/scripts/downloads/encoder.js
If anyone's curious, this is the code I wound up using to sanitize the untrusted input for display. It's not safe for use inside tags, in script sections, etc. That's why Google's context aware sanitization is so handy.
function dumbEscapeAndBreak(str) {
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\n/g, '<br/>');
}
function _testEscape() {
GSUnit.assertEquals('my<test<string>is>not&good&okay<br/>fine<br/>okay', dumbEscapeAndBreak("my<test<string>is>not&good&okay\nfine\nokay"));
}
Or you can do this:
In your .gs script function:
var t = HtmlService.createTemplateFromFile("test.html");
var paragraphs = "test\nstring";
t.str = paragraphs.split("\n");
In your test.html:
<?
for (i = 0; i < str.length; i++) {
?>
<span><?= str[i]?></span><br />
<!-- <p><?= str[i]?></p> -->
<?
}
?>
You can use the <span> or <p> tag, that is up to you. You can also write some simple logic to decide when to put the <br />, e.g. before <span> when i > 0. That will completely fulfil your "test\nstring".

Json parsing fails out of the blue

So I've been struggling with JSON for awhile now, however last night something weird happened, even tho I have " escaped it brings up an error, here's my JSON string
var data = $.parseJSON('{"rows":[{"type":"row","width_class":"row new_row","column_class":"col3 column_model","columns":{"0":{"class":"column one","children":[]},"1":{"class":"column one","children":[{"type":"bullet-block","html":"<div class=\\"bullet-block-element\\"><ul><li style='padding-left:36px;background-image:url(\\"http://example.com/includes/images/bulletins/large-0.png\\");'>123</li><li style='padding-left:36px;background-image:url(\\"http://example.com/includes/images/bulletins/large-0.png\\");'>456</li><li style='padding-left:36px;background-image:url(\\"http://example.com/includes/images/bulletins/large-0.png\\");'>789</li></ul></div>","image":"http://example.com/includes/images/bulletins/large-0.png","size":"large","items":["123","456","789"]}]},"2":{"class":"column one","children":[]}}}]}');
This is generated via
var data = $.parseJSON('<?= str_replace('\\','\\\\',base64_decode($data['d'])) ?>');
Am I just being blind or have I had too much redbull? Help would be appreciated!
json_encode does the escaping and it will automatically be exposed as JSON, you don't need $.parseJSON, it's double decoding there.
Simply use this:
<?php
$php = array('test' => 'hi');
$data['d'] = base64_encode(json_encode($php)); // 'eyJ0ZXN0IjoiaGkifQ=='
?>
<script>
var data = <?php echo base64_decode($data['d']); ?>;
console.debug(data.test); // Prints 'hi' in the console ;-)
</script>
See the codepad: http://codepad.org/VmKGt0JD
you need to escape the ''s as well (styles in the html tags)
so this will work
var data = $.parseJSON('{"rows":[{"type":"row","width_class":"row new_row","column_class":"col3 column_model","columns":{"0":{"class":"column one","children":[]},"1":{"class":"column one","children":[{"type":"bullet-block","html":"<div class=\\"bullet-block-element\\"><ul><li style=\'padding-left:36px;background-image:url(\\"http://example.com/includes/images/bulletins/large-0.png\\");\'>123</li><li style=\'padding-left:36px;background-image:url(\\"http://example.com/includes/images/bulletins/large-0.png\\");\'>456</li><li style=\'padding-left:36px;background-image:url(\\"http://example.com/includes/images/bulletins/large-0.png\\");\'>789</li></ul></div>","image":"http://example.com/includes/images/bulletins/large-0.png","size":"large","items":["123","456","789"]}]},"2":{"class":"column one","children":[]}}}]}');
copied and pasted to a fiddle

Word having single quotes search from xml file using jquery issue

Hi I need to parse XML file using jquery. I created read and display functionality. But when a word having single quote not working.
My XML is like this
<container>
<data name="Google" definition="A search engine"/>
<data name=" Mozilla's " definition="A web browser"/>
</ container>
using my jquery code I can read definition of Google. But I can't read Mozilla's definition due to that single quotes. This is my jquery code.
var displayDefinition = function(obj){
$.get("definitions.xml", function(data){
xml_data1.find("data[name^='"+obj.innerHTML+"']").each(function(k, v){
right=''+ $(this).attr("Defination") + '';
}
}
$(".result").append(right);
}
Any body knows the solution for this please help me.
Thanks
jQuery deals with single quotes very well. the structure of your function looks really wild though. I changed it a big assuming you want to create a function that can display the definition based on passing it a name: http://jsfiddle.net/rkw79/VQxZ2/
function display(id) {
$('container').find('data[name="' +id.trim()+ '"]').each(function() {
var right = $(this).attr("definition");
$(".result").html(right);
});
}
Note, you have to make sure your 'name' attribute does not begin or end with spaces; and just trim the string that the user passes in.

How to display code in plain text?

I want to display bare code on an HTML page, I tried this:
<script>
function getSize() {
var myFSO = new ActiveXObject("Scripting.FileSystemObject");
var filepath = document.upload.file.value;
var thefile = myFSO.getFile(filepath);
var size = thefile.size;
alert(size + " bytes");
}
</script>
The above JavaScript code is some code entered by the user. I can't figure out to show this bare code on the html page without being interpreted and screwed up by the browser.
How do I display bare code on an HTML page?
I'm not quite clear on the specifics of the issue, as pre tags should, in general, do the trick, but here's an alternative tag:
<xmp>[Code can be displayed here]</xmp>
If you're using a server-side language, though, I'd suggest converting to HTML entities before outputting, then using CSS to style it.
As well, be sure if you're accepting user input that any JavaScript is being filtered and never executed.
You can use the <pre> and <code> tags to display formatted code. But to prevent the code from executing and not displaying you'll need to convert the text to character entities. > becomes >, < becomes &lt, etc.
You could do this by using PHP, for example:
<?php echo htmlentities('function getSize() { var myFSO = new
ActiveXObject("Scripting.FileSystemObject");
var filepath =
document.upload.file.value; var
thefile = myFSO.getFile(filepath);
var size = thefile.size; alert(size
+ " bytes"); }'); ?>
As your system relies on user input, you might have to rely on AJAX to actually process the user input and convert it to HTML entities.
Use the <code></code> tag, and use javascript or your sever-side scripting language
Dump it into a textarea and render it like a div tag
This is a bit of a hack and parlor trick, but it works.
Get bare code rendered onto an HTML page is to place it in a text area and remove all the formatting around the textarea so it looks like a <div> tag:
Code:<br>
<textarea style="border: none;width:400;height:200;background-color:lightgrey;">
#include<iostream>
using namespace std;
class Box{
public:
int mymethod(){ cout << "is method"; }
};
int myfunction(){ cout << "is function"; }
int main(){
Box b;
b.mymethod();
myfunction();
}
</textarea>
<br>
Output:
<pre>is methodis function
</pre>
The above html code should render like this on the page:
What I've done is invalid HTML, it only works because customary error handling happens to handle it this way. You shouldn't put unescaped angle brackets in the content of a <textarea>. You get undefined behavior depending on how the browser chooses to interpret your textarea tag.
The most reliable method is to htmlencode the code to be displayed on the page.
For example
< into &lt
space into &nbsp
etc.

Sending values through links

Here is the situation: I have 2 pages.
What I want is to have a number of text links(<a href="">) on page 1 all directing to page 2, but I want each link to send a different value.
On page 2 I want to show that value like this:
Hello you clicked {value}
Another point to take into account is that I can't use any php in this situation, just html.
Can you use any scripting? Something like Javascript. If you can, then pass the values along in the query string (just add a "?ValueName=Value") to the end of your links. Then on the target page retrieve the query string value. The following site shows how to parse it out: Parsing the Query String.
Here's the Javascript code you would need:
var qs = new Querystring();
var v1 = qs.get("ValueName")
From there you should be able to work with the passed value.
Javascript can get it. Say, you're trying to get the querystring value from this url: http://foo.com/default.html?foo=bar
var tabvalue = getQueryVariable("foo");
function getQueryVariable(variable)
{
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++)
{
var pair = vars[i].split("=");
if (pair[0] == variable)
{
return pair[1];
}
}
}
** Not 100% certain if my JS code here is correct, as I didn't test it.
You might be able to accomplish this using HTML Anchors.
http://www.w3schools.com/HTML/html_links.asp
Append your data to the HREF tag of your links ad use javascript on second page to parse the URL and display wathever you want
http://java-programming.suite101.com/article.cfm/how_to_get_url_parts_in_javascript
It's not clean, but it should work.
Use document.location.search and split()
http://www.example.com/example.html?argument=value
var queryString = document.location.search();
var parts = queryString.split('=');
document.write(parts[0]); // The argument name
document.write(parts[1]); // The value
Hope it helps
Well this is pretty basic with javascript, but if you want more of this and more advanced stuff you should really look into php for instance. Using php it's easy to get variables from one page to another, here's an example:
the url:
localhost/index.php?myvar=Hello World
You can then access myvar in index.php using this bit of code:
$myvar =$_GET['myvar'];
Ok thanks for all your replies, i'll take a look if i can find a way to use the scripts.
It's really annoying since i have to work around a CMS, because in the CMS, all pages are created with a Wysiwyg editor which tend to filter out unrecognized tags/scripts.
Edit: Ok it seems that the damn wysiwyg editor only recognizes html tags... (as expected)
Using php
<?
$passthis = "See you on the other side";
echo '<form action="whereyouwantittogo.php" target="_blank" method="post">'.
'<input type="text" name="passthis1" value="'.
$passthis .' " /> '.
'<button type="Submit" value="Submit" >Submit</button>'.
'</form>';
?>
The script for the page you would like to pass the info to:
<?
$thispassed = $_POST['passthis1'];
echo '<textarea>'. $thispassed .'</textarea>';
echo $thispassed;
?>
Use this two codes on seperate pages with the latter at whereyouwantittogo.php and you should be in business.