When you host something on Drive, it takes the url https://googledrive.com/host/fileid , so it actually still continues to work from the trash bin. Yesterday I thought it was time to clean out my trash so I permanently deleted everything, including the hosted gadget – so every page on this site started showing an error where the missing gadget used to be.
Luckily I had the source for the gadget on GitHub, so I could easily recreate it, but the problem with using Drive as a host is that the fileid is a oneoff thing – meaning that I cannot just create another file with the same id.
So I was faced with either manually editing each of 700+ pages on this site and reinserting a new gadget, or patching up the existing gadget with the new fileid.
Here’s a snippet to do it.
DANGER and IMPORTANT – make sure you do lots of checking on what will be changed before actually doing the setHtmlContent() . This could mess up your site if you replace the wrong thing with the wrong thing. NOTE also that some deprecated gadgets will stop working when rewritten. For example , those old Adsense gadgets that Google deprecated on Sites. If your page gets rewritten and you still have some of them on your site – they will disappear forever. If you have gadgets on your site, test thoroughly that they will not be screwed up by rewriting the html before running.
All I had to do was set the old fileId
1 |
var searchRx = /0B92ExLh4POiZT081dWl6WjdwbFk/g; |
And the new one
1 |
var replaceWith = "0B92ExLh4POiZb19Qc3hidFgzS2M"; |
Always worth giving it a trial run first by setting this to false
1 |
var actuallyDoIt = true; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
function patch() { // set this to true to actually do the update as opposed to just reporing it var actuallyDoIt = false; // this is the site i'm working with var site = SitesApp.getSite("mcpher.com", "share"); // get all the pages on the site var pages = getPages(site); // get all the pages that contain the search term in their html var searchRx = /0B92ExLh4POiZT081dWl6WjdwbFk/g; var workingPages = pages.reduce (function (p,c) { var html = c.getHtmlContent(); // if its a target page then select it and avoid getting the html again later if (html.search (searchRx , html) >=0) { p.push ({html:html, page:c}); } return p; },[]); //now we'll update these pages with the replacement value var replaceWith = "0B92ExLh4POiZb19Qc3hidFgzS2M"; workingPages.forEach (function (d,i) { Logger.log (""+i+" "+(actuallyDoIt ? "updating " : "would have updated ") + d.page.getUrl()); // REMEMBER TO DO LOTS OF LOGGING AND CHECKING HERE BEFORE SETTING ACTUALLYDOIT TO TRUE if (actuallyDoIt) { d.page.setHtmlContent ( d.html.replace (searchRx, replaceWith) ); } }); } /** * get all the pages on my site - into a heirach object * @param {Site} site the site * @param {number} optMax max number of pages to go for * @param {string} optQuery a search query (unfortunately this doesnt search html) * @param {number} optStart you can start later - useful for restarting if you run out of execution time * @return {Array.Page} all the pages on the site **/ function getPages(site,optMax,optQuery,optStart) { var chunk,pages = [], options = {}; do { options.start= pages.length + (optStart || 0); if (optMax) options.max = optMax - pages.length ; if (optQuery) options.search = optQuery; chunk = cUseful.rateLimitExpBackoff( function (){ return site.getAllDescendants(options); }); cUseful.arrayAppend(pages, chunk); } while (chunk.length && (!optMax || pages.length < optMax)); return pages; } |
For this snippet you’ll need my cUseful library. You can find the details below or get it from github.