diff --git a/src/clj/shapey_shifty/context/core.clj b/src/clj/shapey_shifty/context/core.clj
new file mode 100644
index 0000000..01079ac
--- /dev/null
+++ b/src/clj/shapey_shifty/context/core.clj
@@ -0,0 +1,9 @@
+(ns shapey-shifty.context.core
+ (:require [clojure.spec.alpha :as s]
+ [shapey-shifty.posts.core :as posts]
+ [shapey-shifty.index.index :as index]))
+
+(s/def ::posts (s/coll-of :posts/post))
+(s/def ::index :index/index)
+
+(s/def ::context (s/keys :req [::posts ::current-time ::index]))
diff --git a/src/clj/shapey_shifty/core.clj b/src/clj/shapey_shifty/core.clj
index 604ae1e..04b9b74 100644
--- a/src/clj/shapey_shifty/core.clj
+++ b/src/clj/shapey_shifty/core.clj
@@ -7,6 +7,7 @@
[shapey-shifty.config :refer [env]]
[clojure.tools.cli :refer [parse-opts]]
[clojure.tools.logging :as log]
+ [shapey-shifty.posts.post-io :as io]
[mount.core :as mount])
(:gen-class))
@@ -25,6 +26,7 @@
(mount/defstate index :start (if-let [path (env :index-path)]
(index/create-index path)
(index/create-index "resources/index.edn")))
+(mount/defstate file-keeper :start)
(mount/defstate ^{:on-reload :noop} http-server
:start
diff --git a/src/clj/shapey_shifty/posts/core.clj b/src/clj/shapey_shifty/posts/core.clj
index 3aa38bf..9d07735 100644
--- a/src/clj/shapey_shifty/posts/core.clj
+++ b/src/clj/shapey_shifty/posts/core.clj
@@ -22,10 +22,10 @@
(s/def ::status keyword?)
(s/def ::properties
- (s/keys :req [::name ::author ::published ::stub ::filename ::created]))
+ (s/keys :req-un [::name ::author ::published ::stub ::filename ::created]))
(s/def ::post
- (s/keys :req [::type ::properties ::content]))
+ (s/keys :req-un [::type ::properties ::content]))
(defprotocol PostKeeper
(create-post [this post])
diff --git a/tags b/tags
new file mode 100644
index 0000000..e87bbd9
--- /dev/null
+++ b/tags
@@ -0,0 +1,88 @@
+!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
+!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
+!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/
+!_TAG_PROGRAM_AUTHOR Universal Ctags Team //
+!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
+!_TAG_PROGRAM_URL https://ctags.io/ /official site/
+!_TAG_PROGRAM_VERSION 0.0.0 //
+-main src/clj/shapey_shifty/core.clj /^(defn -main [& args]$/;" f namespace:shapey-shifty.core
+.material-icons resources/public/css/screen.css /^.material-icons {$/;" c
+Error: {{status}} resources/html/error.html /^
Error: {{status}}<\/span><\/h1>$/;" h
+License README.md /^## License$/;" s
+Managing your middleware resources/docs/docs.md /^#### Managing your middleware$/;" t
+Need some help? resources/docs/docs.md /^#### Need some help?$/;" t
+Organizing the routes resources/docs/docs.md /^#### Organizing the routes$/;" t
+Prerequisites README.md /^## Prerequisites$/;" s
+Running README.md /^## Running$/;" s
+Why are you seeing this page? resources/docs/docs.md /^#### Why are you seeing this page?$/;" t
+about-page src/clj/shapey_shifty/routes/home.clj /^(defn about-page [request]$/;" f namespace:shapey-shifty.routes.home
+add-load-post-step src/clj/shapey_shifty/pipeline/core.clj /^(defn add-load-post-step [f]$/;" f namespace:shapey-shifty.pipeline.core
+add-pipeline src/clj/shapey_shifty/pipeline/core.clj /^(defn add-pipeline [k v]$/;" f namespace:shapey-shifty.pipeline.core
+add-post-to-index src/clj/shapey_shifty/index/index.clj /^(defn add-post-to-index [index post]$/;" f namespace:shapey-shifty.index.index
+add-render-post-step src/clj/shapey_shifty/pipeline/core.clj /^(defn add-render-post-step [f]$/;" f namespace:shapey-shifty.pipeline.core
+add-write-post-step src/clj/shapey_shifty/pipeline/core.clj /^(defn add-write-post-step [f]$/;" f namespace:shapey-shifty.pipeline.core
+app src/clj/shapey_shifty/handler.clj /^(defn app []$/;" f namespace:shapey-shifty.handler
+assoc-author src/clj/shapey_shifty/posts/posts_io.clj /^(defn assoc-author [post]$/;" f namespace:shapey-shifty.posts.posts-io
+body resources/public/css/screen.css /^body {$/;" s
+count-posts-in-date src/clj/shapey_shifty/posts/posts_io.clj /^(defn count-posts-in-date [dt-path]$/;" f namespace:shapey-shifty.posts.posts-io
+crawl-posts! src/clj/shapey_shifty/index/index.clj /^(defn crawl-posts!$/;" f namespace:shapey-shifty.index.index
+create-author src/clj/shapey_shifty/authors/author_core.clj /^(defn create-author []$/;" f namespace:shapey-shifty.authors.author-core
+create-empty-post src/clj/shapey_shifty/posts/core.clj /^(defn create-empty-post [] {::type :note ::key (java.util.UUID\/randomUUID) ::content ""$/;" f namespace:shapey-shifty.posts.core
+create-index src/clj/shapey_shifty/index/index.clj /^(defn create-index [index-path]$/;" f namespace:shapey-shifty.index.index
+create-path-by-date src/clj/shapey_shifty/posts/posts_io.clj /^(defn create-path-by-date [year month day]$/;" f namespace:shapey-shifty.posts.posts-io
+datetime-filename-resolver src/clj/shapey_shifty/posts/posts_io.clj /^(defn datetime-filename-resolver [post]$/;" f namespace:shapey-shifty.posts.posts-io
+error-page src/clj/shapey_shifty/layout.clj /^(defn error-page$/;" f namespace:shapey-shifty.layout
+execute-pipeline src/clj/shapey_shifty/pipeline/core.clj /^(defn execute-pipeline [k params]$/;" f namespace:shapey-shifty.pipeline.core
+get-post src/clj/shapey_shifty/routes/post_router.clj /^(defn get-post$/;" f namespace:shapey-shifty.routes.post-router
+home-page src/clj/shapey_shifty/routes/home.clj /^(defn home-page [request]$/;" f namespace:shapey-shifty.routes.home
+home-routes src/clj/shapey_shifty/routes/home.clj /^(defn home-routes []$/;" f namespace:shapey-shifty.routes.home
+html resources/public/css/screen.css /^html,$/;" s
+load-all-authors src/clj/shapey_shifty/authors/author_core.clj /^(defn load-all-authors []$/;" f namespace:shapey-shifty.authors.author-core
+load-author src/clj/shapey_shifty/authors/author_core.clj /^(defn load-author [author-name]$/;" f namespace:shapey-shifty.authors.author-core
+nav-menu resources/html/base.html /^