Эффективно добавляйте гиперссылку к только что замененному тексту в Google Slides

Я вставляю список дескрипторов Instagram из Google Sheets в Google Slides с помощью скрипта Google Apps.

  • Таблицы Google содержат список дескрипторов Instagram, таких как @Apple, @Google и т. д. Для удобства в приведенном ниже примере предположим, что дескриптор «@Apple» уже был получен из листа в виде строки и помещен в переменная с именем handle.
  • Слайд Google содержит один заполнитель в текстовом поле {{handle}}.

Моя цель — вставить «@Apple» в заполнитель {{handle}} и добавить к нему гиперссылку (https://www.instagram.com/apple/). То есть я хочу добавить гиперссылку к тексту, который я только что вставил/заменил.

Я могу добиться этого с помощью приведенного ниже кода, но это крайне неэффективно. В моем реальном приложении нужно вставить много записей и еще много фигур на слайдах, поэтому мне бы хотелось иметь возможность делать это эффективно. Я готов попробовать и другие методы. Любое руководство приветствуется.

Мой код:

var handle = "@Apple";

// extract username to get url
let regExp = new RegExp("[^@]*$");
var username = regExp.exec(handle)[0];
var url = "https://www.instagram.com/" + username;

// insert the handle at {{handle}} and make it a hyperlink
var allShapes = (currentSlide.getShapes());
allShapes.forEach(function(shape) {
    var text = shape.getText();
    var n = text.replaceAllText("{{handle}}", handle);
    if (n > 0) {
        var textRange = text.getTextStyle();
        text.find(handle).forEach((v) => {
            v.getTextStyle().setLinkUrl(url);
        });
    }
});

Можете ли вы поделиться минимальным, воспроизводимым примером, который сообщество сможет использовать, чтобы увидеть, что вы хотите сделать? Как макет листа, чтобы мы могли визуализировать и воспроизвести то, что у вас есть. Вы также можете включить в него желаемый результат.

Saddles 06.03.2024 09:44

@Saddles Спасибо за ваш комментарий! Я прочитал страницу, на которую вы ссылаетесь, и отредактировал свой вопрос. Теперь стало яснее? P.S. Меня немного смущает то, что вы подразумеваете под «пустышным листом». Должен ли я создать новый лист Google или мне следует создать таблицу здесь, в моем вопросе?

steak 06.03.2024 11:14
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
171
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Я считаю, что ваша цель состоит в следующем.

  • Вы хотите снизить стоимость процесса вашего сценария.

В вашей ситуации как насчет использования Slides API? При использовании Slides API ваш скрипт можно изменить следующим образом. Я предположил, что при использовании Slides API стоимость процесса можно снизить.

В этой модификации, начиная с The Google Sheets contains a list of instagram handles, such as @Apple, @Google, etc., предполагается использование нескольких текстов замены. Модифицированный сценарий выглядит следующим образом.

Модифицированный скрипт:

Скопируйте и вставьте следующий скрипт в редактор скриптов Google Slide. И включите Slides API в расширенных сервисах Google.

Сначала установите handles для вашей реальной ситуации. В этой модификации вы можете использовать несколько замен текста. В этом образце фигуры с текстом {{handle}} заменяются на @Apple. фигуры с текстом {{handle2}} заменяются на @Google. И гиперссылки установлены.

function myFunction() {
  // Prepare values.
  var handles = [ // Please prepare this object for your actual situation.
    { replaceFrom: "{{handle}}", replaceTo: "@Apple" },
    { replaceFrom: "{{handle2}}", replaceTo: "@Google" },
  ];
  handles.forEach(e => {
    let regExp = new RegExp("[^@]*$");
    var username = regExp.exec(e.replaceTo)[0];
    var url = "https://www.instagram.com/" + username;
    e.url = url;
  });

  // Replace texts and set hyperlinks.
  var s = SlidesApp.getActivePresentation();
  var sId = s.getId();
  var currentSlide = s.getSelection().getCurrentPage();
  var pageId = currentSlide.getObjectId();
  var obj = Slides.Presentations.Pages.get(sId, pageId);
  var requests = handles.map(({ replaceFrom, replaceTo, url }) => {
    var temp = [{ replaceAllText: { containsText: { text: replaceFrom }, replaceText: replaceTo, pageObjectIds: [pageId] } }];
    obj.pageElements.forEach(e => e.shape.text.textElements.forEach(f => {
      var t = f?.textRun?.content;
      if (t && t.trim() == replaceFrom) {
        temp.push({ updateTextStyle: { style: { link: { url } }, objectId: e.objectId, fields: "link" } });
      }
    }));
    return temp;
  });
  if (requests.length == 0) return;
  Slides.Presentations.batchUpdate({ requests }, sId);
}
  • При запуске этого скрипта выбранная страница Google Slide обрабатывается с помощью handles одним вызовом API.

Примечание:

  • Важным моментом является то, что URL-адрес вашего сценария показа создается с использованием вашего сценария. Пожалуйста, будьте осторожны с этим.
  • Из вашего скрипта выполняется поиск только фигур. Пожалуйста, будьте осторожны с этим.

Использованная литература:

  • Метод:presentations.get
  • Метод:presents.batchUpdate

Добавлен:

Из вашего следующего ответа,

но моя ситуация такова: для списка маркеров на моем листе Google (в одном столбце) для каждой строки я 1. создаю новый слайд из шаблона с написанным внутри {{handle}}, 2. замените {{handle}} дескриптор (например, @Apple), 3. вставьте URL. Поэтому вместо обновления нескольких мест на одном слайде я фактически создаю слайд каждый раз, когда читаю новую строку. Можно ли в этой ситуации использовать пакетное обновление?

К сожалению, из вашего ответа я не смог понять номер столбца с in a single column. Итак, в этом примере сценария предполагается, что это столбец «А» со строкой заголовка. И ещё, к сожалению, я не смогла понять create a new slide from a template. Итак, в этом примере сценария предполагается, что слайд первой страницы Google Slide является слайдом шаблона. И первый слайд шаблона копируется. Когда это отражено в образце сценария, это выглядит следующим образом.

Пример сценария:

Скопируйте этот пример сценария и вставьте его в редактор сценариев электронной таблицы Google. И, пожалуйста, установите templateSlideId и sheetName. Предполагается, что Google Slide of templateSlideId имеет шаблон слайда на 1-й странице. Пожалуйста, будьте осторожны с этим.

Этот скрипт использует Slides API. Пожалуйста, будьте осторожны с этим.

function myFunction() {
  // Please set your template Google Slide ID.
  // In this script, the 1st slide is used by copying.
  var templateSlideId = "###";
  var sheetName = "Sheet1"; // Please set your sheet name.

  // Prepare values.
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);
  var values = sheet.getRange("A2:A" + sheet.getLastRow()).getDisplayValues().filter(([a]) => a);
  var handles = values.map(([a]) => ({ replaceFrom: "{{handle}}", replaceTo: a }))
  handles.forEach(e => {
    let regExp = new RegExp("[^@]*$");
    var username = regExp.exec(e.replaceTo)[0];
    var url = "https://www.instagram.com/" + username;
    e.url = url;
  });

  // Duplicate a template slide and replace texts and set hyperlinks.
  var topPageId = SlidesApp.openById(templateSlideId).getSlides()[0].getObjectId();
  var requests1 = [...Array(handles.length)].map((_, i) => ({ duplicateObject: { objectId: topPageId } }));
  Slides.Presentations.batchUpdate({ requests: requests1 }, templateSlideId);
  var [, ...obj] = Slides.Presentations.get(templateSlideId).slides;
  var requests = handles.map(({ replaceFrom, replaceTo, url }, i) => {
    var temp = [{ replaceAllText: { containsText: { text: replaceFrom }, replaceText: replaceTo, pageObjectIds: [obj[i].objectId] } }];
    obj[i].pageElements.forEach(e => e.shape.text.textElements.forEach(f => {
      var t = f?.textRun?.content;
      if (t && t.trim() == replaceFrom) {
        temp.push({ updateTextStyle: { style: { link: { url } }, objectId: e.objectId, fields: "link" } });
      }
    }));
    return temp;
  });
  if (requests.length == 0) return;
  Slides.Presentations.batchUpdate({ requests }, templateSlideId);
}

