Google AdWord Example to haml - haml

Given this example: https://support.google.com/adwords/answer/3207306?hl=en&rd=1
How would I convert the code listed under the "Troubleshooting your code snippet" section to haml?
The closest I've come is:
%script{:type=>"text/javascript"}
:cdata
var google_conversion_id = 123456789;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "AAAAAAAAAAAAAAAAAAA";
var google_conversion_value = 0;
var google_remarketing_only = false;
%script{:type => "text/javascript", :src => "//www.googleadservices.com/pagead/conversion.js"}
%noscript
%div{:style => "display:inline;"}
%img{:height => "1", :width => "1", :style => "border-style:none;", :alt => "", :src => "//www.googleadservices.com/pagead/conversion/123456789/?value=0&label= AAAAAAAAAAAAAAAAAAA&guid=ON&script=0".html_safe}
The problem with above is the :cdata tag produces:
<script type="text/javascript">
<![CDATA[
var google_conversion_id = 123456789;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "AAAAAAAAAAAAAAAAAAA";
var google_conversion_value = 0;
var google_remarketing_only = false;
]]>
</script>
And not:
<script type="text/javascript">
/* <![CDATA[ */
var google_conversion_id = 123456789;
var google_conversion_language = "en";
var google_conversion_format = "2";
var google_conversion_color = "ffffff";
var google_conversion_label = "AAAAAAAAAAAAAAAAAAA";
var google_conversion_value = 0;
/* ]]> */
</script>
Is there a way to explicitly declare the CDATA tag? Or is Google not that picky about it?

You can escape / in haml with a \ at the beginning of the line. I had the same issue and the following worked for me to include the google adwords conversion tracking code in our site:
<script type="text/javascript">
\/* <![CDATA[ */
var google_conversion_id = 123456789;
var google_conversion_language = "en";
var google_conversion_format = "2";
var google_conversion_color = "ffffff";
var google_conversion_label = "AAAAAAAAAAAAAAAAAAA";
var google_conversion_value = 0;
\/* ]]> */
</script>
which after haml processing turns into:
<script type="text/javascript">
/* <![CDATA[ */
var google_conversion_id = 123456789;
var google_conversion_language = "en";
var google_conversion_format = "2";
var google_conversion_color = "ffffff";
var google_conversion_label = "AAAAAAAAAAAAAAAAAAA";
var google_conversion_value = 0;
/* ]]> */
</script>

After haggling with many variations of the above, I finally "cheated" and just used the :plain tag to get it exactly the way I wanted. The code below exactly replicates what was on the Google Analytics example page, and the Google Tag Assistant plugin for Chrome confirms that it's coming through properly. Note: I also had to change the googleadservices link to HTTPS so that it would match the rest of my page (that was causing other problems that were hard to chase down, and Tag Assistant helped to sort it out).
This should do it for you:
%script{:type=>"text/javascript"}
:plain
/* <![CDATA[ */
var google_conversion_id = 123456789;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "AAAAAAAAAAAAAAAAAAA";
var google_conversion_value = 0;
var google_remarketing_only = false;
/* ]]> */
%script{:type => "text/javascript", :src => "https://www.googleadservices.com/pagead/conversion.js"}

The CDATA tag isn’t really needed in HTML. The intention is that it allows the use of things like literal < in the javascript without having to escape them. CDATA sections are sometimes used with XHTML, but even then XHTML is usually treated as HTML by the browser.
With Haml, you could use the :javascript filter for blocks like this. That will add the CDATA section if your document format is XHTML, and leave it out otherwise. It will also omit the type attribute if the format is HTML5, since the default is text/javascript in that case.
So:
:javascript
var google_conversion_id = 123456789;
// etc ...
Will produce this when the format is HTML5 (the default)
<script>
var google_conversion_id = 123456789;
// etc ...
</script>
and this when the format is XHTML:
<script type='text/javascript'>
//<![CDATA[
var google_conversion_id = 123456789;
// etc ...
//]]>
</script>
Note that this uses // comments for the CDATA markers rather than /* ... */ that the Google page suggests, but this shouldn’t matter.

Related

html2canvas add multiple pages using jspdf?

