The caveman Reference Manual

Table of Contents

Next: , Previous: , Up: (dir)   [Contents][Index]

The caveman Reference Manual

This is the caveman Reference Manual, version 12.8.0, generated automatically by Declt version 2.4 "Will Decker" on Wed Jun 20 10:52:09 2018 GMT+0.


Next: , Previous: , Up: Top   [Contents][Index]

1 Introduction

Caveman2 - Lightweight web application framework

Build Status

Usage

(defparameter *web* (make-instance '<app>))

@route GET "/"
(defun index ()
  (render #P"index.tmpl"))

@route GET "/hello"
(defun say-hello (&key (|name| "Guest"))
  (format nil "Hello, ~A" |name|))

About Caveman2

What's the difference from Caveman "1"?

All of them. Caveman2 was written from scratch.

These are noticeable points.

The reason I wrote it from scratch

One of the most frequently asked questions was "Which should I use ningle or Caveman? What are the differences?" I think it was because the roles of them were too similar. Both of them are saying "micro" and no database support.

Caveman2 is no more "micro" web application framework. It supports CL-DBI and has database connection management by default. Caveman has started growing up.

Design Goal

Caveman is intended to be a collection of common parts of web applications. Caveman has 3 rules to make decisions.

Quickstart

You came here because you're interested in living like a caveman, right? There's no Disneyland, but it's good place to start. Let's get into a cave.

Installation

Caveman2 is now available on Quicklisp.

(ql:quickload :caveman2)

Generating a project skeleton

(caveman2:make-project #P"/path/to/myapp/"
                       :author "<Your full name>")
;-> writing /path/to/myapp/.gitignore
;   writing /path/to/myapp/README.markdown
;   writing /path/to/myapp/app.lisp
;   writing /path/to/myapp/db/schema.sql
;   writing /path/to/myapp/shlyfile.lisp
;   writing /path/to/myapp/myapp-test.asd
;   writing /path/to/myapp/myapp.asd
;   writing /path/to/myapp/src/config.lisp
;   writing /path/to/myapp/src/db.lisp
;   writing /path/to/myapp/src/main.lisp
;   writing /path/to/myapp/src/view.lisp
;   writing /path/to/myapp/src/web.lisp
;   writing /path/to/myapp/static/css/main.css
;   writing /path/to/myapp/t/myapp.lisp
;   writing /path/to/myapp/templates/_errors/404.html
;   writing /path/to/myapp/templates/index.tmpl
;   writing /path/to/myapp/templates/layout/default.tmpl

Routing

Caveman2 provides 2 ways to define a route -- @route and defroute. You can choose which to use.

@route is an annotation macro defined by using cl-annot. It takes a method, an URL-string and a function.

@route GET "/"
(defun index ()
  ...)

;; A route with no name.
@route GET "/welcome"
(lambda (&key (|name| "Guest"))
  (format nil "Welcome, ~A" |name|))

This is similar to Caveman1's @url except its argument list. You don't have to specify an argument when you don't need it.

defroute is just a macro. It provides same feature to @route.

(defroute index "/" ()
  ...)

;; A route with no name.
(defroute "/welcome" (&key (|name| "Guest"))
  (format nil "Welcome, ~A" |name|))

Since Caveman bases on ningle, Caveman also has the Sinatra-like routing system.

;; GET request (default)
@route GET "/" (lambda () ...)
(defroute ("/" :method :GET) () ...)

;; POST request
@route POST "/" (lambda () ...)
(defroute ("/" :method :POST) () ...)

;; PUT request
@route PUT "/" (lambda () ...)
(defroute ("/" :method :PUT) () ...)

;; DELETE request
@route DELETE "/" (lambda () ...)
(defroute ("/" :method :DELETE) () ...)

;; OPTIONS request
@route OPTIONS "/" (lambda () ...)
(defroute ("/" :method :OPTIONS) () ...)

;; For all methods
@route ANY "/" (lambda () ...)
(defroute ("/" :method :ANY) () ...)

Route pattern may contain "keyword" to put the value into the argument.

(defroute "/hello/:name" (&key name)
  (format nil "Hello, ~A" name))

The above controller will be invoked when you access to "/hello/Eitaro" or "/hello/Tomohiro", and then name will be "Eitaro" and "Tomohiro".

(&key name) is almost same as a lambda list of Common Lisp, excepts it always allows other keys.

(defroute "/hello/:name" (&rest params &key name)
  ;; ...
  )

Route patterns may also contain "wildcard" parameters. They are accessible by splat.

(defroute "/say/*/to/*" (&key splat)
  ; matches /say/hello/to/world
  splat ;=> ("hello" "world")
  ))

(defroute "/download/*.*" (&key splat)
  ; matches /download/path/to/file.xml
  splat ;=> ("path/to/file" "xml")
  ))

If you'd like to write a regular expression for URL rule, :regexp t should work for it.

(defroute ("/hello/([\\w]+)" :regexp t) (&key captures)
  (format nil "Hello, ~A!" (first captures)))

Normally, routes are matched in the order they are defined. Only the first route matched is invoked and rest of them just will be ignored. But, a route can punt processing to the next matching route using next-route.

(defroute "/guess/:who" (&key who)
  (if (string= who "Eitaro")
      "You got me!"
      (next-route)))

(defroute "/guess/*" ()
  "You missed!")

You can return following formats as the result of defroute.

Structured query/post parameters

Parameter keys contain square brackets ("[" & "]") will be parsed as structured parameters. You can access the parsed parameters as _parsed in routers.

<form action="/edit">
  <input type="name" name="person[name]" />
  <input type="name" name="person[email]" />
  <input type="name" name="person[birth][year]" />
  <input type="name" name="person[birth][month]" />
  <input type="name" name="person[birth][day]" />
</form>
(defroute "/edit" (&key _parsed)
  (format nil "~S" (cdr (assoc "person" _parsed :test #'string=))))
;=> "((\"name\" . \"Eitaro\") (\"email\" . \"e.arrows@gmail.com\") (\"birth\" . ((\"year\" . 2000) (\"month\" . 1) (\"day\" . 1))))"

Blank keys mean they have multiple values.

<form action="/add">
  <input type="text" name="items[][name]" />
  <input type="text" name="items[][price]" />

  <input type="text" name="items[][name]" />
  <input type="text" name="items[][price]" />

  <input type="submit" value="Add" />
</form>
(defroute "/add" (&key _parsed)
  (format nil "~S" (assoc "items" _parsed :test #'string=)))
;=> "(((\"name\" . \"WiiU\") (\"price\" . \"30000\")) ((\"name\" . \"PS4\") (\"price\" . \"69000\")))"

Templates

Caveman adopts Djula for the default templating engine.

{% extends "layouts/default.html" %}
{% block title %}Users | MyApp{% endblock %}
{% block content %}
<div id="main">
  <ul>
  {% for user in users %}
    <li><a href="{{ user.url }}">{{ user.name }}</a></li>
  {% endfor %}
  </ul>
</div>
{% endblock %}
(import 'myapp.view:render)

(render #P"users.html"
        '(:users ((:url "/id/1"
                   :name "nitro_idiot")
                  (:url "/id/2"
                   :name "meymao"))
          :has-next-page T))

If you want to get something from a database or execute any function using Djula you have to explicity call list when passing the arguments to render so that the code executes.

(import 'myapp.view:render)

(render #P"users.html"
        (list :users (get-users-from-db)))

JSON API

This is an example of a JSON API.

(defroute "/user.json" (&key |id|)
  (let ((person (find-person-from-db |id|)))
    ;; person => (:|name| "Eitaro Fukamachi" :|email| "e.arrows@gmail.com")
    (render-json person)))

;=> {"name":"Eitaro Fukamachi","email":"e.arrows@gmail.com"}

render-json is a part of a skeleton project. You can find its code in "src/view.lisp".

Static file

Images, CSS, JS, favicon.ico and robot.txt in "static/" directory will be served by default.

/images/logo.png => {PROJECT_ROOT}/static/images/logo.png
/css/main.css    => {PROJECT_ROOT}/static/css/main.css
/js/app/index.js => {PROJECT_ROOT}/static/js/app/index.js
/robot.txt       => {PROJECT_ROOT}/static/robot.txt
/favicon.ico     => {PROJECT_ROOT}/static/favicon.ico

You can change these rules by rewriting "PROJECT_ROOT/app.lisp". See Clack.Middleware.Static for detail.

Configuration

Caveman adopts Envy as a configuration switcher. It allows to define multiple configurations and to switch them by an environment variable.

This is a typical example.

(defpackage :myapp.config
  (:use :cl
        :envy))
(in-package :myapp.config)

(setf (config-env-var) "APP_ENV")

(defconfig :common
  `(:application-root ,(asdf:component-pathname (asdf:find-system :myapp))))

(defconfig |development|
  '(:debug T
    :databases
    ((:maindb :sqlite3 :database-name ,(merge-pathnames #P"test.db"
                                                        *application-root*)))))

(defconfig |production|
  '(:databases
    ((:maindb :mysql :database-name "myapp" :username "whoami" :password "1234")
     (:workerdb :mysql :database-name "jobs" :username "whoami" :password "1234"))))

(defconfig |staging|
  `(:debug T
    ,@|production|))

Every configuration is a property list. You can choose the configuration which to use by setting APP_ENV.

To get a value from the current configuration, call myapp.config:config with a key you want.

(import 'myapp.config:config)

(setf (osicat:environment-variable "APP_ENV") "development")
(config :debug)
;=> T

Database

When you add :databases to the configuration, Caveman enables database support. :databases is an association list of database settings.

(defconfig |production|
  '(:databases
    ((:maindb :mysql :database-name "myapp" :username "whoami" :password "1234")
     (:workerdb :mysql :database-name "jobs" :username "whoami" :password "1234"))))

db in a package myapp.db is a function for connecting to each databases configured the above. Here is an example.

(use-package '(:myapp.db :sxql :datafly))

(defun search-adults ()
  (with-connection (db)
    (retrieve-all
      (select :*
        (from :person)
        (where (:>= :age 20))))))

The connection is alive during the Lisp session and will be reused in each HTTP requests.

retrieve-all and the query language came from datafly and SxQL. See those documentations for more informations.

Set HTTP headers or HTTP status

There are several special variables available during a HTTP request. *request* and *response* represents a request and a response. If you are familiar with Clack, these are instances of subclasses of Clack.Request and Clack.Response.

(use-package :caveman2)

;; Get a value of Referer header.
(http-referer *request*)

;; Set Content-Type header.
(setf (getf (response-headers *response* :content-type) "application/json")

;; Set HTTP status.
(setf (status *response*) 304)

If you would like to set Content-Type "application/json" for all "*.json" requests, next-route will help you.

(defroute "/*.json" ()
  (setf (getf (response-headers *response*) :content-type) "application/json")
  (next-route))

(defroute "/user.json" () ...)
(defroute "/search.json" () ...)
(defroute ("/new.json" :method :POST) () ...)

Using session

Session data is for memorizing user-specific data. *session* is a hash table represents session data.

This example increments :counter in the session and displays it for each visitors.

(defroute "/counter" ()
  (format nil "You came here ~A times."
          (incf (gethash :counter *session* 0))))

Caveman2 stores the session data in-memory by default. To change it, specify :store to :session in "PROJECT_ROOT/app.lisp".

This example uses RDBMS to store it.

      '(:backtrace
        :output (getf (config) :error-log))
      nil)
- :session
+ (:session
+  :store (make-dbi-store :connector (lambda ()
+                                      (apply #'dbi:connect
+                                             (myapp.db:connection-settings)))))
  (if (productionp)
      nil
      (lambda (app)

NOTE: Don't forget to add :lack-session-store-dbi as :depends-on of your app. It is not a part of Clack/Lack.

See the source code of Lack.Session.Store.DBi for more informations.

Throw an HTTP status code

(import 'caveman2:throw-code)

(defroute ("/auth" :method :POST) (&key |name| |password|)
  (unless (authorize |name| |password|)
    (throw-code 403)))

Specify error pages

To specify error pages for 404, 500 or so, define a method on-exception of your app.

(defmethod on-exception ((app <web>) (code (eql 404)))
  (declare (ignore app code))
  (merge-pathnames #P"_errors/404.html"
                   *template-directory*))

Start a server

Your application has functions named start and stop to start/stop your web application. This is a example assuming that the name of your application is "myapp".

(myapp:start :port 8080)

As Caveman bases on Clack/Lack, you can choose which server to run on -- Hunchentoot, mod_lisp or FastCGI.

(myapp:start :server :hunchentoot :port 8080)
(myapp:start :server :fcgi :port 8080)

I recommend you to use Hunchentoot in local machine and use FastCGI/Woo for production environment.

You can also start your application by using clackup command.

$ ros install clack
$ which clackup
/Users/nitro_idiot/.roswell/bin/clackup

$ APP_ENV=development clackup --server :fcgi --port 8080 app.lisp

Hot Deployment

Though Caveman doesn't have a feature for hot deployment, Server::Starter -- a Perl module -- makes it easy.

$ APP_ENV=production start_server --port 8080 -- clackup --server :fcgi app.lisp

NOTE: Server::Starter requires the server to support binding on a specific fd, which means only :fcgi and :woo are the ones work with start_server command.

To restart the server, send HUP signal (kill -HUP <pid>) to the start_server process.

Error Log

Caveman outputs error backtraces to a file which is specified at :error-log in your configuration.

(defconfig |default|
  `(:error-log #P"/var/log/apps/myapp_error.log"
    :databases
    ((:maindb :sqlite3 :database-name ,(merge-pathnames #P"myapp.db"
                                                        *application-root*)))))

Use another templating library

CL-WHO

(import 'cl-who:with-html-output-to-string)

(defroute "/" ()
  (with-html-output-to-string (output nil :prologue t)
    (:html
      (:head (:title "Welcome to Caveman!"))
      (:body "Blah blah blah."))))
;=> "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
;   <html><head><title>Welcome to Caveman!</title></head><body>Blah blah blah.</body></html>"

CL-Markup

(import 'cl-markup:xhtml)

(defroute "/" ()
  (xhtml
    (:head (:title "Welcome to Caveman!"))
    (:body "Blah blah blah.")))
;=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html><head><title>Welcome to Caveman!</title></head><body>Blah blah blah.</body></html>"

cl-closure-template

{namespace myapp.view}

{template renderIndex}
<!DOCTYPE html>
<html>
<head>
  <title>"Welcome to Caveman!</title>
</head>
<body>
  Blah blah blah.
</body>
</html>
{/template}
(import 'myapp.config:*template-directory*)

(closure-template:compile-cl-templates (merge-pathnames #P"index.tmpl"
                                                        *template-directory*))

(defroute "/" ()
  (myapp.view:render-index))

See Also

Author

License

Licensed under the LLGPL License.


Next: , Previous: , Up: Top   [Contents][Index]

2 Systems

The main system appears first, followed by any subsystem dependency.


Previous: , Up: Systems   [Contents][Index]

2.1 caveman

Author

Eitaro Fukamachi

License

LLGPL

Description

Web Application Framework for Common Lisp

Long Description

# Caveman2 - Lightweight web application framework

[![Build Status](https://travis-ci.org/fukamachi/caveman.svg?branch=master)](https://travis-ci.org/fukamachi/caveman)

## Usage

“‘common-lisp
(defparameter *web* (make-instance ’<app>))

@route GET "/"
(defun index ()
(render #P"index.tmpl"))

@route GET "/hello"
(defun say-hello (&key (|name| "Guest"))
(format nil "Hello, ~A" |name|))
“‘

## About Caveman2

### What’s the difference from Caveman "1"?

All of them. Caveman2 was written from scratch.

These are noticeable points.

* Bases on [ningle](http://8arrow.org/ningle/)
* Database integration
* New separated configuration system ([Envy](https://github.com/fukamachi/envy))
* New routing macro

### The reason I wrote it from scratch

One of the most frequently asked questions was "Which should I use ningle or Caveman? What are the differences?" I think it was because the roles of them were too similar. Both of them are saying "micro" and no database support.

Caveman2 is no more "micro" web application framework. It supports CL-DBI and has database connection management by default. Caveman has started growing up.

## Design Goal

Caveman is intended to be a collection of common parts of web applications. Caveman has 3 rules to make decisions.

* Be extensible.
* Be practical.
* Don’t force anything.

## Quickstart

You came here because you’re interested in living like a caveman, right? There’s no Disneyland, but it’s good place to start. Let’s get into a cave.

### Installation

Caveman2 is now available on [Quicklisp](https://www.quicklisp.org/beta/).

“‘common-lisp
(ql:quickload :caveman2)
“‘

### Generating a project skeleton

“‘common-lisp
(caveman2:make-project #P"/path/to/myapp/"
:author "<Your full name>")
;-> writing /path/to/myapp/.gitignore
; writing /path/to/myapp/README.markdown
; writing /path/to/myapp/app.lisp
; writing /path/to/myapp/db/schema.sql
; writing /path/to/myapp/shlyfile.lisp
; writing /path/to/myapp/myapp-test.asd
; writing /path/to/myapp/myapp.asd
; writing /path/to/myapp/src/config.lisp
; writing /path/to/myapp/src/db.lisp
; writing /path/to/myapp/src/main.lisp
; writing /path/to/myapp/src/view.lisp
; writing /path/to/myapp/src/web.lisp
; writing /path/to/myapp/static/css/main.css
; writing /path/to/myapp/t/myapp.lisp
; writing /path/to/myapp/templates/_errors/404.html
; writing /path/to/myapp/templates/index.tmpl
; writing /path/to/myapp/templates/layout/default.tmpl
“‘

### Routing

Caveman2 provides 2 ways to define a route – ‘@route‘ and ‘defroute‘. You can choose which to use.

‘@route‘ is an annotation macro defined by using [cl-annot](https://github.com/arielnetworks/cl-annot). It takes a method, an URL-string and a function.

“‘common-lisp
@route GET "/"
(defun index ()
...)

;; A route with no name.
@route GET "/welcome"
(lambda (&key (|name| "Guest"))
(format nil "Welcome, ~A" |name|))
“‘

This is similar to Caveman1’s ‘@url‘ except its argument list. You don’t have to specify an argument when you don’t need it.

‘defroute‘ is just a macro. It provides same feature to ‘@route‘.

“‘common-lisp
(defroute index "/" ()
...)

;; A route with no name.
(defroute "/welcome" (&key (|name| "Guest"))
(format nil "Welcome, ~A" |name|))
“‘

Since Caveman bases on ningle, Caveman also has the [Sinatra](http://www.sinatrarb.com/)-like routing system.

“‘common-lisp
;; GET request (default)
@route GET "/" (lambda () ...)
(defroute ("/" :method :GET) () ...)

;; POST request
@route POST "/" (lambda () ...)
(defroute ("/" :method :POST) () ...)

;; PUT request
@route PUT "/" (lambda () ...)
(defroute ("/" :method :PUT) () ...)

;; DELETE request
@route DELETE "/" (lambda () ...)
(defroute ("/" :method :DELETE) () ...)

;; OPTIONS request
@route OPTIONS "/" (lambda () ...)
(defroute ("/" :method :OPTIONS) () ...)

;; For all methods
@route ANY "/" (lambda () ...)
(defroute ("/" :method :ANY) () ...)
“‘

Route pattern may contain "keyword" to put the value into the argument.

“‘common-lisp
(defroute "/hello/:name" (&key name)
(format nil "Hello, ~A" name))
“‘

The above controller will be invoked when you access to "/hello/Eitaro" or "/hello/Tomohiro", and then ‘name‘ will be "Eitaro" and "Tomohiro".

‘(&key name)‘ is almost same as a lambda list of Common Lisp, excepts it always allows other keys.

“‘common-lisp
(defroute "/hello/:name" (&rest params &key name)
;; ...
)
“‘

Route patterns may also contain "wildcard" parameters. They are accessible by ‘splat‘.

“‘common-lisp
(defroute "/say/*/to/*" (&key splat)
; matches /say/hello/to/world
splat ;=> ("hello" "world")
))

(defroute "/download/*.*" (&key splat)
; matches /download/path/to/file.xml
splat ;=> ("path/to/file" "xml")
))
“‘

If you’d like to write a regular expression for URL rule, ‘:regexp t‘ should work for it.

“‘common-lisp
(defroute ("/hello/([\\w]+)" :regexp t) (&key captures)
(format nil "Hello, ~A!" (first captures)))
“‘

Normally, routes are matched in the order they are defined. Only the first route matched is invoked and rest of them just will be ignored. But, a route can punt processing to the next matching route using ‘next-route‘.

“‘common-lisp
(defroute "/guess/:who" (&key who)
(if (string= who "Eitaro")
"You got me!"
(next-route)))

(defroute "/guess/*" ()
"You missed!")
“‘

You can return following formats as the result of ‘defroute‘.

* String
* Pathname
* Clack’s response list (containing Status, Headers and Body)

### Structured query/post parameters

Parameter keys contain square brackets ("[" & "]") will be parsed as structured parameters. You can access the parsed parameters as ‘_parsed‘ in routers.

“‘html
<form action="/edit">
<input type="name" name="person[name]" />
<input type="name" name="person[email]" />
<input type="name" name="person[birth][year]" />
<input type="name" name="person[birth][month]" />
<input type="name" name="person[birth][day]" />
</form>
“‘

“‘common-lisp
(defroute "/edit" (&key _parsed)
(format nil "~S" (cdr (assoc "person" _parsed :test #’string=))))
;=> "((\"name\" . \"Eitaro\") (\"email\" . \"e.arrows@gmail.com\") (\"birth\" . ((\"year\" . 2000) (\"month\" . 1) (\"day\" . 1))))"
“‘

Blank keys mean they have multiple values.

“‘html
<form action="/add">
<input type="text" name="items[][name]" />
<input type="text" name="items[][price]" />

<input type="text" name="items[][name]" />
<input type="text" name="items[][price]" />

<input type="submit" value="Add" />
</form>
“‘

“‘common-lisp
(defroute "/add" (&key _parsed)
(format nil "~S" (assoc "items" _parsed :test #’string=)))
;=> "(((\"name\" . \"WiiU\") (\"price\" . \"30000\")) ((\"name\" . \"PS4\") (\"price\" . \"69000\")))"
“‘

### Templates

Caveman adopts [Djula](http://mmontone.github.io/djula/) for the default templating engine.

“‘html
{% extends "layouts/default.html" %}
{% block title %}Users | MyApp{% endblock %}
{% block content %}
<div id="main">
<ul>
{% for user in users %}
<li><a href="{{ user.url }}">{{ user.name }}</a></li>
{% endfor %}
</ul>
</div>
{% endblock %}
“‘

“‘common-lisp
(import ’myapp.view:render)

(render #P"users.html"
’(:users ((:url "/id/1"
:name "nitro_idiot")
(:url "/id/2"
:name "meymao"))
:has-next-page T))
“‘

If you want to get something from a database or execute any function using [Djula](http://mmontone.github.io/djula/) you have to explicity call ‘list‘ when passing the arguments to render so that the code executes.

“‘common-lisp
(import ’myapp.view:render)

(render #P"users.html"
(list :users (get-users-from-db)))
“‘

### JSON API

This is an example of a JSON API.

“‘common-lisp
(defroute "/user.json" (&key |id|)
(let ((person (find-person-from-db |id|)))
;; person => (:|name| "Eitaro Fukamachi" :|email| "e.arrows@gmail.com")
(render-json person)))

;=> {"name":"Eitaro Fukamachi","email":"e.arrows@gmail.com"}
“‘

‘render-json‘ is a part of a skeleton project. You can find its code in "src/view.lisp".

### Static file

Images, CSS, JS, favicon.ico and robot.txt in "static/" directory will be served by default.

“‘
/images/logo.png => {PROJECT_ROOT}/static/images/logo.png
/css/main.css => {PROJECT_ROOT}/static/css/main.css
/js/app/index.js => {PROJECT_ROOT}/static/js/app/index.js
/robot.txt => {PROJECT_ROOT}/static/robot.txt
/favicon.ico => {PROJECT_ROOT}/static/favicon.ico
“‘

You can change these rules by rewriting "PROJECT_ROOT/app.lisp". See [Clack.Middleware.Static](http://quickdocs.org/clack/api#package-CLACK.MIDDLEWARE.STATIC) for detail.

### Configuration

Caveman adopts [Envy](https://github.com/fukamachi/envy) as a configuration switcher. It allows to define multiple configurations and to switch them by an environment variable.

This is a typical example.

“‘common-lisp
(defpackage :myapp.config
(:use :cl
:envy))
(in-package :myapp.config)

(setf (config-env-var) "APP_ENV")

(defconfig :common
‘(:application-root ,(asdf:component-pathname (asdf:find-system :myapp))))

(defconfig |development|
’(:debug T
:databases
((:maindb :sqlite3 :database-name ,(merge-pathnames #P"test.db"
*application-root*)))))

(defconfig |production|
’(:databases
((:maindb :mysql :database-name "myapp" :username "whoami" :password "1234")
(:workerdb :mysql :database-name "jobs" :username "whoami" :password "1234"))))

(defconfig |staging|
‘(:debug T
,@|production|))
“‘

Every configuration is a property list. You can choose the configuration which to use by setting ‘APP_ENV‘.

To get a value from the current configuration, call ‘myapp.config:config‘ with a key you want.

“‘common-lisp
(import ’myapp.config:config)

(setf (osicat:environment-variable "APP_ENV") "development")
(config :debug)
;=> T
“‘

### Database

When you add ‘:databases‘ to the configuration, Caveman enables database support. ‘:databases‘ is an association list of database settings.

“‘common-lisp
(defconfig |production|
’(:databases
((:maindb :mysql :database-name "myapp" :username "whoami" :password "1234")
(:workerdb :mysql :database-name "jobs" :username "whoami" :password "1234"))))
“‘

‘db‘ in a package ‘myapp.db‘ is a function for connecting to each databases configured the above. Here is an example.

“‘common-lisp
(use-package ’(:myapp.db :sxql :datafly))

(defun search-adults ()
(with-connection (db)
(retrieve-all
(select :*
(from :person)
(where (:>= :age 20))))))
“‘

The connection is alive during the Lisp session and will be reused in each HTTP requests.

‘retrieve-all‘ and the query language came from [datafly](https://github.com/fukamachi/datafly) and [SxQL](https://github.com/fukamachi/sxql). See those documentations for more informations.

### Set HTTP headers or HTTP status

There are several special variables available during a HTTP request. ‘*request*‘ and ‘*response*‘ represents a request and a response. If you are familiar with [Clack](http://clacklisp.org/), these are instances of subclasses of [Clack.Request](http://quickdocs.org/clack/api#package-CLACK.REQUEST) and [Clack.Response](http://quickdocs.org/clack/api#package-CLACK.RESPONSE).

“‘common-lisp
(use-package :caveman2)

;; Get a value of Referer header.
(http-referer *request*)

;; Set Content-Type header.
(setf (getf (response-headers *response* :content-type) "application/json")

;; Set HTTP status.
(setf (status *response*) 304)
“‘

If you would like to set Content-Type "application/json" for all "*.json" requests, ‘next-route‘ will help you.

“‘common-lisp
(defroute "/*.json" ()
(setf (getf (response-headers *response*) :content-type) "application/json")
(next-route))

(defroute "/user.json" () ...)
(defroute "/search.json" () ...)
(defroute ("/new.json" :method :POST) () ...)
“‘

### Using session

Session data is for memorizing user-specific data. ‘*session*‘ is a hash table represents session data.

This example increments ‘:counter‘ in the session and displays it for each visitors.

“‘common-lisp
(defroute "/counter" ()
(format nil "You came here ~A times."
(incf (gethash :counter *session* 0))))
“‘

Caveman2 stores the session data in-memory by default. To change it, specify ‘:store‘ to ‘:session‘ in "PROJECT_ROOT/app.lisp".

This example uses RDBMS to store it.

“‘diff
’(:backtrace
:output (getf (config) :error-log))
nil)
- :session
+ (:session
+ :store (make-dbi-store :connector (lambda ()
+ (apply #’dbi:connect
+ (myapp.db:connection-settings)))))
(if (productionp)
nil
(lambda (app)
“‘

NOTE: Don’t forget to add ‘:lack-session-store-dbi‘ as ‘:depends-on‘ of your app. It is not a part of Clack/Lack.

See the source code of Lack.Session.Store.DBi for more informations.

- [Lack.Session.Store.Dbi](https://github.com/fukamachi/lack/blob/master/src/middleware/session/store/dbi.lisp)

### Throw an HTTP status code

“‘common-lisp
(import ’caveman2:throw-code)

(defroute ("/auth" :method :POST) (&key |name| |password|)
(unless (authorize |name| |password|)
(throw-code 403)))
“‘

### Specify error pages

To specify error pages for 404, 500 or so, define a method ‘on-exception‘ of your app.

“‘common-lisp
(defmethod on-exception ((app <web>) (code (eql 404)))
(declare (ignore app code))
(merge-pathnames #P"_errors/404.html"
*template-directory*))
“‘

### Start a server

Your application has functions named ‘start‘ and ‘stop‘ to start/stop your web application. This is a example assuming that the name of your application is "myapp".

“‘common-lisp
(myapp:start :port 8080)
“‘

As Caveman bases on Clack/Lack, you can choose which server to run on – Hunchentoot, mod_lisp or FastCGI.

“‘common-lisp
(myapp:start :server :hunchentoot :port 8080)
(myapp:start :server :fcgi :port 8080)
“‘

I recommend you to use Hunchentoot in local machine and use FastCGI/Woo for production environment.

You can also start your application by using [clackup command](https://github.com/fukamachi/clack/blob/master/roswell/clackup.ros).

$ ros install clack
$ which clackup
/Users/nitro_idiot/.roswell/bin/clackup

$ APP_ENV=development clackup –server :fcgi –port 8080 app.lisp

### Hot Deployment

Though Caveman doesn’t have a feature for hot deployment, [Server::Starter](http://search.cpan.org/~kazuho/Server-Starter-0.15/lib/Server/Starter.pm) – a Perl module – makes it easy.

$ APP_ENV=production start_server –port 8080 – clackup –server :fcgi app.lisp

NOTE: Server::Starter requires the server to support binding on a specific fd, which means only ‘:fcgi‘ and ‘:woo‘ are the ones work with ‘start_server‘ command.

To restart the server, send HUP signal (‘kill -HUP <pid>‘) to the ‘start_server‘ process.

### Error Log

Caveman outputs error backtraces to a file which is specified at ‘:error-log‘ in your configuration.

“‘common-lisp
(defconfig |default|
‘(:error-log #P"/var/log/apps/myapp_error.log"
:databases
((:maindb :sqlite3 :database-name ,(merge-pathnames #P"myapp.db"
*application-root*)))))
“‘

## Use another templating library

### CL-WHO

“‘common-lisp
(import ’cl-who:with-html-output-to-string)

(defroute "/" ()
(with-html-output-to-string (output nil :prologue t)
(:html
(:head (:title "Welcome to Caveman!"))
(:body "Blah blah blah."))))
;=> "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">
; <html><head><title>Welcome to Caveman!</title></head><body>Blah blah blah.</body></html>"
“‘

* [CL-WHO Website](http://weitz.de/cl-who/)

### CL-Markup

“‘common-lisp
(import ’cl-markup:xhtml)

(defroute "/" ()
(xhtml
(:head (:title "Welcome to Caveman!"))
(:body "Blah blah blah.")))
;=> "<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html><head><title>Welcome to Caveman!</title></head><body>Blah blah blah.</body></html>"
“‘

* [CL-Markup repository](https://github.com/arielnetworks/cl-markup)

### cl-closure-template

“‘html
{namespace myapp.view}

{template renderIndex}
<!DOCTYPE html>
<html>
<head>
<title>"Welcome to Caveman!</title>
</head>
<body>
Blah blah blah.
</body>
</html>
{/template}
“‘

“‘common-lisp
(import ’myapp.config:*template-directory*)

(closure-template:compile-cl-templates (merge-pathnames #P"index.tmpl"
*template-directory*))

(defroute "/" ()
(myapp.view:render-index))
“‘

* [cl-closure-template](http://quickdocs.org/cl-closure-template/)
* [Closure Templates Documentation](https://developers.google.com/closure/templates/docs/overview)

<!– Commenting out because these are old.

## Use another database library

### CLSQL

You can use Lack.Middleware.Clsql to use CLSQL in Clack compliant application.

In Caveman, add the middleware to ‘builder‘ in "PROJECT_ROOT/app.lisp".

“‘common-lisp
(ql:quickload :clack-middleware-clsql)
(import ’clack.middleware.clsql:<clack-middleware-clsql>)

(builder
(<clack-middleware-clsql>
:database-type :mysql
:connection-spec ’("localhost" "db" "fukamachi" "password"))
*web*)
“‘

* [Clack.Middleware.Clsql](http://quickdocs.org/clack/api#system-clack-middleware-clsql)
* [CLSQL: Common Lisp SQL Interface](http://clsql.b9.com/)

### Postmodern

You can use Clack.Middleware.Postmodern to use Postmodern in Clack compliant application.

In Caveman, add the middleware to ‘builder‘ in "PROJECT_ROOT/app.lisp".

“‘common-lisp
(ql:quickload :clack-middleware-postmodern)
(import ’clack.middleware.postmodern:<clack-middleware-postmodern>)

(builder
(<clack-middleware-postmodern>
:database "database-name"
:user "database-user"
:password "database-password"
:host "remote-address")
*web*)
“‘

* [Clack.Middleware.Postmodern](http://quickdocs.org/clack/api#system-clack-middleware-postmodern)
* [Postmodern](http://marijnhaverbeke.nl/postmodern/)

–>

## See Also

* [Clack](http://clacklisp.org/) - Web application environment.
* [Lack](https://github.com/fukamachi/lack) - The core of Clack.
* [ningle](http://8arrow.org/ningle/) - Super micro web application framework Caveman bases on.
* [Djula](http://mmontone.github.io/djula/) - HTML Templating engine.
* [CL-DBI](http://8arrow.org/cl-dbi/) - Database independent interface library.
* [SxQL](http://8arrow.org/sxql/) - SQL builder library.
* [Envy](https://github.com/fukamachi/envy) - Configuration switcher.
* [Roswell](https://github.com/snmsts/roswell) - Common Lisp implementation manager.

## Author

* Eitaro Fukamachi (e.arrows@gmail.com)

# License

Licensed under the LLGPL License.

Version

12.8.0

Dependencies
Source

caveman.asd (file)

Component

v1/src (module)


Next: , Previous: , Up: Top   [Contents][Index]

3 Modules

Modules are listed depth-first from the system components tree.


Next: , Previous: , Up: Modules   [Contents][Index]

3.1 caveman/v1/src

Parent

caveman (system)

Location

v1/src/

Components

Next: , Previous: , Up: Modules   [Contents][Index]

3.2 caveman/v1/src/core

Parent

v1/src (module)

Location

v1/src/core/

Components

Next: , Previous: , Up: Modules   [Contents][Index]

3.3 caveman/v1/src/lib

Dependency

core (module)

Parent

v1/src (module)

Location

v1/src/lib/

Components

Next: , Previous: , Up: Modules   [Contents][Index]

3.4 caveman/v1/src/lib/widget

Parent

lib (module)

Location

v1/src/lib/widget/

Component

form.lisp (file)


Previous: , Up: Modules   [Contents][Index]

3.5 caveman/v1/src/lib/view

Parent

lib (module)

Location

v1/src/lib/view/

Components

Next: , Previous: , Up: Top   [Contents][Index]

4 Files

Files are sorted by type and then listed depth-first from the systems components trees.


Previous: , Up: Files   [Contents][Index]

4.1 Lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.1 caveman.asd

Location

caveman.asd

Systems

caveman (system)

Packages

caveman-asd


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.2 caveman/v1/src/core/caveman.lisp

Dependencies
Parent

core (module)

Location

v1/src/core/caveman.lisp

Packages

caveman

Exported Definitions

Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.3 caveman/v1/src/core/app.lisp

Dependencies
Parent

core (module)

Location

v1/src/core/app.lisp

Packages

caveman.app

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.4 caveman/v1/src/core/project.lisp

Dependencies
Parent

core (module)

Location

v1/src/core/project.lisp

Packages

caveman.project

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.5 caveman/v1/src/core/request.lisp

Parent

core (module)

Location

v1/src/core/request.lisp

Packages

caveman.request

Exported Definitions

Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.6 caveman/v1/src/core/response.lisp

Parent

core (module)

Location

v1/src/core/response.lisp

Packages

caveman.response

Exported Definitions

<response> (class)


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.7 caveman/v1/src/core/context.lisp

Dependencies
Parent

core (module)

Location

v1/src/core/context.lisp

Packages

caveman.context

Exported Definitions

Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.8 caveman/v1/src/core/middleware/context.lisp

Dependency

context.lisp (file)

Parent

core (module)

Location

v1/src/core/middleware/context.lisp

Packages

caveman.middleware.context

Exported Definitions

<caveman-middleware-context> (class)


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.9 caveman/v1/src/core/skeleton.lisp

Parent

core (module)

Location

v1/src/core/skeleton.lisp

Packages

caveman.skeleton

Exported Definitions

generate (function)

Internal Definitions

*skeleton-directory* (special variable)


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.10 caveman/v1/src/core/route.lisp

Dependency

app.lisp (file)

Parent

core (module)

Location

v1/src/core/route.lisp

Packages

caveman.route

Exported Definitions
Internal Definitions

add-query-parameters (function)


Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.11 caveman/v1/src/core/widget.lisp

Parent

core (module)

Location

v1/src/core/widget.lisp

Packages

caveman.widget

Exported Definitions

Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.12 caveman/v1/src/lib/widget/form.lisp

Parent

widget (module)

Location

v1/src/lib/widget/form.lisp

Packages

caveman.widget.form

Exported Definitions
Internal Definitions

Next: , Previous: , Up: Lisp files   [Contents][Index]

4.1.13 caveman/v1/src/lib/view/function.lisp

Parent

view (module)

Location

v1/src/lib/view/function.lisp

Packages

caveman.view.function

Exported Definitions

render (function)


Previous: , Up: Lisp files   [Contents][Index]

4.1.14 caveman/v1/src/lib/view/emb.lisp

Dependency

function.lisp (file)

Parent

view (module)

Location

v1/src/lib/view/emb.lisp

Packages

caveman.view.emb

Exported Definitions

render (function)


Next: , Previous: , Up: Top   [Contents][Index]

5 Packages

Packages are listed by definition order.


Next: , Previous: , Up: Packages   [Contents][Index]

5.1 caveman-asd

Source

caveman.asd

Use List

Next: , Previous: , Up: Packages   [Contents][Index]

5.2 caveman

Source

caveman.lisp (file)

Use List

common-lisp

Exported Definitions

Next: , Previous: , Up: Packages   [Contents][Index]

5.3 caveman.app

Source

app.lisp (file)

Use List
Exported Definitions
Internal Definitions

Next: , Previous: , Up: Packages   [Contents][Index]

5.4 caveman.project

Source

project.lisp (file)

Use List
Exported Definitions
Internal Definitions

Next: , Previous: , Up: Packages   [Contents][Index]

5.5 caveman.request

Source

request.lisp (file)

Use List
Exported Definitions

Next: , Previous: , Up: Packages   [Contents][Index]

5.6 caveman.response

Source

response.lisp (file)

Use List
Exported Definitions

<response> (class)


Next: , Previous: , Up: Packages   [Contents][Index]

5.7 caveman.context

Source

context.lisp (file)

Use List
Exported Definitions

Next: , Previous: , Up: Packages   [Contents][Index]

5.8 caveman.middleware.context

Source

middleware/context.lisp (file)

Use List
Used By List

caveman.app

Exported Definitions

<caveman-middleware-context> (class)


Next: , Previous: , Up: Packages   [Contents][Index]

5.9 caveman.skeleton

Source

skeleton.lisp (file)

Use List

common-lisp

Exported Definitions

generate (function)

Internal Definitions

*skeleton-directory* (special variable)


Next: , Previous: , Up: Packages   [Contents][Index]

5.10 caveman.route

Source

route.lisp (file)

Use List
Exported Definitions
Internal Definitions

add-query-parameters (function)


Next: , Previous: , Up: Packages   [Contents][Index]

5.11 caveman.widget

Source

widget.lisp (file)

Use List
Used By List

caveman.widget.form

Exported Definitions

Next: , Previous: , Up: Packages   [Contents][Index]

5.12 caveman.widget.form

Source

form.lisp (file)

Use List
Exported Definitions
Internal Definitions

Next: , Previous: , Up: Packages   [Contents][Index]

5.13 caveman.view.function

Source

function.lisp (file)

Use List

common-lisp

Exported Definitions

render (function)


Previous: , Up: Packages   [Contents][Index]

5.14 caveman.view.emb

Source

emb.lisp (file)

Use List

common-lisp

Exported Definitions

render (function)


Next: , Previous: , Up: Top   [Contents][Index]

6 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.


Next: , Previous: , Up: Definitions   [Contents][Index]

6.1 Exported definitions


Next: , Previous: , Up: Exported definitions   [Contents][Index]

6.1.1 Special variables

Special Variable: *context*

Special variable to store Caveman Context, a hash table.
Don’t set to this variable directly. This is designed to be bound in lexical let.

Package

caveman.context

Source

context.lisp (file)

Special Variable: *project*

Special variable to store current Caveman application.
Don’t set to this variable directly. This is designed to be bound in lexical let.

Package

caveman.context

Source

context.lisp (file)

Special Variable: *request*

Special variable to store Caveman Request, a instance of ‘<request>’ in Caveman.Request package. Don’t set to this variable directly. This is designed to be bound in lexical let.

Package

caveman.context

Source

context.lisp (file)

Special Variable: *response*

Special variable to store Caveman Response, a instance of ‘<response>’ in Caveman.Response package. Don’t set to this variable directly. This is designed to be bound in lexical let.

Package

caveman.context

Source

context.lisp (file)

Special Variable: *session*

Special variable to store session.
Don’t set to this variable directly. This is designed to be bound in lexical let.

Package

caveman.context

Source

context.lisp (file)


Next: , Previous: , Up: Exported definitions   [Contents][Index]

6.1.2 Macros

Macro: defroute METHOD URL-RULE FORM

Recreation of @URL annotation in S-expression form

Package

caveman.route

Source

route.lisp (file)

Macro: url METHOD URL-RULE FORM

Useful annotation to define actions.

Example:
;; for Function
@url GET "/login"
(defun login (req)
;; response
)

;; for Clack Component
@url GET "/member/:id"
(defclass <member-profile> (<component>) ()) (defmethod call ((this <member-profile>) req) ;; response
)

Package

caveman.route

Source

route.lisp (file)

Macro: url->routing-rule METHOD URL-RULE FORM

Convert action form into a routing rule, a list.

Example:
((member-profile #<url-rule> #’member-profile) (login-form #<url-rule> #’login-form))

Package

caveman.route

Source

route.lisp (file)

Macro: with-context-variables (&rest VARS) &body BODY
Package

caveman.context

Source

context.lisp (file)


Next: , Previous: , Up: Exported definitions   [Contents][Index]

6.1.3 Functions

Function: app-path &rest PATHS
Package

caveman

Source

caveman.lisp (file)

Function: config &optional KEY
Package

caveman

Source

caveman.lisp (file)

Function: context &optional KEY

Access to current context. If key is specified, return the value in current context. If not, just return a current context.

Example:
(context)
;=> #<HASH-TABLE :TEST EQL size 0/60 #x3020025FF5FD>
(context :request)
;=> #<CAVEMAN.REQUEST:<REQUEST> #x3020024FCCFD>

Package

caveman.context

Source

context.lisp (file)

Writer

(setf context) (function)

Function: (setf context) VAL KEY
Package

caveman.context

Source

context.lisp (file)

Reader

context (function)

Function: current-mode ()
Package

caveman

Source

caveman.lisp (file)

Function: current-uri ()
Package

caveman

Source

caveman.lisp (file)

Function: forward-to SYMBOL &rest PARAMS
Package

caveman

Source

caveman.lisp (file)

Function: generate PATH &rest PARAMS &key NAME DESCRIPTION AUTHOR EMAIL LICENSE DEPENDS-ON &allow-other-keys

Generate a skeleton of Caveman Application.
‘name’ must be a symbol or a keyword. ‘path’ must be a pathname. If ‘path’ isn’t specified, generate a skeleton to current directory.

Package

caveman.skeleton

Source

skeleton.lisp (file)

Function: make-context REQ

Create a new Context.

Package

caveman.context

Source

context.lisp (file)

Function: make-form &rest ARGS

A synonim for ‘(make-instance ’<caveman-widget-form> ...)‘.

Package

caveman.widget.form

Source

form.lisp (file)

Function: make-request REQ

Construct a request instance.

Package

caveman.request

Source

request.lisp (file)

Function: next-route ()
Package

caveman.app

Source

app.lisp (file)

Function: not-found ()

An action when no routing rules are found.

Package

caveman.app

Source

app.lisp (file)

Function: redirect-to URL-OR-ACTION &rest PARAMS
Package

caveman

Source

caveman.lisp (file)

Function: render FN PARAMS

Render function for Functions.

Package

caveman.view.function

Source

function.lisp (file)

Function: render FILE PARAMS

Render function for CL-EMB templates.

Package

caveman.view.emb

Source

emb.lisp (file)

Function: url-for SYMBOL &rest PARAMS

Make an URL for the action with PARAMS.

Example:
@url GET "/animals/:type"
(defun animals (params))

(url-for ’animals :type "cat")
;; => "/animals/cat"

Package

caveman.route

Source

route.lisp (file)


Next: , Previous: , Up: Exported definitions   [Contents][Index]

6.1.4 Generic functions

Generic Function: add THIS WIDGET
Package

caveman.widget.form

Methods
Method: add (THIS <caveman-widget-form>) WIDGET

Add another widget to this form. That will be rendered in ’form’ tag.

Source

form.lisp (file)

Generic Function: add-route THIS ROUTING-RULE
Package

caveman.app

Methods
Method: add-route (THIS <app>) ROUTING-RULE

Add a routing rule to the Application.

Source

app.lisp (file)

Generic Function: build PROJECT

Build up an application for this project and return it. This method must be implemented in subclasses.

Package

caveman.project

Source

project.lisp (file)

Generic Function: config OBJECT
Generic Function: (setf config) NEW-VALUE OBJECT
Package

caveman.project

Methods
Method: config (<PROJECT> <project>)

automatically generated reader method

Source

project.lisp (file)

Method: (setf config) NEW-VALUE (<PROJECT> <project>)

automatically generated writer method

Source

project.lisp (file)

Generic Function: debug-mode-p OBJECT
Generic Function: (setf debug-mode-p) NEW-VALUE OBJECT
Package

caveman.project

Methods
Method: debug-mode-p (<PROJECT> <project>)

automatically generated reader method

Source

project.lisp (file)

Method: (setf debug-mode-p) NEW-VALUE (<PROJECT> <project>)

automatically generated writer method

Source

project.lisp (file)

Generic Function: load-config THIS MODE
Package

caveman.project

Methods
Method: load-config (THIS <project>) MODE
Source

project.lisp (file)

Generic Function: lookup-route THIS SYMBOL
Package

caveman.app

Methods
Method: lookup-route (THIS <app>) SYMBOL

Lookup a routing rule with SYMBOL from the application.

Source

app.lisp (file)

Generic Function: project-mode OBJECT
Generic Function: (setf project-mode) NEW-VALUE OBJECT
Package

caveman.project

Methods
Method: project-mode (<PROJECT> <project>)

automatically generated reader method

Source

project.lisp (file)

Method: (setf project-mode) NEW-VALUE (<PROJECT> <project>)

automatically generated writer method

Source

project.lisp (file)

Generic Function: render THIS &optional PARAMS
Package

caveman.widget

Methods
Method: render (THIS <caveman-widget>) &optional PARAMS
Source

widget.lisp (file)

Generic Function: start THIS &key PORT SERVER MODE DEBUG LAZY &allow-other-keys
Package

caveman.project

Methods
Method: start (THIS <project>) &key PORT SERVER &allow-other-keys
Source

project.lisp (file)

Method: start (THIS <project>) &key MODE DEBUG LAZY &allow-other-keys around
Source

project.lisp (file)

Generic Function: stop THIS
Package

caveman.project

Methods
Method: stop (THIS <project>)

Stop a server.

Source

project.lisp (file)

Generic Function: validate THIS VALUES
Package

caveman.widget.form

Methods
Method: validate (THIS <caveman-widget-form>) VALUES
Source

form.lisp (file)

Generic Function: view OBJECT
Generic Function: (setf view) NEW-VALUE OBJECT
Package

caveman.widget

Methods
Method: view (<CAVEMAN-WIDGET> <caveman-widget>)

automatically generated reader method

Source

widget.lisp (file)

Method: (setf view) NEW-VALUE (<CAVEMAN-WIDGET> <caveman-widget>)

automatically generated writer method

Source

widget.lisp (file)


Previous: , Up: Exported definitions   [Contents][Index]

6.1.5 Classes

Class: <app> ()

Base class for Caveman Application. All Caveman Application must inherit this class.

Package

caveman.app

Source

app.lisp (file)

Direct superclasses

<component> (class)

Direct methods
Direct slots
Slot: routing-rules
Initargs

caveman.app::routing-rules

Readers

routing-rules (generic function)

Writers

(setf routing-rules) (generic function)

Class: <caveman-middleware-context> ()

Clack Middleware to set context for each request.

Package

caveman.middleware.context

Source

middleware/context.lisp (file)

Direct superclasses

<middleware> (class)

Direct methods

call (method)

Class: <caveman-widget-form> ()
Package

caveman.widget.form

Source

form.lisp (file)

Direct superclasses

<caveman-widget> (class)

Direct methods
Direct slots
Slot: action
Type

string

Initargs

:action

Initform

""

Readers

form-action (generic function)

Writers

(setf form-action) (generic function)

Slot: method
Type

keyword

Initargs

:method

Initform

:post

Readers

form-method (generic function)

Writers

(setf form-method) (generic function)

Slot: components
Type

list

Initargs

:components

Readers

form-components (generic function)

Writers

(setf form-components) (generic function)

Class: <caveman-widget> ()

Base class of view widget.

Package

caveman.widget

Source

widget.lisp (file)

Direct superclasses

standard-object (class)

Direct subclasses

<caveman-widget-form> (class)

Direct methods
Direct slots
Slot: view
Type

(or null function clack.component:<component>)

Initargs

:view

Readers

view (generic function)

Writers

(setf view) (generic function)

Class: <project> ()
Package

caveman.project

Source

project.lisp (file)

Direct superclasses

<component> (class)

Direct methods
Direct slots
Slot: config
Initargs

:config

Readers

config (generic function)

Writers

(setf config) (generic function)

Slot: acceptor
Readers

acceptor (generic function)

Writers

(setf acceptor) (generic function)

Slot: debug-mode-p
Type

boolean

Initargs

:debug-mode-p

Initform

t

Readers

debug-mode-p (generic function)

Writers

(setf debug-mode-p) (generic function)

Slot: mode
Type

keyword

Initargs

:mode

Readers

project-mode (generic function)

Writers

(setf project-mode) (generic function)

Class: <request> ()

Class for Caveman Request.

Package

caveman.request

Source

request.lisp (file)

Direct superclasses

<request> (class)

Class: <response> ()

Class for Caveman Response.

Package

caveman.response

Source

response.lisp (file)

Direct superclasses

<response> (class)


Previous: , Up: Definitions   [Contents][Index]

6.2 Internal definitions


Next: , Previous: , Up: Internal definitions   [Contents][Index]

6.2.1 Special variables

Special Variable: *next-route-function*

A function called when ‘next-route’ is invoked. This will be overwritten in ‘dispatch-with-rules’.

Package

caveman.app

Source

app.lisp (file)

Special Variable: *skeleton-directory*
Package

caveman.skeleton

Source

skeleton.lisp (file)


Next: , Previous: , Up: Internal definitions   [Contents][Index]

6.2.2 Functions

Function: add-query-parameters BASE-URL PARAMS

Add a query parameters string of PARAMS to BASE-URL.

Package

caveman.route

Source

route.lisp (file)

Function: dispatch-with-rules RULES
Package

caveman.app

Source

app.lisp (file)

Function: member-rule PATH-INFO METHOD RULES &key ALLOW-HEAD
Package

caveman.app

Source

app.lisp (file)

Function: slurp-file PATH

Read a specified file and return the content as a sequence.

Package

caveman.project

Source

project.lisp (file)


Previous: , Up: Internal definitions   [Contents][Index]

6.2.3 Generic functions

Generic Function: acceptor OBJECT
Generic Function: (setf acceptor) NEW-VALUE OBJECT
Package

caveman.project

Methods
Method: acceptor (<PROJECT> <project>)

automatically generated reader method

Source

project.lisp (file)

Method: (setf acceptor) NEW-VALUE (<PROJECT> <project>)

automatically generated writer method

Source

project.lisp (file)

Generic Function: form-action OBJECT
Generic Function: (setf form-action) NEW-VALUE OBJECT
Package

caveman.widget.form

Methods
Method: form-action (<CAVEMAN-WIDGET-FORM> <caveman-widget-form>)

automatically generated reader method

Source

form.lisp (file)

Method: (setf form-action) NEW-VALUE (<CAVEMAN-WIDGET-FORM> <caveman-widget-form>)

automatically generated writer method

Source

form.lisp (file)

Generic Function: form-components OBJECT
Generic Function: (setf form-components) NEW-VALUE OBJECT
Package

caveman.widget.form

Methods
Method: form-components (<CAVEMAN-WIDGET-FORM> <caveman-widget-form>)

automatically generated reader method

Source

form.lisp (file)

Method: (setf form-components) NEW-VALUE (<CAVEMAN-WIDGET-FORM> <caveman-widget-form>)

automatically generated writer method

Source

form.lisp (file)

Generic Function: form-method OBJECT
Generic Function: (setf form-method) NEW-VALUE OBJECT
Package

caveman.widget.form

Methods
Method: form-method (<CAVEMAN-WIDGET-FORM> <caveman-widget-form>)

automatically generated reader method

Source

form.lisp (file)

Method: (setf form-method) NEW-VALUE (<CAVEMAN-WIDGET-FORM> <caveman-widget-form>)

automatically generated writer method

Source

form.lisp (file)

Generic Function: routing-rules OBJECT
Generic Function: (setf routing-rules) NEW-VALUE OBJECT
Package

caveman.app

Methods
Method: routing-rules (<APP> <app>)

automatically generated reader method

Source

app.lisp (file)

Method: (setf routing-rules) NEW-VALUE (<APP> <app>)

automatically generated writer method

Source

app.lisp (file)


Previous: , Up: Top   [Contents][Index]

Appendix A Indexes


Next: , Previous: , Up: Indexes   [Contents][Index]

A.1 Concepts

Jump to:   C   F   L   M  
Index Entry  Section

C
caveman.asd: The caveman<dot>asd file
caveman/v1/src: The caveman/v1/src module
caveman/v1/src/core: The caveman/v1/src/core module
caveman/v1/src/core/app.lisp: The caveman/v1/src/core/app<dot>lisp file
caveman/v1/src/core/caveman.lisp: The caveman/v1/src/core/caveman<dot>lisp file
caveman/v1/src/core/context.lisp: The caveman/v1/src/core/context<dot>lisp file
caveman/v1/src/core/middleware/context.lisp: The caveman/v1/src/core/middleware/context<dot>lisp file
caveman/v1/src/core/project.lisp: The caveman/v1/src/core/project<dot>lisp file
caveman/v1/src/core/request.lisp: The caveman/v1/src/core/request<dot>lisp file
caveman/v1/src/core/response.lisp: The caveman/v1/src/core/response<dot>lisp file
caveman/v1/src/core/route.lisp: The caveman/v1/src/core/route<dot>lisp file
caveman/v1/src/core/skeleton.lisp: The caveman/v1/src/core/skeleton<dot>lisp file
caveman/v1/src/core/widget.lisp: The caveman/v1/src/core/widget<dot>lisp file
caveman/v1/src/lib: The caveman/v1/src/lib module
caveman/v1/src/lib/view: The caveman/v1/src/lib/view module
caveman/v1/src/lib/view/emb.lisp: The caveman/v1/src/lib/view/emb<dot>lisp file
caveman/v1/src/lib/view/function.lisp: The caveman/v1/src/lib/view/function<dot>lisp file
caveman/v1/src/lib/widget: The caveman/v1/src/lib/widget module
caveman/v1/src/lib/widget/form.lisp: The caveman/v1/src/lib/widget/form<dot>lisp file

F
File, Lisp, caveman.asd: The caveman<dot>asd file
File, Lisp, caveman/v1/src/core/app.lisp: The caveman/v1/src/core/app<dot>lisp file
File, Lisp, caveman/v1/src/core/caveman.lisp: The caveman/v1/src/core/caveman<dot>lisp file
File, Lisp, caveman/v1/src/core/context.lisp: The caveman/v1/src/core/context<dot>lisp file
File, Lisp, caveman/v1/src/core/middleware/context.lisp: The caveman/v1/src/core/middleware/context<dot>lisp file
File, Lisp, caveman/v1/src/core/project.lisp: The caveman/v1/src/core/project<dot>lisp file
File, Lisp, caveman/v1/src/core/request.lisp: The caveman/v1/src/core/request<dot>lisp file
File, Lisp, caveman/v1/src/core/response.lisp: The caveman/v1/src/core/response<dot>lisp file
File, Lisp, caveman/v1/src/core/route.lisp: The caveman/v1/src/core/route<dot>lisp file
File, Lisp, caveman/v1/src/core/skeleton.lisp: The caveman/v1/src/core/skeleton<dot>lisp file
File, Lisp, caveman/v1/src/core/widget.lisp: The caveman/v1/src/core/widget<dot>lisp file
File, Lisp, caveman/v1/src/lib/view/emb.lisp: The caveman/v1/src/lib/view/emb<dot>lisp file
File, Lisp, caveman/v1/src/lib/view/function.lisp: The caveman/v1/src/lib/view/function<dot>lisp file
File, Lisp, caveman/v1/src/lib/widget/form.lisp: The caveman/v1/src/lib/widget/form<dot>lisp file

L
Lisp File, caveman.asd: The caveman<dot>asd file
Lisp File, caveman/v1/src/core/app.lisp: The caveman/v1/src/core/app<dot>lisp file
Lisp File, caveman/v1/src/core/caveman.lisp: The caveman/v1/src/core/caveman<dot>lisp file
Lisp File, caveman/v1/src/core/context.lisp: The caveman/v1/src/core/context<dot>lisp file
Lisp File, caveman/v1/src/core/middleware/context.lisp: The caveman/v1/src/core/middleware/context<dot>lisp file
Lisp File, caveman/v1/src/core/project.lisp: The caveman/v1/src/core/project<dot>lisp file
Lisp File, caveman/v1/src/core/request.lisp: The caveman/v1/src/core/request<dot>lisp file
Lisp File, caveman/v1/src/core/response.lisp: The caveman/v1/src/core/response<dot>lisp file
Lisp File, caveman/v1/src/core/route.lisp: The caveman/v1/src/core/route<dot>lisp file
Lisp File, caveman/v1/src/core/skeleton.lisp: The caveman/v1/src/core/skeleton<dot>lisp file
Lisp File, caveman/v1/src/core/widget.lisp: The caveman/v1/src/core/widget<dot>lisp file
Lisp File, caveman/v1/src/lib/view/emb.lisp: The caveman/v1/src/lib/view/emb<dot>lisp file
Lisp File, caveman/v1/src/lib/view/function.lisp: The caveman/v1/src/lib/view/function<dot>lisp file
Lisp File, caveman/v1/src/lib/widget/form.lisp: The caveman/v1/src/lib/widget/form<dot>lisp file

M
Module, caveman/v1/src: The caveman/v1/src module
Module, caveman/v1/src/core: The caveman/v1/src/core module
Module, caveman/v1/src/lib: The caveman/v1/src/lib module
Module, caveman/v1/src/lib/view: The caveman/v1/src/lib/view module
Module, caveman/v1/src/lib/widget: The caveman/v1/src/lib/widget module

Jump to:   C   F   L   M  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.2 Functions

Jump to:   (  
A   B   C   D   F   G   L   M   N   P   R   S   U   V   W  
Index Entry  Section

(
(setf acceptor): Internal generic functions
(setf acceptor): Internal generic functions
(setf config): Exported generic functions
(setf config): Exported generic functions
(setf context): Exported functions
(setf debug-mode-p): Exported generic functions
(setf debug-mode-p): Exported generic functions
(setf form-action): Internal generic functions
(setf form-action): Internal generic functions
(setf form-components): Internal generic functions
(setf form-components): Internal generic functions
(setf form-method): Internal generic functions
(setf form-method): Internal generic functions
(setf project-mode): Exported generic functions
(setf project-mode): Exported generic functions
(setf routing-rules): Internal generic functions
(setf routing-rules): Internal generic functions
(setf view): Exported generic functions
(setf view): Exported generic functions

A
acceptor: Internal generic functions
acceptor: Internal generic functions
add: Exported generic functions
add: Exported generic functions
add-query-parameters: Internal functions
add-route: Exported generic functions
add-route: Exported generic functions
app-path: Exported functions

B
build: Exported generic functions

C
config: Exported functions
config: Exported generic functions
config: Exported generic functions
context: Exported functions
current-mode: Exported functions
current-uri: Exported functions

D
debug-mode-p: Exported generic functions
debug-mode-p: Exported generic functions
defroute: Exported macros
dispatch-with-rules: Internal functions

F
form-action: Internal generic functions
form-action: Internal generic functions
form-components: Internal generic functions
form-components: Internal generic functions
form-method: Internal generic functions
form-method: Internal generic functions
forward-to: Exported functions
Function, (setf context): Exported functions
Function, add-query-parameters: Internal functions
Function, app-path: Exported functions
Function, config: Exported functions
Function, context: Exported functions
Function, current-mode: Exported functions
Function, current-uri: Exported functions
Function, dispatch-with-rules: Internal functions
Function, forward-to: Exported functions
Function, generate: Exported functions
Function, make-context: Exported functions
Function, make-form: Exported functions
Function, make-request: Exported functions
Function, member-rule: Internal functions
Function, next-route: Exported functions
Function, not-found: Exported functions
Function, redirect-to: Exported functions
Function, render: Exported functions
Function, render: Exported functions
Function, slurp-file: Internal functions
Function, url-for: Exported functions

G
generate: Exported functions
Generic Function, (setf acceptor): Internal generic functions
Generic Function, (setf config): Exported generic functions
Generic Function, (setf debug-mode-p): Exported generic functions
Generic Function, (setf form-action): Internal generic functions
Generic Function, (setf form-components): Internal generic functions
Generic Function, (setf form-method): Internal generic functions
Generic Function, (setf project-mode): Exported generic functions
Generic Function, (setf routing-rules): Internal generic functions
Generic Function, (setf view): Exported generic functions
Generic Function, acceptor: Internal generic functions
Generic Function, add: Exported generic functions
Generic Function, add-route: Exported generic functions
Generic Function, build: Exported generic functions
Generic Function, config: Exported generic functions
Generic Function, debug-mode-p: Exported generic functions
Generic Function, form-action: Internal generic functions
Generic Function, form-components: Internal generic functions
Generic Function, form-method: Internal generic functions
Generic Function, load-config: Exported generic functions
Generic Function, lookup-route: Exported generic functions
Generic Function, project-mode: Exported generic functions
Generic Function, render: Exported generic functions
Generic Function, routing-rules: Internal generic functions
Generic Function, start: Exported generic functions
Generic Function, stop: Exported generic functions
Generic Function, validate: Exported generic functions
Generic Function, view: Exported generic functions

L
load-config: Exported generic functions
load-config: Exported generic functions
lookup-route: Exported generic functions
lookup-route: Exported generic functions

M
Macro, defroute: Exported macros
Macro, url: Exported macros
Macro, url->routing-rule: Exported macros
Macro, with-context-variables: Exported macros
make-context: Exported functions
make-form: Exported functions
make-request: Exported functions
member-rule: Internal functions
Method, (setf acceptor): Internal generic functions
Method, (setf config): Exported generic functions
Method, (setf debug-mode-p): Exported generic functions
Method, (setf form-action): Internal generic functions
Method, (setf form-components): Internal generic functions
Method, (setf form-method): Internal generic functions
Method, (setf project-mode): Exported generic functions
Method, (setf routing-rules): Internal generic functions
Method, (setf view): Exported generic functions
Method, acceptor: Internal generic functions
Method, add: Exported generic functions
Method, add-route: Exported generic functions
Method, config: Exported generic functions
Method, debug-mode-p: Exported generic functions
Method, form-action: Internal generic functions
Method, form-components: Internal generic functions
Method, form-method: Internal generic functions
Method, load-config: Exported generic functions
Method, lookup-route: Exported generic functions
Method, project-mode: Exported generic functions
Method, render: Exported generic functions
Method, routing-rules: Internal generic functions
Method, start: Exported generic functions
Method, start: Exported generic functions
Method, stop: Exported generic functions
Method, validate: Exported generic functions
Method, view: Exported generic functions

N
next-route: Exported functions
not-found: Exported functions

P
project-mode: Exported generic functions
project-mode: Exported generic functions

R
redirect-to: Exported functions
render: Exported functions
render: Exported functions
render: Exported generic functions
render: Exported generic functions
routing-rules: Internal generic functions
routing-rules: Internal generic functions

S
slurp-file: Internal functions
start: Exported generic functions
start: Exported generic functions
start: Exported generic functions
stop: Exported generic functions
stop: Exported generic functions

U
url: Exported macros
url->routing-rule: Exported macros
url-for: Exported functions

V
validate: Exported generic functions
validate: Exported generic functions
view: Exported generic functions
view: Exported generic functions

W
with-context-variables: Exported macros

Jump to:   (  
A   B   C   D   F   G   L   M   N   P   R   S   U   V   W  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.3 Variables

Jump to:   *  
A   C   D   M   R   S   V  
Index Entry  Section

*
*context*: Exported special variables
*next-route-function*: Internal special variables
*project*: Exported special variables
*request*: Exported special variables
*response*: Exported special variables
*session*: Exported special variables
*skeleton-directory*: Internal special variables

A
acceptor: Exported classes
action: Exported classes

C
components: Exported classes
config: Exported classes

D
debug-mode-p: Exported classes

M
method: Exported classes
mode: Exported classes

R
routing-rules: Exported classes

S
Slot, acceptor: Exported classes
Slot, action: Exported classes
Slot, components: Exported classes
Slot, config: Exported classes
Slot, debug-mode-p: Exported classes
Slot, method: Exported classes
Slot, mode: Exported classes
Slot, routing-rules: Exported classes
Slot, view: Exported classes
Special Variable, *context*: Exported special variables
Special Variable, *next-route-function*: Internal special variables
Special Variable, *project*: Exported special variables
Special Variable, *request*: Exported special variables
Special Variable, *response*: Exported special variables
Special Variable, *session*: Exported special variables
Special Variable, *skeleton-directory*: Internal special variables

V
view: Exported classes

Jump to:   *  
A   C   D   M   R   S   V  

Previous: , Up: Indexes   [Contents][Index]

A.4 Data types

Jump to:   <  
C   P   S  
Index Entry  Section

<
<app>: Exported classes
<caveman-middleware-context>: Exported classes
<caveman-widget-form>: Exported classes
<caveman-widget>: Exported classes
<project>: Exported classes
<request>: Exported classes
<response>: Exported classes

C
caveman: The caveman system
caveman: The caveman package
caveman-asd: The caveman-asd package
caveman.app: The caveman<dot>app package
caveman.context: The caveman<dot>context package
caveman.middleware.context: The caveman<dot>middleware<dot>context package
caveman.project: The caveman<dot>project package
caveman.request: The caveman<dot>request package
caveman.response: The caveman<dot>response package
caveman.route: The caveman<dot>route package
caveman.skeleton: The caveman<dot>skeleton package
caveman.view.emb: The caveman<dot>view<dot>emb package
caveman.view.function: The caveman<dot>view<dot>function package
caveman.widget: The caveman<dot>widget package
caveman.widget.form: The caveman<dot>widget<dot>form package
Class, <app>: Exported classes
Class, <caveman-middleware-context>: Exported classes
Class, <caveman-widget-form>: Exported classes
Class, <caveman-widget>: Exported classes
Class, <project>: Exported classes
Class, <request>: Exported classes
Class, <response>: Exported classes

P
Package, caveman: The caveman package
Package, caveman-asd: The caveman-asd package
Package, caveman.app: The caveman<dot>app package
Package, caveman.context: The caveman<dot>context package
Package, caveman.middleware.context: The caveman<dot>middleware<dot>context package
Package, caveman.project: The caveman<dot>project package
Package, caveman.request: The caveman<dot>request package
Package, caveman.response: The caveman<dot>response package
Package, caveman.route: The caveman<dot>route package
Package, caveman.skeleton: The caveman<dot>skeleton package
Package, caveman.view.emb: The caveman<dot>view<dot>emb package
Package, caveman.view.function: The caveman<dot>view<dot>function package
Package, caveman.widget: The caveman<dot>widget package
Package, caveman.widget.form: The caveman<dot>widget<dot>form package

S
System, caveman: The caveman system

Jump to:   <  
C   P   S