Luminusを触ってみたのでメモ
Luminusを触ってみたのでメモ。
概要
- 軽量ライブラリをベースにした小さなWEBアプリケーションフレームワーク
- 以下を狙いとする
- 堅牢
- スケーラブル
- プラットフォームの利用を簡単に
試用
Leiningen テンプレートLuminus-Templateを利用してテンプレートプロジェクトを作成。
なお、今回利用する Leiningen のバージョンは 2.1.3。
lein new luminus myapp cd myapp lein ring server
依存ライブラリ
上記で作成すると、project.clj(抜粋)は↓の感じに。
:dependencies [[org.clojure/clojure "1.5.1"] [lib-noir "0.7.1"] [compojure "1.1.5"] [ring-server "0.3.0"] [selmer "0.4.3"] [com.taoensso/timbre "2.6.2"] [com.postspectacular/rotor "0.1.0"] [com.taoensso/tower "1.7.1"] [markdown-clj "0.9.33"]] :plugins [[lein-ring "0.8.7"]]
Ring, Compojure, lib-noir はいいとして、他を簡単に調べてみた。
生成されたソースの構成
src └─myapp │ handler.clj …defines the base routes for the application, this is the entry point into the applicationand any pages │ repl.clj …provides functions to start and stop the application from the REPL │ util.clj │ ├─routes …routes and controllers for our homepage are located │ home.clj …a namespace that defines the home and about pages of the application │ └─views │ layout.clj …a namespace for the layout helpers │ └─templates base.html …the base layout for the site home.html about.html
誤解を恐れず描くなら、リクエストの流れは概ね↓のイメージだろう。
チュートリアルをやってみる
Your first applicationに沿ってやってみる。
テンプレートを編集して、HOMEページをメッセージボードに置き換えるという内容。
プロジェクト新規作成
lein new luminus guestbook +h2
(H2の組み込みデータベースエンジンをサポートするテンプレートを作成)
(補足)+h2 オプションによって増えた依存ライブラリ
[com.h2database/h2 "1.3.172"] [korma "0.3.0-RC5"] [log4j "1.2.17" :exclusions [javax.mail/mail javax.jms/jms com.sun.jdmk/jmxtools com.sun.jmx/jmxri]]]
(補足)生成されたソースの構成
src │ ★+h2オプションによって増えた部分★ │ log4j.xml …logging configuration for Korma │ └─guestbook │ handler.clj │ repl.clj │ util.clj │ ├─models ★+h2オプションによって増えた部分★ │ db.clj …used to house the functions for interacting with the database │ schema.clj …used to define the connection parameters and the database tables │ ├─routes │ home.clj │ └─views │ layout.clj │ └─templates base.html home.html about.html
DB接続情報の編集
schema.clj の db-spec および db-store を編集する。
なお、create-tables関数が呼ばれたタイミングで、site.db.h2.dbファイルが resources フォルダ直下に生成される。
(def db-store "site.db") (def db-spec {:classname "org.h2.Driver" :subprotocol "h2" :subname (str (io/resource-path) db-store) :user "sa" :password "" :naming {:keys clojure.string/lower-case :fields clojure.string/upper-case}})
テーブル生成関数の編集
schema.clj に create-guestbook-table 関数を追加し、create-tables から呼び出すように編集する。
(defn create-guestbook-table [] (sql/with-connection db-spec (sql/create-table :guestbook [:id "INTEGER PRIMARY KEY AUTO_INCREMENT"] [:timestamp :timestamp] [:name "varchar(30)"] [:message "varchar(200)"]) (sql/do-commands "CREATE INDEX timestamp_index ON guestbook (timestamp)")))
(defn create-tables "creates the database tables used by the application" [] (create-guestbook-table))
DBアクセス関数の編集
db.cljに以下を追記。
(defentity guestbook) (defn save-message [name message] (insert guestbook (values {:name name :message message :timestamp (new java.util.Date)}))) (defn get-messages [] (select guestbook))
アプリケーションの初期化処理の編集(DB初期化処理を追加)
handler.cljの関数 init(アプリケーション開始時に一度だけ呼ばれる関数)に、DB初期化処理(テーブル生成関数の呼び出し)を追加する。
requireに以下を追加。
[guestbook.models.schema :as schema]
init関数内の set-config! に続けて、以下を追加。
;;initialize the database if needed (if-not (schema/initialized?) (schema/create-tables))
コントローラの編集
home.clj の home-page 関数の定義を以下の通り置き換え(ゲストブック表示用のパラメータを追加)。
;(defn home-page [] ; (layout/render ; "home.html" {:content (util/md->html "/md/docs.md")})) (defn home-page [& [name message error]] (layout/render "home.html" {:error error :name name :message message :messages (db/get-messages)}))
require に以下を追加。
[guestbook.models.db :as db]
また、ゲストブックへのメッセージ登録用のコントローラを追加する。
(defn save-message [name message] (cond (empty? name) (home-page name message "Somebody forgot to leave a name") (empty? message) (home-page name message "Don't you have something to say?") :else (do (db/save-message name message) (home-page))))
home-routes の定義に以下を追加する。
(POST "/" [name message] (save-message name message))
HTMLテンプレートの編集
home.html を以下の内容に置き換える。
{% extends "guestbook/views/templates/base.html" %} {% block content %} <ul> {% for item in messages %} <li> <time>{{item.timestamp|date:"yyyy-MM-dd HH:mm"}}</time> <p>{{item.message}}</p> <p> - {{item.name}}</p> </li> {% endfor %} </ul> {% if error %} <p>{{error}}</p> {% endif %} <form action="/" method="POST"> <p> Name: <input type="text" name="name" value={{name}}> </p> <p> Message: <textarea rows="4" cols="50" name="message"> {{message}} </textarea> </p> <input type="submit" value="comment"> </form> {% endblock %}
レイアウトを整える
resources/public/css/screen.css に以下を追記。
form { width: 200px; clear: both; } form input { width: 50%; clear: both; }
パッケージング
- 実行可能jar
lein ring uberjar java -jar target/guestbook-0.1.0-SNAPSHOT-standalone.jar
- war
lein ring uberwar