Difference between revisions of "Google Slides - Creating an Add On"

From NoskeWiki
Jump to navigation Jump to search
(Google Slides Add On - Acknowledgement Slide Generator)
Line 53: Line 53:
 
             })
 
             })
 
             .withUserObject(this)
 
             .withUserObject(this)
             .addAcknowledgmentSlide("en");
+
             .addAcknowledgmentSlide("100x100");
 
         this.disabled = false;
 
         this.disabled = false;
 
       }
 
       }
Line 60: Line 60:
 
   </head>
 
   </head>
 
   <body>
 
   <body>
 +
 
     <form class="sidebar branding-below">
 
     <form class="sidebar branding-below">
 
       <h4>Size of profile cards:</h4>
 
       <h4>Size of profile cards:</h4>
       ...
+
       TODO(anoske): Add preset sizes here + input for number of slides.
 
       <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 74: Line 75:
 
     </div>
 
     </div>
  
    <!---
 
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
 
    <script>
 
      $(function() {
 
        // Add an input radio button for every language.
 
        var languages = {
 
          ar: 'Arabic',
 
          zh: 'Chinese',
 
          en: 'English',
 
          fr: 'French',
 
          de: 'German',
 
          hi: 'Hindi',
 
          ja: 'Japanese',
 
          pt: 'Portuguese',
 
          es: 'Spanish'
 
        };
 
        var languageList = Object.keys(languages).map(function(id) {
 
          return $('<li>').html([
 
            $('<input>')
 
                .attr('type', 'radio')
 
                .attr('name', 'dest')
 
                .attr('id', 'radio-dest-' + id)
 
                .attr('value', id),
 
            $('<label>')
 
                .attr('for', 'radio-dest-' + id)
 
                .html(languages[id])
 
          ]);
 
        });
 
 
        $('#run-generator').click(runGenerator);
 
        $('#languages').html(languageList);
 
      });
 
 
      /**
 
      * Runs a server-side function to translate the text on all slides.
 
      */
 
      function runGenerator() {
 
        this.disabled = true;
 
        $('#error').text('');
 
        google.script.run
 
            .withUserObject(this)
 
            .addAcknowledgmentSlide($('input[name=dest]:checked').val());
 
      }
 
    </script>
 
    -->
 
 
   </body>
 
   </body>
 
</html>
 
</html>
Line 237: Line 193:
 
  * Translates selected slide elements to the target language using Apps Script's Language service.
 
  * Translates selected slide elements to the target language using Apps Script's Language service.
 
  *
 
  *
  * @param {string} targetLanguage The two-letter short form for the target language. (ISO 639-1)
+
  * @param {string} sizePreset String desired size.
 
  * @return {number} The number of profiles created.
 
  * @return {number} The number of profiles created.
 
  */
 
  */
