Editing HTML content in Google Sites - google-apps-script

Editing HTML content in Google Sites
I have a small project in mind but cant seem to get past this one obstacle.
Having trouble getting the HTML content of this Google Sites Page and adding a single line too it. So if one would keep refreshing the page the 'Hello World' line would keep adding itself over and over. I have noticed that the original code that embeds the gadget gets altered quite a bit too.
function doGet() {
var app = UiApp.createApplication();
var page = SitesApp.getActivePage();
var html = page.getHtmlContent();
var main = page.setHtmlContent(html + '<br>Hello World<br>');
return app;
}

.getHtmlContent() will return all the html markup and tags. So, you're trying to set "Hello World" after all the tags have been closed.
Throw a Logger.log(html); in there to see what you need to get at and change. Ultimately you'll need to replace the text you want within the html instead of just adding a line to the end.

its by design that the html keeps chsnging every time you run it. your script permanently modifies the site.
instead you need to publish a htnlservice appscript and insert it on the site.

Related

Click a _self targeted link twice in GAS?

First of all I am sorry if I use GAS tools incorrectly.
Context :
I need to generate a simple webapp including link that will be framed in a google-site.
target="_self" and .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL) are ensential for this reason. I cannot set target on any other values than _self, (I'm aware that the following code wok perfectly with _top)
see this previous question : Can't have link in Embedded web app in Google site?
Code :
Use this simple code sample deployed as an Web app :
function doGet(e) {
var count = Number(e.parameters.count) || 0
var html = "<a target='_self' href='https://script.google.com/macros/s/";
html += ScriptApp.getService().getUrl().substr(35); //the id of the script
html += "?count="+ (count+1) + "'>click me twice</a><br>" + count;
return HtmlService.createHtmlOutput(html).setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
It just insert a link to the curent page, counting in the get how many times the link is clicked.
Issues :
First you can see that the code dont work in the "latest code" preview (url ending by /dev). setXFrameOptionsMode dont seem to work on preview. We cant test it their but we can still deploy it so that's ok.
Once published (url ending by /exec) the web app seem to work correctly at first sight but you can click on the link only once.

How can you add a link to a google site via a Google Apps Script?

I have been scripting a few ways to make my Google site easier to manage by dynamically creating pages. I want to be able to create a directory with links to those pages.
So i was thinking something like...
var page = site.getChildByName("NEW URL");
var link = [page.getUrl()];
page = site.getChildByName("URL TO DIRECTORY").addListItem(link);
...using google apps scripts. Haven't tested this too thoroughly as of yet but it haven't been able to get the links to work in the list. I was hoping to just keep the page template as a normal webpage.
If I went that route would editing the html be the only option? Hopefully there is an easier way.
Any ideas would be great. Thanks!
here is a small test that shows a list of all the pages in your site
function doGet() {
var app=UiApp.createApplication().setTitle("Directory of this site")
var mainPanel = app.createAbsolutePanel().setStyleAttributes({background:'beige',padding:'20px'});
var scroll = app.createScrollPanel().setPixelSize(450,300);
var site = SitesApp.getSiteByUrl('https://sites.google.com/site/appsscriptexperiments/')
var pages = site.getAllDescendants()
var grid = app.createGrid(pages.length,2).setWidth(400)
for(n=0;n<pages.length;++n){
grid.setText(n, 0, pages[n].getName()).setWidget(n, 1, app.createAnchor('open', pages[n].getUrl()))
}
app.add(mainPanel.add(scroll.add(grid)))
return app
}
I suppose you know ho to use it in your sitepage but just for info for anyone else : you have to go to manage site > script apps > create a new script > save a version > deploy with appropriate authorizations and finally return to your page and insert it as a gadget (better with a border and a size of 450x300, personal pov ^^) . You can also use it as a standalone webapp using its deploy url.

IE injects VBScript tags in the middle of rendering, causing malformed HTML

For some reason, it seems like IE9 (I believe IE8 too, but not sure), is injecting
<SCRIPT LANGUAGE=VBScript>on error resume next pluginFound = IsObject(CreateObject("DIFFERENT PLUGIN EVERY TIME"))
in the middle of my content without any regards to surrounding context. This means it gets added in the middle of an attribute, or in the middle of some JavaScript, causing the HTML to be malformed and causing all sorts of problems.
This happens on multiple computers with different plugins, so it's not machine specific. And it's also not consistent: the location in which the offending script gets injected varies, the offending script varies. Sometimes you'll get several page loads without a problem and then you'll get the broken HTML.
My page is using a fair amount of JS, but nothing crazy. It's currently using jQuery, Google Maps, Bootstrap, Google Tag Manager, and loading a couple of Twitter, Google+, Facebook Iframes with their own little JS snippets. So, there are some asynchronous callbacks happening, but I wouldn't think this would interfere with how the browser renders the DOM and when it decides to inject plugin code.
You can see the problem if you reload http://www.rew.ca/properties/search/839721 enough times. If you scroll to the bottom of the page, you'll see raw JSON, or sometimes just some random HTML snippet will show in the middle of the page (because of mismatched tags).
Any ideas of why these scripts get injected arbitrarily and how to work around that?
Thanks
[UPDATE]
Here's another example of the script tags getting included in the middle of HTML content:
In my opinion, the problem lies in the http://cn.clickable.net/js/cct.js script, and specifically in the IsIEPlugin method of the __cct_tracker class:
this.IsIEPlugin = function (e) {
var t = !1;
return document.write('<SCRIPT LANGUAGE=VBScript>\n on error resume next \n pluginFound = IsObject(CreateObject("' + e + '")) </SCR' + "IPT>\n"), t ? 1 : 0
}
This method is called several times, with different arguments:
this.pixelRequestParams.cctDir = this.IsIEPlugin("SWCtl.SWCtl.1"),
this.pixelRequestParams.cctFlashPlugin = this.IsIEPlugin("ShockwaveFlash.ShockwaveFlash.1");
if (this.IsIEPlugin("PDF.PdfCtrl.1") == 1 ||
this.IsIEPlugin("PDF.PdfCtrl.5") == 1 ||
this.IsIEPlugin("PDF.PdfCtrl.6") == 1)
this.pixelRequestParams.cctPdf = 1;
this.pixelRequestParams.cctQuickTime = this.IsIEPlugin("Quicktime.Quicktime"),
this.pixelRequestParams.cctRealPlayer = this.IsIEPlugin("rmocx.RealPlayer G2 Control.1"),
this.pixelRequestParams.cctWmPlayer = this.IsIEPlugin("wmplayer.ocx")
I suppose (even I'm not sure) that "cct" stands for "Clickable Conversion Tracking", so it must be some sort of tracking code.
After further investigations, I've determined that the "cct.js" script gets loaded by the Google Tag Manager (GTM) script http://www.googletagmanager.com/gtm.js.
So, if I'm not wrong, by removing the GTM code snippet from your HTML page, you should be able to solve the problem.
It seems that the VBSCRIPT code dynamically injected by the GTM JavaScript code sometimes is not executed, but don't ask me why, since I don't really know.

how to replace a image url in all occurrences of it in html

i have a blogger blog. there is one image which i put in each of my blog's post( of my signature). earlier it was hosted on an image hosting site but now i want it to put it on my own site since the old hosting site may delete it any time. how can i replace all occurrences of the image previous url with the new url without changing it manually in each post?
it is almost impossible to do it manually because i already have made more than a hundred posts.
like is there any code which i can insert in the template which will replace the previous url with the new one whenever a page is opened?
With jQuery: -
$("a").each(function() {
var existingURI = $(this).attr('href');
$(this).attr('href', './path_to_new_location/' + existingURI);
});
If you're not sure how to use jQuery comment here and i'll give you a hand. Js Fiddle here: http://jsfiddle.net/jTnpk/
Are you able to copy all of your blog's HTML contents, because if you were able to then you could simply paste them into any good text editing software like Notepad++
from there you could go to "Replace..." under search and after typing in the old link in one and the new link in the other hit "Replace All" and from there you could just copy all the code and paste it back, if you have that option, if not you could add a script to the page which goes a little something like this:
<script>
for(i=0;i<document.links.length;i++)
{
if(document.links[i].href == /*Insert old link here*/)
document.links[i].href = /*Insert new link here*/ ;
}
</script>

JQUERY: Dynamically loading and updating iframe content on change() / keyup()

I've been working on a custom CMS in drupal for about two or three weeks now, and I keep running into this same problem. I'm trying to load a dynamically generated url (by extracting the node id of the target drupal page into $resultCut and appending it to the baseurl of the website). This iframe is embedded next to an instance of CKEditor, and the idea is to have the content in the iframe change when the fields in CKEditor are modified. I have the following Jquery:
<script type="text/javascript">
$(document).ready(function(){
baseurl = urlhere;
url = baseurl+"<?php echo $resultCut ?>"
$('#EmuFrame').attr('src', url);
var HTML = $('#EmuFrame').contents().find('body').html();
alert ( "LOADING COMPLETE" + HTML );
});
$('#edit-field-mobile-page-header-label-0-value').change(function () { // writes changes to the header text to emulaor
var curr = $(this).val();
$('#EmuFrame').contents().find("h1").text(curr);
});
$('#edit-body').keyup(function(e) { // writes changes to the body text to emulator
var curr = $(this).val();
currhead = $('#EmuFrame').contents().find("h1").html();
$('#EmuFrame').contents().find('#content').html("<h1>"+currhead+"</h1>"+curr);
});
where #EmuFrame is the id of an iframe, and the #edit-* tags are the ids of fields in CKEditor that I am monitoring for change. When the user types, the keyup() or change() events is supposed to grab the new html and swap it with the html in the iframe.
As of right now, the LOADING COMPLETE alert fires, but there is no html in the alert. I noticed that the content of the iframe loads AFTER the alert fires, however, which is what led me to believe that it's a problem with the order in which the events trigger.
Further, I had an alert in the callback function of keyup that returned the new html [ alert(curr) ] that was generated when a user started typing, and this alert returns html (although, it is being grabbed from CKEditor). However, the iframe does not reflect any changes. If I append [ alert (currhead) ] though, nothing is alerted at all.
It might be of interest to note that the source url is technically on a different domain than the parent. however, I used a workaround (i'm pretty sure it works, because I've previously gotten the whole html replacement thing working, and then somehow it broke). Also, neither Firebug nor Chrome's console report any XMLHttpRequest errors. Also, I keep getting this error: "Uncaught Syntax error, unrecognized expression: [#disabled]" and I'm not sure what it means, and whether its relevant to my problem as stated above.
That was a ridiculously long plea for help, so THANKS FOR READING, and thank you for any help!!
Your note about about the cross-domain iframe src is worrisome -- you shouldn't be able to access its contents with javascript. Nevertheless:
You have these two lines in quick succession:
$('#EmuFrame').attr('src', url);
var HTML = $('#EmuFrame').contents().find('body').html();
Try waiting for the iframe to load first:
$('#EmuFrame').load(function() {
var HTML = $('#EmuFrame').contents().find('body').html();
}