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" ]]]]]]))
잘 나온다. ㅎㅎ