 
 (def new-login-form-schema
   {(s/optional-key :path) s/Str
-   (s/optional-key :context) s/Str})
+   (s/optional-key :context) s/Str
+   (s/optional-key :boilerplate) (s/=> 1)})
 
 (defn new-login-form [& {:as opts}]
-  (let [{:keys [path context]}
+  (let [{:keys [path context boilerplate]}
         (->> opts
              (merge {:context ""
-                     :path "/login"})
+                     :path "/login"
+                     :boilerplate #(html [:body %])})
              (s/validate new-login-form-schema))]
-    (component/using (->LoginForm path context) [:authorizer :http-session-store])))
+    (component/using (->LoginForm path context boilerplate) [:authorizer :http-session-store])))
 
 ;; Now we can build a protection domain, composed of a login form, user
 ;; authorizer and session store. Different constructors can build this

  (context [this] context))

(defn new-mandatory-protected-bidi-routes
  "Create a set of protected routes. The absence of a :protection-domain
  dependency will cause an error. Routes can a bidi route structure, or
  a function that takes the component and returns a bidi route
  structure."
  [routes context]
  (component/using (->ProtectedBidiRoutes routes context) [:protection-domain]))

(defn new-protected-bidi-routes
  "Create a set of protected routes. The absence of a :protection-domain
  dependency will remove the protection. If protection is mandatory, use


(defn- make-login-handlers [opts]
  (let [p (promise)]
    @(deliver p {:get-handler (new-login-get-handler p :post-handler (select-keys opts [:boilerplate]))
                 :post-handler (wrap-params (new-login-post-handler p :get-handler (select-keys opts [:authorizer :http-session-store])))})))

(defrecord LoginForm [path context boilerplate]
  component/Lifecycle
  (start [this]
    (let [handlers (make-login-handlers (select-keys this [:authorizer :http-session-store :boilerplate]))]
      (assoc this
        :handlers handlers
        :routes [path (->WrapMiddleware
