Scout Camp

You want to write a website, but don't want any hassle.
You want it to be cool, with Ajax, Server-side scripts, Unicode and all.
You don't want ugly php polluting your html files.
Look no further. We have what you need. For free.

We let you separate the Ajax engines, run on the server, and the web interface, conveying information and giving the possibility of interaction with the engines.

We give you:

Download Scout.js! Download Scout.js Minified!
Download Camp.js! Look at Node.js!

Where should I start?

First, download Node.js, scout.js minified, camp.js. Don't know where to find them? Please, look up! There, with the odd flashy colors!

Then, you will want to set up your working environment like this.

camp.js   # it should be next to your main server.
run.js    # your main server is there!
web/      # all things html are here...
  /index.html   # root of the website.
  /.robots.txt  # file for spiders, always handy.
  /js/
    /scout.js   # scout.js, always within reach.
  ...

# Worth noting: you can find amazing default stuff
# at html5boilerplate.com.

The run.js file is something like this:

// run.js: starts the web server. Run "cd web && sudo node ../run.js"

var server = require ('camp').Camp;
server.start ();

From the command line, you want to navigate to the web folder. Then, if you have node.js installed, this should set fire to the dynamite!

$ pwd
/.../web
$ sudo node ../run.js &      # Yay!

Pages and Ajax

What's in a page? A page in Scout Camp is a way to view some data in a specific way, and have certain interaction with this data. Each time you want a new way to view data, a way that has a different purpose, you should create a new page.

Creating a new page is easy:

$ pwd
/.../web
$ edit page.html     # with an alias edit='vi' or something...
$ ls
js/  index.html  page.html ...

But what if you want Ajax interaction?

Core Ajax scripts

Your new Ajax page might look like this...

<!doctype html>
<script src="/js/scout.js"></script>

<p>Post a message:
<form id=form>
  <input name="message"/>
  <button>Post message</button>

  <script>
  Scout('#form').on('submit', function(xhr, e, params) {
    xhr.but = Scout('#form>button');
    xhr.but.disabled = true;
    xhr.but.textContent = 'Submitting...';
    
    params.open = {url:'/$note'};
    params.data = {message: this.firstElementChild.value};
    params.resp = function (xhr, resp) {
      xhr.but.disabled = false;
      Scout('output#msg').textContent = resp.message;
      xhr.but.textContent = 'New post';
    };
  });
  </script>

</form>
<br/>

<p>Last message:
  <output id=msg form=form>nothing</output>.

You can register the site-wide action "note" that answers to this Ajax call by writing, in run.js, something like:

// run.js: starts the web server. Run "cd web && sudo node ../run.js"

var server = require ('./camp').Camp;

var notes = [];
server('note', function(json) {
  /* Remember the note. */
  notes.push(json.message);
  return {message:json.message};  // This will be sent back the html page.
});

/* The following line starts the web server. */
server.start();

Hard drive programs

Another reasonable choice is to use a binary program to register a specific action. It means that the Ajax call will cause the server to access the hard drive to fetch and run the program. This may be faster if the associated action already uses the hard drive.

The server will then receive a request that looks something like this: "http://example.com/$prog?message=[input]". It will then run the c program located at /$prog, whose source code may look like that, using ScoutCamp's apis:

int main (int argc, char** argv) {
  json_object *query = scQueryString();
  /* Tells the user its name. */
  json_object *msg = json_object_object_get(query, "message");
  if (msg) {
    scReturn(msg);
  } else {
    scReturn(NULL);
  }
  return 0;
}

The scQueryString() function returns a json object whose keys and values are that of the query string. In this case, we ask for a message; we may have a query string like "message=something" (corresponding to a GET request that would look like http://example.com/page.html?message=something).

Then, the program returns another (preferably different, unlike the example given) JSON object, which the webpage can manipulate in the second javascript function given, through the resp parameter.

Libraries

Scout.js

function Scout ( id ) { return domEltWrapped; }
The id is a string that identifies a list of html elements using a selector string (see www.w3.org/TR/selectors-api). It returns a modified version of the DOM element corresponding to the first match, or null, if there is no match. The modification of this element is the addition of a on function, decribed furthermore here.
domEltWrapped.on = function ( eventName, function ( xhr, event, params ) { } )
The eventName parameter is the name of the event we are listening to, and the second parameter is a function triggered immediately before the ajax call. The first and second parameters of this function are, respectively, the xmlHttpRequest object and the event object; its third parameter is an object with the following overridable properties: Inside the callback function, the this parameter is bound to the DOM element that was called.
function Scout.send ( function ( xhr, params ) { } )
A call to this function returns a function that, when run, triggers an xmlHttpRequest. The params parameter to the function is the same as in the domEltWrapped.on function parameter.
It can be handy when using timeouts, setTimeout(Scout.send(...), 1000);.

Please note that the Content-Type header of a POST ajax call will be "application/x-www-form-urlencoded".

Camp.js

var camp = require ( './camp.js' );

camp.add = function ( action, function ( jsonQuery, ... ) { return jsonResp; }, eventname = undefined )
The Camp function registers an action located at '/$[action]', which runs the function given as the second argument.
If the "eventname" parameter is given, the answer will be hold until the camp.Server.emit ( eventname, argument ) event is emitted from your app. Then, the function will be launched, with possible additional parameters (here, "argument"), and the result of evaluating it will be sent back to the client if not undefined.
camp.Server.start = function ( port='80', debug=false ) { }
The start function starts the web server, listening on port 80 by default.

The rest of it

JSON library. This is actually the json-c library.

Scout Camp C library. Useful for stand-alone C programs.

If you wish to be part of this project, send me a mail.

Current members:

Thäddëë Tÿl (thaddee.tyl, gmail.com)
Jän Kërömnës (jan.keromnes, gmail.com)
Räphäël Cätölïnö (raphael.catolino, gmail.com)
Gäëtän Trïvïnö (gaetan, trivino.fr)
Jönäs Lënwë (jonas.lenwe, gmail.com)
Hïchäm Ël-Fäthï (hicham.el-fathi, insa-lyon.fr)
Mïchäël Fägnö (michael.fagno, free.fr)