2013-03-16 3 views
3

저는 웹 프로젝트에서 noir을 사용 해왔고 defpage 매크로로 정의 된 모든 가능한 경로에 대한 액세스 수준 (및 하위 수준)에 따라 사용자 액세스를 제한 할 시점에 이르렀습니다. 그래서 원래 내가Clojure에서 매크로 정의에서 맵을 소멸시키는 관용적 인 방법이 있습니까?

(defpage [:post "/mysite"] {:as input} 
    (if-not (has-reqd-user-level? :levelX :sublevelY "/grantedRoute") 
    (noir.response/redirect "/insufficientRights") 
    ...)) 

있었다 그리고 나는이 상용구 코드를 제거 것이라고 생각 :

(defpage-with-user-level :levelX :sublevelY "/grantedRoute" 
    [:post "/mysite"] {:as input} 
    (html 
    [:body [:h1 (str "Hello " (:name input) "!")]])) 

을하지만이에 언급 한 바와 같이 마지막으로

(defmacro defpage-with-user-level [level sublevel granted-route route data expr] 
    `(defpage ~route ~data 
    (if-not (has-reqd-user-level? ~level ~sublevel ~granted-route) 
     (noir.response/redirect "/insufficientRights") 
     ~expr))) 

다음과 같이, 우리는 그것을 사용 Rich Hickey가 작성한 글 https://groups.google.com/forum/#!msg/clojure/4II-HKr_Pu0/2IcKit99cagJ은 위치 바인딩 때문에 약간 어색함을 느낍니다. 이는 이미지도가 존재할 때 관용적이지 않습니다.

그러나 매크로에서 비 구속 바인딩 사용과 관련된 몇 가지 예 또는 토론을 찾고 있었지만 슬프게도 평가되지 않은 표현이 계속지나 가기 때문에 명확한 사용법을 찾지 못했습니다.

그래서, 다음과 같은 솔루션은 내 마음에 온 :

(defmacro defpage-with-user-level [dts expr] 
    `(defpage (:route ~dts) (:data ~dts) 
    (if-not (has-reqd-user-level? (:level ~dts) (:sublevel ~dts) (:granted-route ~dts)) 
     (noir.response/redirect "/insufficientRights") 
     ~expr))) 

하지만 지금, 그것은에서 지역 주민을 매핑하는 데이터 맵 전달하는 방법을 분명하지 않다 : 위의 예와 같이 로컬로 게시물 : 얻을를 .

첫 번째 시도를 변경하지 않고 바로 수행하고 있습니까? 아니면 실제로 두 번째 접근 방식을 사용해야합니까? 내가하지 희망. 다른 옵션이 있습니까? 제발, 알려줘.

답변

4

첫 번째 해결책은 좋습니다. Rich가 말한 것은 평범한 구 맵을 사용하여 각 유형의 데이터에 대해 새로운 유형/클래스를 작성하는 대신 데이터를 전달하는 것입니다. 예 : 사용자 데이터를 나타내는 클래스를 만드는 대신 간단한지도를 사용하여 사용자 정보를 표현할 수 있습니다.

는 지금까지 두 번째 시도, 당신은 같은 매크로 맵 드 구조를 사용할 수에 관한 한 :

(defmacro defpage-with-user-level [{:keys [route data level sublevel granted-route]} expr] 
    `(defpage ~route ~data 
    (if-not (has-reqd-user-level? ~level ~sublevel ~granted-route) 
     (noir.response/redirect "/insufficientRights") 
     ~expr))) 

(defpage-with-user-level {:level :levelX 
          :sublevel :sublevelY 
          :granted-route "/grantedRoute" 
          :route [:post "/mysite"] 
          :data {:as input}} 
    (html 
    [:body [:h1 (str "Hello " (:name input) "!")]])) 
+0

대단히 감사합니다! 이것은 내가 알고 싶었던 바로 그 것이다. 따라서 제안 된 해결책에 충실해야합니까? 아니면 첫 시도를 사용해야합니까? 기본적으로 릭 (Rick)의 게시물과 관련하여 언급 한대로 페이지 데이터를지도로 둘러 쌉니다. –

+0

그건 그렇고, 그 남자는 릭이 아니에요;) – Ankur

+0

거대한 duh !! 죄송합니다 ... 고마워요. –

관련 문제