From e455387f9645e089f2f62d37ea2554dc8d9abf14 Mon Sep 17 00:00:00 2001 From: Simon Brooke Date: Tue, 1 Jul 2014 11:35:55 +0100 Subject: [PATCH] OK, at this stage it's just an empty LuminusWeb project... --- Procfile | 1 + README.md | 19 ++ project.clj | 32 +++ resources/public/css/screen.css | 6 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 35281 bytes .../fonts/glyphicons-halflings-regular.svg | 229 ++++++++++++++++++ .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 55079 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 41722 bytes resources/public/md/docs.md | 21 ++ resources/templates/about.html | 4 + resources/templates/base.html | 40 +++ resources/templates/home.html | 14 ++ src/mw_ui/handler.clj | 59 +++++ src/mw_ui/layout.clj | 24 ++ src/mw_ui/middleware.clj | 24 ++ src/mw_ui/repl.clj | 34 +++ src/mw_ui/routes/home.clj | 15 ++ src/mw_ui/util.clj | 10 + test/mw_ui/test/handler.clj | 15 ++ 19 files changed, 547 insertions(+) create mode 100644 Procfile create mode 100644 README.md create mode 100644 project.clj create mode 100644 resources/public/css/screen.css create mode 100644 resources/public/fonts/glyphicons-halflings-regular.eot create mode 100644 resources/public/fonts/glyphicons-halflings-regular.svg create mode 100644 resources/public/fonts/glyphicons-halflings-regular.ttf create mode 100644 resources/public/fonts/glyphicons-halflings-regular.woff create mode 100644 resources/public/md/docs.md create mode 100644 resources/templates/about.html create mode 100644 resources/templates/base.html create mode 100644 resources/templates/home.html create mode 100644 src/mw_ui/handler.clj create mode 100644 src/mw_ui/layout.clj create mode 100644 src/mw_ui/middleware.clj create mode 100644 src/mw_ui/repl.clj create mode 100644 src/mw_ui/routes/home.clj create mode 100644 src/mw_ui/util.clj create mode 100644 test/mw_ui/test/handler.clj diff --git a/Procfile b/Procfile new file mode 100644 index 0000000..a4bcedb --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: lein with-profile production trampoline ring server diff --git a/README.md b/README.md new file mode 100644 index 0000000..329710d --- /dev/null +++ b/README.md @@ -0,0 +1,19 @@ +# mw-ui + +FIXME + +## Prerequisites + +You will need [Leiningen][1] 2.0 or above installed. + +[1]: https://github.com/technomancy/leiningen + +## Running + +To start a web server for the application, run: + + lein ring server + +## License + +Copyright © 2014 FIXME diff --git a/project.clj b/project.clj new file mode 100644 index 0000000..b57ba24 --- /dev/null +++ b/project.clj @@ -0,0 +1,32 @@ +(defproject mw-ui "0.1.0-SNAPSHOT" + :description "FIXME: write description" + :url "http://example.com/FIXME" + :dependencies [[org.clojure/clojure "1.6.0"] + [mw-engine "0.1.0-SNAPSHOT"] + [lib-noir "0.8.4"] + [ring-server "0.3.1"] + [selmer "0.6.8"] + [com.taoensso/timbre "3.2.1"] + [com.taoensso/tower "2.0.2"] + [markdown-clj "0.9.44"] + [environ "0.5.0"] + [noir-exception "0.2.2"]] + + :repl-options {:init-ns mw-ui.repl} + :plugins [[lein-ring "0.8.10"] + [lein-environ "0.5.0"]] + :ring {:handler mw-ui.handler/app + :init mw-ui.handler/init + :destroy mw-ui.handler/destroy} + :profiles + {:uberjar {:aot :all} + :production {:ring {:open-browser? false + :stacktraces? false + :auto-reload? false}} + :dev {:dependencies [[ring-mock "0.1.5"] + [ring/ring-devel "1.3.0"] + [pjstadig/humane-test-output "0.6.0"]] + :injections [(require 'pjstadig.humane-test-output) + (pjstadig.humane-test-output/activate!)] + :env {:dev true}}} + :min-lein-version "2.0.0") \ No newline at end of file diff --git a/resources/public/css/screen.css b/resources/public/css/screen.css new file mode 100644 index 0000000..d759510 --- /dev/null +++ b/resources/public/css/screen.css @@ -0,0 +1,6 @@ +html, +body { + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + height: 100%; + padding-top: 40px; +} diff --git a/resources/public/fonts/glyphicons-halflings-regular.eot b/resources/public/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 0000000000000000000000000000000000000000..78b119f513a5730156a9f4a160435f652ef960b8 GIT binary patch literal 35281 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/public/fonts/glyphicons-halflings-regular.ttf b/resources/public/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ba41d0f12928fbbe271ffcad9318a9f84778b0cf GIT binary patch literal 55079 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 literal 0 HcmV?d00001 diff --git a/resources/public/fonts/glyphicons-halflings-regular.woff b/resources/public/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 0000000000000000000000000000000000000000..60dd28d27acb31c0c903e8e2d6b6aea4a894005a GIT binary patch literal 41722 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 literal 0 HcmV?d00001 diff --git a/resources/public/md/docs.md b/resources/public/md/docs.md new file mode 100644 index 0000000..a86e3fe --- /dev/null +++ b/resources/public/md/docs.md @@ -0,0 +1,21 @@ + +### Managing Your Middleware + +Two middleware functions are provided by default in the `mw-ui.middleware` namespace. + +* `log-request` - logs all requests using the debug level +* `template-error-page` - provides friendly formatting for Selmer errors in dev mode + +See the `:middleware` key of the `app` definition located in the `mw-ui.handler` namespace to manage the enabled middleware. + +### Here are some links to get started + +1. [HTML templating](http://www.luminusweb.net/docs/html_templating.md) +2. [Accessing the database](http://www.luminusweb.net/docs/database.md) +3. [Serving static resources](http://www.luminusweb.net/docs/static_resources.md) +4. [Setting response types](http://www.luminusweb.net/docs/responses.md) +5. [Defining routes](http://www.luminusweb.net/docs/routes.md) +6. [Adding middleware](http://www.luminusweb.net/docs/middleware.md) +7. [Sessions and cookies](http://www.luminusweb.net/docs/sessions_cookies.md) +8. [Security](http://www.luminusweb.net/docs/security.md) +9. [Deploying the application](http://www.luminusweb.net/docs/deployment.md) diff --git a/resources/templates/about.html b/resources/templates/about.html new file mode 100644 index 0000000..730fc45 --- /dev/null +++ b/resources/templates/about.html @@ -0,0 +1,4 @@ +{% extends "templates/base.html" %} +{% block content %} +

