2013-03-16 60 views
3

我一直在一个web项目中使用noir,并且根据他们的访问级别(以及sublevel)来定义由defpage宏定义的所有可能的路由,我想到了限制对用户的访问。所以,我原本在Clojure中,是否有一种在宏定义中解构地图的习惯方式?

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

然后,我想这将摆脱样板代码:

(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))) 

最后,我们使用它,如下所示:

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

但在本提到由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))) 

但现在,目前还不清楚如何从映射当地人的数据映射传递:获取和张贴到本地,如上面的例子。

我是否正确地离开我的第一次尝试untampered或我真的需要使用第二种方法?我希望不是。有没有其他的选择?请告诉我。

回答

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

非常感谢您!这正是我想知道的。那么,我应该坚持你提出的解决方案,还是应该使用我的第一次尝试?基本上,我们将页面数据作为地图加入,就像您在里克的帖子中提到的那样,所以我认为您的更正确。 – 2013-03-16 16:17:23

+0

顺便说一句,这家伙是富里克里克;) – Ankur 2013-03-16 16:26:47

+0

巨大的呃!对不起......谢谢。 – 2013-03-16 16:51:06

相关问题