SkillAgentSearch skills...

Chp

ClojureHomePage is a Compojure based web framework that allows you to write the backend and frontend with Clojure.

Install / Use

/learn @runexec/Chp
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

CHP endorse

ClojureHomePage is a Clojure Web Framework that provides the following.

  • Run Clojure inside a HTML file with the <clj></clj> tags
  • Request params ex. ($p userid)
  • Common web headers ex. ($ user-agent)
  • Web Headers ex. ($$ cache-control)
  • Environmental variables ex. (env java.vm.name)
  • Have multiple method handlers under a single route (get, post, put, delete, and head)
  • Routes can be defined in seperate files and namespaces
  • Style templates can be written in CHTML ex. chp.template/using-template
  • Create SQL database schemas ex. lein schema
  • Perform SQL database migrations ex. lein migrate
  • Perform migration rollbacks ex. lein rollback
  • Manipulate SQL databases with KormaSQL
  • Generate Page views (new,view,edit,list)
  • Generate JavaScript / ECMAScript
  • Generate HTML
  • Generate CSS

Documentation

<b> CHTML, Routing, and Sessions </b>

<b> Ring </b>

<b> Code Generation, Modules, and JSON API </b>

<b> SQL Configuration, Migrations, and Manipulation </b>

<b> General Information </b>

Example CHTML & Routes

Routes can be stored in two places

  1. File: src/chp/handler.clj
  2. Folder: src/chp/routes/

The following link is the chtml page that is used in the example below. <a href="https://github.com/runexec/chp/blob/master/chp-root/test-page.chtml"> test-page.chtml </a>

More CHTML examples are located in <a href="https://github.com/runexec/chp/blob/master/chp-root/">chp-root</a>

<b> Routes Example </b>

(defchp app-routes

  ;; Load CHP File

  (chp-route "/chtml" 
             (binding [*title* "Test Page Example"]
               (or (root-parse "test-page.chtml")
                   "error")))
  (chp-route "/chp"
	     ;; root-parse = root-path "/" file
             (or (root-parse "chp-info.chtml")
                 "error"))
  (chp-route "/session"
            (or (root-parse "session-example.chtml")
                "error"))

  ;; Named params

  (chp-route "/index/:id"
             (format "ID is %s" 
                     (escape ($p id))))
  (chp-route "/index/:id/:action"
             (format "Action is %s" 
                     (escape ($p action))))

  ;; Multiple handlers under a single route

  (chp-route "/testing"
             (or 
              (chp-when :post "POST METHOD RETURN")
              (chp-when :get
                        (str (format "chp-body wasn't used to access %s from %s with %s"
                                     ($ uri) ($ ip) ($ user-agent))
                             (format "<p>Tracking you? DNT HTTP Header = %s</p>" ($$ dnt))
                             (format "<p>HTTP Header cache-control = %s</p>" ($$ cache-control))))
              "Not Found"))

  ;; Multiple handlers under a single route

  (chp-route "/"
             (let [display (str (format "Method %s <br />" (escape ($ method)))
                                (format "URI %s <br />" (escape ($ uri)))
                                (format "Params %s <br />" (escape ($ params)))
                                (format "Header Values <p>%s</p>"
                                        (with-out-str
                                          (doseq [[k v] (escape-map ($ headers))]
                                            (println k "=" v "<br />"))))
                                (format "Server Name %s <br /> Server IP %s"
                                        ($ server-name)
                                        ($ server-ip)))]
               (chp-body {:-get (str "Get => " display)
                          :-post (str "Post => " display)
                          :-not-found "Sorry, but this page doesn't exist"})))

  ;; Bind to templates

  (chp-route "/template"
             (using-template "example.chtml"
                             {:body "chp-info.chtml"
                              :test-tag "test-page.chtml"}))

  (route/resources "/")
  (route/not-found "Not Found"))

(def app
  (chp-site example-routes
            app-routes))

