[Drogon]CSSを利用してみる
Drogonは、リリースされて間もないこともあり、例えばVue.jsのNuxt.jsのような、見た目の部分をどうにかしてくれるようなフレームワークがありません。
しかし、せっかくサービスを作って公開するのであれば、ある程度見栄えのする内容にしたいと思うはずです。
そこで今回はDrogonフレームワークで作成したページにCSSを適用する手順を、静的コンテンツと動的コンテンツ双方について書いていきたいと思います。
プロジェクトの作成まではこちらの記事を参照ください。
共通の手順
さて、ここでは静的/動的双方のコンテンツどちらを作る場合でも必要な手順を記載します。
プロジェクトを無事作成し終えたらプロジェクトディレクトリに入り、まずはbuildディレクトリに移動します。この理由は後程解説します。
$ cd build
そこにstatic_contentsディレクトリを作成します。
ディレクトリ名は任意で構いません。
$ mkdir static_contents
ディレクトリを作成したら、さらにそこにお決まりのindex.htmlファイルを作成します。
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta name="description" content="DrogonのCSS利用サンプル">
<meta name="keywords" content="Drogon,CSS,MVCフレームワーク,C++,高速">
<meta name="Mizinko-Kinako" content="MKnote">
<meta name="copyright" content="Mizinko-Kinako">
<!--
Drogon ではPathの起点がconfig.jsonのdocument_rootの設定値、
又はがデフォルトではバイナリの実行ディレクトリなので、
htmlファイルからの相対パスではなく、
document_rootからのパスで設定する必要がある。
-->
<link rel="stylesheet" type="text/css" href="/static_contents/css/sample.css">
<title>DrogonでCSSを使う</title>
</head>
<body>
<form action="" method="">
<p>
Textbox:<input type="text" name="textbox" size="128">
</p>
<p>
Radio:
<input type="radio" name="radioButton" value="radio1">1
<input type="radio" name="radioButton" value="radio2">2
</p>
<p>
Select:
<select name="selector">
<option value="A">A</option>
<option value="B">B</option>
</select>
</p>
<p>
TextArea:<br>
<textarea name="Textarea" rows="20" cols="20"></textarea>
</p>
<p>
button:
<button type="button" name="button" value="buttonValue">
This Is button
</button>
</p>
</form>
</body>
index.htmlファイルを作成し終えたら、今度はCSSを作成します。私はhtmlとかcssとかはディレクトリを分けて書くのが好みなので、今回はcssディレクトリを作成してその中にcssファイルを用意します。ディレクトリ分けは必須ではありません。
$ mkdir css
これで一旦下準備は完了です。移行の手順は静的なコンテンツか動的なコンテンツかで別れます。
静的なコンテンツの場合
静的なコンテンツの場合は、config.jsonのdocument_rootキーへのパスの設定、もしくはhome_pageキーへのパスの設定が必要となります。
config.jsonへの設定
document_rootキーはそのものずばりドキュメントルートの設定を行うキーです。このキーにパスを設定すると、HTTPドキュメントの探索パスの起点を設定することができます。
注意するべき点は、ここに設定する値を相対パスで設定した場合、プロジェクトディレクトリからのパスではなく、ビルドした成果物を実行しているディレクトリからの相対パスとなる点です。
絶対パスによってプロジェクトディレクトリの中のファイルを参照することもできなくはありませんが、開発環境から実行環境に持っていくべきは、原則的にはbuildディレクトリの下に格納された実行に関係するファイルのみであるべきですので、そうした内容はすべてbuildディレクトリにまとまっていた方が管理しやすいと考えられます。
そのため、実際にデプロイする場合を想定して、static_contentsディレクトリをbuildディレクトリの下に作成しました。
静的なコンテンツをdocument_rootキーで設定する場合、config_jsonのdocument_rootキーの内容を以下のように編集します。
//document_root: Root path of HTTP document, defaut path is ./
"document_root": "./static_contents",
静的なコンテンツも動的なコンテンツも同様に扱いたい場合には、個人的にはhome_pageキーの設定による探索をお勧めします。
home_pageキーでやる場合は、document_rootキーの値を変更せずに、home_pageを設定します。
今回の場合はstatic_contentの下に用意したindex.htmlですので、以下のようにします。
//home_page: Set the HTML file of the home page, the default value is "index.html"
//If there isn't any handler registered to the path "/", the home page file in the "document_root" is send to clients as a response
//to the request for "/".
"home_page": "static_contents/index.html",
document_rootキーの設定値は、モデル、ビュー、コントローラそれぞれの探索パスの起点としても使用されています。
プロジェクトの中に含まれるページが静的なコンテンツのみで生成されている場合はdocument_rootキーでやっても問題はありませんが、静的なコンテンツのみで構成されたWebアプリケーションというのはそれほど多くないと考えられますので、大抵の場合はhome_pageキーでの制御となるでしょう。
動的なコンテンツの場合
動的なコンテンツでやる場合は、コントローラでパスの制御を行いますので、config.jsonへのパスの設定は特に必要ありません。
controllersディレクトリで以下のコマンドを打ちます。
$ dg_ctl create controller -h dynamic_css
これによって出来上がったソースを以下のように書いていきます。
dynamic_css.h
#pragma once
#include <drogon/HttpController.h>
using namespace drogon;
class dynamic_css : public drogon::HttpController<dynamic_css>
{
public:
METHOD_LIST_BEGIN
METHOD_ADD(dynamic_css::InsertCSS, "/", Get);
METHOD_LIST_END
void InsertCSS(
const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback
) const;
};
dynamic_css.cc
#include "dynamic_css.h"
// Add definition of your processing function here
void dynamic_css::InsertCSS(const HttpRequestPtr &req,
std::function<void(const HttpResponsePtr &)> &&callback
) const
{
auto viewData = drogon::HttpViewData();
viewData.insert("css_path", std::string("/static_contents/css/sample.css"));
callback(drogon::HttpResponse::newHttpViewResponse("cssSampleView.csp", viewData));
return;
}
次に、modelsディレクトリに移動して、cspファイルを用意します。
cssSampleView.csp
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta name="description" content="DrogonのCSS利用サンプル">
<meta name="keywords" content="Drogon,CSS,MVCフレームワーク,C++,高速">
<meta name="Mizinko-Kinako" content="MKnote">
<meta name="copyright" content="Mizinko-Kinako">
<%c++ auto css_path=@@.get<std::string>("css_path"); %>
<link rel="stylesheet" type="text/css" href="{% css_path %}">
<title>DrogonでCSSを使う</title>
</head>
<body>
<form action="" method="">
<p>
Textbox:<input type="text" name="textbox" size="128">
</p>
<p>
Radio:
<input type="radio" name="radioButton" value="radio1">1
<input type="radio" name="radioButton" value="radio2">2
</p>
<p>
Select:
<select name="selector">
<option value="A">A</option>
<option value="B">B</option>
</select>
</p>
<p>
TextArea:<br>
<textarea name="Textarea" rows="20" cols="20"></textarea>
</p>
<p>
button:
<button type="button" name="button" value="buttonValue">
This Is button
</button>
</p>
</form>
</body>
やっていることそのものはこれまでの記事でも紹介したように、ビューへデータを渡しているだけなので、それほど難しいことは無いと思います。
ビルドと実行
ビルドと実行の手順は従来通りbuildディレクトリに移動して以下のコマンドを実行です。
$ cmake .. && make$ ./css_sample
最後に確認として、ブラウザからアクセスしてみます。
今回作成したサンプルの場合、
静的コンテンツの場合は、localhost:80/
動的コンテンツの場合は、localhost:80/dynamic_css/
このようなページが表示されれば成功です。
cssによってパラグラフタグで囲われた部分に背景色がついているかと思います。
さいごに
DrogonではHTTPやHTTPSで送信するhtmlの内容を、サーバ内で組み立てて送信しています。そのため、今回行ったような手順を実行すれば、コンテンツの見た目を簡単かつ動的に差し替えることができるのです。
また、今回の手順で紹介したのはCSSですが、これをjavascriptなどに差し替えて実行することももちろんできますので、HTTPリクエストの処理を高速なDrogonに任せつつ、見た目によりリッチな仕組みを使用することで、性能の良いWebアプリケーションを作成することもできるのです。
皆様もぜひ試してみてください。