Below are my snippet right now its printing all canvas in single page. I want to print the each canvas in a new page.
I have use Fabricjs to render the canvas from json. Other pdf library not able to print the canvas it download empty PDF so i try JSPDF But stuck in a point.
DEMO
<script>
var jsPDF = window.jspdf.jsPDF;
var html2canvas = window.html2canvas;
function downloadpdf(){
console.log('Inside downloadpdf ');
var quotes = document.getElementById('generatePDF');
html2canvas(quotes, {
onrendered: function(canvas) {
canvas.getContext('2d');
var HTML_Width = canvas.width;
var HTML_Height = canvas.height;
var top_left_margin = 15;
var PDF_Width = HTML_Width+parseInt(top_left_margin*2);
var PDF_Height = parseInt(PDF_Width*1.5)+parseInt(top_left_margin*2);
var canvas_image_width = HTML_Width;
var canvas_image_height = HTML_Height;
var totalPDFPages = Math.ceil(HTML_Height/PDF_Height)-1;
var pages = $('#generatePDF .canvas-container').length;
console.log('height => '+canvas.height+" width => "+canvas.width+'totalpage => '+pages);
var imgData = canvas.toDataURL("image/jpeg", 1.0);
var pdf = new jsPDF('p', 'pt', [PDF_Width, PDF_Height]);
pdf.addImage(imgData, 'JPG', top_left_margin, top_left_margin,canvas_image_width,canvas_image_height);
for (var i = 1; i <= pages; i++) {
//pdf.addPage(PDF_Width, PDF_Height);
pdf.addPage();
let margin=-parseInt(PDF_Height*i)+parseInt(top_left_margin*4);
if(i>1){
margin= parseInt(margin+i*8);
}
pdf.addImage(imgData, 'JPG', top_left_margin, margin,canvas_image_width,canvas_image_height);
}
pdf.save("HTML-Document.pdf");
}
});
}
</script>

Can you pretty print IHtmlContent?

If I have a IHtmlContent can I pretty print it?
Example:
var html = new HtmlString("<article><h2>Hello!</h2></article>");
I want it pretty printed with line breaks and indention into:
<article>
<h2>Hello!</h2>
</article>
I do not want:
<article><h2>Hello!</h2></article>
You could try to JavaScript to add the line breaks and indention into, then, use <pre> tag to render the html content. Please check the following sample:
Index.cshtml:
#{
var html ="<article><h2>Hello!</h2></article>";
}
<div id="printdiv">
#Html.Raw(html)
</div>
<div id="output">
</div>
<input type='button' id='btn' value='Print' onclick='printDiv();'>
#section Scripts{
<script>
function printDiv() {
var divToPrint = document.getElementById('printdiv');
//display the pretty html content in the web page.
document.getElementById("output").innerHTML = "<pre>" + process(divToPrint.innerHTML).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">") + "</pre>";
//create a new window to print the div content.
var newWin = window.open('', 'Print-Window');
newWin.document.open();
newWin.document.write('<html><body onload="window.print()"><pre>' + process(divToPrint.innerHTML).replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">") + '</pre></body></html>');
newWin.document.close();
setTimeout(function () { newWin.close(); }, 10);
}
function process(str) {
var div = document.createElement('div');
div.innerHTML = str.trim();
return format(div, 0).innerHTML;
}
function format(node, level) {
var indentBefore = new Array(level++ + 1).join(' '),
indentAfter = new Array(level - 1).join(' '),
textNode;
for (var i = 0; i < node.children.length; i++) {
textNode = document.createTextNode('\n' + indentBefore);
node.insertBefore(textNode, node.children[i]);
format(node.children[i], level);
if (node.lastElementChild == node.children[i]) {
textNode = document.createTextNode('\n' + indentAfter);
node.appendChild(textNode);
}
}
return node;
}
</script>
}
The result like this:
You can parse it XML with XDocument.Parse then use XmlWriter with its settings set to Indent to true. Worked for me on my HTML too.
var html = new HtmlString("<article><h2>Hello!</h2></article>");
using var writer = new StringWriter();
html.WriteTo(writer, HtmlEncoder.Default);
var htmlString = writer.ToString();
var settings = new XmlWriterSettings
{
OmitXmlDeclaration = true,
Encoding = Encoding.UTF8,
Indent = true,
};
var sb = new StringBuilder();
using (var writer = XmlWriter.Create(sb, settings))
{
XDocument.Parse(htmlString).Save(writer);
}
Console.WriteLine(sb.ToString());

Google remarketing/conversion currency code errors

