Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Browse files

update readme

  • Loading branch information...
commit fc43344cb344ba2d40f0bdf141eb71f9d06e8ff1 1 parent 802e68f
@duck1123 authored
Showing with 203 additions and 48 deletions.
  1. +203 −48
@@ -11,72 +11,227 @@ x1 (mass) is a system interrelated by structure x2 among components x3
## About Ciste
-Ciste attempts to provide a structure to Clojure applications. The
-main idea revolves around matching a request to a action variable and
-a pair of format and serialization parameters.
+Ciste attempts to provide a structure to Clojure applications.
-The action is simply a function that accepts a request and returns
-either: a record of some sort (or a sequence of them); or nil.
+Ciste is a complete framework for building modular Clojure
+applications and servers. Ciste contains an app runner an service
+initializer, a environment-aware configuration system, an extensible
+request routing framework, a MVC-like page building mechanism, a
+dynamic record transformation tool for displaying your resources in
+multiple response formats, an asynchronous trigger system, support for
+running and managing independent worker threads, and command system
+for controlling aspects of the system from remote clients.
-The response of the action method is then passed to the apply-view
-family of multimethods. The view will match the combination of action
-(expressed as a var) and the format (a keyword). The view will return
-a logically true value (generally a hash). If there is no view defined
-for both the action and the format, a view will be searched for using
-only the format. This allows generic handlers to be defined for a
-format (eg, converting the structure to JSON).
+## Installation
-The response from the view is then passed to the formatter. This
-allows extra transformations to be applied for the given format. An
-example of this would be converting a series of vectors into HTML
-using Hiccup.
+Add the following to your project.clj dependencies
-Finally, the response is formatted according to the serialization
-type. This framework has been used to respond to request
-simultaneously over an HTTP and XMPP connection. This allows any final
-transformations to be applied (eg, adding common headers).
+ [ciste "0.4.0-SNAPSHOT"]
-In addition to the main thread of request and response, triggers can
-also be defined. When a matching action is invoked, the request and
-the response from the action are sent to the specified
-trigger. Triggers are for side effects only.
+## Running a Ciste Application
-### Example
+Ciste comes with a -main function specially designed to bootstrap your
+application and start any required services. Simply add the following
+to your project.clj file.
-``` clojure
-(ns my-app.core
- (:use ciste.core))
+ :main ciste.runner
-(defaction index
- [options]
- (index-db-method :limit (:limit options)))
+## Configuration
-(deffilter #'index :html
- [action request]
- (action {:limit (-> request :params :limit)}))
+There are 2 files that must be present in order to properly configure
+your Ciste application: ciste.clj and config.clj. These files should
+be located at the root of your project.
-(defview #'index :html
- [records]
- {:body (show-list records)})
+### ciste.clj
-(defsection show-list [RecordModel]
- [records]
- [:ul (map show-list-item records)])
+ciste.clj (known as the site config) contains only configuration
+needed during the initial startup of the application. This file should
+contain only a properly formatted Clojure hash-map. The site config
+should contain configuration options that are strictly static for
+every environment.
-## Applications Using Ciste
+There are currently 3 properties defined, but you can add your own.
-The prime example of Ciste in action is my OStatus server located at
+* :environment - This should contain a keyword specifying the default
+ environment of the application. This is the environment that will be
+ run if not otherwise overridden.
-If you find Ciste useful for your purposes, I'd love to hear about it.
+* :modules - A list of modules to load
+* :services - A list of services to run
-## Installation
+### config.clj
-Add the following to your project.clj dependencies
+config.clj is also a file containing a Clojure hash-map. Each key in
+the map specifies a different environment, and the values are another
+hash containing all the config for the application.
+## Modules and Services
+When Ciste is starting the application, is looks for :modules and
+:services keys in both the config file and the site config. Each of
+these keys should have a vector of strings. The loader service will
+require each namespace.
+Modules allow you to create namespaces that change the state of the
+system in some way, but do not need to be required directly by the
+rest of your namespaces. Ciste makes use of several different
+multimethods and protocols. Implementations can be stored in a module
+and easily included into an application.
+Services are similar to Modules, except their start and stop functions
+will be invoked at the proper point in the application's lifecycle.
+## Actions
+Actions for the core API of your application. Any major state change
+should happen through an Action. Anything that you might want to log
+(if action logging is enabled), or anything you might want callbacks
+should be run for should be an Action. In the role of Actions with
+respect to routing, a traditional function may be substituted.
+Action should only have a single arity.
+## Routing
+Ciste's routing system allows any request map (usually a ring request,
+but any map works) to be matched against a sequence of predicates and
+match info maps and return a response map that can be invoked to
+generate a full response.
+The router will thread the request through each of the predicates
+applying them against the match info providing parameters for the
+predicates. The first route to return a non-nil response will be
+The predicates and predicate list can be adapted to any type of
+## Serialization
+Each instance of a router should define a serialization type with
+with-serialization (specified as a keyword). The serialization type
+identifies the type of request coming in (used by filters) and to
+determine a final transformation of returned responses.
+## Filters
+When a route is selected, it is first passed to the Action's
+filter. The filter is a serialization-specific wrapper around the
+action. The filter is where the request should be parsed, normalized,
+and passed to the action returning its response.
+## Formats
+Ciste is designed to make it easy to serve resources in multiple
+format. Each router should specify a default format for the interface
+as a keyword (eg. :html) as well as allow it to be set by route
+predicates. Formats are used by Views and Sections as well as the
+formatter as the penultimate step in request processing.
+Formatters allow you to deal in easy to manipulate data structures
+throughout your request, deferring the final transformation till the
+very end. A formatter might convert a hiccup structure into html or
+convert a clojure map into a json string or whatever needs to be done
+for responses of that type.
+## Views
+After the Filter has processed the action and returned the result, it
+is passed to a view for the given Action and Format. The View returns
+a map containing parameters for the generation of the response. The
+:body key of the response should contain the data that should be
+inserted into the main part of the template and converted by the
+formatter, but may also contain any other key needed to control the
+eventual output.
+If the View contains the pair :template false, templating will be
+skipped for this response. This is useful for simple responses, such
+as redirects or serialization-specific error responses.
+## Models
+Ciste is designed to work best with Records or any type of object
+where dispatch can function off the class name. There are few
+functions that directly support this at the moment. An abstraction
+around using records against various backends is in the works.
+## Sections
+Sections allow records to be formatted properly according to their
+context. Calling a section function with a Record will apply the
+appropriate multimethod for the currently bound Serialization and
+Format. This allows you to easily do things like display a sequence of
+records, display a single record, get the context-appropriate title
+for that record or link to a record using a common language without
+needing to define distinct names for each of the many formats you
+## Templates
+Unless templating has been disabled by the view, a template method
+will be applied to the response for the given Serialization type. A
+Template will generally use many different keys from the view to build
+the page, but will primarily read from the :body key
+## Triggers and the Action channel
+Actions allow triggers to be added that will be run in a different
+thread. Triggers allow callbacks to be performed in response to an
+In addition to Triggers, an event is emitted to a lamina
+channel. Workers can monitor this channel to perform other actions.
+Note: The trigger system is set to be changed soon. In the future,
+triggers will be run as part of a Worker set to read from the action
+channel. Use at your own risk.
+## Workers
+Workers are functions that are identified by a keyword name. Workers
+can be started and told to stop. (Workers can check if they've been
+asked to stop.) The lists of available and running workers can be
+queried and manipulated. Workers can update a per-worker counter
+allowing metrics (number of packets processed) to be displayed.
+Note: This section is in need of work and will most likely be
+re-written to be simply a wrapper over a more robust thread manager.
+## Commands
+Commands are a special route map and serialization type. Commands
+allow simple string names to be mapped to actions. Commands exist to
+work with services that provide an interface to the command system.
+## Modularity
+The goal of Ciste is to make each part as optional as possible
+allowing parts to be used without incurring the cost of the whole
+In addition, there are many supplemental libraries that provide new
+services, custom formatters, and other tools that work with Ciste. The
+intention is that you should be able to build up a base application by
+combining together whatever pieces you need.
+## Maturity
+While Ciste has been around for quite some time, I have not been able
+to devote as much time to it as I would like. Ciste has formed the
+basis of a few highly complex applications, but hasn't been
+extensively tested by others. If you find Ciste useful to your needs,
+please let me know so I can take care to limit breaking changes.
+## In the wild
+The prime example of Ciste in action is my OStatus server located at
+Jiksnu has been the primary driver of new features in Ciste and is the
+best example of a fully functioning Ciste application.
- [ciste "0.3.0-SNAPSHOT"]
## License

0 comments on commit fc43344

Please sign in to comment.
Something went wrong with that request. Please try again.