HTML 서비스: 템플릿 HTML

Apps Script 코드와 HTML을 함께 사용하면 최소한의 비용으로 동적 페이지를 생성할 수 있습니다. 노력할 것입니다. 다음과 같이 코드와 HTML을 혼합하는 템플릿 언어를 사용한 경우 PHP, ASP 또는 JSP를 사용하는 경우 구문이 익숙하게 느껴질 것입니다.

스크립트

Apps Script 템플릿은 스크립릿(scriptlet)이라고 하는 세 개의 특수 태그를 포함할 수 있습니다. 내부 스크립트를 작성해 두면 일반 Apps Script에서 작동하는 모든 코드를 작성할 수 있습니다. 파일: 스크립릿은 다른 코드 파일에 정의된 함수를 호출할 수 있고, 전역 변수를 사용하거나 Apps Script API를 사용할 수 있습니다. 또한 사전 정의된 머신 유형이나 스크립트릿 내의 함수 및 변수를 사용할 수 없다는 코드 파일 또는 다른 템플릿에 정의된 함수에 의해 호출됩니다.

아래 예를 스크립트 편집기에 붙여넣으면 <?= ... ?> 태그 (인쇄 스크립트릿)가 기울임꼴 기울임꼴 코드는 페이지가 게재되기 전에 서버에서 실행됩니다. 제공됩니다. 스크립릿 코드는 페이지가 게재되기 전에 실행되기 때문에 페이지당 한 번만 실행할 수 있음 클라이언트 측 자바스크립트나 Apps Script와는 달리 여러 가지 함수와 google.script.run, 스크립트 다시 실행할 수 있습니다.

Code.gs

