目次
Google Apps Script と Single Page Application (SPA)
Google Apps Script は Google Drive 上で 作成し、 google の認証機構を利用できる、無料環境です。
その特性から、認証必須の社内アプリやグループ内部アプリの作成に向いています。
今回は、Google Apps Script 環境において、複数ページに遷移するアプリケーションの作成例です。
Google Apps Script における”遷移”
Google Apps Script では、URL指定の、気軽なページ遷移が出来ません。
SandBoxといわれる閉じた環境内部でアプリケーションを制御しており、そのURLも自動生成されています。
もしクリックにより普通に遷移しようとするならば、
1 |
<a href="{url}">遷移</a> |
onclickでGASコードをcallして、doGet 関数に書いてある読み込み処理をもう一度行い、ページまるごと読み直す、ように実装します。
再読み込みは多少時間がかかるため、サクサク、というわけには行かなそうです。
また、社内アプリケーションは一般のアプリケーションのように表示してからが本番です。多用な機能を盛り込み、使いやすくすることがポイントです。
そこで、Single Page Application (SPA)です。
SPAの実装方法とは
Single Page Application (SPA) とは、単一ページ内部でアプリケーションとして動作させる、WEBアプリケーションの形です。ブラウザによるページ遷移を必要とせず、ページ内部でコンテンツを切り替え、動かすことで機能を実装します。これがとっても相性がいいのです。
フロントエンドでの主役は、HTMLと、そしてjavascriptです。
jQueryでも頑張れば実装可能ですし、随所に使うと便利ですが、javascriptのフレームワークを用いるとより効果的です。
javascript の フレームワークには、昨今様々なものが群雄割拠の状態です。主に、React.js, Vue.js, Angular などなどがあります。
基本的にはModelの変更にしたがってHTMLのDOMを再構成する機能を持っています。(仮想DOM)
今回は個人的に気に入っていて多用している、「Riot.js」を使います。
Riot.js の利点は「とにかくわかりやすい」ことです。コツさえ掴めば簡単に使えます。
今回はこのRiot.js を GASのアプリケーションで利用していきます。
Riot.js について
Riot.js は 本来のHTMLの書き方を維持しつつ、非常にシンプルに変化のあるページを記述出来ます。=> Riot.js
現在の riot.js の最新バージョンは Riot.js 4 になりますが、ここでは Riot.js 2 を使っていきます。
Riot.js は 4から、破壊的な変更が行われ、export default をはじめとする、最新のES6環境になりました。よりReact等によった設計になっており、柔軟性よりも画一的な記述方法を推奨しているようです。
Node.js によりコンパイルする場合には、Riot.js 4 で問題ないと思います。
Google Apps Script で利用するには、インブラウザコンパイル、かつインブラウザ表記が必要です。
よりその辺りに柔軟な、Riot.js 2 の方がシンプルに記述できますので、Riot.js 2 を用いていきます。(Riot.js 3 でも同じように柔軟です)
Riot.js 2 で todoアプリを作る (1) 読み込む
CDNから、Riot.js 2 をリンクします。
compiler を含んでいるものが必要です。
index.htmlは以下のようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <app></app> <script src="https://cdnjs.cloudflare.com/ajax/libs/riot/2.6.2/riot+compiler.min.js"></script> <script> riot.compile('<?= include("todo") ?>') riot.mount('app','todo') </script> </body> </html> |
今回は「todo」アプリを作成します。
まずbody直下に app のカスタムタグを置き、その下でriot.js 2 を CDNから読み込んでいます。
次に 別に作った todo.html を include 関数(GAS)で読み込みます。
最後にriot の compile を行い、その結果を待って app タグに対して、 todo をマウント(接続)する、という流れです。
Riot.js 2 で todo アプリを作る (2) タグファイルを分割して作成する
1 |
<app></app> |
カスタムタグ、と言われます。”app” でなくても構いません。
Appの中心部分が記述される、という意味で、app タグにしています。
ここに読み込む内容を、todo.htmlに記述します。
includeでは読み込むというより、別ファイルをそこに表示しているだけなので、index.htmlに全部書いてもかまいません。
include 関数は、コード.gsに記述します。
1 2 3 |
function include(filename) { return HtmlService.createHtmlOutputFromFile(filename).getContent(); } |
続いてtodo.html を作成し 以下のように記述します。
1 2 3 4 5 6 7 8 |
<todo> <div each={items}>{label}</div> <script> this.items = [ {label: "task1"} ] </script> </todo> |
task1
と表示されれば、ひとまず成功になります。
Riot.js 2 で todo アプリを作る (3) todo.htmlを完成させる
Todo アプリの記述を行っていきましょう。
例を参考に、色々いじってみると、非常に楽しいです。
todo.html を記述していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<todo> <div each={items}><input type="checkbox" checked={checked} id="checkbox-{id}" /><label for="checkbox-{id}">{content}</label></div> <input type="text" name="input-field" /><button onclick={add}>add</button> <script> let id = 0 this.items = [] this.add = (e) => { let content = document.querySelector("[name=input-field]").value if( content == "" ){ return } this.items.unshift({ id:id, checked: false, content: content }) id++ this.update() } </script> </todo> |
this.items にデータを入れて、updateをかけるとそれで、HTMLが更新されます。
この仕組みを用いて、 SPAを構築していきます。
Riot.js で、Page 遷移を実装する
page 遷移も試して見ましょう。
Riot.js を使って、ブラウザによる遷移なしで、ページを遷移します。
具体的には先ほど app に todo をマウントしましたが、別のタグを app にマウントすると、そちらに遷移するのです。
other.html を作成します。
1 2 3 |
<other> <div>ok?</div> </other> |
tagとなるhtmlは、必ずカスタムでくくり、内部はdivなどでくくる必要があります。
<app></app> の上に、other.htmlに遷移するボタンをつけて見ます。
同時に other.html を include、 compile しておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<!DOCTYPE html> <html> <head> <base target="_top"> </head> <body> <button onclick="riot.mount('app','other')">other.htmlを表示</button><br> <app></app> <script src="https://cdnjs.cloudflare.com/ajax/libs/riot/2.6.2/riot+compiler.min.js"></script> <script> riot.compile('<?= include("todo") ?>') riot.compile('<?= include("other") ?>') riot.mount('app','todo') </script> </body> </html> |
これでbuttonを押すと、other.htmlの内容が表示されるようになりました。
これでルーティングを作成することが出来ます。
仮想DOMによるデータからの反映と、ルーティング機能を用いることで、SPA をGoogle Apps Script で作成することが出来るようになりました!