(use joy)


(route :get "/{{plural}}" :{{plural}}/index)
(route :get "/{{plural}}/new" :{{plural}}/new)
(route :get "/{{plural}}/:id" :{{plural}}/show)
(route :post "/{{plural}}" :{{plural}}/create)
(route :get "/{{plural}}/:id/edit" :{{plural}}/edit)
(route :patch "/{{plural}}/:id" :{{plural}}/patch)
(route :delete "/{{plural}}/:id" :{{plural}}/delete)


(defn {{singular}} [req]
  (let [id (get-in req [:params :id])]
    (db/find :{{table}} id)))


(def {{singular}}/body
  (body :{{table}}
    (validates [{{#app-columns}} :{{name}}{{/app-columns}}] :required true)
    (permit [{{#app-columns}} :{{name}}{{/app-columns}}])))


(defn {{plural}}/index [req]
  (let [{{plural}} (db/from :{{table}})]
   [:div
    [:a {:href (url-for :{{plural}}/new)} "New {{singular}}"]

    [:table
     [:thead
      [:tr
       {{#columns}}
       [:th "{{name}}"]
       {{/columns}}
       [:th]
       [:th]
       [:th]]]
     [:tbody
      (foreach [{{singular}} {{plural}}]
        [:tr
          {{#columns}}
          [:td ({{singular}} :{{name}})]
          {{/columns}}
          [:td
           [:a {:href (url-for :{{plural}}/show {{singular}})} "Show"]]
          [:td
           [:a {:href (url-for :{{plural}}/edit {{singular}})} "Edit"]]
          [:td
           (form-for [req :{{plural}}/delete {{singular}}]
            [:input {:type "submit" :value "Delete"}])]])]]]))


(defn {{plural}}/show [req]
  (when-let [{{singular}} ({{singular}} req)]

    [:div
     {{#columns}}
     [:strong "{{name}}"]
     [:div ({{singular}} :{{name}})]

     {{/columns}}

     [:a {:href (url-for :{{plural}}/index)} "All {{plural}}"]]))


(defn {{plural}}/new [req &opt errors]
  (let [{{singular}} ({{singular}}/body req)]

    (form-for [req :{{plural}}/create]
      {{#app-columns}}
      [:div
       [:label {:for "{{name}}"} "{{name}}"]
       [:input {:type "text" :name "{{name}}" :value ({{singular}} :{{name}})}]
       [:small (get errors :{{name}})]]

      {{/app-columns}}
      [:input {:type "submit" :value "Save"}])))


(defn {{plural}}/create [req]
  (let [{{singular}} (-> req {{singular}}/body db/save)]

    (if (saved? {{singular}})
      (redirect-to :{{plural}}/index)
      ({{plural}}/new req (errors {{singular}})))))


(defn {{plural}}/edit [req &opt errors]
  (when-let [{{singular}} ({{singular}} req)
             {{singular}} (merge {{singular}} ({{singular}}/body req))]

    (form-for [req :{{plural}}/patch {{singular}}]
      {{#app-columns}}
      [:div
       [:label {:for "{{name}}"} "{{name}}"]
       [:input {:type "text" :name "{{name}}" :value ({{singular}} :{{name}})}]
       [:small (get errors :{{name}})]]

      {{/app-columns}}
      [:input {:type "submit" :value "Save"}])))


(defn {{plural}}/patch [req]
  (when-let [{{singular}} ({{singular}} req)
             {{singular}} (->> req {{singular}}/body (merge {{singular}}) db/save)]

    (if (saved? {{singular}})
      (redirect-to :{{plural}}/index)
      ({{plural}}/edit req (errors {{singular}})))))


(defn {{plural}}/delete [req]
  (when-let [{{singular}} ({{singular}} req)]

    (db/delete {{singular}})

    (redirect-to :{{plural}}/index)))
