整合到一起
我们将要把db添加到home中去。
(ns guestbook.routes.home
(:require [compojure.core :refer :all]
[guestbook.views.layout :as layout]
[hiccup.form :refer :all]
[guestbook.models.db :as db]))
接下来我们来修改一下show-guests
方法,让它来调用db/read-guests
:
(defn show-guests []
[:ul.guests
(for [{:keys [message name timestamp]} (db/read-guests)]
[:li
[:blockquote message]
[:p "-" [:cite name]]
[:time timestamp]])])
最后,我们修改save-mesage
方法,让它使用db/save-message
来代替将输入参数打印到控制台这一步:
(defn save-message [name message]
(cond
(empty? name)
(home name message "Some dummy forgot to leave a name")
(empty? message)
(home name message "Don't you have something to say?")
:else
(do
(db/save-message name message)
(home))))
现在,就可以去页面上刷新看看变换了。可以试着添加更多的消息进去,来测试一下它是否真的正常运行了。
这个时候你可能已经注意到了在我们的应用在显示时间的地方有一个小小的瑕疵,现在的时间就是一串毫秒数值,这个一点也称不上用户友好。那么我们就来加一个函数来处理这个问题吧。
我们使用java的一些类(JAVA Interop)来完成这个函数:创建一个SimpleDateFormat
的实例来格式化我们的时间戳:
(defn format-time [timestamp]
(-> "dd/MM/yyyy"
(java.text.SimpleDateFormat.) ;; 创建了 SimpleDateFormat 的实例
(.format timestamp)))
(defn show-guests []
[:ul.guests
(for [{:keys [message name timestamp]} (db/read-guests)]
[:li
[:blockquote message]
[:p "-" [:cite name]]
[:time (format-time timestamp)]])])
好了,现在去看时间肯定就正常了~。(这句是我加的)
收尾
现在我们把最后一件事情做完,就完成我们留言簿的所有工作了。现在的数据库创建是依靠我们在repl中的访问而创建的,如果要改成需要的时候创建,我们就需要往命名空间handler
中添加一点东西。
首先,先将db
的依赖添加进去:
(ns guestbook.handler
...
(:require ...
[guestbook.models.db :as db]))
然后,我们需要更新的是init
函数,使它能在需要的时候判断数据库是否存在,如果不存在就创建一个数据库。
(defn init []
(println "guestbook is starting")
(if-not (.exists (java.io.File. "./db.sq3"))
(db/create-guestbook-table)))
现在每当init
被调用,它都会去确保一遍数据库是否已经存在了。
我们都做了点什么?
前面的例子,让我们体会了一下开发Clojure的web应用是一个什么样的滋味。可能你已经意识到了,你只需要写很少的一点代码,程序就可以运行起来了,而且写的代码几乎都不是千篇一律的相同。
现在你应该已经对程序的结构了若指掌:每个主要的部分,以及他们是怎样进行相互间的配合。
当你回忆起来的时候,你应该还记得它有以下的几个命名空间:
命名空间guestbook.handler
,它负责的是引导和创建将客户端请求传递给服务器端进行处理的程序。
接下来是guestbook.routes.home
命名空间:这里包含了我们大部分的逻辑的使用,以及创建我们实际的工作流(workflow)的地方。如果你需要更多的工作流,你可以在guestbook.routes
下创建新的命名空间来完成这些:举个例子,比如你可以有一个命名空间叫做guestbook.routes.auth
用来处理用户的注册以及认证工作。
在应用中,每个在routes
下的命名空间应该都是一个包含自己的工作流程的封装。(Each namespace under routes will typically encapsulate a self-contained workflow in the application.)【看到workflow我就不知道怎么翻译了!天啊~来个大神救救我!!】 所有的从属于它的代码都应该可以在一个地方找到,并且相对于其它的路由来说应该是可以独立运行的。一个工作流可以进行是处理用户认证的,也可以是进行内容编辑,或者进行一些管理。
命名空间guestbook.views.layout
管理的是应用的布局,其中的代码都是用于生成普通的页面以及对页面的信息进行调整。通常情况下布局还将管理一些页面需要的诸如CSS和Javascript的静态文件,也会设置一些静态的页面元素,比如说header和footer。
最后,我们还有一个命名空间guestbook.models.db
。这个命名空间维护的是应用的数据模型。其中表的定义决定了数据库存储的数据类型。
当我们开始着手于大型应用开发的时候,这些东西也将保持不变。一个正常的Clojure应用的结构应该是易于理解和维护的。这对你的应用的生命周期来说也是一件好事:你将不必像往常在使用其它语言开发程序时候一样,来浏览一个项目复杂的层次结构。
在这里我们使用的是Light Table来开发我们的应用,虽然它简洁应用,但是在有些方面它还是有些力不从心,没有一些IDE提供的有用功能,诸如代码完成,代码结构调整等等。
在这一点上,你可以花时间去尝试一些其他的开发环境,比如Eclipse或者是Emac。本书的其余部分都会将Eclipse作为开发环境(译者:T^T 我好不容易弄好Light Table! 没有看后面,不知道是不是真的这样,后面我就继续滚回Intellij啦),但是无论你使用哪个编辑器,你都应该可以轻易的做好这些事情。
到时候你就会发现,我们在开发应用的时候会频繁的使用REPL。它不同于任何的IDE,它可以在你进行开发的时候更快速的执行代码以及返回结果。
在第一章中,我们创建好了自己的开发环境,概览了Clojure的web应用到底是怎样的一个组织结构。在下一章节中,我们将主要关注Clojure网络栈(web stack)的核心库上。你将会学习到关于请求/响应的生命周期,路由的定义,session的管理以及使用中间件(middleware)来提升核心请求处理的功能。
第一章结束啦,撒花撒花~
总体感觉翻译的不是那么的顺畅,真对不起自己的第二专业啊…
但是我也慢慢的找到了感觉,对于翻译有任何吐槽都直接说出来把~!
小弟明天就开始继续上班啦,但是翻译还会继续进行下去,毕竟这也是我想要学习的东西嘛。
最好,再次欢迎和我进行交流,提出建议~
email: samuel.m.shen#gmail.com
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。