从列表创建 Compojure 路由
我最近刚刚开始使用 Compojure,并且有一个小型的基本网络应用程序。对于我的 HTML 模板,我使用 Enlive,并且我有一个包含所有简单静态页面的命名空间。这些页面的 defroute 调用如下所示:
(defroutes public-routes
(GET "/" []
(info/index-template))
(GET "/about" []
(info/about-template))
(GET "/contact" []
(info/contact-template)))
实际上我还有更多的页面,但这应该可以让我了解我正在做什么。
现在,我想,这实际上只是我的一堆重复,所以我想我会尝试以下操作:
(defroutes info-routes
(map #(GET (str "/" %) [] (ns-resolve 'webapp.pages.info
(symbol (str % "-template"))))
'("about" "contact")))
当然,这不起作用,因为映射返回一个惰性序列而不是函数体(?) 。 有人知道我需要做什么才能让这个想法发挥作用吗?
或者我应该使用完全不同的方法来减少重复?
I've just been playing with Compojure recently, and I've got a small basic webapp. For my HTML templates I'm using Enlive, and I've got a namespace that holds all the simple, static pages. The defroute call for these pages looks like this:
(defroutes public-routes
(GET "/" []
(info/index-template))
(GET "/about" []
(info/about-template))
(GET "/contact" []
(info/contact-template)))
I've actually got a few more than that, but that should give the idea of what I'm doing.
Now, I thought, that's really just bunch of repetition on my part, so I thought I would try the following:
(defroutes info-routes
(map #(GET (str "/" %) [] (ns-resolve 'webapp.pages.info
(symbol (str % "-template"))))
'("about" "contact")))
Of course, this doesn't work, as the map is returning a lazy sequence and not a body (?) of functions.
Does someone know what I need to do to get this idea to work?
Or should I be using a completely different approach to cut down on repeating myself?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您始终可以使用 defroutes 使用的
routes
函数:但这仍然很无聊,让我们给它加点趣味! ;-)
使用此代码,
templates-for
函数将在给定的命名空间中查找以“-template”结尾的任何函数,并用它们编写适当的路由。看看我没有使用任何宏,而是使用了大量的组合。You can always use the
routes
function which is used by defroutes:But that's still quite boring, let's spice it up! ;-)
With this code, the
templates-for
function will look for any functions finishing with "-template" in the namespaces given and write the appropriate route with them. Look how I'm not using any macro, but plenty of composition.defroutes
是一个宏 所以不幸的是你无法将它传递给像map这样的函数。您需要编写一个宏来扩展为对 defroutes 的调用。或者查看它扩展成的函数并直接调用它们。在 defroutes 调用中创建路由列表是行不通的,这样
会扩展为路由列表:
如果
defroutes
是一个普通函数,您可以使用apply
解决这个问题因为 defroutes 是一个宏,所以在 apply 运行之前它就已经完全完成了,并且结果没有多大意义。您确实无法将宏组合为函数。宏不是 clojure(或我所知道的任何 lisp)中的一等公民
当一些 Clojurian 人(通常不是我)说“宏是邪恶的”时,他们经常会想到这样的情况:当你试图编写某个东西却无法编写它时,你会遇到这样一个事实:某个东西是宏。
解决方案是不使用defroutes宏并直接调用routes函数。
defroutes
is a macro so unfortunately you wont be able to pass it to a function like map. You would need to write a macro that expanded into a call to defroutes. or look at the functions that it expands into and call them directly.It wont work to create a list of routes within the call to defroutes like this
would expand into a list of routes:
if
defroutes
where a normal function you would solve this withapply
because
defroutes
is a macro it is completely finished before apply could run and the results would not make a lot of sense. You really can't compose macroes as functions. macroes are not first class citizens in clojure (or any lisp i know of)When some Clojurians (not usually me) say "Macroes are evil" they often think about situations like this where you run into the fact that something is a macro when you try to compose it and can't.
the solution is to not use the defroutes macro and call the routes function directly.