Get HTML content out of apps script application - google-apps-script

I've been struggling with this a while. My script runs from within a spreadsheet to update a site with its data formatted as HTML.
Within the script I'm using app.add(app.createHTML(values[i][j])) within a loop over the data range. I'm also appending various panels within this loop.
At the end I then find the page I want to update in the site and call page.setHtmlContent(app) which obviously doesn't work - what do I need to do here instead?

The object app is a UiApp instance, not an html content. One should consider it more as a command that tells the Google server to generate an html page using GWT toolkit so obviously (as you said) the code you tried can't work.
If you try to get the content of the shown page using something like
var htmlContent = UrlFetchApp.fetch('https://script.google.com/macros/s/AKf------Z1BBusUdHBmbWI-eqNjM/exec').getContentText();
you will see that it looks like anything but an understandable html code , plus you will meet issues with authorizations, warning messages and/or 'loading' messages...
As far as I know there is not way to capture the html content from a webapp in a form that would be compatible with the site method page.setHtml, at least not using Google Apps Script methods.
maybe some hack somewhere but not that I know...

Related

Modifying storefront HTML using Shopify app

I have been reviewing the Rest Admin API to try to figure out the answer to this question and I may be simply be looking at the wrong documentation.
We're trying to develop an application that will add custom data-driven pages to the site that will take product(s) from multiple selected categories and display them all on a single page, with checkout forms for each. This is done already by other apps, but we have to do a custom implementation so we can match the client's specific functionality needs. An example of an app that does something similar is the Bundle Builder app, which appears to modify the output of {{ content_for_layout }} in the theme.liquid file. It outputs some JSON gathered from the Shopify database (which can be done with the Shopify REST API) and an empty div. Getting the data isn't my concern, but I can't find anywhere in the docs I've looked at where it describes how to modify storefront HTML output.
I suspect it may do this by adding a template (but it has not added that template to the theme files) and associating it with the page URL, or by modifying the output of an existing template, or by adding a section and somehow integrating it with a page, or otherwise, but I have been unable to find documentation for how to do any of those tasks in the docs I've looked at. Other apps appear to add HTML to the storefront as well, such as Privy (which adds pop-ups), Easy Contact Form, and User Photos
What am I missing?
If you want to fill in an empty element with content, one easy way is to use an App Proxy. Shopify will make a secure callback to your endpoint of choice, and you can return data. You could also return Liquid and Shopify will render it along side the rest of the page chrome, ensuring your Liquid becomes the page.

Is there a way to access the HTML of an In App Browser (Themeable Browser)

I am using the ionic framework and would like to be able to read from the HTML from the current webpage and then send the selection back to my application.
I have the Theme-able Browser Plugin setup and can use it like any other web browser.
I have tried looking at ways to include my own script with the .executeScript() function but no luck.
I have also tried to read data from custom buttons that I have inserted into the tool/nav bar but that gives me the HTML of my application.
TL;DR: (Basically want access to the DOM of the current webpage and have the user use native selection to read the document.getSelection() and send that text back to my application.)
Any help would be highly appreciated.
After browsing the forums on Ionic I found the solution:
browser.executeScript({code:'window.getSelection().toString();'}).then((selection)=>{
packet.text = selection[0];});
This allows me to get the selection.

Serve up different HTML pages from same script?