I am implementing a simple Google remarketing/conversion script to a client site... But having issues with the setting of the currency code for some reason.
I get 2 errors using the tag assistant which are:
Conversion Value should be prefixed with standard currency.
Non-standard implementation
Code
<script type="text/javascript">
/* <![CDATA[ */
var google_conversion_id = ABC123;
var google_conversion_language = "en";
var google_conversion_format = "3";
var google_conversion_color = "ffffff";
var google_conversion_label = "ABC123";
var google_remarketing_only = false;
var google_conversion_value = 1.00;
var google_conversion_currency = "GBP";
/* ]]> */
</script>
<script type="text/javascript"
src="//www.googleadservices.com/pagead/conversion.js">
</script>
<noscript>
<div style="display:inline;">
<img height="1" width="1" style="border-style:none;" alt=""
src="//www.googleadservices.com/pagead/conversion/ABC123/?value=1&currency_code=GBP&label=ABC123&guid=ON&script=0"/>
Anyone know what the issue is? Google help online seems to skip this issue!

Multiple Bing Map Pushpins from SQL not showing in Firefox & Chrome but do in IE

I'm displaying a Bing Map (v7) in my Webmatrix2 website with a series of pushpins & infoboxes drawn from a SQL Express database using a JSON enquiry.
While the maps appears in all 3 browsers I'm testing (IE, FF & Chrome) the pushpins are sometimes not showing in FF & Chrome, particularly if I refresh with Cntrl+F5
This is my first JSON and Bing Maps app so expect there's a few mistakes.
Any suggestions on how to improve the code and get display consistency?
#{
Layout = "~/_MapLayout.cshtml";
}
<script type="text/javascript" src="~/Scripts/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
<link rel="StyleSheet" href="infoboxStyles.css" type="text/css">
<script type="text/javascript">
var map = null;
var pinLayer, pinInfobox;
var mouseover;
var pushpinFrameHTML = '<div class="infobox"><a class="infobox_close" href="javascript:closeInfobox()"><img src="/Images/close2.jpg" /></a><div class="infobox_content">{content}</div></div><div class="infobox_pointer"><img src="images/pointer_shadow.png"></div>';
var pinLayer = new Microsoft.Maps.EntityCollection();
var infoboxLayer = new Microsoft.Maps.EntityCollection();
function getMap() {
map = new Microsoft.Maps.Map(document.getElementById('map'), {
credentials: "my-key",
zoom: 4,
center: new Microsoft.Maps.Location(-25, 135),
mapTypeId: Microsoft.Maps.MapTypeId.road
});
pinInfobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { visible: false });
AddData();
}
$(function AddData() {
$.getJSON('/ListSchools', function (data) {
var schools = data;
$.each(schools, function (index, school) {
for (var i = 0; i < schools.length; i++) {
var pinLocation = new Microsoft.Maps.Location(school.SchoolLat, school.SchoolLon);
var NewPin = new Microsoft.Maps.Pushpin(pinLocation);
NewPin.title = school.SchoolName;
NewPin.description = "-- Learn More --";
pinLayer.push(NewPin); //add pushpin to pinLayer
Microsoft.Maps.Events.addHandler(NewPin, 'mouseover', displayInfobox);
}
});
infoboxLayer.push(pinInfobox);
map.entities.push(pinLayer);
map.entities.push(infoboxLayer);
});
})
function displayInfobox(e) {
if (e.targetType == "pushpin") {
var pin = e.target;
var html = "<span class='infobox_title'>" + pin.title + "</span><br/>" + pin.description;
pinInfobox.setOptions({
visible: true,
offset: new Microsoft.Maps.Point(-33, 20),
htmlContent: pushpinFrameHTML.replace('{content}', html)
});
//set location of infobox
pinInfobox.setLocation(pin.getLocation());
}
}
function closeInfobox() {
pinInfobox.setOptions({ visible: false });
}
function getCurrentLocation() {
var geoLocationProvider = new Microsoft.Maps.GeoLocationProvider(map);
geoLocationProvider.getCurrentPosition();
}
</script>
<body onload="getMap();">
<div id="map" style="position:relative; width:800px; height:600px;"></div>
<div>
<input type="button" value="Find Nearest Schools" onclick="getCurrentLocation();" />
</div>
</body>
The JSON file is simply
#{
var db = Database.Open("StarterSite");
var sql = #"SELECT * FROM Schools WHERE SchoolLon != ' ' AND SchoolLon != 'null' ";
var data = db.Query(sql);
Json.Write(data, Response.Output);
}
Add your pinLayer, infobox, and infoboxLayer before calling the AddData function and see if that makes a difference. Also verify that school.SchoolLat and school.SchoolLon are numbers and not a string version of a number. If they are a string, then use parseFloat to turn them into a number. Other than that everything looks fine.

