4

I'm new to clojure and compojure and trying out the compojure along with ring to create a basic web application.

here is my handler.clj

(ns gitrepos.handler
  (:require [compojure.core :refer :all]
            [compojure.route :as route]
            [ring.util.response :as resp]
            [ring.middleware.defaults :refer [wrap-defaults site-defaults]]))

(defroutes app-routes
  (GET "/" [] (resp/file-response "index.html" {:root "public"}))
  (route/not-found "Not Found"))

(def app
  (wrap-defaults app-routes site-defaults))

i have this index.html file under /resources/public but the application is not rendering this html file. Instead getting Not found

I have searched a lot it, even this Serve index.html at / by default in Compojure does not seems to resolve the issue.

Not sure what am i missing here.

Community
  • 1
  • 1
navyad
  • 3,752
  • 7
  • 47
  • 88

3 Answers3

1

Naveen

Here is a snippet of my own that seems to work. In comparison with yours, you do not have a resource path in defroutes:

(defroutes default-routes
  (route/resources "public")
  (route/not-found
   "<h1>Resource you are looking for is not found</h1>"))

(defroutes app
  (wrap-defaults in-site-routes site-defaults)
  (wrap-defaults test-site-routes site-defaults)
  (wrap-restful-format api-routes)
  (wrap-defaults default-routes site-defaults))
Frank C.
  • 7,758
  • 4
  • 35
  • 45
1

You don't need specify your routing for serving files from resoures/public using file-response at this directory will be served thanks to site-defaults. The only part you are missing is mapping / path to /index.html which can be done with the code you mentioned from another question. So the solution would be:

(defn wrap-dir-index [handler]
  (fn [req]
    (handler
      (update
        req
        :uri
        #(if (= "/" %) "/index.html" %)))))

(defroutes app-routes
  (route/not-found "Not Found"))

(def app
  (-> app-routes
    (wrap-defaults site-defaults)
    (wrap-dir-index)

On a side note, you should prefer using ring.util.response/resource-response as it serves files from classpath and will work also when you package you app into a jar file. file-response uses file system to locate files and won't work from inside jar file.

Piotrek Bzdyl
  • 12,965
  • 1
  • 31
  • 49
  • Could the downvoter explain what is wrong with my answer? I would be more than happy to fix it or delete it if I know why it's wrong. – Piotrek Bzdyl Mar 07 '16 at 11:43
1

Maybe you want to try use some template library, such as Selmer. So you can do something like this:

(defroutes myapp
  (GET "/hello/" []
    (render-string (read-template "templates/hello.html"))))

Or passing some value:

(defroutes myapp
  (GET "/hello/" [name]
    (render-string (read-template "templates/hello.html") {name: "Jhon"})))

And, as @piotrek-Bzdyl said:

(GET  "/" [] (resource-response "index.html" {:root "public"}))
Édipo Féderle
  • 4,169
  • 5
  • 31
  • 35