При запуске этого сценария копируется первая страница (слайд-шаблон) слайда Google. При этом текст {{handle}} заменяется с использованием каждой строки ячеек «A2:A» и установки гиперссылок.

Спасибо за подробный ответ. Прошу прощения за то, что не уточнил это в своем первоначальном вопросе, но моя ситуация такова: для списка дескрипторов на моем листе Google (в одном столбце) для каждой строки я 1. создам новый слайд из шаблон, внутри которого написано {{handle}}, 2. замените {{handle}} дескриптор (например, @Apple), 3. вставьте URL-адрес. Поэтому вместо обновления нескольких мест на одном слайде я фактически создаю слайд каждый раз, когда читаю новую строку. Можно ли в этой ситуации использовать пакетное обновление?

steak 06.03.2024 17:31

@steak Спасибо за ответ. Во-первых, я прошу прощения за то, что не смог понять ваш фактический ожидаемый результат от вашего опубликованного вопроса из-за моего плохого знания английского языка. Судя по вашему ответу, угадав ваш реальный ожидаемый результат, я добавил еще один пример сценария. Пожалуйста, подтвердите это. Если я снова неправильно понял ваш фактический ожидаемый результат, я еще раз извиняюсь.

Tanaike 07.03.2024 02:07

АЛЬТЕРНАТИВНОЕ РЕШЕНИЕ

