cfmljure
文件大小: unknow
源码售价: 5 个金币 积分规则     积分充值
资源说明:A way to dynamically call Clojure from CFML
# Clojure and CFML Sitting in a tree

cfmljure is a utility that lets you easily call Clojure code from CFML!

It works by leveraging Leiningen to obtain the classpath for a Clojure project that you want to load into
your CFML project. The examples provided use two Clojure projects in the `clj` folder. One is very basic
Clojure code that is loaded and run directly in the `index.cfm` page, the other loads the Clojure code
at application startup and makes that code available in the `variables` scope of each page of the example.

## Installation (with Leiningen)

Install the **lein** script from http://github.com/technomancy/leiningen 
(download the **lein** script, make it executable, run **lein self-install** to complete 
the installation). If you're on Windows, use the Windows installer for Leiningen.

**Note: cfmljure expects the `lein` command to be on the path used by `cfexecute` inside your CFML engine!**

### Verifying Leiningen / Clojure

In each of the projects, `clj/cfml` and `clj/tasks`, you should be able to run the tests with Leiningen:

    lein test

In `clj/cfml` you should see:

    lein test cfml.test.examples
    
    Ran 7 tests containing 7 assertions.
    0 failures, 0 errors.

In `clj/task` you should see:

    lein test task.test.core
    
    lein test task.test.create
    
    Ran 4 tests containing 14 assertions.
    0 failures, 0 errors.

The first time you run `lein test` you may see all sorts of stuff being downloaded from Maven Central. Do not panic! This is how Leiningen (Clojure's build tool) manages dependencies automatically for you.

### Running the CFML/Clojure examples

Assuming you deployed `cfmljure` (via cloning from Github or unzipping a release) to a folder within a CFML webroot somewhere, you should be able to navigate your browser to the cfmljure home page, e.g.,

    http://localhost:8080/cfmljure/

This will take a few seconds the first time but should then show the output of the **Basic Examples**. You can click through to the more advanced **Task** example which uses Clojure for all the business logic, including reading and writing to a Derby database!

## Using Your Own Clojure Code

Create a new project somewhere with Leiningen:

    lein new mystuff

That will create a complete Clojure project with a `mystuff.core` namespace containing a `foo` function that accepts a string argument and prints a message (to the console of your CFML engine).

Now create a CFML page containing:

    
    
    
    Done!

And now hit that page in your browser - it should say `Done!` in your browser and if you look in your CFML engine's console you should see:

    Detected Clojure 1.6 or later
    From CFML Hello, World!

The first line is cfmljure telling you whether it found a recent version of Clojure or an older one (Clojure 1.6 introduced a new, improved way to embed Clojure into an application).

The second line was printed by the Clojure code in that `core.clj` example!

### Installing Namespaces

CFML can only "see" the Clojure code in the namespaces you specify in `install()`. This allows you to organize your Clojure code however you want and only expose a specific API to your CFML code.

You can expose any of the namespaces in your Clojure project, including those from third party libraries specified as dependencies in your `project.clj` file. It's often convenient to install `clojure.core` as it provides a lot of useful functions!

## Using Clojure Functions

As you can see above, you can call any (public) function in a Clojure namespace just by using the dotted path to it. CFML strings work as Clojure strings, CFML numbers are Clojure floating point (double) values - on Lucee and Railo at least, on ColdFusion they're still strings... duh! You can pass CFML arrays and structs to Clojure and they can be treated as sequences and hashmaps (with "UPPERCASE" string keys) respectively. If Clojure passes back a vector or list, CFML can treat it like an array (in most cases). If Clojure passes back a traditional hashmap, it will usually have keywords as keys. You can make a keyword from a string by calling `clojure.core.keyword("str")` which produces `:str` in Clojure terms - a keyword. You will often need to use Clojure functions to get stuff out of hashmaps if they use keywords:

    

That returns the `:k` key value from `cljMap` or null if there's no such key.

Sometimes, instead of calling a function, you want to get a reference to it. For example, here's Clojure code that increments every element of a list:

    (map inc [1 2 3 4])

To do that from CFML, you would need this code:

    

The `_inc()` call returns a reference to `inc`. In general `name.space._func()` will return a reference to the `func` function in the specified `name.space` namespace, so that you can pass it to other functions.

本源码包内暂不包含可直接显示的源代码文件,请下载源码包。