LoginSignup
8
6

More than 3 years have passed since last update.

GASで別のHTMLファイルをインクルードする

Posted at

はじめに

「画面の共通部分を部品化して、複数の画面から使いたい」ということはよくあると思います。
これまで経験したプロジェクトでも include という関数を作ってそのようなことを実現してきていましたが、インクルード先ではスクリプトレットが使えない、など制限があるものでした。
もっと使いやすくならないかといろいろ試した結果を書いておきます。

対象者

  • 基本的な JavaScript が読める方
  • GAS で Web アプリを作ったことがある方

いきなり結論

試行錯誤の結果、これでやりたかった以下のことができました。

  • インクルード先の HTML でもスクリプトレットを使える
  • インクルードのネスト(インクルード先でインクルード可能)
  • インクルード先にパラメーターを渡せる
Code.gs
/**
 * HTMLをインクルードする.
 *
 * @param {string} filename HTMLファイル名
 * @param {Object} params インクルード先に渡すパラメーター
 */
function include(filename, params) {
  const template = HtmlService.createTemplateFromFile(filename);
  if (params) {
    for (const key in params) {
      template[key] = params[key];
    }
  }
  return template.evaluate().getContent();
}

動作確認

:arrow_up:include 関数を動作確認します。
以下のように複数の HTML を作りました。

index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <?!= include('css'); ?>
  </head>
  <body class="index">
    <h2>this is index.</h2>
    <?!= include('sub1'); ?>
    <?!= include('sub2', { a:1, b:2 }); ?>
  </body>
</html>
css.html
<style>
div {
  margin: 5px;
  padding: 5px;
}
.index { background-color: #ffffff; }  /* 白 */
.calc  { background-color: #99ffff; }  /* 水色 */
.sub1  { background-color: #99ff99; }  /* 緑 */
.sub2  { background-color: #ffff99; }  /* 黄色 */
.sub2_1 { background-color: #9999ff; } /* 紫 */
</style>
calc.html
<div class="calc">
  <h4>this is calc.</h4>
  <?= a ?> + <?= b ?> = <?= a + b ?>
</div>
sub1.html
<div class="sub1">
  <h3>this is sub1.</h3>
<?
const a = 'A';
const b = 'B';
?>
  <?= a + b ?>
</div>
sub2.html
<div class="sub2">
  <h3>this is sub2.</h3>
  <?!= include('calc', { a:a, b:b }); ?>
  <?!= include('sub2_1', { a:a*2, b:b*2 }); ?>
</div>
sub2_1.html
<div class="sub2_1">
  <h3>this is sub2_1.</h3>
  <?!= include('calc', { a:a, b:b }); ?>
</div>

HTML どうしの関係は以下のようになっています。

  • index.html
    • css.html
    • sub1.html
    • sub2.html
      • calc.html
      • sub2_1.html
        • calc.html

つづけて Code.gsdoGet を追加します。

Code.gs
function doGet(e) {
  return HtmlService.createTemplateFromFile('index').evaluate();
}

最後に作成した Web アプリにアクセスすると以下のように表示され、期待通りの動作が確認できました。

3.png

所感

  • GAS で HTML を扱うクラスには、HtmlOutputHtmlTemplate があり、色々と機能を持っているようなのでもっと深堀りしてみると面白そうです
  • doGet 関数は HtmlOutput を返す必要があるようなので、最初は return HtmlService.createHtmlOutputFromFile('index'); と書いていましたが、これではインクルードが期待通り動きませんでした。
    • 一度 HtmlTemplate 経由で HtmlOutput を生成することに意味がある模様
8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6