function addAcknowledgmentSlide(targetLanguage) {
+
function addAcknowledgmentSlide(sizePreset) {
 
   // Add title slide to start:
 
   // Add title slide to start:
 
   var numProfiles = 6;
 
   var numProfiles = 6;
Line 264: Line 220:
 
* Publish:
 
* Publish:
 
** If you were developing a real add-on, the last step would be to [https://developers.google.com/gsuite/add-ons/how-tos/publishing-editor-addons publish] it for other people to find and install.
 
** If you were developing a real add-on, the last step would be to [https://developers.google.com/gsuite/add-ons/how-tos/publishing-editor-addons publish] it for other people to find and install.
 
 
  
 
==Links==
 
==Links==

Revision as of 18:22, 26 July 2019

About

NOTE: This page is a daughter page of: Google Slides, and is related to: JavaScript


This demos a simple "Google Slides Acknowledgement Slide Generator" which inserts a bunch of images into . a new slide via a Google Slides Add On.

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.

File:Google slides acknowledgement genrator.png
What the thing looks like after run

Steps:

  1. Create a new Google Presentation.
  2. From within your new presentation, select the menu item Tools > Script editor. If you are presented with a welcome screen, click Blank Project.
  3. 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").
  4. Create a new file by selecting the menu item File > New > HTML file. Name this file sidebar.html.
  5. 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.
       */
      function runGenerator() {
        this.disabled = true;
        google.script.run
              .withSuccessHandler(function(numAddedProfiles, element) {
              element.disabled = false;
              if (numAddedProfiles > 0) {
                document.getElementById("txt-feedback").append('Slide created!');
              }
              return false;
             })
            .withFailureHandler(function(msg, element) {
              element.disabled = false;
              document.getElementById("txt-feedback").append('Something went wrong');
              return false;
            })
            .withUserObject(this)
            .addAcknowledgmentSlide("100x100");
        this.disabled = false;
      }
    </script>
 
  </head>
  <body>

    <form class="sidebar branding-below">
      <h4>Size of profile cards:</h4>
      TODO(anoske): Add preset sizes here + input for number of slides.
      <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.
 */

/**
 * Create a open translate 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 Generator');
  SlidesApp.getUi().showSidebar(ui);
}

/**
 * Insert a new slide at the start of the current presentatino.
 */
function insertTitleSlideAtStart() {
  var presentation = SlidesApp.getActivePresentation();
  presentation.insertSlide(0, SlidesApp.PredefinedLayout.TITLE_ONLY);
}

/**
 * Adds profile images and text, evenly spaced into the chosen slide.
 *
 * @param {int} numProfiles Number of profiles to insert.
 */
function insetAckSlideAtStart(numProfiles){
  // 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 = Math.ceil(SLIDE_HEIGHT / 5);
  
  // Profile dimensions:
  var PROFILE_WIDTH = 100;
  var PROFILE_HEIGHT = 150;
  var PROFILE_NAME_HEIGHT = 30;
  var PROFILE_COMMENT_HEIGHT = 20;
  var PROFILE_PIC_HEIGHT = PROFILE_HEIGHT - PROFILE_NAME_HEIGHT;

  var PROFILE_NAME_Y_OFFSET = PROFILE_PIC_HEIGHT;
  var PROFILE_COMMENT_Y_OFFSET = PROFILE_NAME_Y_OFFSET + PROFILE_NAME_HEIGHT;
  
  // Determine number of rows/columns and spacing between boxes:
  var kMaxColsPerRow = 6;
  var numCols = (numProfiles > kMaxColsPerRow) ? kMaxColsPerRow : numProfiles;
  var numRows = Math.ceil(numProfiles / kMaxColsPerRow);

  var xSpacing = (SLIDE_WIDTH - (numCols * PROFILE_WIDTH)) / (numCols + 1);
  var ySpacing = ((SLIDE_HEIGHT - SLIDE_TOP_BANNER) - (numRows * PROFILE_HEIGHT)) / (numRows + 1);
  
  console.log('SLIDE_WIDTH=' + SLIDE_WIDTH + ' * SLIDE_HEIGHT=' + SLIDE_HEIGHT);  // DO NOT SUBMIT.
  console.log('numCols=' + numCols + ' * numRows=' + numRows);  // DO NOT SUBMIT.
  console.log('xSpacing=' + xSpacing + ' * ySpacing=' + ySpacing);  // DO NOT SUBMIT.
  
  // For each image:
  for(var i = 0; i < numProfiles; i++) {
    var rowIdx = Math.floor(i / kMaxColsPerRow);
    var colIdx = i - (rowIdx * kMaxColsPerRow);
    
    var x = (colIdx * PROFILE_WIDTH) + ((colIdx + 1) * xSpacing);
    var y = (rowIdx * PROFILE_HEIGHT) + ((rowIdx + 1) * ySpacing) + SLIDE_TOP_BANNER;
    
    console.log(' ' +  i + ':  x,y=' + x + ',' + y);  // DO NOT SUBMIT.
    
    var img = slide.insertImage("https://andrewnoske.com/w/images/1/16/Unknown_profile_300x300.png",
                                x, y, PROFILE_WIDTH, PROFILE_PIC_HEIGHT);
    
    var nameBox = slide.insertTextBox("Andrew",
                                       x, y + PROFILE_NAME_Y_OFFSET, PROFILE_WIDTH, PROFILE_NAME_HEIGHT);
    nameBox.getText().getTextStyle().setBold(true);
    var commentBox = slide.insertTextBox("anoske@",
                                          x, y + PROFILE_COMMENT_Y_OFFSET, PROFILE_WIDTH, PROFILE_COMMENT_HEIGHT);
    commentBox.getText().getTextStyle()
        .setLinkUrl('www.example.com')
        .setFontSize(10)
        .setForegroundColor('#0000dd');
  }
}

/**
 * Translates selected slide elements to the target language using Apps Script's Language service.
 *
 * @param {string} sizePreset String desired size.
 * @return {number} The number of profiles created.
 */
function addAcknowledgmentSlide(sizePreset) {
  // Add title slide to start:
  var numProfiles = 6;
  insetAckSlideAtStart(numProfiles);
  
  return numProfiles;
}


  • 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.