【问题标题】:troubleshooting clojure web-app: connecting html and css for heroku deploymentclojure web-app 疑难解答:连接 html 和 css 以进行 heroku 部署
【发布时间】:2014-02-13 17:32:44
【问题描述】:

我有两个文件,一个 html 和一个 css。我试图将它们变成一个 heroku 应用程序,甚至使用 lein 命令创建一个对 heroku 友好的骨架并将这两个文件插入,但无法让它为我的生活工作。关于如何协调视图与后端控件,有一些非常基本的东西我还不明白。 hello world 教程对我没有帮助,因为它们没有向我展示如何做不同的事情或解释我的 defroutes 功能需要改变什么,例如,为了实现这一点。简而言之,我的问题是:如何将这两个文件协调到一个 Clojure 项目中,以使 html 呈现为 webapp 的首页,然后将其部署到 heroku 上?

html:

<html>
    <head>
        <link rel="stylesheet" href="style.css" />
    </head>

    <body>
        <img id="sun" src="http://goo.gl/dEEssP">
        <div id='earth-orbit'>
            <img id="earth" src="http://goo.gl/o3YWu9">
        </div>
    </body>
</html>

“lein new heroku ...”项目中的web.clj 文件:

(ns solar_system.web
  (:require [compojure.core :refer [defroutes GET PUT POST DELETE ANY]]
            [compojure.handler :refer [site]]
            [compojure.route :as route]
            [clojure.java.io :as io]
            [ring.middleware.stacktrace :as trace]
            [ring.middleware.session :as session]
            [ring.middleware.session.cookie :as cookie]
            [ring.adapter.jetty :as jetty]
            [ring.middleware.basic-authentication :as basic]
            [cemerick.drawbridge :as drawbridge]
            [environ.core :refer [env]]))

(defn- authenticated? [user pass]
  ;; TODO: heroku config:add REPL_USER=[...] REPL_PASSWORD=[...]
  (= [user pass] [(env :repl-user false) (env :repl-password false)]))

(def ^:private drawbridge
  (-> (drawbridge/ring-handler)
      (session/wrap-session)
      (basic/wrap-basic-authentication authenticated?)))

(defroutes app
  (ANY "/repl" {:as req}
       (drawbridge req))
  (GET "/" []
       {:status 200
        :headers {"Content-Type" "text/plain"}
        :body (pr-str ["Hello" :from 'Heroku])})  ; <= Should I change this part here?
  (ANY "*" []
       (route/not-found (slurp (io/resource "404.html")))))

(defn wrap-error-page [handler]
  (fn [req]
    (try (handler req)
         (catch Exception e
           {:status 500
            :headers {"Content-Type" "text/html"}
            :body (slurp (io/resource "500.html"))}))))

(defn -main [& [port]]
  (let [port (Integer. (or port (env :port) 5000))
        ;; TODO: heroku config:add SESSION_SECRET=$RANDOM_16_CHARS
        store (cookie/cookie-store {:key (env :session-secret)})]
    (jetty/run-jetty (-> #'app
                         ((if (env :production)
                            wrap-error-page
                            trace/wrap-stacktrace))
                         (site {:session {:store store}}))
                     {:port port :join? false})))

;; For interactive development:
;; (.stop server)
;; (def server (-main)) 

project.clj 文件

(defproject solar_system "1.0.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://solar_system.herokuapp.com"
  :license {:name "FIXME: choose"
            :url "http://example.com/FIXME"}            
  :dependencies [[org.clojure/clojure "1.4.0"]
                 [compojure "1.1.1"]
                 [ring/ring-jetty-adapter "1.1.0"]
                 [ring/ring-devel "1.1.0"]
                 [ring-basic-authentication "1.0.1"]
                 [environ "0.2.1"]
                 [com.cemerick/drawbridge "0.0.6"]]
  :min-lein-version "2.0.0"
  :plugins [[environ/environ.lein "0.2.1"]]
  :hooks [environ.leiningen.hooks]
  :profiles {:production {:env {:production true}}})

呈现文本的典型处理程序代码示例:

(ns hello-world.core
(:use ring.adapter.jetty))

(defn app [req]
    {:status 200
    :headers {"Content-Type" "text/plain"}
    :body "Hello, world"}) ; <= Could I just change this part to slurp in
                           ;    the html file and stick it in a file in my 
                           ;    root directory to get a successful 'git push heroku master'?

【问题讨论】:

  • 您可能希望包含详细信息,例如您正在使用的堆栈以及您尝试过的内容。
  • 我是一个初学者,所以即使是“堆栈”这个词的确切含义我也不清楚。这与我在 project.clj 文件中使用的框架或库集不同吗?我尝试使用此处的教程 devcenter.heroku.com/articles/getting-started-with-clojure> 和终端中的“lein new heroku app-name”命令。我想知道管道是如何工作的,如果这有意义的话。如果您仍然不明白我使用的是什么堆栈,您能否为我推荐一个好的堆栈?
  • 这是您的技术堆栈,就像一叠纸。在这种情况下,您使用ring 库来定义您的路线。提供索引页面的方式有很多很多,了解您想要如何做的细节非常有帮助(尽管ring 几乎是标准方式)。如果你想在你的问题上更加模糊,并且想要知道从哪里开始做某事,你可能需要考虑在 freenode irc 上加入#clojure。
  • 哎呀,ring 是用于 http,我把它和 compojure 混淆了。您可能想查看compojure 来定义路由。
  • 重新阅读以上内容,您似乎已经在使用defroutes,这很重要,您可能想发布相关代码?

标签: html css web-applications heroku clojure


【解决方案1】:

修改你的代码:

(defroutes app
  (ANY "/repl" {:as req}
       (drawbridge req))
  (GET "/" []
       {:status 200
        :headers {"Content-Type" "text/html"} ; change content type
        :body (slurp "resources/public/my-file.html")}) ; wherever your file is
  (ANY "*" []
       (route/not-found (slurp (io/resource "404.html")))))

我会怎么写:

(defroutes app
  (ANY "/repl" {:as req} (drawbridge req))
  (GET "/" [] (slurp "resources/public/my-file.html")) ; wherever your file is
  (route/resources "/") ; special route for serving static files like css
                        ; default root directory is resources/public/
  (route/not-found (slurp (io/resource "404.html")))) ; IDK what io/resource does
                                                      ; you might not need it

【讨论】:

  • 我已经使用了你的建议并设法让它在本地主机上运行:(defroutes... :headers {"Content-Type" "text/html"} :body (slurp (io/resource "index.html"))}) 我现在有一个全新的问题,虽然 CSS 没有修改 html,但我要发布在一个新问题中。而且我确信在那之后我会发布另一篇关于为什么它不会部署在 heroku 上的文章。
  • (route/resources "/") 解决了我提供静态文件的问题。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-05
  • 1970-01-01
相关资源
最近更新 更多