ivaneye.com

Luminus手册-升级

Upgrading to the Latest Version

不幸的是,框架无法自动从老版本升级到新版本。主要原因是新版本的依赖可能会有接口方面的修改,导致老代码无法正常运行。

最好的方法是使用lein-ancient插件来保持你的依赖包时刻为最新。这将会帮你很容易的发现哪些插件有了新的版本。

Luminus手册-实用库

Luminus的目标是从细粒度来方便你开发web应用。所以它默认包含了很多库包。

包括lib-noir提供一般工具,Selmer/Hiccup提供HTML模板,Timbre提供日志功能, Tower提供国际化等等其他包。

当然,还有很多的包能给web开发带来便利。

具体请见此处

Luminus手册-部署

Running Standalone

要创建一个可独立运行的包,只需要运行如下的命令:

lein ring uberjar

打包完成的jar会出现在target目录下。可以通过下面的命令运行:

java -jar myapp-0.1.0-SNAPSHOT-standalone.jar

独立可运行的程序可以使用Jetty来运行。如果要设置端口号,你需要设置\$PORT 环境变量:

export PORT=8080
java -jar target/myapp1-0.1.0-SNAPSHOT-standalone.jar

Delpoying on Immutant

如果想部署应用到Immutant,请执行如下命令:

lein immutant deploy

更多信息请访问官网

Deploying to Tomcat

如果想打包应用为war包:

lein ring uberwar

然后只需要将打好的包拷贝到tomcat的webapps目录下即可:

cp target/myapp-0.1.0-SNAPSHOT-standalone.war ~/tomcat/webapps/myapp.war

Luminus手册-国际化

Internationalization

Luminius模板包含了Tower依赖,Tower提供了函数式的国际化和翻译。

首先,我们需要创建一个字典map:

(def tconfig
  {:fallback-locale :en-US
   :dictionary
   {:en-US   {:page {:title "Here is a title"
                     :content "Time to start building your site."}
              :missing  "<Missing translation: [%1$s %2$s %3$s]>"}
    :fr-FR {:page {:title "Voici un titre"
                   :content "Il est temps de commencer votre site."}}
    }})

然后添加Tower中间件来包装我们的配置:

(def app
 (app-handler
   [routes]
   :middleware
   [#(taoensso.tower.ring/wrap-tower-middleware % {:tconfig tconfig})]))

中间件将会通过accept-language头来确定相应的语言。中间件将会添加两个key到请求中。地一个key是:t,它的值是翻译函数。第二个key是:locale,它的值是中间件提供的语言类型。

你可以提供一个自定义的locale-selector函数给中间件。

(defn my-selector [req]
  (when (= (:remote-addr req) "127.0.0.1") :en))
(def app
  (app-handler
    [routes]
    :middleware
    [#(wrap-tower-middleware % {:tconfig tconfig
                                :locale-selector my-selector})]))

Luminus手册-日志

Logging

Luminus模板中包括TimbreRotor

日志通过在handler/init函数中进行如下的设置进行初始化:

  (timbre/set-config!
    [:appenders :rotor]
    {:min-level :info
     :enabled? true
     :async? false ; should be always false for rotor
     :max-message-per-msecs nil
     :fn rotor/append})
  (timbre/set-config!
    [:shared-appender-config :rotor]
    {:path ".log" :max-size 10000 :backlog 10})

Timbre可以记录Clojure的所有日志.

(ns example
 (:use [taoensso.timbre :only [trace debug info warn error fatal]]))
(info "Hello")
=>2012-Dec-24 09:03:09 -0500 Helios.local INFO [timbretest] - Hello
(info {:user {:id "Anonymous"}})
=>2012-Dec-24 09:02:44 -0500 Helios.local INFO [timbretest] - {:user {:id "Anonymous"}}

更多信息请见Github

Luminus手册-数据迁移

Migrations

默认情况下Luminus使用Ragtime来进行数据迁移。当你在创建Luminus项目时添加了+mysql或+postgres选项时,Ragtime会自动被添加进来。

Migrations with Ragtime

Ragtime通过Leiningen插件来执行。此插件需要配置project.clj的:plugins中。

:plugins [... [ragtime/ragtime.lein "0.3.4"]]

实际的迁移动作是由ragtime.sql.files这个适配器来执行。此适配器需要配置在依赖列表中,同时配置相关数据库配置。

:dependencies [... [ragtime/ragtime.sql.files "0.3.4"]]
:ragtime {:migrations ragtime.sql.files/migrations
          :database "jdbc:mysql://localhost:3306/example_db?user=root"}

ragtime.sql.files适配器会从项目根目录下的指定目录查找sql脚本。我们只需要将脚本添加到对应目录下即可。

脚本按字母顺序排序。我们来创建两个脚本。

migrations/2014-13-57-30-create-tables.up.sql
CREATE TABLE users (id INT, name VARCHAR(25));
migrations/2014-13-57-30-create-tables.down.sql
DROP TABLE users;

通过如下命令执行:

lein ragtime migrate

通过如下命令回滚:

lein ragtime rollback

Luminus手册-访问数据库

Configuring the Database

当你使用数据库参数来创建Luminus工程时,比如+postgress,那么Luminus会使用Korma来处理数据库操作.

Korma是一个基于Clojure的数据库操作DSL。Korma提供了一套简单的接口,方便你来处理复杂的数据。

给一个现有的项目添加数据库支持,非常的简单。首先,你需要在project.clj文件中添加Korma依赖。

[korma "0.4.0"]

另外还需要相应数据库的驱动,所以你还需要在project.clj中添加相关的数据库驱动。比如说,你要连接PostreSQL数据库,你需要添加如下的依赖.

[postgresql/postgresql "9.3-1102-jdbc41"]

添加完依赖后,你可以创建一个新的namespace来管理你的model,这个namespace建议叫db.core。你需要在里面引入korma.db。

(ns myapp.db.core
  (:use korma.core
        [korma.db :only (defdb)]))

Setting up the database connection

配置完依赖后,我们要做的事情就是定义数据库连接。我们只需要提供一个包含连接信息的map。

(def db-spec {:subprotocol "postgresql"
         :subname "//localhost/my_website"
         :user "admin"
         :password "admin"})

或者也可以配置服务器提供的JNDI名称来创建连接。

(def db-spec {:name "jdbc/myDatasource"})