Skip to content

A simple CRUD companion for Clojure Luminous-Based applications

License

Notifications You must be signed in to change notification settings

macrofex/crudgen

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

crudgen

A simple tool to generate a CRUD module for a Luminus-based server-side rendered web application. Given the definition of a modele in your domain, this tool will generate a Luminus-based (Compojure) route file, template for Index, New, and Edit view, and a supporting HugSQL file.

A model definition is based on a simple EDN structure as illustrated below:

{
 :person {
   :name "Person"
   :plural "people"
   :generate true
   :fields [
      {:name "id" :key true :label "id" :type "integer" :required true}
      {:name "first_name" :key false  :label "First Name" :type "text" :required true}
      {:name "middle_name" :key false  :label "Middle Name" :type "text" :required false}
      {:name "last_name" :key false  :label "Last Name" :type "text" :required true}
      {:name "email"  :key false :label "Email" :type "enail" :required false}
      {:name "home_phone"  :key false :label "Home Phone" :type "text" :required false}
      {:name "mobile_phone" :key false  :label "Mobile Phone" :type "text" :required false}
      {:name "street1" :key false  :label "Street 1" :type "text" :required false}
      {:name "street2" :key false  :label "Street 2" :type "text" :required false}
      {:name "city" :key false  :label "City" :type "text" :required false}
      {:name "state" :key false  :label "State" :type "text" :required false}
      {:name "zip_code" :key false  :label "Zip Code" :type "text" :required false}
   ]
  }
 :appointment {
   :name "Appointment"
   :plural "appointments"
   :generate true
   :fields [
     ...
   ]
 }
}

The tool is driven by reading /resources/models.edn which includes the definition of one or more models, each one identified by a keyword (e.g., :person). Each model results in the generation of the following files:

 {model-name}.clj
 {model-name}.sql
 index.html
 new.html
 edit.html

For example, given the above definition of the :person model, the following person.clj file would be generated:

(ns amw.routes.person
(:require [amw.layout :as layout]
            [amw.db.core :as db]
            [compojure.core :refer [defroutes GET POST PUT]]
            [ring.util.response :refer [redirect]]
            [ring.util.http-response :as response]
            [struct.core :as st]
            [ring.middleware.anti-forgery :as af]
            [ring.middleware.anti-forgery.strategy :as strategy]
            [compojure.coercions :refer [as-int]]
            [clojure.java.io :as io])
  )

;;
;; http://funcool.github.io/struct/latest/#quick-start
;;
(def person-schema
  {
   
     :id [st/string]  
     :first_name [[st/required :message "You must provide First Name."] [st/string]]   
     :middle_name [st/string]  
     :last_name [[st/required :message "You must provide Last Name."] [st/string]]   
     :email [st/string]  
     :home_phone [st/string]  
     :mobile_phone [st/string]  
     :street1 [st/string]  
     :street2 [st/string]  
     :city [st/string]  
     :state [st/string]  
     :zip_code [st/string] 
   ;; examples of validations
   ;; :home_phone [[st/min-count 10 :message "Invalid Home phone number. Must have 10 digits or more."]]
   ;; :zipcode [[st/max-count 9 :message "Invalid Zip Code. Cannot have more than 9 digits"]]
   })

(defn index-action [request]
  (let [ (db/get-)]
    (layout/render request "person/index.html" { :collection   })
    )
  )

(defn new-action [request]
  (layout/render request "person/new.html" {:username "Some value"}))


(defn create-action [request]
  (do
    (db/create-person! (:params request))
    (redirect (str "/person"))
   )
  )

(defn edit-action [id]
  (let [person (db/get-person {:id id})]
    (layout/render {:params {:id id}} "person/edit.html" {:person person} )
    )
  )

(defn update-action [raw-request]
  (let [request (:params raw-request)
        validated-request (st/validate request person-schema)
        validation-result (first validated-request)
        person (second validated-request)]
    (if (nil? validation-result)
      (do
        (db/update-person! person)
        (redirect (str "/person"))
        )
      (do
        (layout/render {:params {:id (:id person  ) } } "person/edit.html" {:person person :errors validation-result}  )
       )
      )
    )
  )

(defroutes person-routes
  (GET   "/person"           request (index-action request))
  (GET   "/person/new"       request (new-action request))
  (GET   "/person/:id/edit"  [id :<< as-int] (edit-action id))
  (POST  "/person/update"    request (update-action request))
  (POST  "/person/create"    request (create-action request))
  )

These files are generated in the /output/{model-name} folder.

Installation

Clone this repo:

git clone git@github.com:macrofex/crudgen.git

Usage

After cloning this repo, define in the /resources/models.edn one or more models as illustrated above, then,

lein run

The generated files can be found in:

/output/{model-name}

In addition to generating files which can be copied and used directly within your Luminus project, the tool outputs text

Add the following content to the identified files.

Examples

License

Copyright © 2019 MACROFEX LLC

Distributed under the Eclipse Public License either version 1.0 or any later version.

About

A simple CRUD companion for Clojure Luminous-Based applications

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published