HTML サービス: テンプレート化された HTML

Apps Script コードと HTML を組み合わせて、最小限のコーディングで動的ページを生成できます。 手間がかかります。次のようなコードと HTML が混在するテンプレート言語を使用していて、 その構文は、PHP、ASP、JSP のいずれでもかまいません。

スクリプレット

Apps Script テンプレートには、スクリプトレットと呼ばれる特別なタグを 3 つ含めることができます。屋内 通常の Apps Script で動作するコードであれば、 ファイル: スクリプトレットは、他のコードファイルで定義された関数を呼び出すことができます。 Apps Script API のいずれかを使用できます。必要に応じて スクリプトレット内の関数と変数を使用できます。ただし、 コードファイルまたは他のテンプレートで定義された関数によって呼び出されます。

以下の例をスクリプト エディタに貼り付けると、 <?= ... ?> タグ(印刷スクリプレット)が 斜体にします。斜体のコードは、ページが表示される前にサーバー上で実行されます ユーザーに提示します。スクリプレット コードは、ページが提供される前に実行されるため、 1 ページにつき 1 回しか実行できませんクライアントサイドの JavaScript や Apps Script とは異なり、 呼び出す方法は 3 通りです。 google.script.run、スクリプトレットは ページの読み込み後に再度実行します

コード.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 オブジェクトによって作成されます。 配信できるようになります

標準のスクリプトレット

構文 <? ... ?> を使用する標準のスクリプトレットは、 コンテンツを明示的に出力することもできますただし この例に示すように スクリプレット内のコードの result が HTML コンテンツに影響を与える可能性がある 使用できます。

コード.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)攻撃から保護するために

この例では、最初の出力スクリプトレットが文字列を直接出力します。それは その後に、配列とループを設定する標準のスクリプレットが続き、 配列の内容を出力するもう 1 つの出力スクリプトレットです。

コード.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>

印刷スクリプレットは、最初のステートメントの値のみを出力します。 残りのステートメントは、標準列に含まれているかのように動作します。 使用します。たとえば、スクリプトレット <?= 'Hello, world!'; 'abc' ?> のみがあるとします。 「Hello, world!」が出力される

強制印刷のスクリプトレット

構文 <?!= ... ?> を使用する強制出力スクリプトレットは、印刷に類似しています 例外的に、コンテキストのエスケープを回避します。

スクリプトが信頼できないユーザー入力を許可している場合、コンテキスト エスケープが重要です。方法 スクリプレットの出力を意図的に強制する場合は には、指定したとおりに挿入する HTML またはスクリプトを含めます。

原則として、スクリプトレットを強制印刷するのではなく、印刷スクリプトレットを使用します。 ただし、HTML または JavaScript を変更せずに出力する必要がある場合は除きます。

スクリプトレット内の Apps Script コード

スクリプトレットは、通常の JavaScript の実行に限定されません。また、kubectl の テンプレートから Apps Script にアクセスできるようにするための 分析できます

ただし、ページが提供される前にテンプレート コードが実行されるため、 これらの手法では、最初のコンテンツをページにフィードすることしかできません。アクセス方法 対話形式での Apps Script データの作成には、 google.script.run API を使用してください。

テンプレートから Apps Script 関数を呼び出す

スクリプトレットは、Apps Script コードファイルまたはライブラリで定義されている任意の関数を呼び出すことができます。 この例では、スプレッドシートからテンプレートにデータを pull し、 データから HTML テーブルを作成します。

コード.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 コードをスクリプトレットで直接使用することもできます。この例 データを 使用するのではなく、テンプレート自体を使用してテンプレートを作成します。

コード.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>

テンプレートへの変数のプッシュ

最後に、変数をプロパティとして割り当て、テンプレートに push できます。 HtmlTemplate オブジェクトのイベント。1 回 この例でも前の例と同じ結果が得られます。

コード.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>

デバッグ テンプレート

作成したコードが実行されないため、テンプレートのデバッグが難しい場合がある 直接サーバーがテンプレートをコードに変換してから コードの記述を行います。

テンプレートがスクリプトレットをどのように解釈しているか不明な場合は、 デバッグ メソッドを HtmlTemplate クラスが役立ちます 状況を把握しやすくなります

getCode()

getCode() は サーバーがテンプレートから作成するコードを含む文字列です。もし log: スクリプト エディタに貼り付けて実行します。 通常どおりデバッグする Apps Script コード。

これは、Google サービスのリストを再度表示するシンプルなテンプレートです。 その後に getCode() の結果が続きます。

コード.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 は 2 つの特別な HtmlOutput オブジェクト。 異常な名前のプロパティ __$ は、 append() および appendUntrusted()

output にはもう 1 つ特別なプロパティ $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. */ ?>