Difference between revisions of "Google Slides - Creating an Add On"
Jump to navigation
Jump to search
(3 intermediate revisions by the same user not shown) | |||
Line 9: | Line 9: | ||
This is similar to instructions from the [https://developers.google.com/gsuite/add-ons/editors/slides/quickstart/translate Google Slides Quickstart (Translate)]... and then the rest I figured out from the [https://developers.google.com/slides/ Slides API]. | This is similar to instructions from the [https://developers.google.com/gsuite/add-ons/editors/slides/quickstart/translate Google Slides Quickstart (Translate)]... and then the rest I figured out from the [https://developers.google.com/slides/ Slides API]. | ||
− | {{ | + | {{Warning|message=The code works, but I never managed to actually get this published, because the documentation for that was nasty. I work at Google and I couldn't figure it out. Similar to this is my page: [[JavaScript - Generating Image Boxes from a Text Area]].}} |
− | + | ||
− | + | [[image:Google_slides_addon_acknowledges_slide_generator_1200x559.png|thumb|center|1200px|What the thing looks like after run]] | |
− | |||
Steps: | Steps: | ||
Line 40: | Line 39: | ||
<script> | <script> | ||
/** | /** | ||
− | * Runs generator. | + | * Runs generator (in ackgenerator.gs). |
*/ | */ | ||
function runGenerator() { | function runGenerator() { | ||
− | this.disabled = true; | + | this.disabled = true; // Disable buttons, etc, until done. |
+ | |||
+ | var numPeople = parseInt(document.getElementById("txt-num-people").value); | ||
+ | var picWidth = parseInt(document.getElementById("txt-pic-width").value); | ||
+ | var picHeight = parseInt(document.getElementById("txt-pic-height").value); | ||
+ | var maxCols = parseInt(document.getElementById("txt-max-cols").value); | ||
+ | |||
google.script.run | google.script.run | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
.withUserObject(this) | .withUserObject(this) | ||
− | .addAcknowledgmentSlide( | + | .addAcknowledgmentSlide(numPeople, picWidth, picHeight, maxCols); |
− | this.disabled = false; | + | |
+ | this.disabled = false; // Re-enable buttons. | ||
} | } | ||
</script> | </script> | ||
Line 67: | Line 61: | ||
<form class="sidebar branding-below"> | <form class="sidebar branding-below"> | ||
− | < | + | Number people: <input type="number" name="txt-num-people" id="txt-num-people" |
− | + | min="1" max="30" value="4"> | |
+ | <br> | ||
+ | Picture size: <input type="number" name="txt-pic-width" id="txt-pic-width" | ||
+ | min="10" max="300" value="100" step="5" style="width:60px"> x | ||
+ | <input type="number" name="txt-pic-height" id="txt-pic-height" | ||
+ | min="10" max="300" value="100" step="5" style="width:60px"> | ||
+ | <br> | ||
+ | Max columns: <input type="number" name="txt-max-cols" id="txt-max-cols"\ | ||
+ | min="1" max="30" value="6"><br> | ||
+ | |||
<div class="block" id="button-bar"> | <div class="block" id="button-bar"> | ||
<button class="blue" id="run-generator" onclick="runGenerator()">Generate</button> | <button class="blue" id="run-generator" onclick="runGenerator()">Generate</button> | ||
Line 89: | Line 92: | ||
<u>ackgenerator.gs</u> | <u>ackgenerator.gs</u> | ||
<syntaxhighlight lang="JavaScript"> | <syntaxhighlight lang="JavaScript"> | ||
+ | |||
/** | /** | ||
* @OnlyCurrentDoc Limits the script to only accessing the current presentation. | * @OnlyCurrentDoc Limits the script to only accessing the current presentation. | ||
+ | * | ||
+ | * CREDIT: Andrew Noske. 2019. | ||
+ | * SOURCE: https://andrewnoske.com/wiki/Google_Slides_-_Creating_an_Add_On . | ||
*/ | */ | ||
/** | /** | ||
− | * Create | + | * Create an Open "Acknowledgement Generator" menu item. |
* @param {Event} event The open event. | * @param {Event} event The open event. | ||
*/ | */ | ||
Line 118: | Line 125: | ||
var ui = HtmlService | var ui = HtmlService | ||
.createHtmlOutputFromFile('sidebar') | .createHtmlOutputFromFile('sidebar') | ||
− | .setTitle('Acknowledgement Generator'); | + | .setTitle('Acknowledgement Slide Generator'); |
SlidesApp.getUi().showSidebar(ui); | SlidesApp.getUi().showSidebar(ui); | ||
} | } | ||
/** | /** | ||
− | * Insert a new slide at the start of the current | + | * Insert a new blank slide at the start of the current presentation |
+ | * with a title that says "Acknowledgements". | ||
*/ | */ | ||
function insertTitleSlideAtStart() { | function insertTitleSlideAtStart() { | ||
var presentation = SlidesApp.getActivePresentation(); | var presentation = SlidesApp.getActivePresentation(); | ||
− | presentation.insertSlide(0, SlidesApp.PredefinedLayout. | + | var slide = presentation.insertSlide(0, SlidesApp.PredefinedLayout.BLANK); |
+ | |||
+ | var SLIDE_WIDTH = SlidesApp.getActivePresentation().getPageWidth(); | ||
+ | var titleText = slide.insertTextBox("Acknowledgements", 10, 10, SLIDE_WIDTH - 20, 50); | ||
+ | titleText.getText().getTextStyle() | ||
+ | .setFontSize(30) | ||
+ | .setBold(true); | ||
} | } | ||
/** | /** | ||
− | * | + | * Inserts a new "Acknowledgement Slide at the start of the presentation. |
+ | * This slide has the given number of profile images and text, | ||
+ | * evently spaced in a grid. | ||
* | * | ||
− | * @param { | + | * @param {number} numPeople The number of profiles to create. |
+ | * @param {number} picWidth The width of each picture in pixels. | ||
+ | * @param {number} picHeight The height of each picture in pixels. | ||
+ | * @param {number} maxColumns The maximum number of columns to show. If numPeople | ||
+ | * is more than this it will start adding rows. | ||
+ | * @return {number} The number of profiles created. | ||
*/ | */ | ||
− | function | + | function addAcknowledgmentSlide(numPeople, picWidth, picHeight, maxColumns) { |
// Insert new slide to start of presentation. | // Insert new slide to start of presentation. | ||
insertTitleSlideAtStart(); | insertTitleSlideAtStart(); | ||
Line 146: | Line 167: | ||
var SLIDE_WIDTH = slideDeck.getPageWidth(); | var SLIDE_WIDTH = slideDeck.getPageWidth(); | ||
var SLIDE_HEIGHT = slideDeck.getPageHeight(); | var SLIDE_HEIGHT = slideDeck.getPageHeight(); | ||
− | var SLIDE_TOP_BANNER = | + | var SLIDE_TOP_BANNER = 60; // Bedause we already added a title that says "Acknowledgements". |
// Profile dimensions: | // Profile dimensions: | ||
− | var | + | var profileNameHeight = 30; |
− | var | + | var profileCommentHeight = 20; |
− | var | + | var profileHeight = picHeight + profileNameHeight + profileCommentHeight; |
− | var | + | |
− | var | + | var profileNameYOffset = picHeight; |
+ | var profileCommentYOffset = profileNameYOffset + profileNameHeight; | ||
− | |||
− | |||
− | |||
// Determine number of rows/columns and spacing between boxes: | // Determine number of rows/columns and spacing between boxes: | ||
− | var | + | var cols = (numPeople > maxColumns) ? maxColumns : numPeople; |
− | + | var rows = Math.ceil(numPeople / maxColumns); | |
− | var | + | var xSpacing = (SLIDE_WIDTH - (cols * picWidth)) / (cols + 1); |
− | + | var ySpacing = ((SLIDE_HEIGHT - SLIDE_TOP_BANNER) - (rows * profileHeight)) / (rows + 1); | |
− | var xSpacing = (SLIDE_WIDTH - ( | ||
− | var ySpacing = ((SLIDE_HEIGHT - SLIDE_TOP_BANNER) - ( | ||
console.log('SLIDE_WIDTH=' + SLIDE_WIDTH + ' * SLIDE_HEIGHT=' + SLIDE_HEIGHT); // DO NOT SUBMIT. | console.log('SLIDE_WIDTH=' + SLIDE_WIDTH + ' * SLIDE_HEIGHT=' + SLIDE_HEIGHT); // DO NOT SUBMIT. | ||
− | console.log(' | + | console.log('cols=' + cols + ' * rows=' + rows); // DO NOT SUBMIT. |
console.log('xSpacing=' + xSpacing + ' * ySpacing=' + ySpacing); // DO NOT SUBMIT. | console.log('xSpacing=' + xSpacing + ' * ySpacing=' + ySpacing); // DO NOT SUBMIT. | ||
− | // For each | + | // For each person: |
− | for(var i = 0; i < | + | for(var i = 0; i < numPeople; i++) { |
− | var rowIdx = Math.floor(i / | + | var rowIdx = Math.floor(i / maxColumns); |
− | var colIdx = i - (rowIdx * | + | var colIdx = i - (rowIdx * maxColumns); |
− | var x = (colIdx * | + | var x = (colIdx * picWidth) + ((colIdx + 1) * xSpacing); |
− | var y = (rowIdx * | + | var y = (rowIdx * profileHeight) + ((rowIdx + 1) * ySpacing) + SLIDE_TOP_BANNER; |
console.log(' ' + i + ': x,y=' + x + ',' + y); // DO NOT SUBMIT. | console.log(' ' + i + ': x,y=' + x + ',' + y); // DO NOT SUBMIT. | ||
− | + | ||
+ | // Add placeholder image: | ||
var img = slide.insertImage( | var img = slide.insertImage( | ||
"https://andrewnoske.com/w/images/1/16/Unknown_profile_300x300.png", | "https://andrewnoske.com/w/images/1/16/Unknown_profile_300x300.png", | ||
− | x, y, | + | x, y, picWidth, picHeight); |
− | + | ||
+ | // Add text box for name: | ||
var nameBox = slide.insertTextBox( | var nameBox = slide.insertTextBox( | ||
"First Last", | "First Last", | ||
− | x, y + | + | x, y + profileNameYOffset, picWidth, profileNameHeight); |
nameBox.getText().getTextStyle().setBold(true); | nameBox.getText().getTextStyle().setBold(true); | ||
+ | |||
+ | // Add text box for comment or email. | ||
var commentBox = slide.insertTextBox( | var commentBox = slide.insertTextBox( | ||
"andrew.noske@", | "andrew.noske@", | ||
− | x, y + | + | x, y + profileCommentYOffset, picWidth, profileCommentHeight); |
commentBox.getText().getTextStyle() | commentBox.getText().getTextStyle() | ||
− | .setLinkUrl('www. | + | .setLinkUrl('http://www.andrewnoske.com') |
.setFontSize(10) | .setFontSize(10) | ||
.setForegroundColor('#0000dd'); | .setForegroundColor('#0000dd'); | ||
} | } | ||
+ | |||
+ | return numPeople; | ||
} | } | ||
/** | /** | ||
− | * | + | * Test function you can run in http://script.google.com without opening the menu. |
− | |||
− | |||
− | |||
*/ | */ | ||
− | function | + | function testAddAcknowledgmentSlide() { |
− | + | var numPeople = 4; | |
− | var | + | var picWidth = 100; |
− | + | var picHeight = 100; | |
− | + | var maxColumns = 6; | |
− | + | addAcknowledgmentSlide(numPeople, picWidth, picHeight, maxColumns); | |
} | } | ||
− | |||
Latest revision as of 20:18, 26 July 2019
Contents
About
NOTE: This page is a daughter page of: Google Slides, and is related to: JavaScript
This demos a Google Slides Add On I call "Acknowledgement Slide Generator" which inserts new slide then a grid of images and text boxes.
Background and Instructions
This is similar to instructions from the Google Slides Quickstart (Translate)... and then the rest I figured out from the Slides API.
Warning: The code works, but I never managed to actually get this published, because the documentation for that was nasty. I work at Google and I couldn't figure it out. Similar to this is my page: JavaScript - Generating Image Boxes from a Text Area. |
Steps:
- Create a new Google Presentation.
- From within your new presentation, select the menu item Tools > Script editor. If you are presented with a welcome screen, click Blank Project.
- Delete any code in the script editor and rename Code.gs to ackgenerator.gs. You may be prompted to give a project name first (call it "Acknowledgement Slide Generator").
- Create a new file by selecting the menu item File > New > HTML file. Name this file sidebar.html.
- Replace any code in these two files with the following content, respectively:
Google Slides Add On - Acknowledgement Slide Generator
sidebar.html
<html>
<head>
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons1.css">
<style>
.logo { vertical-align: middle; }
ul { list-style-type: none; padding: 0; }
h4 { margin: 0; }
</style>
<script>
/**
* Runs generator (in ackgenerator.gs).
*/
function runGenerator() {
this.disabled = true; // Disable buttons, etc, until done.
var numPeople = parseInt(document.getElementById("txt-num-people").value);
var picWidth = parseInt(document.getElementById("txt-pic-width").value);
var picHeight = parseInt(document.getElementById("txt-pic-height").value);
var maxCols = parseInt(document.getElementById("txt-max-cols").value);
google.script.run
.withUserObject(this)
.addAcknowledgmentSlide(numPeople, picWidth, picHeight, maxCols);
this.disabled = false; // Re-enable buttons.
}
</script>
</head>
<body>
<form class="sidebar branding-below">
Number people: <input type="number" name="txt-num-people" id="txt-num-people"
min="1" max="30" value="4">
<br>
Picture size: <input type="number" name="txt-pic-width" id="txt-pic-width"
min="10" max="300" value="100" step="5" style="width:60px"> x
<input type="number" name="txt-pic-height" id="txt-pic-height"
min="10" max="300" value="100" step="5" style="width:60px">
<br>
Max columns: <input type="number" name="txt-max-cols" id="txt-max-cols"\
min="1" max="30" value="6"><br>
<div class="block" id="button-bar">
<button class="blue" id="run-generator" onclick="runGenerator()">Generate</button>
</div>
<h5 class="error" id="txt-feedback"></h5>
</form>
<div class="sidebar bottom">
<img alt="Add-on logo" class="logo"
src="https://www.gstatic.com/images/branding/product/1x/translate_48dp.png" width="27" height="27">
<span class="gray branding-text">Ack Generator</span>
</div>
</body>
</html>
ackgenerator.gs
/**
* @OnlyCurrentDoc Limits the script to only accessing the current presentation.
*
* CREDIT: Andrew Noske. 2019.
* SOURCE: https://andrewnoske.com/wiki/Google_Slides_-_Creating_an_Add_On .
*/
/**
* Create an Open "Acknowledgement Generator" menu item.
* @param {Event} event The open event.
*/
function onOpen(event) {
SlidesApp.getUi().createAddonMenu()
.addItem('Open', 'showSidebar')
.addToUi();
}
/**
* Open the Add-on upon install.
* @param {Event} event The install event.
*/
function onInstall(event) {
onOpen(event);
}
/**
* Opens a sidebar in the document containing the add-on's user interface.
*/
function showSidebar() {
var ui = HtmlService
.createHtmlOutputFromFile('sidebar')
.setTitle('Acknowledgement Slide Generator');
SlidesApp.getUi().showSidebar(ui);
}
/**
* Insert a new blank slide at the start of the current presentation
* with a title that says "Acknowledgements".
*/
function insertTitleSlideAtStart() {
var presentation = SlidesApp.getActivePresentation();
var slide = presentation.insertSlide(0, SlidesApp.PredefinedLayout.BLANK);
var SLIDE_WIDTH = SlidesApp.getActivePresentation().getPageWidth();
var titleText = slide.insertTextBox("Acknowledgements", 10, 10, SLIDE_WIDTH - 20, 50);
titleText.getText().getTextStyle()
.setFontSize(30)
.setBold(true);
}
/**
* Inserts a new "Acknowledgement Slide at the start of the presentation.
* This slide has the given number of profile images and text,
* evently spaced in a grid.
*
* @param {number} numPeople The number of profiles to create.
* @param {number} picWidth The width of each picture in pixels.
* @param {number} picHeight The height of each picture in pixels.
* @param {number} maxColumns The maximum number of columns to show. If numPeople
* is more than this it will start adding rows.
* @return {number} The number of profiles created.
*/
function addAcknowledgmentSlide(numPeople, picWidth, picHeight, maxColumns) {
// Insert new slide to start of presentation.
insertTitleSlideAtStart();
// Get first slide:
var slideDeck = SlidesApp.getActivePresentation();
var slide = slideDeck.getSlides()[0];
// Slide dimensions:
var SLIDE_WIDTH = slideDeck.getPageWidth();
var SLIDE_HEIGHT = slideDeck.getPageHeight();
var SLIDE_TOP_BANNER = 60; // Bedause we already added a title that says "Acknowledgements".
// Profile dimensions:
var profileNameHeight = 30;
var profileCommentHeight = 20;
var profileHeight = picHeight + profileNameHeight + profileCommentHeight;
var profileNameYOffset = picHeight;
var profileCommentYOffset = profileNameYOffset + profileNameHeight;
// Determine number of rows/columns and spacing between boxes:
var cols = (numPeople > maxColumns) ? maxColumns : numPeople;
var rows = Math.ceil(numPeople / maxColumns);
var xSpacing = (SLIDE_WIDTH - (cols * picWidth)) / (cols + 1);
var ySpacing = ((SLIDE_HEIGHT - SLIDE_TOP_BANNER) - (rows * profileHeight)) / (rows + 1);
console.log('SLIDE_WIDTH=' + SLIDE_WIDTH + ' * SLIDE_HEIGHT=' + SLIDE_HEIGHT); // DO NOT SUBMIT.
console.log('cols=' + cols + ' * rows=' + rows); // DO NOT SUBMIT.
console.log('xSpacing=' + xSpacing + ' * ySpacing=' + ySpacing); // DO NOT SUBMIT.
// For each person:
for(var i = 0; i < numPeople; i++) {
var rowIdx = Math.floor(i / maxColumns);
var colIdx = i - (rowIdx * maxColumns);
var x = (colIdx * picWidth) + ((colIdx + 1) * xSpacing);
var y = (rowIdx * profileHeight) + ((rowIdx + 1) * ySpacing) + SLIDE_TOP_BANNER;
console.log(' ' + i + ': x,y=' + x + ',' + y); // DO NOT SUBMIT.
// Add placeholder image:
var img = slide.insertImage(
"https://andrewnoske.com/w/images/1/16/Unknown_profile_300x300.png",
x, y, picWidth, picHeight);
// Add text box for name:
var nameBox = slide.insertTextBox(
"First Last",
x, y + profileNameYOffset, picWidth, profileNameHeight);
nameBox.getText().getTextStyle().setBold(true);
// Add text box for comment or email.
var commentBox = slide.insertTextBox(
"andrew.noske@",
x, y + profileCommentYOffset, picWidth, profileCommentHeight);
commentBox.getText().getTextStyle()
.setLinkUrl('http://www.andrewnoske.com')
.setFontSize(10)
.setForegroundColor('#0000dd');
}
return numPeople;
}
/**
* Test function you can run in http://script.google.com without opening the menu.
*/
function testAddAcknowledgmentSlide() {
var numPeople = 4;
var picWidth = 100;
var picHeight = 100;
var maxColumns = 6;
addAcknowledgmentSlide(numPeople, picWidth, picHeight, maxColumns);
}
- Save the project:
- Select the menu item File > Save all. Name your new script "Acknowledgement Slide Generator" and click OK. The script's name is shown to end users in several places, including the authorization dialog.
- Select the menu item File > Managed versions save as a first version.
- Try it out:
- Switch back to your presentation and reload the page.
After a few seconds, a "Acknowledgement Generator" sub-menu appears under the Add-ons menu. Click Add-ons > Acknowledgement Generator > Start.
- A dialog box indicates that the script requires authorization. Click Continue. A second dialog box requests authorization for specific Google services. Click Allow.
- A sidebar appears. To test it, type some text into your presentation, then select it, and click the blue Generate button. To replace the text in the presentation, click Insert.
- Publish:
- If you were developing a real add-on, the last step would be to publish it for other people to find and install.
Links
- Google Slides - official site, where you can create your own slides.