- Notifications
You must be signed in to change notification settings - Fork5
ClojureHomePage is a Compojure based web framework that allows you to write the backend and frontend with Clojure.
runexec/chp
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
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
CHTML, Routing, and Sessions
Ring
Code Generation, Modules, and JSON API
- Generating views from a table
- View bindings
- View bindings Example
- Enable admin account
- Database and Bindings tutorial
- HTML Generation
- CSS Generation
- JavaScript Generation
- CHP Modules
- Module Packages
- JSON API
- Auto Documenting API
SQL Configuration, Migrations, and Manipulation
General Information
Routes can be stored in two places
- File: src/chp/handler.clj
- Folder: src/chp/routes/
The following link is the chtml page that is used in the example below.test-page.chtml
More CHTML examples are located inchp-root
Routes Example
(defchpapp-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"))(defapp (chp-site example-routes app-routes))
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! k1)) (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.
(defnchp-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.
The default configuration for CHP is located in project.clj
:ring {:port8000:auto-reload?true:auto-refresh?true:reload-paths ["src/chp/""chp-root/""resources/middleware/""resources/public/"]:handler chp.handler/app}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.(defnexample-middleware [handler] (fn [request] (let [resp (handler request) headers (:headers resp)] (println"resources/middleware/example.clj says""- Incoming request >>" headers) resp)))
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 aliaslein schema
$ lein schemaCreating Table => resources/schema/example.cljOKAYCreating Table => resources/schema/user.cljOKAY
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:name20) (varchar:password100) (unique [:name])))(create *db* (table:some_other_table (integer:id:primary-key:auto-inc) (varchar:name20) (varchar:password100) (unique [:name])))
Perform migration
$ lein migrateadd-topic-tableadd-topic-subject-tableadd-tag-table
Lobos migration files
$ cat resources/migrations/01-add-topic-tables.clj
(defmigrationadd-topic-table (up [] (create (tbl:topic (varchar:title50:unique) (text:content)))) (down [] (drop (table:topic))))(defmigrationadd-topic-subject-table (up [] (create (tbl:topicSubject (varchar:title50:unique) (integer:id:auto-inc:primary-key)))) (down [] (drop (table:topicSubject))))
$ cat resources/migrations/02-add-tag-table.clj
(defmigrationadd-tag-table (up [] (create (tbl:tag (varchar:title25) (integer:id:auto-inc:primary-key)))) (down [] (drop (table:tag))))
Tables after migration
example=# \dt List of relations Schema| Name| Type| Owner --------+------------------+-------+------- public| example| table| on public| lobos_migrations| table| on public| tag| table| on public| topic| table| on public| topicSubject| table| on public| user| table| on(6 rows)
Rollbacks
$ lein rollbackadd-tag-table$ lein rollbackadd-topic-subject-table
Tables after rollback
example-#\dt List of relations Schema| Name| Type| Owner --------+------------------+-------+------- public| example| table| on public| lobos_migrations| table| on public| topic| table| on public| user| table| on(4 rows)example-#
ClojureHomePage uses the SQLKorma DSL by default. korma.db is required as kdb and korma.core is required as kc
The $cljdb macro binds a row and allows the $db macro to retrieve columns of the row.Example, ($cljdb table-keyword where-clause & code-body)
Here's how to use these macros
chp.test.core> ($cljdb:user {:id2} (format"%s id is %d" ($db name) ($db id)))"admin id is 2"chp.test.core> (kc/select {:table"user"} (kc/fields:name:id))[{:id2,:name"admin"}]
$ lein gen userresources/generation-templates/routes/name.clj -> src/chp/routes/user.cljresources/generation-templates/chtml/new.chtml -> chp-root/user/new.chtmlresources/generation-templates/chtml/edit.chtml -> chp-root/user/edit.chtmlresources/generation-templates/chtml/view.chtml -> chp-root/user/view.chtmlresources/generation-templates/chtml/list.chtml -> chp-root/user/list.chtmlURL DATA BOUND TO => resources/bindings/user.clj site.com/new/user site.com/list/user site.com/edit/user/:id site.com/view/user/:id$ cat resources/bindings/user.clj
;; Example bindings for resources/schema/user.clj;; All values will be retrieved by the id column;; table must match the filename withut the clj extension;; user.clj -> user{:table:user;; List view value;; (chp.builder/binding-list :user 0 10);; /chp/list/user:list (list:name:id);; View view values;; (chp.builder/binding->view :user 1);; site.com/chp/view/user/:id:view (list:name:password:admin);; Edit view values;; (chp.builder/binding->edit :user 1);; site.com/chp/edit/user/:id;; site.com/chp/new/user;; edit is a hash-set with table columns;; as the key and the chp.html namespace;; function used to display the value.:edit {:name #(text-field:name (escape %)):password #(password-field:password (escape %)):admin #(check-box:admin (Boolean/valueOf %))};; enforce data type with fn to check and;; or convert before going into database.;; The function must take one arg.;; :name is limited to a string of 20 chars;; :password is limited to 100 chars;; :admin mut be a boolean value:edit-enforce {:name #(->> % str seq (take20) (apply str)):password #(->> % str seq (take100) (apply str)):admin #(Boolean/valueOf %)}}
The example user.clj bindings below will be used to make the new, list, view, and edit pages of the user table in schema/user.clj.
;; Example bindings for resources/schema/user.clj;; All values will be retrieved by the id column;; table must match the filename withut the clj extension;; user.clj -> user{:table:user;; List view value;; (chp.builder/binding-list :user 0 10);; /chp/list/user:list (list:name:id);; View view values;; (chp.builder/binding->view :user 1);; site.com/chp/view/user/:id:view (list:name:password:admin);; Edit view values;; (chp.builder/binding->edit :user 1);; site.com/chp/edit/user/:id;; site.com/chp/new/user;; edit is a hash-set with table columns;; as the key and the chp.html namespace;; function used to display the value.:edit {:name #(text-field:name (escape %)):password #(password-field:password (escape %)):admin #(check-box:admin (Boolean/valueOf %))};; enforce data type with fn to check and;; or convert before going into database.;; The function must take one arg.:edit-enforce {:name str:password str:admin #(Boolean/valueOf %)}}
$cd chp$ cat resources/schema/user.clj(create *db* (table:user (integer:id:primary-key:auto-inc) (varchar:name20) (varchar:password100) (boolean:admin) (unique [:name])))
$ lein schemaCreating Table => resources/schema/example.cljOKAYCreating Table => resources/schema/user.cljOKAY$ lein gen userresources/generation-templates/routes/name.clj -> src/chp/routes/user.cljresources/generation-templates/chtml/new.chtml -> chp-root/user/new.chtmlresources/generation-templates/chtml/edit.chtml -> chp-root/user/edit.chtmlresources/generation-templates/chtml/view.chtml -> chp-root/user/view.chtmlresources/generation-templates/chtml/list.chtml -> chp-root/user/list.chtmlURL DATA BOUND TO => resources/bindings/user.clj site.com/new/user site.com/list/user site.com/edit/user/:id site.com/view/user/:id$ psql examplepsql (9.2.4)Type"help"for help.example=# INSERT INTO "user" (name,password,admin) VALUES ('user1','badcleartext',true);example=# \q$ lein ring server&Jun 24, 2013 3:40:47 PM com.mchange.v2.log.MLog<clinit>INFO: MLog clients using java 1.4+ standard logging.2013-06-24 15:40:47.999:INFO:oejs.Server:jetty-7.6.1.v201202152013-06-24 15:40:48.064:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8000Started server on port 8000# In another terminal ###$ telnet localhost 8000Trying ::1...Connected to localhost.Escape character is'^]'.GET /list/user
$ telnet localhost 8000Trying ::1...Connected to localhost.Escape character is '^]'.GET /view/user/1
<h1>Viewing 1</h1>[name user1][password badcleartext][admin true]```bashConnection closed by foreign host.$ telnet localhost 8000Trying ::1...Connected to localhost.Escape character is '^]'.GET /edit/user/1<h1> Editing user #1 </h1><form action="/edit/user/1" method="POST"><label for=":admin">admin</label><br /><input checked="checked" name="admin" type="checkbox" value="true" /><br /><br /><label for=":password">password</label><br /><input name="password" type="password" value="badcleartext" /><br /><br /><label for=":name">name</label><br /><input name="name" type="text" value="user1" /><br /><br /> <input type="submit" value="save" /></form>Connection closed by foreign host.[user@machine~]$cd /tmp/; mkdir admin-example;cd admin-example;[user@machine admin-example]$ git clone https://github.com/runexec/chp.gitCloning into'chp'...remote: Counting objects: 594, done.remote: Compressing objects: 100% (331/331), done.remote: Total 594 (delta 287), reused 501 (delta 194)Receiving objects: 100% (594/594), 160.96 KiB| 34.00 KiB/s, done.Resolving deltas: 100% (287/287), done.[user@machine admin-example]$cd chp/[user@machine chp]$ lschp-examples/ chp-root/ resources/ src/ test/ tutorial/ project.clj README.md[user@machine chp]$ rm -rf chp-examples/ tutorial/ [user@machine chp]$ cat resources/schema/user.clj
(create *db* (table:user (integer:id:primary-key:auto-inc) (varchar:name20) (varchar:password128) (varchar:salt128) (boolean:admin) (unique [:name])))
[user@machine chp]$ lein schemaCreating Table => resources/schema/user.cljOKAYCreating Table => resources/schema/example.cljOKAY[user@machine chp]$ lein migrateJun 30, 2013 2:47:07 AM com.mchange.v2.log.MLog<clinit>INFO: MLog clients using java 1.4+ standard logging.create-chp-admin
The admin password is located in the migration file resources/migrations/01-add-admin.clj
;; (chp.password/salt-set "your password here")
[user@machine chp]$ cat resources/migrations/01-add-admin.clj
(let [table (kc/create-entity"user")] (comment Assuming resources/schema/user.clj (table:user (integer:id:primary-key:auto-inc) (varchar:name20) (varchar:password128) (varchar:salt128) (boolean:admin) (unique [:name]))) (defmigrationcreate-chp-admin (up [] (let [{:keys [salt password]} (chp.password/salt-set"admin")] (kc/insert table (kc/values {:name"admin":password password:salt salt:admintrue})))) (down [] (kc/delete table (kc/where {:name"admin"})))))
[user@machine chp]$ lein ring serverJun 30, 2013 2:54:20 AM com.mchange.v2.log.MLog<clinit>INFO: MLog clients using java 1.4+ standard logging.2013-06-30 02:54:21.391:INFO:oejs.Server:jetty-7.6.1.v201202152013-06-30 02:54:21.489:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8000Started server on port 8000### In a new shell ###[user@machine chp]$ curl --data"username=admin&password=admin" http://localhost:8000/chp/login<html><head><title>Login Handler</title></head><body>Logged in{:user"admin", :logged-in? true}</body></html>[user@machine chp]$ curl --data"username=admin&password=adminadasdsad" http://localhost:8000/chp/login<html><head><title>Login Handler</title></head><body>Login Failed</body></html>
##### get CHP [user@machine~]$ mkdir blog;cd blog/ [user@machine blog]$ git clone https://github.com/runexec/chp.git Cloning into'chp'... remote: Counting objects: 456, done. remote: Compressing objects: 100% (224/224), done. remote: Total 456 (delta 208), reused 413 (delta 165) Receiving objects: 100% (456/456), 144.89 KiB| 80.00 KiB/s, done. Resolving deltas: 100% (208/208), done. [user@machine blog]$cd chp/; ls chp-examples/ chp-root/ resources/ src/ test/ tutorial/ project.clj README.md##### Remove extra directories [user@machine chp]$ rm -rf chp-examples/ tutorial/##### Create Database configuration and db [user@machine chp]$cd resources/config/ [user@machine config]$ emacs -nw -q db.clj [user@machine config]$ psql example -c'CREATE DATABASE "blog";' CREATE DATABASE##### Create tables[user@machine config]$cd ../schema/[user@machine schema]$ cat user.clj (create*db* (table :user (integer :id :primary-key :auto-inc) (varchar :name 20) (varchar :password 128) (varchar :salt 128) (boolean :admin) (unique [:name])))[user@machine schema]$ emacs -nw news.clj [user@machine schema]$ cat news.clj (create*db* (table :news (integer :id :primary-key :auto-inc) (integer :userid) (varchar :title 100) (text :body) (unique [:title])))[user@machine schema]$ lein schemaCreating Table => resources/schema/user.cljOKAYCreating Table => resources/schema/news.cljOKAY##### Create binding[user@machine bindings]$ emacs -nw news.clj[user@machine bindings]$ cat news.clj {:table :news :list (list :title :id) :view (list :title :body) :edit {:title#(text-field :title (escape %)) :body#(text-area :body (escape %))} :edit-enforce {:title#(->> % str seq (take 100) (apply str)) :body str}}##### Create Views[user@machine bindings]$ lein gen news Jul 14, 2013 9:59:55 AM com.mchange.v2.log.MLog<clinit>INFO: MLog clients using java 1.4+ standard logging. resources/generation-templates/routes/name.clj -> src/chp/routes/news.cljresources/generation-templates/chtml/new.chtml -> chp-root/news/new.chtmlresources/generation-templates/chtml/edit.chtml -> chp-root/news/edit.chtmlresources/generation-templates/chtml/view.chtml -> chp-root/news/view.chtmlresources/generation-templates/chtml/list.chtml -> chp-root/news/list.chtmlURL DATA BOUND TO => resources/bindings/news.clj site.com/new/news site.com/list/news site.com/edit/news/:id site.com/view/news/:id##### Add Routes to chp/src/chp/handler.clj
(:require [chp.routes.news:refer [news-table-routes]])(defapp (chp-site news-table-routes example-routes user-table-routes chp-builder-paths app-routes))
[user@machine bindings]$ lein ring serverJul 06, 2013 9:29:46 PM com.mchange.v2.log.MLog<clinit>INFO: MLog clients using java 1.4+ standard logging.2013-07-06 21:29:47.735:INFO:oejs.Server:jetty-7.6.1.v201202152013-07-06 21:29:48.834:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8000Started server on port 8000##### Create new blog post[user@machine bindings]$ firefox http://localhost:8000/new/news
The following methods presented in the documentation below areaccessible from within CHTML files by default. These abstractionsare drop-in replacements for the Hiccup API located athttp://weavejester.github.io/hiccup/.Please note that these forms DO NOT generate Hiccup code, but HTML.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Form Fields(escape string)(url-encode string)(check-box attr-map? name)(check-box attr-map? name checked?)(check-box attr-map? name checked? value)(drop-down attr-map? name options)(drop-down attr-map? name options selected)(email-field attr-map? name)(email-field attr-map? name value)(file-upload attr-map? name)(form-to attr-map? [method action] & body)(hidden-field attr-map? name)(hidden-field attr-map? name value)(label attr-map? name text)(password-field attr-map? name)(password-field attr-map? name value)(radio-button attr-map? group)(radio-button attr-map? group checked?)(radio-button attr-map? group checked? value)(reset-button attr-map? text)(select-options attr-map? coll)(select-options attr-map? coll selected)(submit-button attr-map? text)(text-area attr-map? name)(text-area attr-map? name value)(text-field attr-map? name)(text-field attr-map? name value);;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Common Elements(javascript-tag script)(image attr-map? src)(image attr-map? src alt)(link-to attr-map? url & content)(mail-to attr-map? e-mail & [content])(ordered-list attr-map? coll)(unordered-list attr-map? coll)
ClojureHomePage uses the Garden CSS generation library by default.The Garden documentation page is located athttps://github.com/noprompt/garden
ClojureHomePage uses ClojureScript and lein-cljsbuild to generate javascript.CHP uses the directory resources/cljs/ as the default cljs source code directory.
Modules are optional resources that are shipped with every release.
$ lein mod-enable middleware verbose-log exampleCopying resources/modules/middleware/verbose-log.clj -> resources/middleware/verbose-log.cljCopying resources/modules/middleware/example.clj -> resources/middleware/example.clj$ lein mod-disable middleware verbose-logDeleting resources/middleware/verbose-log.clj$ lein mod-listresources/modulesresources/modules/migrationsresources/modules/migrations/01-add-admin.cljresources/modules/cljsresources/modules/middlewareresources/modules/middleware/example.cljresources/modules/middleware/operating-status.cljresources/modules/middleware/text-mime-only.cljresources/modules/middleware/verbose-log.cljresources/modules/schemaresources/modules/schema/example.cljresources/modules/schema/user.cljresources/modules/schema/blog-post.cljresources/modules/bindingsresources/modules/bindings/user.clj
Module packages are stored inresources/packages/. Each package is a clj file that describes what modules to install when callinglein package-run name1 name2 etc...
$ cat resources/packages/admin.clj
;; CHP Admin module;; {:module-type [:module :module :module etc..]}{:schema [:user];; resources/modules/schema/user.clj:migrations [:01-add-admin];; resources/modules/migrations/01-add-admin.clj:bindings [:user];; resources/modules/bindings/user.clj:middleware [];; resources/modules/middleware/ -- nothing:cljs [];; resources/modules/cljs/ -- nothing:api []};; resources/modules/api/ -- nothing
$ lein package-run admin Loadingfor :schemaCopying resources/modules/schema/user.clj -> resources/schema/user.cljCreating Table => resources/schema/user.cljOKAY Loadingfor :migrationsCopying resources/modules/migrations/01-add-admin.clj -> resources/migrations/01-add-admin.cljJul 09, 2013 7:52:37 PM com.mchange.v2.log.MLog<clinit>INFO: MLog clients using java 1.4+ standard logging.create-chp-admin Loadingfor :bindingsCopying resources/modules/bindings/user.clj -> resources/bindings/user.clj Loadingfor :middleware Loadingfor :cljs Loadingfor :api
To enable the JSON read-only API, create an API config file in resources/api/. Once this configuration file is made, you can access JSON values @ site.com/chp/api/{table-name}
GET params can be used to locate specific values. If the params aren't listed in the configuration, the extra params are ignored.
$ cat resources/api/user.clj
;; API settings for the User table;; the filename must be the same as the table name;; {:table :user} => user.clj{:table:user:return [:id:name];; The where key holds a map that describes;; columns that can be used to locate the;; data.;; Each column key needs to have a function;; as the value that accepts one arg. This;; function needs to convert the arg to the;; proper data type.;; The single arg is a string from the uri:where {:id #(Integer. %):name str:admin #(Boolean. %)}}
$ curl http://localhost:8000/chp/api/user;echo" << done"{"data": [{"name":"admin","id": 1},{"name":"example","id": 3}]}<<done$ curl http://localhost:8000/chp/api/user?id=3; echo " << done"{"data": [{ "name" : "example", "id" : 3}]} << done$ curl http://localhost:8000/chp/api/user?name=admin; echo " << done"{"data": [{ "name" : "admin", "id" : 1}]} << done$ curl http://localhost:8000/chp/api/userasdasd; echo " << done"An error occured << done
After creating an API config file inresources/api/, you can view the dynamically generated API documentation atsite.com/chp/api.
Before showing the documentation page, here's what the default user API config looks like.
$ cat resources/api/user.clj
;; API settings for the User table;; the filename must be the same as the table name;; {:table :user} => user.clj{:table:user:return [:id:name];; The where key holds a map that describes;; columns that can be used to locate the;; data.;; Each column key needs to have a function;; as the value that accepts one arg. This;; function needs to convert the arg to the;; proper data type.;; The single arg is a string from the uri:where {:id #(Integer. %):name str:admin #(Boolean. %)}}
And here's what the documentation looks like for all config files inresources/api/
$ curl localhost:8000/chp/api
- Download & Run
git clone https://github.com/runexec/chpcd chplein ring server- Edit the default app-routes template located at the bottom of src/chp/handler.clj
Full image size athttps://raw.github.com/runexec/chp/master/violet-uml-workings.png
(2013-07-08 JST) NOTICE: This graph is not consistent with the latest update(s) and contains minor errors.
(Generated by ntable)https://github.com/runexec/ntable
:usechp.corecompojure.core[chp.html :only [escape]]:usechp.core:usechp.core[cheshire.core :only [generate-string]][chp.api :only [api->where]][chp.builder :only [binding-exist?]]:refer-clojure:exclude[complement alter drop bigint boolean char double float time]:use[chp.db :only [*db*]](lobos core connectivity migration):usecompojure.corechp.htmlchp.template[chp.core :exclude [korma-db]][chp.api :only [api->where api-dir]][chp.db :only [*db*]][garden.core :only [css]]:requirechp.server[compojure.route :as route][korma.db :as kdb][korma.core :as kc][noir.session :as session][chp.routes.chp :refer [chp-builder-paths]][chp.routes.example :refer [example-routes]][chp.routes.user :refer [user-table-routes]]:requirehiccup.corehiccup.utilhiccup.formhiccup.element:use[chp.db :only [*db*]]:require[korma.db :as kdb][korma.core :as kc]:refer-clojure:exclude[bigint boolean char double float time]:use[chp.schema :only [load-schemas]][chp.migration :only [chp-migrate]][chp.module :only [mod-enable]]:usechp.core:use[chp.db :only [*db*]][chp.core :exclude [korma-db]]chp.htmlchp.password[chp.login :exclude [korma-db]]:require[korma.core :as kc][korma.db :as kdb][noir.session :as session]:require[korma.db :as kdb][korma.core :as kc]:use[chp.db :only [*db*]][chp.password :only [password]]:usecompojure.core[noir.session :only [wrap-noir-flash wrap-noir-session]][chp.db :only [*db*]]:requirechp.server[compojure.handler :as handler][clojure.string :as string][korma.db :as kdb][korma.core :as kc]:use[chp.core :only [root-path]]:require[clojure.java.io :as io]:refer-clojure:exclude[bigint boolean char double float time]:use[chp.db :only [*db*]][lobos.core :only [create]]
By default, the CHTML files are located in chp-root folder of the project folder.When a CHTML file is parsed, all public variables of the chp.handler namespaceare accessible during the evaluation of the<clj></clj> tags. Use printor println within the tags to have the results displayed.
$ ls chp-examples/ chp-root/ resources/ src/ target/ test/ tutorial/ project.clj README.md$ lein chp-cleanRemoving README.mdRemoving resources/schemaRemoving resources/schema/example.cljRemoving resources/schema/user.cljRemoving resources/bindingsRemoving resources/bindings/user.cljRemoving resources/migrationsRemoving resources/migrations/02-add-tag-table.cljRemoving resources/migrations/01-add-topic-tables.clj$ lschp-root/ resources/ src/ target/ test/ project.clj$ ls resources/bindings/ cljs/ config/ generation-templates/ migrations/ public/ schema/
Copyright © 2013 Runexec
Distributed under the Eclipse Public License, the same as Clojure.
About
ClojureHomePage is a Compojure based web framework that allows you to write the backend and frontend with Clojure.
Resources
Uh oh!
There was an error while loading.Please reload this page.

