clojure + 스마트폰 = <3
lein 설정및 noir 웹 프로젝트 생성하기
~/.lein/profiles.clj 를 편집한다.
1 2 3 4 
  | {:user {:plugins [[cider/cider-nrepl "0.10.0-SNAPSHOT"]                   [lein-localrepo "0.5.2"] 				  [noir "1.3.0"]] 	    :dependencies [[org.clojure/tools.nrepl "0.2.7"]]}} 
  | 
 
다음 프로젝트 폴더 (예를들어 ~/Project ) 에 방문하여 다음을 입력하여 noir 프로젝트를 생성한다.
디펜던시들을 다운받고 다음의 메시지가 출력되며 프로젝트가 생성된다.
1 
  | Generating a lovely new Noir project named foo-web... 
  | 
 
emacs 로 다음의 파일을 연다.
1 
  | emacs ~/Project/foo-web/project.clj 
  | 
 
:dependencies 중 clojure 정도만 1.7.0 정도로 바꿔준다..
C-c, M-j 로 clojure-jack-in 함수를 호출한다. 좀 오래 기다리면 REPL 버퍼가 열린다.
1 2 
  | CIDER 0.10.0snapshot (package: 20150901.1605) (Java 1.8.0_45, Clojure 1.7.0, nREPL 0.2.7) foo-web.server> 
  | 
 
C-c, C-z 를 눌러 project.clj 버퍼가 열리도록 한 뒤에,
C-x, C-f 를 눌러 ~/Project/foo-web/src/foo_web/server.clj 파일을 연다.
C-c, C-k 를 눌러 컴파일한다.
C-c, C-z 를 눌러 REPL 버퍼로 다시 이동한다.
1 2 3 4 5 6 
  | foo-web.server> (def srv (-main)) Starting server... Server started on port [8080]. You can view the site at http://localhost:8080 #'foo-web.server/srv foo-web.server> 
  | 
 
이것으로 최초로 서버를 기동했다. aws ip 에 8080 포트로 접근해보자.
웹 페이지 만들기
src/foo_web/views/welcome.clj 파일을 연다.
C-c, M-n 를 눌러서 REPL 버퍼의 namespace 를  현재 열린 버퍼의 namespace 로 전환한다.
1 2 3 4 5 6 7 8 
  | (ns foo-web.views.welcome   (:require [foo-web.views.common :as common]               [noir.content.getting-started]) 			    (:use [noir.core :only [defpage]])) (defpage "/welcome" []          (common/layout 		            [:p "Welcome to foo-web"])) 
  | 
 
defpage 매크로로 선언된 부분을 보면 이후 따라오는 주소로 다음과 같은 html 을 렌더링했음을 알 수 있다.
1 
  | <p>Welcome to foo-web</p> 
  | 
 
html5 매크로에 의해 [:p] 는 hiccup 이라는 라이브러리의 hiccup.core/html 매크로를 호출하여 html로 치환된다. 다음의 표현이 가능하다
1 2 3 4 5 6 7 8 9 10 
  | foo-web.views.welcome> (println (hiccup.core/html [:h1.foo-class  "bar"])) ;; <h1 class="foo-class">bar</h1> ;; => nil foo-web.views.welcome> (println (hiccup.core/html [:h1#an-id.foo-class  "bar"])) ;; <h1 class="foo-class" id="an-id">bar</h1> ;; => nil foo-web.views.welcome> (println (hiccup.core/html [:div [:h1#an-id.foo-class  "bar"]])) ;; <div><h1 class="foo-class" id="an-id">bar</h1></div> ;; => nil foo-web.views.welcome> 
  | 
 
다음과 같은 페이지를 만들어 보자.
1 2 3 4 5 6 
  | (defpage "/foo" []   (common/layout     [:div.wrapper 	  [:input {:type "text"}] 	  [:button "OK"] 	  ])) 
  | 
 
common/layout 이란 매크로를 주목하자. 여기에 커서를 위치시킨뒤 M-. 를 이용하여 이동할 수 있다.
defpartial 매크로는 결국 hiccup 매크로로 작성된 블럭들을 조립할 수 있음을 알 수 있다.
따라서 좀더 활용가능하도록 바꿔보자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
  | (defpartial layout [ & {:keys [style                                script                                header                                content                                footer]}]   (html5    [:head     [:title "Macadamia!"]     `(~@script)]    [:body     [:div#header `(~@header)]     [:div#wrapper       [:div#content `(~@content)]]     [:div#footer `(~@footer)]     ])) 
  | 
 
foo 페이지는 다음과 같이 변경한다.
1 2 3 4 5 6 7 
  | (defpage "/foo" []   (common/layout    :content    [[:div.wrapper     [:input {:type "text"}] 	[:button "OK"] 	]])) 
  | 
 
이렇게 해서 템플릿 레이아웃을 쓸 수 있게 되었다.
이제 이 템플릿 레이아웃에 bootstrap 을 적용하도록 하자.
css,js 등 정적파일은 resources/public/ 에 추가하면 된다. 여기서는 그냥 cdn을 이용하는것으로.
common.clj 의 :use 함수에 include-js 를 추가하고 layout 을 수정하자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 
  | (ns my-website.views.common   (:use [noir.core :only [defpartial]]         [hiccup.page :only [include-css include-js html5]])) 		 (defpartial layout [ & {:keys [style                                script                                header                                content                                footer]}]   (html5    [:head     [:title "Macadamia!"] 	(include-css "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css") 	(include-js "//code.jquery.com/jquery-1.11.3.min.js")     `(~@script)]    [:body     [:div#header `(~@header)]     [:div#wrapper.container {:style "display: table; height: 100vh;"}      [:div#content {:style "display: table-cell; vertical-align: middle;"} `(~@content)]]     [:div#footer `(~@footer)] 	(include-js "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js")	     ])) 
  | 
 
자 이제 bootstrap 으로 스타일링을 하자.
1 2 3 4 5 6 7 8 9 
  | (defpage "/foo" []   (common/layout    :content    [[:div.col-md-12      [:div.row.col-md-6.col-md-offset-3 	  [:div.input-group 	   [:input.form-control {:type "text"}] 	   [:span.input-group-btn 		[:button.btn.btn-primary "OK"]]]]]])) 
  | 
 
잘 나온다. ㅎㅎ