מדריך למתחילים: תוסף Google Slides Editor

המדריך למתחילים הזה יוצר תוסף לעריכת Google Slides לתרגום הטקסט שנבחר במצגת.

מטרות

  • מגדירים את הסקריפט.
  • מריצים את הסקריפט.

דרישות מוקדמות

כדי להשתמש בדוגמה הזו, צריך לעמוד בדרישות המוקדמות הבאות:

  • חשבון Google (חשבונות Google Workspace יכולים נדרש אישור של האדמין).
  • דפדפן אינטרנט עם גישה לאינטרנט.

הגדרת הסקריפט

  1. יוצרים מצגת ב-Slides בכתובת slides.new.
  2. לוחצים על תוספים > Apps Script.
  3. לוחצים על פרויקט ללא שם.
  4. משנים את שם פרויקט Apps Script ל-Translate Slides ולוחצים על שינוי שם.
  5. לצד הקובץ Code.gs, לוחצים על סמל האפשרויות הנוספות > שינוי שם. נותנים לקובץ שם: translate.
  6. לוחצים על 'הוספת קובץ' > HTML. נותנים לקובץ שם: sidebar.
  7. צריך להחליף את התוכן של כל קובץ בקוד המתאים הבא, ואז לוחצים על 'שמירה' סמל השמירה.

    translate.gs

    slides/translate/translate.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 Translate', '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() {
      const ui = HtmlService
          .createHtmlOutputFromFile('sidebar')
          .setTitle('Translate');
      SlidesApp.getUi().showSidebar(ui);
    }
    
    /**
     * Recursively gets child text elements a list of elements.
     * @param {PageElement[]} elements The elements to get text from.
     * @return {Text[]} An array of text elements.
     */
    function getElementTexts(elements) {
      let texts = [];
      elements.forEach((element)=> {
        switch (element.getPageElementType()) {
          case SlidesApp.PageElementType.GROUP:
            element.asGroup().getChildren().forEach((child)=> {
              texts = texts.concat(getElementTexts(child));
            });
            break;
          case SlidesApp.PageElementType.TABLE:
            const table = element.asTable();
            for (let y = 0; y < table.getNumColumns(); ++y) {
              for (let x = 0; x < table.getNumRows(); ++x) {
                texts.push(table.getCell(x, y).getText());
              }
            }
            break;
          case SlidesApp.PageElementType.SHAPE:
            texts.push(element.asShape().getText());
            break;
        }
      });
      return texts;
    }
    
    /**
     * 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)
     * @return {number} The number of elements translated.
     */
    function translateSelectedElements(targetLanguage) {
      // Get selected elements.
      const selection = SlidesApp.getActivePresentation().getSelection();
      const selectionType = selection.getSelectionType();
      let texts = [];
      switch (selectionType) {
        case SlidesApp.SelectionType.PAGE:
          selection.getPageRange().getPages().forEach((page)=> {
            texts = texts.concat(getElementTexts(page.getPageElements()));
          });
          break;
        case SlidesApp.SelectionType.PAGE_ELEMENT:
          const pageElements = selection.getPageElementRange().getPageElements();
          texts = texts.concat(getElementTexts(pageElements));
          break;
        case SlidesApp.SelectionType.TABLE_CELL:
          selection.getTableCellRange().getTableCells().forEach((cell)=> {
            texts.push(cell.getText());
          });
          break;
        case SlidesApp.SelectionType.TEXT:
          selection.getPageElementRange().getPageElements().forEach((element) =>{
            texts.push(element.asShape().getText());
          });
          break;
      }
    
      // Translate all elements in-place.
      texts.forEach((text)=> {
        text.setText(LanguageApp.translate(text.asRenderedString(), '', targetLanguage));
      });
    
      return texts.length;
    }

    sidebar.html

    slides/translate/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>
    </head>
    <body>
    <form class="sidebar branding-below">
      <h4>Translate selected slides into:</h4>
      <ul id="languages"></ul>
      <div class="block" id="button-bar">
        <button class="blue" id="run-translation">Translate</button>
      </div>
      <h5 class="error" id="error"></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">Translate sample by Google</span>
    </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.
        const languages = {
          ar: 'Arabic',
          zh: 'Chinese',
          en: 'English',
          fr: 'French',
          de: 'German',
          hi: 'Hindi',
          ja: 'Japanese',
          pt: 'Portuguese',
          es: 'Spanish'
        };
        const languageList = Object.keys(languages).map((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-translation').click(runTranslation);
        $('#languages').html(languageList);
      });
    
      /**
       * Runs a server-side function to translate the text on all slides.
       */
      function runTranslation() {
        this.disabled = true;
        $('#error').text('');
        google.script.run
                .withSuccessHandler((numTranslatedElements, element) =>{
                  element.disabled = false;
                  if (numTranslatedElements === 0) {
                    $('#error').empty()
                            .append('Did you select elements to translate?')
                            .append('<br/>')
                            .append('Please select slides or individual elements.');
                  }
                  return false;
                })
                .withFailureHandler((msg, element)=> {
                  element.disabled = false;
                  $('#error').text('Something went wrong. Please check the add-on logs.');
                  return false;
                })
                .withUserObject(this)
                .translateSelectedElements($('input[name=dest]:checked').val());
      }
    </script>
    </body>
    </html>

מריצים את הסקריפט

  1. טוענים מחדש את הדף במצגת ב-Slides.
  2. לוחצים על תוספים &gt;. תרגום שקפים &gt; התחלה. התהליך עשוי להימשך כמה שניות כדי שהאפשרות בתפריט של התוסף תופיע.
  3. כשמוצגת הנחיה, מאשרים את התוסף.
  4. שוב, לוחצים על תוספים &gt;. תרגום שקפים &gt; התחלה.
  5. מוסיפים טקסט למצגת ובוחרים אותה.
  6. בתוסף, לוחצים על תרגום כדי להחליף את הטקסט שנבחר.

השלבים הבאים