2011-04-28 3 views
6

저는 Compojure와 함께 최근에 놀았으며, 기본적인 웹 애플리케이션이 있습니다. 내 HTML 템플릿의 경우 Enlive를 사용하고 있으며 모든 단순한 정적 페이지를 포함하는 네임 스페이스가 있습니다.목록에서 Compojure 경로 만들기

(defroutes public-routes 
    (GET "/" [] 
    (info/index-template)) 
    (GET "/about" [] 
    (info/about-template)) 
    (GET "/contact" [] 
    (info/contact-template))) 

내가 실제로보다 몇 가지 더 있어요,하지만 그건 내가 뭘하는지의 아이디어를 줄 것이다 :이 페이지에 대한 defroute 호출은 다음과 같습니다.

지금, 나는 생각, 내 부분에 반복 정말 무리, 그래서 나는 다음과 같은 시도 할 것이라고 생각 :지도가 반환 한,

물론
(defroutes info-routes 
    (map #(GET (str "/" %) [] (ns-resolve 'webapp.pages.info 
             (symbol (str % "-template")))) 
     '("about" "contact"))) 

는,이 작동하지 않습니다 게으른 시퀀스 및 함수의 본문 (?)이 아닙니다. 누군가가 아이디어를 얻으려면 내가해야 할 일을 알고 있습니까?

아니면 완전히 다른 접근 방식을 사용하여 직접 반복해야합니까?

답변

5

당신은 항상 defroutes 사용하는 routes 기능을 사용할 수 있습니다

(defroutes info-routes 
    (apply routes 
    (map #(GET (str "/" %) [] 
       (ns-resolve 'webapp.pages.info 
          (symbol (str % "-template")))) 
     '("about" "contact")))) 

을하지만 여전히 꽤 지루, 현실을 위로 양념을하자! ;-)이 코드

(defn templates-for [& nss] 
    (->> nss 
     (map ns-publics) 
     (apply concat) 
     (filter #(->> % first str 
        (re-seq #"-template$"))) 
     (map second))) 

(defn template-uri [template] 
    (->> template meta :name name 
     (re-seq #"(.*)-template$") 
     first second (str "/"))) 

(defn template->route [template] 
    (GET (template-uri template) [] template)) 

(defroutes public-routes 
    (GET "/" [] "foo") 
    (apply routes (map template->route 
        (templates-for 'webapp.pages.info)))) 

templates-for 함수가 주어진 네임 스페이스에 "-template"로 마무리 어떤 기능을 찾아 그들과 함께 적절한 경로를 작성합니다. 매크로를 사용하지 않는 방법을 살펴 보겠습니다.

+0

인수가 전달되면서 몇 가지 문제가있었습니다. 이전에는 전달하지 않았지만 defsnippet 인수 목록을 [_]로 고정 시켰습니다. 이제는 완벽하게 작동합니다. 감사합니다. – Mike

1

defroutes is a macro 그래서 불행히도지도와 같은 함수에 전달할 수 없습니다. defroutes 호출로 확장 된 매크로를 작성해야합니다. 또는 확장 된 함수를보고 직접 호출 할 수 있습니다.

그것은 루트의 목록으로 확장 할이

(defroutes public-routes 
    (make-list-of-routes) 

처럼 defroutes에 호출 내에서 경로의 목록을 작성하는 습관 일 :

(defroutes public-routes 
    ((GET "/" [] (info/index-template)) 
    (GET "/about" [] (info/about-template)) 
    (GET "/contact" [] (info/contact-template)))) 

경우 일반 함수는 것 defroutes 경우 이것을 apply

(apply defroutes (conj 'public-routes (make-list-of-routes))) 

으로 해결하십시오. defroutes은 매크로가 적용되기 전에 완전히 끝났기 때문에 결과가 좋지 않습니다. 정말로 매크로를 함수로 작성할 수 없습니다. 매크로 은 clojure (또는 내가 아는 어떤 lisp)의이 아닙니다. 일부 Clojurians (일반적으로는 아닙니다)이 "매크로가 악합니다"라고 말하면 종종 이런 상황에 대해 생각합니다. 매크로를 작성하려고하면 매크로를 사용할 수 없습니다.

해결 방법은 defroutes 매크로를 사용하지 않고 routes 함수를 직접 호출하는 것입니다.

+0

내가 오해하는지 잘 모르겠지만지도에 매크로를 전달하지 않고 매크로로 전달 된지도의 결과를 얻으려고합니다. 필자의 함수는 지연 함수가 처리하기를 원하는 게으른 함수 시퀀스를 리턴하고있다. 아니면 뭔가 빠졌습니까? – Mike

+0

아더 (Arthur)의 조언에 따라''defroutes r a b c ''는''def'' (경로 a b c)''에 대한 지름길입니다.''routes''는 보통 함수입니다. 당신의 예제는'(routes a b c)'대신에 (''routes a b c '')''(routes a b c)'대신에 끝납니다. 이는 apply :'(def r (apply routes [a b c]))'와 함께 고정 될 수 있습니다. 'routes'가 매크로라면, 물론 이것은 효과가 없었을 것입니다. – raek

관련 문제