Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 3b51abd
Showing
6 changed files
with
187 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
/target | ||
/classes | ||
/checkouts | ||
pom.xml | ||
pom.xml.asc | ||
*.jar | ||
*.class | ||
/.lein-* | ||
/.nrepl-port |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# stasis | ||
|
||
A Clojure library of tools for developing static web sites. | ||
|
||
## Install | ||
|
||
Add `[stasis "0.1.0"]` to `:dependencies` in your `project.clj`. | ||
|
||
## Another static site framework? Why? | ||
|
||
I didn't want a static site *framework*, I wanted a *library*. If | ||
you want a framework that makes it really quick and easy to create a | ||
blog, you should take a look at these: | ||
|
||
- https://github.com/liquidz/misaki | ||
- http://algernon.github.io/madness/ | ||
- http://nakkaya.com/static.html | ||
- http://samrat.me/ecstatic/ | ||
- https://github.com/thegeez/clj-static-blog | ||
|
||
They generally come with a folder where you put your blog posts in | ||
some template language, and a set of configuration options about how | ||
to set up your blog. | ||
|
||
This is not that. This is just a set of functions that are pretty | ||
useful when creating static web sites. | ||
|
||
## Usage | ||
|
||
|
||
|
||
## License | ||
|
||
Copyright © 2014 Magnar Sveen | ||
|
||
Distributed under the Eclipse Public License either version 1.0 or (at | ||
your option) any later version. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
(ns user | ||
(:require [clojure.java.io :as io] | ||
[clojure.string :as str] | ||
[clojure.set :as set] | ||
[clojure.pprint :refer (pprint pp)] | ||
[clojure.repl :refer :all] | ||
[print.foo :refer :all])) | ||
|
||
(defmacro dump-locals [] | ||
`(clojure.pprint/pprint | ||
~(into {} (map (fn [l] [`'~l l]) (reverse (keys &env)))))) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
(defproject stasis "0.1.0" | ||
:description "A library of tools for creating static websites." | ||
:license {:name "Eclipse Public License" | ||
:url "http://www.eclipse.org/legal/epl-v10.html"} | ||
:dependencies [[org.clojure/clojure "1.5.1"]] | ||
:profiles {:dev {:dependencies [[midje "1.6.0"] | ||
[print-foo "0.4.2"] | ||
[test-with-files "0.1.0"]] | ||
:plugins [[lein-midje "3.1.3"]] | ||
:source-paths ["dev"]}}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
(ns stasis.core | ||
(:require [clojure.java.io :as io])) | ||
|
||
(defn- normalize-uri [#^String uri] | ||
(cond | ||
(.endsWith uri ".html") uri | ||
(.endsWith uri "/") (str uri "index.html") | ||
:else (str uri "/index.html"))) | ||
|
||
(defn- normalize-page-uris [pages] | ||
(zipmap (map normalize-uri (keys pages)) | ||
(vals pages))) | ||
|
||
(defn- serve-page [page request] | ||
{:status 200 | ||
:body (page request) | ||
:headers {"Content-Type" "text/html"}}) | ||
|
||
(def not-found | ||
{:status 404 | ||
:body "<h1>Page not found</h1>" | ||
:headers {"Content-Type" "text/html"}}) | ||
|
||
(defn serve-pages [pages] | ||
(let [pages (normalize-page-uris pages)] | ||
(fn [request] | ||
(let [uri (normalize-uri (:uri request))] | ||
(if-let [page (pages uri)] | ||
(serve-page page (assoc request :uri uri)) | ||
not-found))))) | ||
|
||
(defn- create-folders [path] | ||
(.mkdirs (.getParentFile (io/file path)))) | ||
|
||
(defn export-pages [pages target-dir options] | ||
(doseq [[uri get-page] pages] | ||
(let [uri (normalize-uri uri) | ||
path (str target-dir uri)] | ||
(create-folders path) | ||
(spit path (get-page (assoc options :uri uri)))))) | ||
|
||
(defn- delete-file-recursively [f] | ||
(let [f (io/file f)] | ||
(if (.isDirectory f) | ||
(doseq [child (.listFiles f)] | ||
(delete-file-recursively child))) | ||
(io/delete-file f))) | ||
|
||
(defn delete-directory! [f] | ||
(if (.isDirectory (io/file f)) | ||
(delete-file-recursively f) | ||
(throw (Exception. (str f " is not a directory."))))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
(ns stasis.core-test | ||
(:require [stasis.core :refer :all] | ||
[midje.sweet :refer :all] | ||
[clojure.java.io :as io] | ||
[test-with-files.core :refer [with-tmp-dir tmp-dir]])) | ||
|
||
(fact | ||
"Stasis creates a Ring handler to serve your pages." | ||
|
||
(let [app (serve-pages {"/page.html" (fn [req] "The page contents")})] | ||
|
||
(fact (app {:uri "/page.html"}) | ||
=> {:status 200 | ||
:body "The page contents" | ||
:headers {"Content-Type" "text/html"}}) | ||
|
||
(fact (app {:uri "/missing.html"}) | ||
=> {:status 404 | ||
:body "<h1>Page not found</h1>" | ||
:headers {"Content-Type" "text/html"}}))) | ||
(fact | ||
"If you use paths without .html, it serves them as directories with | ||
an index.html." | ||
|
||
(let [app (serve-pages {"/page/" (fn [req] (str "I'm serving " (:uri req)))})] | ||
|
||
(fact (:body (app {:uri "/page/index.html"})) => "I'm serving /page/index.html") | ||
(fact (:body (app {:uri "/page/"})) => "I'm serving /page/index.html") | ||
(fact (:body (app {:uri "/page"})) => "I'm serving /page/index.html"))) | ||
|
||
(fact | ||
"Stasis exports pages to your directory of choice." | ||
|
||
(with-tmp-dir | ||
(export-pages {"/page/index.html" (fn [req] "The contents")} | ||
tmp-dir {}) | ||
(slurp (str tmp-dir "/page/index.html")) => "The contents")) | ||
|
||
(fact | ||
"Stasis adds the :uri the 'request' for exported pages too." | ||
|
||
(with-tmp-dir | ||
(export-pages {"/page" (fn [req] (str "I'm serving " (:uri req)))} | ||
tmp-dir {}) | ||
(slurp (str tmp-dir "/page/index.html")) => "I'm serving /page/index.html")) | ||
|
||
(fact | ||
"You can add more information to the 'request' if you want. Like | ||
configuration options, or optimus assets." | ||
|
||
(with-tmp-dir | ||
(export-pages {"/page" (fn [req] (str "I got " (:conf req)))} | ||
tmp-dir {:conf "served"}) | ||
(slurp (str tmp-dir "/page/index.html")) => "I got served")) | ||
|
||
(fact | ||
"It's really easy emptying an entire folder of files. Be careful." | ||
|
||
(with-tmp-dir | ||
(export-pages {"/folder/page.html" (fn [_] "Contents")} tmp-dir {}) | ||
|
||
(io/as-file (str tmp-dir "/folder/page.html")) => #(.exists %) | ||
|
||
(delete-directory! (str tmp-dir "/folder")) | ||
|
||
(io/as-file (str tmp-dir "/folder/page.html")) => #(not (.exists %)) | ||
(io/as-file (str tmp-dir "/folder")) => #(not (.exists %)))) |