googleドキュメントでサイト
図表や数式の入ったページでWEBサイトを作りたいと思います。googleドキュメントはこれをかなえてくれそうです。
これは、事前に試したことで、出来上がった後のことは、「googleドキュメントのCMS」に書きました。
※ただし、見て頂いているのは、おそらく、HTML化したサイトだと思います。GASで作ったCMSは、新たに閲覧する場合、「許可」や「安全ではないページを開く」などのハードルを越えなければ開けません。ドキュメントを書いた本人には障害になりませんが、他人はまずやらないことだと思います。しかし、故意に隠しているわけではないのでリンクは書いておきます。
この方法では、google ドキュメントがHTML化されます。そこで、これを使って、従来のhttpdのサーバにも同じものを移そうと思います。
※数式はHTML化で図になります。HTML化によって与えられたURLを一度開かないと図は作られないようです。また、Lubuntuを起動して見ましたが、同じgoogleアカウントなのに数式は全滅です。400なので図そのものがないのではないようです。また、張り付けた図の一部も表示されていないようです。Google Docsで元のドキュメントを開いて、「ファイル」「共有」「ウェブに公開」としてURLを表示して、これを開くと、このCMSのメニュークリックでも図が出るようになりました。つまり、自分自身にしか見ることのできないサイトができたのかもしれません。もともと、GASなので、アクセス許可や「安全でないページ」を開かなければ見ることができないので誰も見ないとは思いますが。
googleドキュメントの編集中に「ファイル」「ウェブに公開」を選んで公開できます。また、右上の「共有」ボタンから公開することもできます。
この2つは別の機能で、前者はドキュメントをHTMLに変換して普通のサイトのように振る舞うもので、後者はgoogleドキュメントのエディタが開きます。
ここでは、前者を使うことを考えます。この場合「共有」する必要はありません。
googleドキュメントの編集中に「ファイル」「ウェブに公開」を選択すると、URLが与えられます。
このURLにブラウザでアクセスするとHTML化したドキュメントが表示されます。
HTMLの特徴として、A4と言った用紙サイズの概念がなく、ブラウザの表示幅に合わせた幅のロール紙のようになります。
ただし、あまり綺麗ではありません。図と文章の配置が崩れています。表の経線の太さが不揃いです。また、「見出し」に付けた章番号は本文と同じサイズになって小さく細くなっています。フォントの選択が異なっていて、フォントを変えた場所の行間指定だけが有効になっています。
しかし、図表や数式の入った文書を1つのドキュメントで作成、保持できる利便性は揺らぎません。ドキュメントの書き方を工夫すればたいていは何とかなると考えました。
もともと、わたしの利用はメモなので見た目はあまり重要ではありません。
ここでやろうとしていることは、googleドライブに関連した、google固有のサービスであって代替手段はありません。したがって、ここで行なう努力は、いつ無効になるか分かりません。
また、サービスが継続されていても、サービスの内容や利用した機能はいつ変わっても仕方がありません。
しかし、ブラウザと印刷文書作成の知識が1つに集まったシステムをどのように実現しているかを学べるのですから良しと考えます。
googleドキュメントは、「ファイル」「ウェブに公開」によって与えられるURLを使って、普通にWEBサイトで利用できます。
http://mikeo410.minim.ne.jp/html/
に挙げた「資料」はgoogleドキュメントです。
しかし、これは面倒でした。googleドキュメント一つ一つにHTMLファイルを作ることになりました。
直接 URL を開くと、下図のように大きなマージンが取られて文書の幅が十分ではなかったためです。
直接 URL を開くことを諦めて、ドキュメントごとにHTMLを書くことにしましたが、iframeに読み込んだドキュメントのpadding属性を無効にするのは困難です。
|
ドキュメントのHTMLに変更を加えるのは、仕様が変更された場合に不都合となりますが、試して見て、一般性のある変更なら採用しようと思います。
最低限は、以下のようなHTMLを返すようにして、個別にHTMLを書かなくて済むようにしたいと思います。
<html> <head> <style> iframe {display: block; position:fixed; width: 99%; height: 100%; border: none;} </style> </head> <body> <div> <iframe src="https://docs.google.com/document/d/e/xxx/pub?embedded=true" allowfullscreen="allowfullscreen"></iframe> </div> </body> </html> |
多くの場合、HTMLページは図を含み、別のファイルなので管理が困難です。googleドキュメントをページとすれば、ページと図が1つのファイルのように扱えます。
googleドキュメントをページとするにはHTMLページのiframe内に表示する必要があるようです。googleドキュメントはHTML化してURLを付けてくれますが、左右に大きなマージンがあって工夫が必要です。
大抵のCMS(Contents Management System)は、ページの本文をデータベースに入れて、テンプレートのHTMLに埋め込んでいます。ユーザから送られるURLは、httpdの扱うディレクトリ階層のようになっていますが、ユーザのトップディレクトリのindexファイル以外は実在せず、CMSがデータベースを引くキーに使われています。
googleドライブで可能なのは階層的にフォルダを作って、doogleドキュメントを「移動」することです。
googleドライブ上のファイルは自動的に付与されたIDをURLに書いてリクエストされ、googleドライブに作成したディレクトリ階層やファイル名では要求できません。
ページの作成時には、CMSのないHTMLのサイトのようにフォルダ階層でページを格納しますが、外部から指定するのは格納場所やドキュメント名ではないURLになります。
doGet()関数には、URLのクエリパラメータが渡るので、フォルダ名やファイル名を使ってCMSのように仮想のものにすることが出来ると思います。これが必要なのは返すページのHTMLを変更して送り出したいからです。特別なことではなく、デフォルトの左右のマージンが大きすぎて縦長になっていると言うだけです。
こうしたことができるのは、もともと、googleドライブ自体がCMSなのだと思います。
試行錯誤するうちに、一番大きな問題は、googleドキュメントを「ファイル」「ウェブに公開」したときに与えられるURLだと分かりました。これをサーバサイドのスクリプトで取得する方法が分かりません。
このURLは、googleドキュメントを直接指すものではなく、サーバに、ドキュメントをHTMLに変換して送り返す動作を要求するものです。したがって、googleドキュメント自体の持ち物ではないようです。
サイトマップのように公開しているURLの一覧を返すURLと言うのもありそうですが分かりません。
したがって、ドキュメントを作成したときには「ウェブに公開」で与えられるURLと、ドキュメントのファイルIDの対応表に登録するアプリケーションが別途必要です。
目次を作る際にはフォルダの構成に従ってドキュメントのファイルIDを列挙し、ドキュメントの名前を目次項目とします。
目次のHTMLに書き込んで置くドキュメントの識別子にはファイルIDからURLを引いてセットします。
HTMLを返すApps Scriptプロジェクトを作ります。クエリのないURLが要求されれば目次を作って返します。クエリがあれば記述されたクエリに従ってHTMLになったドキュメントを取得して返します。
この処理はコード.gsに記述するdoGet()関数で行ないます。この関数はURLによるブラウザからのリクエストに対してHTMLファイルを返送する関数です。
function doGet(e){ if(e.parameter.doc){ let res=UrlFetchApp.fetch( "https://docs.google.com/document/d/e/XXX/pub?embedded=true"); let html=res.getContentText(); return HtmlService.createTemplate(html).evaluate(); } else { // 本来はここで目次を作って返す return HtmlService.createTemplateFromFile('index').evaluate(); } } |
UrlFetchApp.fetch()で、HTMLになったドキュメントのHTML記述が受け取れます。
doogleドキュメントは、ドキュメント内の目次を作るので、これも利用できます。しかし、トップページには総目次が必要なので、フォルダ構造を反映して、階層化した目次を作成します。
目次に現れる順番は、本来、任意に設定できなければならないのですが諦めます。
googleドライブのトップのフォルダを列挙すると、「マイノートパソコン」などgoogleドライブに接続しているパソコン側の名前らしいものもあって、トップのフォルダが何かは良く分かりませんでした。しかし、サイトのトップと見做すフォルダは、開いた時のURLからフォルダIDが分かります。これを使って、それ以下の階層が一覧できれば目次のソースとなります。
階層構造をgsスクリプトでどう表現するかは良く分からないのでダイレクトにHTMLタグにすることで試します。<ol><li></li></ol> をネストすれば良さそうです。
フォルダとファイルを列挙することは以下のようにしてできます。
function myFunction() { // フォルダ内を列挙 function ListFolder(folderId){ let parent = DriveApp.getFolderById(folderId); let _folders = parent.getFolders(); while(_folders.hasNext()){ let f=_folders.next(); Logger.log(f.getName()+" "+f.getUrl()); ListFolder(f.getId()); } let _files = parent.getFiles(); while(_files.hasNext()){ let f=_files.next(); Logger.log(f.getName()+" "+f.getUrl()); f=_files.next(); } } ListFolder("docフォルダのフォルダID"); } |
HTMLで折りたためる目次を作るには以下のようにすれば良いようです。
<div> <ol> 目次: <li> <details open="true"> <summary>フォルダA</summary> <ol> <li>ファイルA1</li> <li> <details open="true"> <summary>フォルダAA</summary> <ol> <li>ファイルAA1</li> <li>ファイルAA2</li> </ol> </details> </li> </ol> </details> <li>ファイル1</li> <li>ファイル2</li> </il> </ol> </div> |
googleドキュメントを作成して「ファイル」「ウェブに公開」します。googleドキュメントにはURLが与えられています。
googleドキュメントを開くURLは2種類あります。それは、HTML化したものを開くか、googleドキュメントのエディタで開くかと言うことです。
前者は「ファイル」「ウェブに公開」を選択したときに、「リンク」や「埋め込み」で表示されるURLです。必要なのは、このURLですが、gsスクリプトで取得したfile.getURL()関数から返ってくるのは後者でした。
このURLを目次のリンクに使えば良い訳ですが、1つ問題があります。googleドキュメントを公開してURLで開くと左右に大きな余白ができてA4より縦長表示になってしまいます。この対策で上手くいったのはiframe内に表示して、マイナスのマージンを指定することです。これをするためには、リクエストに対して、HTMLで包んで返したいと思います。
これ自体は、HTMLを開くのがブラウザなので問題ありませんが、サーバサイドでgsスクリプトによってgoogleドキュメントが読み出せるなら別の解法が考えられます。