Session handling, Cookies, and Compojure

Sessions are handled with the lib-noir.session namespace under the session alias.

This session example can be accessed at site.com/session

You have viewed this page 

<clj>
(let [k :view-count
      inc-view (if (nil? (session/get k))
                 (k (session/put! k 1))
                 (k (session/update-in! [k] inc)))]
  (print inc-view))
</clj>

time(s).

Because CHP is based on Compojure, you can use Compojure and Ring extensions. These middleware extensions should be added to the chp-routing function of the chp.core namespace. Below is what the function currently looks like.

(defn chp-routing [& -chp-routes]
  ;;; (-> (apply routes ...) middleware-wrap xyz-wrap)
  (let [auto-middleware (fn [x] 
                             (let [wrapped (atom x)]
                               (doseq [m (load-middleware)]
                                 (swap! wrapped m))
                               @wrapped))]
    (-> (apply routes
               (reduce into [] -chp-routes))
        wrap-noir-flash
        wrap-noir-session
        auto-middleware)))

Already included, but not loaded by default (except noir.session), the lib-noir library is a great helper library for Clojure web development.

  1. lib-noir API
  2. lib-noir Github
  3. Ring CSRF protection
  4. Ring Middleware Extensions

Ring configuration

The default configuration for CHP is located in project.clj

:ring {:port 8000
       :auto-reload? true
       :auto-refresh? true
       :reload-paths ["src/chp/"
                      "chp-root/"
                      "resources/middleware/"
                      "resources/public/"]
       :handler chp.handler/app}
  1. Lein-ring documentation

Auto-loading Middleware

Middleware is automatically loaded from '''resources/middleware/*.clj''' when the server starts. The middleware is evaluated in the chp.core namespace with the load-middleware fn. All middleware is reloaded when triggering the ring-autoload.

$ cat resources/middleware/example.clj
;; This file is automatically loaded as middleware
;; and should only contain one function.

(defn example-middleware [handler]
  (fn [request]
    (let [resp (handler request)
          headers (:headers resp)]
      (println "resources/middleware/example.clj says "
               "- Incoming request >> " headers)
      resp)))

DB Configuration and Creation

A Korma SQL and Lobos compatible SQL connection configuration file is located at resources/config/db.clj

The SQL database tables are located in resources/schema/. These files can contain an unlimited amount of create calls and get evaluated by the lein alias lein schema

$ lein schema
Creating Table =>  resources/schema/example.clj
OKAY
Creating Table =>  resources/schema/user.clj
OKAY

The Lobos library handles the table syntax. Below is the user table from user.clj.

(create *db*
        (table :user
               (integer :id :primary-key :auto-inc)
               (varchar :name 20)
               (varchar :password 100)
               (unique [:name])))
(create *db*
        (table :some_other_table
               (integer :id :primary-key :auto-inc)
               (varchar :name 20)
               (varchar :password 100)
               (unique [:name])))
  1. Lobos Project & Documentation
  2. More Lobos Documentation

DB Migrations

<b> Perform migration </b>

$ lein migrate
add-topic-table
add-topic-subject-table
add-tag-table

<b> Lobos migration files </b>

$ cat resources/migrations/01-add-topic-tables.clj
(defmigration add-topic-table
  (up [] (create
          (tbl :topic
                 (varchar :title 50 :unique)
                 (text :content))))
  (down [] (drop (table :topic))))

(defmigration add-topic-subject-table
  (up [] (create
          (tbl :topicSubject
                 (varchar :title 50 :unique)
                 (integer :id :auto-inc :primary-key))))
  (down [] (drop (table :topicSubject))))
$ cat resources/migrations/02-add-tag-table.clj
(defmigration add-tag-t
View on GitHub
GitHub Stars153
CategoryDevelopment
Updated1d ago
Forks5

Languages

Clojure

Security Score

80/100

Audited on Apr 4, 2026

No findings