App Engineのテンプレートファイルと静的ファイルの場所

最近Google App Engine for Goを始めました。
なんとなく興味本位で触ってみたんですが、思いの外Goがいい感じだったので、これからApp Engineの勉強はGoを使おうと思いました。なんと言うかとっても自分にフィットするんですね。


閑話休題
今日のお題はApp Engineでよく使われるHTMLテンプレートファイルとcssや画像などの静的ファイルの場所について。この一件で私は三日棒に振りました (プライベートの時間ですよ) 。


App EngineのTutorialやSDKに付属しているサンプルをみるとだいたいこんな感じの構成になっています。

hogehoge ---+--- app.yaml
            |
            +--- hogehoge --- hogehoge.go
            |
            +--- hogehoge.html
            |
            +--- style.css


つまり、HTMLテンプレートファイル (上の例ではhogehoge.html) がapp.yamlと同じフォルダに配置されている、ということです。でもこんな構成にしたくなりませんか?

hogehoge ---+--- app.yaml
            |
            +--- hogehoge --- hogehoge.go
            |
            +--- templates ---+--- hogehoge.html
                              |
                              +--- style.css


なぜかというと、HTMLテンプレートファイルの数が多くなってくるとトップレベルにファイルがゴロゴロ置かれることになってしまい、ごちゃごちゃした構成になってしまうからです。


フォルダを作ってファイルを移動するのはそりゃ出来ます。では移動したHTMLテンプレートファイルを使うにはどうやったらいいのでしょうか?まずはトップレベルにHTMLテンプレートファイルが存在する場合。

t, err := template.ParseFiles("hogehoge.html")
if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
}

err = t.Execute(w, nil)


なんとなく分かりますよね。hogehoge.htmlを読みこんで (ParseFiles) レンダリングする (Execute) 。
ではHTMLテンプレートファイルの場所を変えた場合は?

t, err := template.ParseFiles("templates/hogehoge.html")
if err != nil {
    http.Error(w, err.Error(), http.StatusInternalServerError)
    return
}

err = t.Execute(w, nil)


と思うでしょ?
このコードを開発用のローカルサーバで動かすと何の問題もないのですが、App Engineにディプロイすると、


あれれ?そんなファイルないと怒られてしまいました。


…それから三日後。原因はapp.yamlにあることが分かりました。app.yamlはこんな感じでした。

# ... 省略 ...

handlers:
- url: /stylesheets
  static_dir: templates

- url: /.*
  script: _go_app


handlersの二つ目はいいとして、一つ目はcssファイルをHTMLテンプレートファイルと同じフォルダに入れていました。なので上記の設定にしていましたが、あるフォルダをstatic_dirに設定すると、そのフォルダ以下にあるファイルはプログラム上から読めなくなってしまうんですね。

そりゃそうか、static_dirのフォルダは静的ファイルサーバに置かれるわけですから。


こんな感じにフォルダ構成を見直しました。

hogehoge ---+--- app.yaml
            |
            +--- hogehoge --- hogehoge.go
            |
            +--- templates --- hogehoge.html
            |
            +--- statics --- style.css


静的ファイルサーバに送るフォルダはこんな風にした方がいいかも。
またapp.yamlも上記フォルダ構成にあわせて修正しました。

# ... 省略 ...

handlers:
- url: /stylesheets
  static_dir: statics  # <- ここ修正

- url: /.*
  script: _go_app


めでたし、めでたし。
久しぶりに気持ちよく床につくことが出来ます♪