【发布时间】:2013-03-16 08:07:52
【问题描述】:
我一直在 Web 项目中使用 noir,我想根据用户对 defpage 宏定义的所有可能路由的访问级别(和子级别)来限制对用户的访问。所以最初我有
(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)))
但是现在,还不清楚如何将映射本地的数据映射从 :get 和 :post 传递到上面的示例中的本地。
我的第一次尝试没有被篡改,还是我真的需要使用第二种方法?我希望不是。还有其他选择吗?请告诉我。
【问题讨论】:
标签: map macros clojure noir destructuring