I am trying to have a single GAS project that changes its UI by serving up different HTML pages based on what the user clicks. I cannot figure out how to serve up different HTML from the script, replace the current browser page and retain state. Any help appreciated. Thank you.
I use two options:
Have a main page which has buttons or text areas with onchange set to a function which calls back to the server side and gets new page data, then replace the current page or a portion of the page, with the new page.
Pass parameters in the URL and have the server side doGet() parse the parameters and branch to load a given page based on these values.
I have used a combination of both of these effectively. Basically I have a div which has my "menu" and a div which is the section to be replaced. My menu changes and then data is sent back to the server to get the dynamic body. The HTML is returned and then I replace using innerHTML.
In the same code I offer the ability to pass menu values via the published URL. This allows me to go directly to some values if I so choose as I have a Google Site where we embed the script into pages and the menu selections may be specific to that page. It allows us to use an iFrame to show the web app and go directly to the pertinent interface.
With google.script.run you can run any script on the server from the html page. By communicating with the server you have access to PropertiesService which gives you the capability to store information between pages. Personally I like the HTML Service createHtmlOutput(html) because I can edit the html without having to edit a separate page.
I decided to answer your question here so that I could use the code section.
Question:
I am actually looking to avoid manipulating the HTML and serve up a
completely different HTML file stored in the project. How do I make
the page call the script again and replace itself with the new
content?
We I'm guessing that completely replacing the page is not really what you want because the user will suffer a page refresh. But you could create divs like this:
<style>#R01{display:none;}</style>
<div class="replaceable" id="R01"></div>
If you put all your replaceable content in divs like that then you can request content from the server via calls like this:
google.script.run
.withSuccessHandler(updateConversation)
.withFailureHandler(showStatus)
.getConversation();
and put the new content into the appropriate divs and then change the css with another pair and turn the old content off and the new content on. Thereby avoiding a page refresh. Don't forget to save the old data into the PropertiesService first. So I don't think changing the entire page is the way to go but I could be wrong. I think just changing some of the internal content will avoid the need for a total page refresh. If you want to change images you can avoid another download by using CSS Sprites

Updating html of a Google Site's page with multiple blocks using Google Apps Script

I've created a page using "Web Page" template on my Google Sites, and I want to update the page using Google Apps Script. My code looks like this:
var template = HtmlService.createTemplateFromFile('mytemplate'); // meaning 'mytemplate.html'
var content = template.evaluate().getContent();
var site = SitesApp.getSiteByUrl('https://sites.google.com/site/example/');
var page = site.getChildByName('home');
page.setHtmlContent(content);
This works pretty well if the page's layout is "One column (simple)". Now my question is, if I choose one of the other layouts, how can I update each individual blocks using setHtmlContent()? Actually, I tried using "Two column (simple)" layout which has 2 blocks. setHtmlContent() changed the left column's html code and cleared the other column.
EDIT: What I actually wanted to do is to create a page with a gadget and update the page using Google Apps Script. According to this issue tracker https://code.google.com/p/google-apps-script-issues/issues/detail?id=572, it looks like we may encounter some problems when updating such page with setHtmlContent(). So I came up with an idea to create a multiple-column page, place a gadget in a column, and only update the HTML code of the other column with the Script to avoid such issue.
You can also create a Stand Alone Web App with Apps Script, then put an Apps Script Gadget into a Sites page. You can have multiple Apps Script Gadgets. I don't know what is triggering the change of the HTML. For all practical purposes, a Stand Alone Apps Script HTML Service App, is basically the same thing as a web site. You don't have a nice, understandable URL, but that won't show up in the Apps Script Gadget. Google will display a message: "This content was not created by Google"
I don't think you'll be able to inject HTML into multiple columns. You could create HTML that has multiple columns in it, and then add that HTML to the one column. So, you would be creating your own columns in HTML.

Obtaining a Snippet of HTML code from an App Script

It appears that when one uses HtmlService.createTemplateFromFile(), the html code that is in the file is just a snippet. The method packages the snippet in an html wrapper which adds things like the DTD, and html, head, and body tags to form a complete html document. The documentation (https://developers.google.com/apps-script/guides/html/) suggests that HtmlService.createHtmlOutputFromFile() works differently. It suggests that in the later case the relevant file contains the ENTIRE html code and the method does not add a wrapper. Experimentation reveals that the later works like the former in that a wrapper is added. My question is this: Is there some way to return a snippet of html code (i.e., no wrapper) from an app-script? The reason that I ask is that I would like to be able to use AJAX to insert a snippet of code from an app-script into some point in the DOM structure. Thanks for any input.
... doug
P.S. I realize it's probably going to be a separate issue; but, it would be nice if the snippet could include a scriptlet.
In general, I can think of 5 basic strategies:
Static HTML from within an Apps Script project
Static HTML from a file outside of Apps Script
Dynamic HTML created from server side code
Dynamic HTML created with JavaScript in the browser, with data retrieved from somewhere.
Retrieve HTML from some other website's page.
You want to use a scriptlet, which is dynamic HTML, triggered from the front end. If it's dynamic HTML, the HTML can be dynamically changed from Javascript in the browser, or you could formulate HTML from the server, and then return a string of HTML. I guess there are multiple strategies for how this could be done.
You can call a Google Apps Script from another website, and use Apps Script as server side code without directly returning any output to the screen. You would use Content Service to do that.