Вы также можете использовать этот код для достижения того, чего хотите:

const myFunction = () => {
  const handles = ["@Apple", "@Google", "@Microsoft"];
  const slides = SlidesApp.getActivePresentation().getSlides();

  slides.forEach((slide, i) => {
    const handle = handles[i];
    const shapes = slide.getShapes();

    shapes.forEach((shape) => {
      const text = shape.getText();
      const n = text.replaceAllText("{{handle}}", handle);

      if (n > 0) {
        const regExp = new RegExp("[^@]*$");
        const username = regExp.exec(handle)[0];
        const url = "https://www.instagram.com/" + username;
        text.find(handle).forEach((v) => {
          v.getTextStyle().setLinkUrl(url);
        });
      }
    });
  });
}

Вы уже получаете то, что хотите, это было сделано для того, чтобы просмотреть все слайды и заменить все {{handle}} тем, что вы поместите в массив handles.

ВЫХОД

ССЫЛКА

ОБНОВЛЯТЬ

Поскольку вы будете использовать электронную таблицу, вы можете изменить это:

const handles = ["@Apple", "@Google", "@Microsoft"];

К:

const ss = SpreadsheetApp.openById("abc1234567").getSheetByName("Sheet1");
const handles = ss.getRange(2, 1, ss.getLastRow() - 1).getValues();

Примечание. Как и в случае с обновленным ответом @Танаике, я также предполагаю, что ваши дескрипторы в Instagram включены A2:A.

Полный код будет выглядеть так:

const myFunction = () => {
  const ss = SpreadsheetApp.openById("abc1234567").getSheetByName("Sheet1");
  const handles = ss.getRange(2, 1, ss.getLastRow() - 1).getValues();
  const slides = SlidesApp.getActivePresentation().getSlides();

  slides.forEach((slide, i) => {
    const handle = handles[i];
    const shapes = slide.getShapes();

    shapes.forEach((shape) => {
      const text = shape.getText();
      const n = text.replaceAllText("{{handle}}", handle);

      if (n > 0) {
        const regExp = new RegExp("[^@]*$");
        const username = regExp.exec(handle)[0];
        const url = "https://www.instagram.com/" + username;
        text.find(handle).forEach((v) => {
          v.getTextStyle().setLinkUrl(url);
        });
      }
    });
  });
}

ВЫХОД

Не стесняйтесь уточнить, если я неправильно понял вашу цель. Буду рад помочь чем смогу!

Saddles 07.03.2024 06:07

Другие вопросы по теме