はじめに
これは、自分用メモ。
Google Apps Script の html テンプレート周りをライブラリ化しようとしている。その関連の話。
内容
HtmlService.createHtmlOutputFromFile()
, HtmlService.createTemplateFromFile()
が読み込むのはどこの html ファイルか
ライブラリになっているプロジェクト lib とそれを使っているプロジェクト proj があるとする。ライブラリを作る側としては、HtmlService
の createTemplateFromFile(name)
関数をプロジェクト lib 側に置きたいのだが、この関数は関数が書かれているプロジェクトの html ファイルを読み込むようだ。つまり、
function loadTemplate(hs, name) {
return hs.createTemplateFromFile(name);
}
となっていた場合、proj 内で
function test() {
var tmpl = lib.loadTemplate(HtmlService, 'sidebar');
...
}
としたときに読み込もうとするのは proj/sidebar.html
ではなくて lib/sidebar.html
である。
別の例を示そう。
HtmlTemplate オブジェクトに次のような include()
メソッド (インスタンスメソッド) を追加できると、html ファイルの中で他の html ファイルをインクルードできるようになる。
つまり、
<?= this.include('style'); ?>
<div id="main_content">
...
</div>
<?= this.include('script'); ?>
みたいに別ファイルで管理している css や js を読み込めると便利だよね、と。
で、問題はこの include()
メソッドをどこで付与してやろうか、ということになるが、ライブラリの方で
function deco(tmpl) {
tmpl.include = function(name) {
return HtmlService.createHtmlOutputFromFile(name).getContent()
};
}
とでもして、ライブラリを使う側では
var tmpl = HtmlService.createTemplateFromFile('index');
tmpl.evaluete();
としたくなるのだが、proj/index.html
の中の <?= this.include('style'); ?>
の個所で読み込まれるのは proj/style.html
ではなくて、lib/style.html
である。
ということで、include()
を mixin するというライブラリ化の夢は破れ去り、プロジェクトごとに毎度
function deco(tmpl) {
tmpl.include = function(name) {
return HtmlService.createHtmlOutputFromFile(name).getContent()
};
}
を書かない限り、この .include()
メソッドは使えないのである。
逆に
このことは、逆に言えば、複数のプロジェクトで共有したいような css や js は、ライブラリとして提供できることを示している。
つまり、自サイトで使う jQuery プラグインを jquery-my-awesome-plugin というライブラリとして提供して、
<?= jquerymyawesomeplugin.awesome(); ?>
として利用するような。