commit
56c3e433e9
20 changed files with 389 additions and 0 deletions
@ -0,0 +1,39 @@ |
||||
(defproject |
||||
ldview |
||||
"0.1.0-SNAPSHOT" |
||||
:dependencies |
||||
[[org.clojure/clojure "1.5.1"] |
||||
[lib-noir "0.7.0"] |
||||
[compojure "1.1.5"] |
||||
[ring-server "0.3.0"] |
||||
[selmer "0.4.2"] |
||||
[com.taoensso/timbre "2.6.2"] |
||||
[com.postspectacular/rotor "0.1.0"] |
||||
[com.taoensso/tower "1.7.1"] |
||||
[markdown-clj "0.9.32"] |
||||
[com.h2database/h2 "1.3.172"] |
||||
[korma "0.3.0-RC5"] |
||||
[log4j |
||||
"1.2.17" |
||||
:exclusions |
||||
[javax.mail/mail |
||||
javax.jms/jms |
||||
com.sun.jdmk/jmxtools |
||||
com.sun.jmx/jmxri]]] |
||||
:ring |
||||
{:handler ldview.handler/war-handler, |
||||
:init ldview.handler/init, |
||||
:destroy ldview.handler/destroy} |
||||
:profiles |
||||
{:production |
||||
{:ring |
||||
{:open-browser? false, :stacktraces? false, :auto-reload? false}}, |
||||
:dev |
||||
{:dependencies [[ring-mock "0.1.5"] [ring/ring-devel "1.2.0"]]}} |
||||
:url |
||||
"http://example.com/FIXME" |
||||
:plugins |
||||
[[lein-ring "0.8.7"]] |
||||
:description |
||||
"FIXME: write description" |
||||
:min-lein-version "2.0.0") |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,47 @@ |
||||
html, |
||||
body { |
||||
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; |
||||
height: 100%; |
||||
} |
||||
|
||||
.error { |
||||
color: red; |
||||
} |
||||
|
||||
/*footer based on http://twitter.github.com/bootstrap/examples/sticky-footer-navbar.html */ |
||||
/* Wrapper for page content to push down footer */ |
||||
#wrap { |
||||
min-height: 100%; |
||||
height: auto !important; |
||||
height: 100%; |
||||
/* Negative indent footer by it's height */ |
||||
margin: 0 auto -60px; |
||||
} |
||||
|
||||
/* Set the fixed height of the footer here */ |
||||
#push, |
||||
#footer { |
||||
height: 60px; |
||||
} |
||||
|
||||
#footer { |
||||
background-color: #f5f5f5; |
||||
} |
||||
|
||||
/* Lastly, apply responsive CSS fixes as necessary */ |
||||
@media (max-width: 767px) { |
||||
#footer { |
||||
margin-left: -20px; |
||||
margin-right: -20px; |
||||
padding-left: 20px; |
||||
padding-right: 20px; |
||||
} |
||||
} |
||||
|
||||
#wrap > .container, |
||||
#wrap > .container-fluid{ |
||||
padding-top: 60px; |
||||
} |
||||
.container .footer-text { |
||||
margin: 20px 0; |
||||
} |
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
@ -0,0 +1,11 @@ |
||||
### 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) |
@ -0,0 +1,51 @@ |
||||
(ns ldview.handler |
||||
(:require [compojure.core :refer [defroutes]] |
||||
[ldview.routes.home :refer [home-routes]] |
||||
[noir.util.middleware :as middleware] |
||||
[compojure.route :as route] |
||||
[taoensso.timbre :as timbre] |
||||
[com.postspectacular.rotor :as rotor])) |
||||
|
||||
(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/append}) |
||||
|
||||
(timbre/set-config! |
||||
[:shared-appender-config :rotor] |
||||
{:path "ldview.log" :max-size (* 512 1024) :backlog 10}) |
||||
|
||||
(timbre/info "ldview started successfully")) |
||||
|
||||
(defn destroy |
||||
"destroy will be called when your application |
||||
shuts down, put any clean up code here" |
||||
[] |
||||
(timbre/info "ldview is shutting down...")) |
||||
|
||||
(def app (middleware/app-handler |
||||
;; add your application routes here |
||||
[home-routes app-routes] |
||||
;; add custom middleware here |
||||
:middleware [] |
||||
;; 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])) |
||||
|
||||
(def war-handler (middleware/war-handler app)) |
@ -0,0 +1,24 @@ |
||||
(ns ldview.models.db |
||||
(:use korma.core |
||||
[korma.db :only (defdb)]) |
||||
(:require [ldview.models.schema :as schema])) |
||||
|
||||
(defdb db schema/db-spec) |
||||
|
||||
(defentity users) |
||||
|
||||
(defn create-user [user] |
||||
(insert users |
||||
(values user))) |
||||
|
||||
(defn update-user [id first-name last-name email] |
||||
(update users |
||||
(set-fields {:first_name first-name |
||||
:last_name last-name |
||||
:email email}) |
||||
(where {:id id}))) |
||||
|
||||
(defn get-user [id] |
||||
(first (select users |
||||
(where {:id id}) |
||||
(limit 1)))) |
@ -0,0 +1,36 @@ |
||||
(ns ldview.models.schema |
||||
(:require [clojure.java.jdbc :as sql] |
||||
[noir.io :as io])) |
||||
|
||||
(def db-store "site.db") |
||||
|
||||
(def db-spec {:classname "org.h2.Driver" |
||||
:subprotocol "h2" |
||||
:subname (str (io/resource-path) db-store) |
||||
:user "sa" |
||||
:password "" |
||||
:naming {:keys clojure.string/lower-case |
||||
:fields clojure.string/upper-case}}) |
||||
(defn initialized? |
||||
"checks to see if the database schema is present" |
||||
[] |
||||
(.exists (new java.io.File (str (io/resource-path) db-store ".h2.db")))) |
||||
|
||||
(defn create-users-table |
||||
[] |
||||
(sql/with-connection db-spec |
||||
(sql/create-table |
||||
:users |
||||
[:id "varchar(20) PRIMARY KEY"] |
||||
[:first_name "varchar(30)"] |
||||
[:last_name "varchar(30)"] |
||||
[:email "varchar(30)"] |
||||
[:admin :boolean] |
||||
[:last_login :time] |
||||
[:is_active :boolean] |
||||
[:pass "varchar(100)"]))) |
||||
|
||||
(defn create-tables |
||||
"creates the database tables used by the application" |
||||
[] |
||||
(create-users-table)) |
@ -0,0 +1,34 @@ |
||||
(ns ldview.repl |
||||
(:use ldview.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) 8080)] |
||||
(reset! server |
||||
(serve (get-handler) |
||||
{:port port |
||||
:init init |
||||
:auto-reload? true |
||||
:destroy destroy |
||||
:join? true})) |
||||
(println (str "You can view the site at http://localhost:" port)))) |
||||
|
||||
(defn stop-server [] |
||||
(.stop @server) |
||||
(reset! server nil)) |
@ -0,0 +1,15 @@ |
||||
(ns ldview.routes.home |
||||
(:use compojure.core) |
||||
(:require [ldview.views.layout :as layout] |
||||
[ldview.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))) |
@ -0,0 +1,10 @@ |
||||
(ns ldview.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))) |
@ -0,0 +1,19 @@ |
||||
(ns ldview.views.layout |
||||
(:require [selmer.parser :as parser] |
||||
[ring.util.response :refer [content-type response]]) |
||||
(:import compojure.response.Renderable)) |
||||
|
||||
(def template-path "ldview/views/templates/") |
||||
|
||||
(deftype RenderableTemplate [template params] |
||||
Renderable |
||||
(render [this request] |
||||
(content-type |
||||
(->> (assoc params :servlet-context (:context request)) |
||||
(parser/render-file (str template-path template)) |
||||
response) |
||||
"text/html; charset=utf-8"))) |
||||
|
||||
(defn render [template & [params]] |
||||
(RenderableTemplate. template params)) |
||||
|
@ -0,0 +1,10 @@ |
||||
|
||||
{% extends "ldview/views/templates/base.html" %} |
||||
|
||||
|
||||
|
||||
{% block content %} |
||||
|
||||
<p>this is the story of ldview... work in progress</p> |
||||
|
||||
{% endblock %} |
@ -0,0 +1,38 @@ |
||||
<!DOCTYPE html PUBLIC ""> |
||||
<html> |
||||
<head> |
||||
<META http-equiv="Content-Type" content="text/html; charset=UTF-8"> |
||||
<title>Welcome to ldview</title> |
||||
<link href="{{servlet-context}}/css/bootstrap.min.css" rel="stylesheet" type="text/css"> |
||||
<link href="{{servlet-context}}/css/bootstrap-responsive.min.css" rel="stylesheet" type="text/css"> |
||||
<link href="{{servlet-context}}/css/screen.css" rel="stylesheet" type="text/css"> |
||||
<script type="text/javascript"> var context = "{{servlet-context}}"; </script><script src="//code.jquery.com/jquery-1.10.1.min.js" type="text/javascript"></script><script src="{{servlet-context}}/js/bootstrap.min.js" type="text/javascript"></script> |
||||
</head> |
||||
<body> |
||||
<div id="wrap"> |
||||
<div class="navbar navbar-fixed-top navbar-inverse"> |
||||
<div class="navbar-inner"> |
||||
<ul class="nav"> |
||||
<li> |
||||
<a href="{{servlet-context}}/">Home</a> |
||||
</li> |
||||
<li> |
||||
<a href="{{servlet-context}}/about">About</a> |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
<div class="container"> |
||||
{% block content %} |
||||
|
||||
{% endblock %} |
||||
</div> |
||||
<div id="push"></div> |
||||
</div> |
||||
<div id="footer"> |
||||
<div class="container"> |
||||
<p class="muted footer-text">Footer content.</p> |
||||
</div> |
||||
</div> |
||||
</body> |
||||
</html> |
@ -0,0 +1,23 @@ |
||||
|
||||
{% extends "ldview/views/templates/base.html" %} |
||||
|
||||
|
||||
|
||||
{% block content %} |
||||
|
||||
|
||||
<div class="hero-unit"> |
||||
<h1>Welcome to ldview</h1> |
||||
<p>Time to start building your site!</p> |
||||
<p><a class="btn btn-primary btn-large" href="http://luminusweb.net">Learn more »</a></p> |
||||
</div> |
||||
|
||||
<div class="row-fluid"> |
||||
<div class="span8"> |
||||
{{content|safe}} |
||||
</div> |
||||
</div> |
||||
|
||||
|
||||
{% endblock %} |
||||
|
@ -0,0 +1,7 @@ |
||||
<?xml version="1.0" encoding="UTF-8" ?> |
||||
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> |
||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> |
||||
<logger name="com.mchange"> |
||||
<level value="WARN"/> |
||||
</logger> |
||||
</log4j:configuration> |
Loading…
Reference in new issue