Rally App SDK: Is there a way to have variable columns for table?

Using the Rally App SDK, is there a way to create a table with a variable number of columns? For example, for a selected release, the columns are the iterations within that release date range, and the rows are each project.
I have all of the data I want to display, but not sure how to create the table.
Here's an example app that dynamically builds a table config with Iteration Names as columns and then adds some dummy data to it. Not too exciting, but it illustrates the idea.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!-- Copyright (c) 2002-2011 Rally Software Development Corp. All rights reserved. -->
<html>
<head>
<title>Iterations as Table Columns</title>
<meta name="Name" content="App: Iterations as Table Columns"/>
<script type="text/javascript" src="https://rally1.rallydev.com/apps/1.29/sdk.js"></script>
<script type="text/javascript">
function iterationsAsTableColumns(rallyDataSource)
{
var wait = null;
var table = null;
var tableHolder = null;
// private method the builds the table of Iteration columns and your info
function showResults(results)
{
if (wait) {
wait.hide();
wait = null;
}
if (table) {
table.destroy();
}
var myIterations = results.iterations;
if (myIterations.length === 0) {
tableHolder.innerHTML = "No iterations were found";
return;
}
var columnKeys = new Array();
var columnHeaders = new Array();
var columnWidths = new Array();
var columnWidthValue = '80px';
var keyName;
// Dynamically build column config arrays for table config
for (i=0; i<myIterations.length;i++){
keyName = "Column"+i;
columnKeys.push(keyName);
columnHeaders.push("'" + myIterations[i].Name + "'");
columnWidths.push("'" + columnWidthValue + "'");
}
var config = { 'columnKeys' : columnKeys,
'columnHeaders' : columnHeaders,
'columnWidths' : columnWidths
};
table = new rally.sdk.ui.Table(config);
var cellValue;
var propertyAttributeStatement;
var rowData = new Array();
for (i=0;i<10;i++){
// create Object for row data
rowItem = new Object();
for (j=0; j<columnKeys.length;j++){
cellValue = "Cell[" + i + "][" + j + "] = Your Data Here";
propertyAttributeStatement = "rowItem." + columnKeys[j] + " = '"+cellValue+"';";
eval(propertyAttributeStatement);
}
rowData.push(rowItem);
}
table.addRows(rowData);
table.display(tableHolder);
}
//private method to query for iterations that get listed as columns
function runMainQuery(sender, eventArgs) {
var queryCriteria = '(Project.Name = "Avalanche Hazard Mapping"")';
var queryConfig =
{
key : "iterations",
type : "Iteration",
fetch : "FormattedID,Name,Project,StartDate,EndDate,CreationDate",
order : "CreationDate desc",
};
tableHolder.innerHTML = "";
wait = new rally.sdk.ui.basic.Wait({});
wait.display(tableHolder);
rallyDataSource.findAll(queryConfig, showResults);
}
//private method to start building controls on page
function initPage() {
buttonSpan = document.getElementById('buttonSpan');
tableHolder = document.getElementById('table');
var buttonConfig = {
text: "Show Table",
value: "myValue"
};
var showTableButton = new rally.sdk.ui.basic.Button(buttonConfig);
showTableButton.display(buttonSpan, runMainQuery);
}
// only public method
this.display = function() {
rally.sdk.ui.AppHeader.showPageTools(true);
initPage();
};
}
</script>
<script type="text/javascript">
rally.addOnLoad(function() {
var rallyDataSource = new rally.sdk.data.RallyDataSource('__WORKSPACE_OID__',
'__PROJECT_OID__',
'__PROJECT_SCOPING_UP__',
'__PROJECT_SCOPING_DOWN__');
var iterationsAsTableColumnsExample = new iterationsAsTableColumns(rallyDataSource);
iterationsAsTableColumnsExample.display();
});
</script>
</head>
<body>
<div>
<span id="buttonSpan"></span>
</div>
<div style="height: 15px;"> </div>
<div id="table"></div>
</body>
</html>