これまでの記事では、Goのnet/httpパッケージ機能でWEBサーバを立て、html/templateパッケージの機能で画面を作成してきました
作成した画面は今のところ、問題なく動作していますが、外部に記述したCSSファイルやJavaScriptファイルをリンクする際には注意が必要です。
HTMLテンプレートのヘッダにlinkタグを記述するだけでは、外部ファイルのスタイルやスクリプトを反映させることができません。
実際に挙動を確認しながら、外部ファイルを正常に読み込むための手順をみていきましょう。
Contents
CSSを記述する
今回はサンプルとして、こちらの記事で作成したフォームのボタンにスタイルを記述してみることにします。
新たにasset/cssディレクトリを作成し、そこにstyle.cssというファイルを作成してください。
ファイルを作成したら、適用したいスタイルを記述します。
スタイルの内容は任意で構いませんが、いちおうサンプルを記載しておきます。
/* -------------- * * ボタンスタイル * ------ */ .btn-push { display: inline-block; padding: 0.5em 1em; text-decoration: none; font-weight: bold; color: #FFF; background: #696969; border-bottom: solid 4px #333333; border-radius: 4px; display: inline-block; max-width: 180px; text-align: left; } .btn-push:active { transform: translateY(4px); border-bottom: none; } .btn-push-blue { background: #668ad8; border-bottom: solid 4px #627295; }
テンプレートにcssファイルへのリンクを記述する
次に、作成済みのテンプレートファイルuser-form.gtpl・user-confirm.gtpl、user-registered.gtplに、外部cssを読み込むためのlinkタグを追記します。
<!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="../asset/css/style.css"> </head> <body> ・ ・ ・ </body> </html>
また、サンプルのcssではクラスに対してスタイルを記述していますので、対象のボタンにそれぞれクラス名も指定しておきます。
<input type="submit" class="btn-push btn-push-blue" value="確認画面へ">
<button type="button" class="btn-push" onclick="history.back()">入力画面に戻る</button> <input type="submit" class="btn-push btn-push-blue" value="この内容で登録する">
<button type=“button” class="btn-push" onclick="location.href='./user-form'">入力画面に戻る</button>
スタイルが反映されない
それでは、main.goを実行してhttp://localhost:8080/user-formにアクセスしてみてください。
以下のように、記述したはずのスタイルが反映されていないはずです。
開発者ツールでソースを確認しても、外部cssは読み込みされていないことが見て取れます。
スタイルが反映されない理由
なぜ、linkタグで指定した外部ファイルの読み込みができていないのでしょうか。
結論から言えば、cssファイルが格納されているasset/cssへのHTTPリクエストハンドラが実装されていないためです。
HTMLからlinkタグで外部ファイルを読み込みする際も、サーバに対するHTTPリクエストが発生しています。
したがって、外部ファイルパスへのリクエストも適切にハンドルされるようサーバのメイン処理を記述しておく必要があります。
ここまでを読んで、「テンプレートファイルと同じディレクトリにcssファイルを配置すればよいのでは?」と思う方もいるかもしれません。
しかし、それだけでは不充分です。
html/templateパッケージでテンプレートファイルを使用する場合と異なり、外部に記述したcssファイルやJavaScriptファイル等は完全に静的なファイルです。
HTTPレスポンスとしてファイルシステムの内容を返すようにハンドラを記述しなければなりません。
メイン処理にリクエストハンドラを追加する
それでは、メイン処理に外部ファイルのパスに対するリクエストハンドラを追記しましょう。
package main import ( "net/http" "./req_handler" // 実装したHTTPリクエストハンドラパッケージの読み込み ) func main() { // "user-form"へのリクエストを関数で処理する http.HandleFunc("/user-form", req_handler.HandlerUserForm) // "user-confirm"へのリクエストを関数で処理する http.HandleFunc("/user-confirm", req_handler.HandlerUserConfirm) // "user-registered"へのリクエストを関数で処理する http.HandleFunc("/user-registered", req_handler.HandlerUserRegistered) // css・js・イメージファイル等の静的ファイル格納パス http.Handle("/asset/", http.StripPrefix("/asset/", http.FileServer(http.Dir("asset/")))) // サーバーを起動 http.ListenAndServe(":8080", nil) }
21行目のhttp.Handle関数が追記箇所です。
/assetへのHTTPリクエストに対するハンドラに、http.FileServerの結果を指定しています。
http.FileServerは、指定したディレクトリのファイルシステム内容をレスポンスするハンドラを返します。
静的ファイルの配信について、詳細はこちらの記事をご参考ください。
【Go入門】net/httpパッケージを使ったWEBサーバの構築とHTTPリクエストハンドラの実装
リクエストハンドラを追記したら、再度main.goを実行し、ブラウザでhttp://localhost:8080/user-formにアクセスしてみてください。
今度は正常にスタイルが適用されていることが確認できるはずです。
終わりに
このように、Goで自前のWEBサーバを構築する場合、HTMLから読み込む静的ファイルへのリクエストハンドラを適切に記述する必要があります。
なので、cssやjsの資材はassetやresourcesといった名称のディレクトリにまとめて格納しておいた方がよいでしょう。