this is the story of mw-ui... work in progress

+{% endblock %} diff --git a/resources/templates/base.html b/resources/templates/base.html new file mode 100644 index 0000000..6a28d46 --- /dev/null +++ b/resources/templates/base.html @@ -0,0 +1,40 @@ + + + + + Welcome to mw-ui + + + + + +
+ {% block content %} + {% endblock %} +
+ + + + {% style "/css/screen.css" %} + + + + + + + + diff --git a/resources/templates/home.html b/resources/templates/home.html new file mode 100644 index 0000000..013b45d --- /dev/null +++ b/resources/templates/home.html @@ -0,0 +1,14 @@ +{% extends "templates/base.html" %} +{% block content %} +
+

Welcome to mw-ui

+

Time to start building your site!

+

Learn more »

+
+ +
+
+ {{content|safe}} +
+
+{% endblock %} diff --git a/src/mw_ui/handler.clj b/src/mw_ui/handler.clj new file mode 100644 index 0000000..7e614d1 --- /dev/null +++ b/src/mw_ui/handler.clj @@ -0,0 +1,59 @@ +(ns mw-ui.handler + (:require [compojure.core :refer [defroutes]] + [mw-ui.routes.home :refer [home-routes]] + [mw-ui.middleware :refer [load-middleware]] + [noir.response :refer [redirect]] + [noir.util.middleware :refer [app-handler]] + [compojure.route :as route] + [taoensso.timbre :as timbre] + [taoensso.timbre.appenders.rotor :as rotor] + [selmer.parser :as parser] + [environ.core :refer [env]])) + +(defroutes app-routes + (route/resources "/") + (route/not-found "Not Found")) + +(defn init + "init will be called once when + app is deployed as a servlet on + an app server such as Tomcat + put any initialization code here" + [] + (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/appender-fn}) + + (timbre/set-config! + [:shared-appender-config :rotor] + {:path "mw_ui.log" :max-size (* 512 1024) :backlog 10}) + + (if (env :dev) (parser/cache-off!)) + (timbre/info "mw-ui started successfully")) + +(defn destroy + "destroy will be called when your application + shuts down, put any clean up code here" + [] + (timbre/info "mw-ui is shutting down...")) + + + +(def app (app-handler + ;; add your application routes here + [home-routes app-routes] + ;; add custom middleware here + :middleware (load-middleware) + ;; timeout sessions after 30 minutes + :session-options {:timeout (* 60 30) + :timeout-response (redirect "/")} + ;; add access rules here + :access-rules [] + ;; serialize/deserialize the following data formats + ;; available formats: + ;; :json :json-kw :yaml :yaml-kw :edn :yaml-in-html + :formats [:json-kw :edn])) diff --git a/src/mw_ui/layout.clj b/src/mw_ui/layout.clj new file mode 100644 index 0000000..6a6c224 --- /dev/null +++ b/src/mw_ui/layout.clj @@ -0,0 +1,24 @@ +(ns mw-ui.layout + (:require [selmer.parser :as parser] + [clojure.string :as s] + [ring.util.response :refer [content-type response]] + [compojure.response :refer [Renderable]])) + +(def template-path "templates/") + +(deftype RenderableTemplate [template params] + Renderable + (render [this request] + (content-type + (->> (assoc params + (keyword (s/replace template #".html" "-selected")) "active" + :servlet-context + (if-let [context (:servlet-context request)] + (.getContextPath context))) + (parser/render-file (str template-path template)) + response) + "text/html; charset=utf-8"))) + +(defn render [template & [params]] + (RenderableTemplate. template params)) + diff --git a/src/mw_ui/middleware.clj b/src/mw_ui/middleware.clj new file mode 100644 index 0000000..3440b32 --- /dev/null +++ b/src/mw_ui/middleware.clj @@ -0,0 +1,24 @@ +(ns mw-ui.middleware + (:require [taoensso.timbre :as timbre] + [selmer.parser :as parser] + [environ.core :refer [env]] + [selmer.middleware :refer [wrap-error-page]] + [noir-exception.core + :refer [wrap-internal-error wrap-exceptions]])) + +(defn log-request [handler] + (fn [req] + (timbre/debug req) + (handler req))) + +(def development-middleware + [log-request + wrap-error-page + wrap-exceptions]) + +(def production-middleware + [#(wrap-internal-error % :log (fn [e] (timbre/error e)))]) + +(defn load-middleware [] + (concat (when (env :dev) development-middleware) + production-middleware)) diff --git a/src/mw_ui/repl.clj b/src/mw_ui/repl.clj new file mode 100644 index 0000000..d05c737 --- /dev/null +++ b/src/mw_ui/repl.clj @@ -0,0 +1,34 @@ +(ns mw-ui.repl + (:use mw-ui.handler + ring.server.standalone + [ring.middleware file-info file])) + +(defonce server (atom nil)) + +(defn get-handler [] + ;; #'app expands to (var app) so that when we reload our code, + ;; the server is forced to re-resolve the symbol in the var + ;; rather than having its own copy. When the root binding + ;; changes, the server picks it up without having to restart. + (-> #'app + ; Makes static assets in $PROJECT_DIR/resources/public/ available. + (wrap-file "resources") + ; Content-Type, Content-Length, and Last Modified headers for files in body + (wrap-file-info))) + +(defn start-server + "used for starting the server in development mode from REPL" + [& [port]] + (let [port (if port (Integer/parseInt port) 3000)] + (reset! server + (serve (get-handler) + {:port port + :init init + :auto-reload? true + :destroy destroy + :join? false})) + (println (str "You can view the site at http://localhost:" port)))) + +(defn stop-server [] + (.stop @server) + (reset! server nil)) diff --git a/src/mw_ui/routes/home.clj b/src/mw_ui/routes/home.clj new file mode 100644 index 0000000..e910032 --- /dev/null +++ b/src/mw_ui/routes/home.clj @@ -0,0 +1,15 @@ +(ns mw-ui.routes.home + (:use compojure.core) + (:require [mw-ui.layout :as layout] + [mw-ui.util :as util])) + +(defn home-page [] + (layout/render + "home.html" {:content (util/md->html "/md/docs.md")})) + +(defn about-page [] + (layout/render "about.html")) + +(defroutes home-routes + (GET "/" [] (home-page)) + (GET "/about" [] (about-page))) diff --git a/src/mw_ui/util.clj b/src/mw_ui/util.clj new file mode 100644 index 0000000..0a41630 --- /dev/null +++ b/src/mw_ui/util.clj @@ -0,0 +1,10 @@ +(ns mw-ui.util + (:require [noir.io :as io] + [markdown.core :as md])) + +(defn md->html + "reads a markdown file from public/md and returns an HTML string" + [filename] + (->> + (io/slurp-resource filename) + (md/md-to-html-string))) diff --git a/test/mw_ui/test/handler.clj b/test/mw_ui/test/handler.clj new file mode 100644 index 0000000..47e4862 --- /dev/null +++ b/test/mw_ui/test/handler.clj @@ -0,0 +1,15 @@ +(ns mw-ui.test.handler + (:use clojure.test + ring.mock.request + mw-ui.handler)) + +(deftest test-app + (testing "main route" + (let [response (app (request :get "/"))] + (is (= (:status response) 200)) + (is (= (:body response) + "\n \n Welcome to mw-ui\n \n \n \n
\n \n
\n \n \n \n\n\n\n")))) + + (testing "not-found route" + (let [response (app (request :get "/invalid"))] + (is (= (:status response) 404)))))