function doGet() {
  return HtmlService
      .createTemplateFromFile('Index')
      .evaluate();
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    Hello, World! The time is <?= new Date() ?>.
  </body>
</html>

템플릿 HTML의 doGet() 함수는 예시와 다릅니다. 기본 HTML 생성 및 게재를 참조하세요. 함수 여기에 표시된 것과 같이 HTML의 HtmlTemplate 객체 파일을 가져온 다음 evaluate() 메서드를 사용하여 스크립틀릿을 실행하고 템플릿을 HtmlOutput 객체를 사용해 사용자에게 게재할 수 있습니다.

표준 스크립릿

<? ... ?> 구문을 사용하는 표준 스크립릿은 명시적으로 페이지에 콘텐츠를 출력합니다. 그러나 이 예에서 알 수 있듯이 결과가 여전히 HTML 콘텐츠에 영향을 줄 수 있음 다음 코드를 스크립트와 함께 사용할 수 있습니다.

Code.gs

function doGet() {
  return HtmlService
      .createTemplateFromFile('Index')
      .evaluate();
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <? if (true) { ?>
      <p>This will always be served!</p>
    <? } else  { ?>
      <p>This will never be served.</p>
    <? } ?>
  </body>
</html>

스크립트 인쇄

<?= ... ?> 구문을 사용하는 스크립릿을 인쇄하면 문맥 이스케이프를 사용하여 코드를 페이지에 삽입할 수 있습니다.

컨텍스트 이스케이프를 사용하면 Apps Script가 출력 컨텍스트를 추적함 페이지에서: HTML 속성 내부, 클라이언트 측 script 태그 내부 또는 이스케이프 문자를 자동으로 추가 교차 사이트 스크립팅 (XSS) 공격으로부터 보호

이 예에서 첫 번째 출력 Scriptlet은 문자열을 직접 출력합니다. 입니다 그 뒤에 배열과 루프를 설정하는 표준scriptlet, 그 뒤에 다른 인쇄 스크립트 렛을 사용하여 배열의 내용을 출력합니다.

Code.gs

function doGet() {
  return HtmlService
      .createTemplateFromFile('Index')
      .evaluate();
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <?= 'My favorite Google products:' ?>
    <? var data = ['Gmail', 'Docs', 'Android'];
      for (var i = 0; i < data.length; i++) { ?>
        <b><?= data[i] ?></b>
    <? } ?>
  </body>
</html>

출력 Scriptlet은 첫 번째 문의 값만 출력합니다. 나머지 문은 표준 스크립트릿 예를 들어, scriptlet <?= 'Hello, world!'; 'abc' ?>만 'Hello, world!'를 출력합니다.

스크립트 강제 인쇄

<?!= ... ?> 구문을 사용하는 스크립트 강제 인쇄는 출력과 비슷합니다. 스크립트릿을 지원하지 않습니다.

문맥 이스케이프는 스크립트가 신뢰할 수 없는 사용자 입력을 허용하는 경우 중요합니다. 기준 대신, Scriptlet의 출력이 의도적으로 출력되는 경우 지정된 대로 정확하게 삽입하려는 HTML 또는 스크립트가 포함되어 있습니다.

일반적으로 스크립트릿을 강제로 출력하는 대신 스크립트릿을 인쇄하는 것이 좋습니다. 를 사용하세요.

Scriptlet의 Apps Script 코드

스크립릿은 일반 JavaScript를 실행하도록 제한되지 않습니다. 또한 다음 세 가지 기법 중 하나를 사용하여 템플릿에 Apps Script에 대한 액세스 권한을 부여합니다. 데이터입니다.

하지만 페이지가 게재되기 전에 템플릿 코드가 실행되므로 이러한 기법은 페이지에 초기 콘텐츠만 제공할 수 있습니다. 액세스 방법 Apps Script 데이터를 대화형으로 만들려면 google.script.run API를 대신 사용하세요.

템플릿에서 Apps Script 함수 호출

스크립릿은 Apps Script 코드 파일 또는 라이브러리에 정의된 모든 함수를 호출할 수 있습니다. 이 예는 스프레드시트의 데이터를 템플릿으로 가져온 다음 데이터에서 HTML 테이블을 생성할 수 있습니다.

Code.gs

function doGet() {
  return HtmlService
      .createTemplateFromFile('Index')
      .evaluate();
}

function getData() {
  return SpreadsheetApp
      .openById('1234567890abcdefghijklmnopqrstuvwxyz')
      .getActiveSheet()
      .getDataRange()
      .getValues();
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <? var data = getData(); ?>
    <table>
      <? for (var i = 0; i < data.length; i++) { ?>
        <tr>
          <? for (var j = 0; j < data[i].length; j++) { ?>
            <td><?= data[i][j] ?></td>
          <? } ?>
        </tr>
      <? } ?>
    </table>
  </body>
</html>

Apps Script API 직접 호출

스크립트릿에서 직접 Apps Script 코드를 사용할 수도 있습니다. 예시 는 이전 예와 동일한 결과를 템플릿 자체에 저장된 데이터를 저장하는 데 사용됩니다

Code.gs

function doGet() {
  return HtmlService
      .createTemplateFromFile('Index')
      .evaluate();
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <? var data = SpreadsheetApp
        .openById('1234567890abcdefghijklmnopqrstuvwxyz')
        .getActiveSheet()
        .getDataRange()
        .getValues(); ?>
    <table>
      <? for (var i = 0; i < data.length; i++) { ?>
        <tr>
          <? for (var j = 0; j < data[i].length; j++) { ?>
            <td><?= data[i][j] ?></td>
          <? } ?>
        </tr>
      <? } ?>
    </table>
  </body>
</html>

템플릿으로 변수 푸시

마지막으로 변수를 속성으로 할당하여 템플릿에 푸시할 수 있습니다. (HtmlTemplate 객체의 정의) 한 번 이 경우에도 이전 예와 동일한 결과를 얻습니다.

Code.gs

function doGet() {
  var t = HtmlService.createTemplateFromFile('Index');
  t.data = SpreadsheetApp
      .openById('1234567890abcdefghijklmnopqrstuvwxyz')
      .getActiveSheet()
      .getDataRange()
      .getValues();
  return t.evaluate();
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <table>
      <? for (var i = 0; i < data.length; i++) { ?>
        <tr>
          <? for (var j = 0; j < data[i].length; j++) { ?>
            <td><?= data[i][j] ?></td>
          <? } ?>
        </tr>
      <? } ?>
    </table>
  </body>
</html>

디버깅 템플릿

작성하는 코드가 실행되지 않으므로 템플릿을 디버깅하기가 어려울 수 있습니다. directly; 대신 서버에서 템플릿을 코드로 변환한 다음 확인할 수 있습니다

템플릿이 스크립트를 해석하는 방식이 분명하지 않은 경우 디버깅 메서드를 HtmlTemplate 수업의 도움을 받을 수 있습니다. 무슨 일이 일어나고 있는지 더 잘 이해할 수 있습니다.

getCode()

getCode()는 서버가 템플릿에서 생성하는 코드가 포함된 문자열입니다. 만약 로그: 붙여넣은 다음 스크립트 편집기에 붙여넣은 후 평소처럼 디버그 Apps Script 코드입니다.

다음은 Google 제품 목록을 다시 표시하는 간단한 템플릿입니다. getCode()의 결과가 표시됩니다.

Code.gs

function myFunction() {
  Logger.log(HtmlService
      .createTemplateFromFile('Index')
      .getCode());
}

index.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <?= 'My favorite Google products:' ?>
    <? var data = ['Gmail', 'Docs', 'Android'];
      for (var i = 0; i < data.length; i++) { ?>
        <b><?= data[i] ?></b>
    <? } ?>
  </body>
</html>

기록 (평가됨)

(function() { var output = HtmlService.initTemplate(); output._ =  '<!DOCTYPE html>\n';
  output._ =  '<html>\n' +
    '  <head>\n' +
    '    <base target=\"_top\">\n' +
    '  </head>\n' +
    '  <body>\n' +
    '    '; output._$ =  'My favorite Google products:' ;
  output._ =  '    ';  var data = ['Gmail', 'Docs', 'Android'];
        for (var i = 0; i < data.length; i++) { ;
  output._ =  '        <b>'; output._$ =  data[i] ; output._ =  '</b>\n';
  output._ =  '    ';  } ;
  output._ =  '  </body>\n';
  output._ =  '</html>';
  /* End of user code */
  return output.$out.append('');
})();

getCodeWithComments()

getCodeWithComments() 드림 getCode()와 비슷하지만 평가된 코드를 원래 템플릿과 나란히 표시됩니다.

평가된 코드 살펴보기

평가된 코드의 샘플에서 가장 먼저 눈에 띄는 것은 HtmlService.initTemplate() 메서드에 의해 생성된 output 객체 이 방법 는 템플릿 자체에서만 사용해야 하므로 문서화되지 않았습니다. output: 두 개의 특수 HtmlOutput 객체 비정상적으로 이름이 지정된 속성인 __$append()appendUntrusted().

output에는 특수 속성 $out가 하나 더 있습니다. 이는 일반적인 HtmlOutput 객체를 반환합니다. 템플릿 는 코드의 끝에 정상 객체를 반환합니다.

이제 이 문법을 이해했으므로 코드의 나머지 부분은 확인할 수 있습니다 스크립틀릿 외부의 HTML 콘텐츠 (예: b 태그)가 추가됨 output._ = 사용 (문맥 이스케이프 없음) 스크립트릿은 JavaScript로 추가됩니다 (컨텍스트 이스케이프 유무와 관계없이, 스크립트릿 유형에 따라 다를 수 있음).

평가된 코드는 템플릿의 줄 번호를 유지합니다. 만약 평가된 코드를 실행하는 동안 오류가 발생하면 줄이 해당 콘텐츠를 찾을 수 있습니다.

댓글의 계층 구조

평가된 코드는 줄 번호를 보존하므로 주석 다른 스크립릿 및 HTML 코드까지 주석 처리할 수 있습니다. 이러한 다음 예는 댓글의 몇 가지 놀라운 효과를 보여줍니다.

<? var x; // a comment ?> This sentence won't print because a comment begins inside a scriptlet on the same line.

<? var y; // ?> <?= "This sentence won't print because a comment begins inside a scriptlet on the same line.";
output.append("This sentence will print because it's on the next line, even though it's in the same scriptlet.”) ?>

<? doSomething(); /* ?>
This entire block is commented out,
even if you add a */ in the HTML
or in a <script> */ </script> tag,
<? until you end the comment inside a scriptlet. */ ?>