• D言語によるWebアプリの実装 その3

    2011年10月26日 19時54分
    前回の続き

    HTMLファイルを表示しましたが、見た目が残念なので
    CSSを当ててそれなりの見た目にしたいと思います。


    今回のソース


    CSSファイルの出力

    CSSファイルはアプリケーションでいじる必要はなく、
    単純にWebサーバが出力できるようにすればよいです。

    /usr/local/bbs/resources/stylesheets以下に、CSSファイルを配置します
    # mkdir -p /usr/local/bbs/resources/stylesheets
    # cp default.css /usr/local/bbs/resources/stylesheets/


    ApacheがCSSのディレクトリを参照できるようhttpd.confにAliasを設定します
    Alias /bbs/stylesheets /usr/local/bbs/resources/stylesheets


    さらにAliasはWebアプリを通したくないので、除外設定も追記します
    RewriteCond %{REQUEST_URI} !^/bbs/stylesheets.+$
    RewriteRule ^/bbs/.*$ /var/www/fcgi-bin/bbs.fcgi [L]



    テンプレートのパス記述

    あとはHTMLテンプレートにCSSの読み込みを書き込めば完了です。
    <link rel="stylesheet" type="text/css" href="/bbs/stylesheets/default.css" />



    完了なのですが、これだと内容が少ない上に、
    プログラム全然関係ないので少し機能を追加します。


    追加機能

    HTMLテンプレートに、「/bbs/stylesheets/default.css」と直接書いてしまうと、
    Webアプリの設置場所を他のURLに変更する時に書き直さなければなりません。

    例えば「/keijiban/」に配置したい時や、
    「/bbs1/」「/bbs2/」のように複数配置したい時などです。


    今はまだ変更が1か所だけなので、さほど手間でもないですが、
    修正箇所が増えてくると面倒になってきます。

    相対パスで書くという手もありますが、
    全てのテンプレートで書き方を統一した方がシンプルなので、
    絶対パスで書きたいです。


    そこで、テンプレートにはアプリ直下のURLのみを記述し、
    プログラムからパスを追加する形にしたいと思います。

    テンプレートに「/stylesheets/default.css」と書いておくと、
    プログラムが出力時に「/bbs/stylesheets/default.css」としてくれるようにします。


    テンプレートの記述

    テンプレートに処理を入れるには、対象のタグにs:idでIDを指定します。
    <link s:id="link" rel="stylesheet" type="text/css" href="/stylesheets/default.css" />


    また、今回は処理対象の属性名も指定してみようと思います。
    s:attributeでURLを変更する属性を指定します。
    <link s:id="link" s:attribute="href" rel="stylesheet" type="text/css" href="/stylesheets/default.css" />


    s:idはテンプレートエンジン標準属性ですが、
    s:attributeは今回の処理を記述するための専用属性です。


    プログラムの記述

    テンプレート1つに対してViewクラスを1つ作るようにプログラムを作成します。
    「ThreadList.html」テンプレートに対し、jp.ku6.bbs.view.ThreadListView.ThreadListViewクラスを作成しました。

    ただ、今回作成する機能は、全画面で使いたいので、
    共通クラスを作成し、それを継承する形にしました。

    共通クラスはjp.ku6.bbs.view.BaseView.BaseViewクラスです。


    テンプレートオブジェクトの生成とHTMLレスポンスの出力については前回同様です。
    ThreadListActionに書かれていた処理を持ってきました。

    追加されたのが次の部分です。
    1// s:id="link"が付いたタグに対する処理を割り当て
    2contents_.assign("link", &linkProcessor);


    この記述は、テンプレート出力時にs:id="link"が書かれたタグの情報を
    指定のdelegateに渡すものです。

    指定しているdelegateは次のメンバ関数です。
    1void linkProcessor(SweetsPrinter printer, SweetsElement element, const(SweetsNode[]) children)


    引数は次の通りです
    • printer → 処理結果データの出力先
    • element → s:idを付けられたタグそのもの
    • children → s:idを付けられたタグの内側のデータです。

    この関数内で、URLが変更されたlinkタグを出力します。


    まずはURLを変更する属性を調べます。
    対象の属性は、テンプレート内でs:attribute属性を使って指定しましたので、これを参照します。
    1const(string)* target = "s:attribute" in element.attributes;



    対象の属性名が取得出来たら、それを利用して同じように対象の属性値を取得します
    1const(string)* v = *target in element.attributes;



    属性値にアプリケーションのURLを追加し、新しい属性値として作成します。
    1string[string] attributes;
    2attributes[*target] = APPLICATION_ROOT_URI ~ *v;


    新しい属性値を追加してタグを表示します。
    1element.printStartTagWithAdditionalAttributes(printer, attributes, true);


    linkタグではありえませんが、子要素を持っていた場合のために、子要素も含めて出力する処理も書いておきます。
    1element.printStartTagWithAdditionalAttributes(printer, attributes, false);
    2foreach (child; children)
    3    child.print(printer);
    4element.printEndTag(printer);




    実行

    テンプレートファイルと実行ファイルを更新すれば、CSSが適用されます。



    次回へ続く

    コメントを書く

    名前
    本文
    編集用パスワード 入力すると編集が行えます
    管理者のみ閲覧