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 ã¯ããã¨ãã¦ãä»ãç°¡åã«èª¿ã¹ã¦ã¿ãã
- Selmerï¼ããã³ãã¬ã¼ãã·ã¹ãã ï¼Djangoã«ã¤ã³ã¹ãã¤ã¢ãããï¼
- Timbreï¼ããã®ã³ã°ï¼ãããã¡ã¤ãªã³ã° ã©ã¤ãã©ãª
- rotorï¼ããã°ãã¼ãã¼ã·ã§ã³ã®ã¢ãã³ã
- Towerï¼ãå½éåã®ã©ã¤ãã©ãª
- markdown-cljï¼ããã¼ã¯ãã¦ã³ãã¼ãµï¼Clojureããã³ClojureScriptã¸ã³ã³ãã¤ã«ããï¼
çæãããã½ã¼ã¹ã®æ§æ
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