tangle: early ajax interface to create and view nodes
parent
b729186986
commit
06d7edbf96
|
@ -18,6 +18,7 @@ test-db [
|
|||
[ 3 ] [ "third node" create-node id>> ] unit-test
|
||||
[ 4 ] [ f create-node id>> ] unit-test
|
||||
[ ] [ 1 f <node> 2 f <node> 3 f <node> create-arc ] unit-test
|
||||
[ { 1 2 3 4 } ] [ all-node-ids ] unit-test
|
||||
] with-db delete-db
|
||||
|
||||
test-db [
|
||||
|
|
|
@ -112,6 +112,9 @@ arc "arc"
|
|||
: param ( value key type -- param )
|
||||
swapd <sqlite-low-level-binding> ;
|
||||
|
||||
: all-node-ids ( -- seq )
|
||||
f "select n.id from node n" results [ first string>number ] map ;
|
||||
|
||||
: subjects-with-cor ( content object relation -- sql-results )
|
||||
[ id>> ] bi@
|
||||
[
|
||||
|
|
|
@ -27,9 +27,11 @@ RELATION: in-directory
|
|||
: (path>node) ( node name -- node )
|
||||
swap [ file-in-directory ] [ drop f ] if* ;
|
||||
|
||||
USE: tools.walker
|
||||
: path>node ( path -- node )
|
||||
"/" split ensure-root swap [ (path>node) ] each ;
|
||||
ensure-root swap [ (path>node) ] each ;
|
||||
|
||||
: path>file ( path -- file )
|
||||
path>node [ has-filename-subjects ?first ] [ f ] if* ;
|
||||
|
||||
: (node>path) ( root seq node -- seq )
|
||||
pick over node= [
|
||||
|
@ -45,7 +47,10 @@ USE: tools.walker
|
|||
|
||||
: node>path* ( root node -- path )
|
||||
V{ } clone swap (node>path) dup empty?
|
||||
[ drop f ] [ <reversed> "/" join ] if ;
|
||||
[ drop f ] [ <reversed> ] if ;
|
||||
|
||||
: node>path ( node -- path )
|
||||
ensure-root swap node>path* ;
|
||||
|
||||
: file>path ( node -- path )
|
||||
has-filename-objects ?first [ node>path ] [ f ] if* ;
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,18 @@
|
|||
<html>
|
||||
<head>
|
||||
<script type="text/javascript" src="jquery-1.2.3.min.js"></script>
|
||||
<script type="text/javascript" src="weave.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<form id="node-form">
|
||||
<select id="nodes">
|
||||
<option value="new">New</option>
|
||||
</select>
|
||||
<div id="node-content" style="display: none;"></div>
|
||||
<div id="edit-wrapper">
|
||||
<textarea id="node-content-edit"></textarea>
|
||||
<button id='node-submit'>Save Node</button>
|
||||
</div>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,27 @@
|
|||
$(function() { $.getJSON("/all", false, function(json) {
|
||||
var nodes = $('#nodes');
|
||||
for (node in json) {
|
||||
nodes.append("<option value='" + json[node] + "'>" + json[node] + "</option>");
|
||||
}
|
||||
nodes.change(function(){
|
||||
if (this.value == 'new') {
|
||||
$('#node-content').hide();
|
||||
$('#edit-wrapper').show();
|
||||
} else {
|
||||
$('#node-content').show();
|
||||
$('#edit-wrapper').hide();
|
||||
$.get('/node', { node_id: this.value }, function(data){
|
||||
$('#node-content').text(data);
|
||||
});
|
||||
}
|
||||
});
|
||||
$('#node-submit').click(function(){
|
||||
$.post('/node', { node_content: $('#node-content-edit').val() }, function(data){
|
||||
nodes.append("<option value='" + data + "'>" + data + "</option>");
|
||||
var option = nodes.get(0).options[data];
|
||||
option.selected = true;
|
||||
nodes.change();
|
||||
});
|
||||
return false;
|
||||
});
|
||||
});})
|
|
@ -0,0 +1,18 @@
|
|||
USING: continuations db db.sqlite http.server io.files kernel namespaces semantic-db tangle tangle.path ;
|
||||
IN: tangle.sandbox
|
||||
|
||||
: db-path "tangle-sandbox.db" temp-file ;
|
||||
: sandbox-db db-path sqlite-db ;
|
||||
: delete-db [ db-path delete-file ] ignore-errors ;
|
||||
|
||||
: make-sandbox ( tangle -- )
|
||||
[
|
||||
init-semantic-db
|
||||
ensure-root "foo" create-file "First Page" create-node swap has-filename
|
||||
] with-tangle ;
|
||||
|
||||
: new-sandbox ( -- )
|
||||
development-mode on
|
||||
delete-db sandbox-db f <tangle>
|
||||
[ make-sandbox ] [ <tangle-dispatcher> ] bi
|
||||
main-responder set ;
|
|
@ -0,0 +1 @@
|
|||
A web framework using semantic-db as a backend
|
|
@ -12,9 +12,9 @@ IN: tangle.tests
|
|||
|
||||
test-db [
|
||||
init-semantic-db test-tangle
|
||||
[ "pluck_eggs" ] [ "foo/bar/pluck_eggs" path>node [ node-content ] when* ] unit-test
|
||||
[ "How to Pluck Eggs" ] [ "foo/bar/pluck_eggs" path>node [ has-filename-subjects first node-content ] when* ] unit-test
|
||||
[ "foo/bar/pluck_eggs" ] [ "foo/bar/pluck_eggs" path>node node>path ] unit-test
|
||||
[ "pluck_eggs" ] [ { "foo" "bar" "pluck_eggs" } path>node [ node-content ] when* ] unit-test
|
||||
[ "How to Pluck Eggs" ] [ { "foo" "bar" "pluck_eggs" } path>node [ has-filename-subjects first node-content ] when* ] unit-test
|
||||
[ { "foo" "bar" "pluck_eggs" } ] [ { "foo" "bar" "pluck_eggs" } path>node node>path >array ] unit-test
|
||||
[ f ] [ TUPLE{ node id: 666 content: "some content" } parent-directory ] unit-test
|
||||
[ f ] [ TUPLE{ node id: 666 content: "some content" } node>path ] unit-test
|
||||
[ "Main Menu" ] [ "Main Menu" ensure-menu node-content ] unit-test
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
! Copyright (C) 2008 Alex Chapman
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors assocs db db.sqlite db.postgresql http http.server http.server.actions io kernel math.parser namespaces semantic-db sequences strings ;
|
||||
USING: accessors assocs db db.sqlite db.postgresql http http.server http.server.actions http.server.static io io.files json.writer kernel math.parser namespaces semantic-db sequences strings tangle.path ;
|
||||
IN: tangle
|
||||
|
||||
GENERIC: render* ( content templater -- output )
|
||||
|
@ -19,15 +19,57 @@ C: <tangle> tangle
|
|||
: with-tangle ( tangle quot -- )
|
||||
[ [ db>> ] [ seq>> ] bi ] dip with-db ;
|
||||
|
||||
TUPLE: node-responder tangle ;
|
||||
C: <node-responder> node-responder
|
||||
: <text-response> ( text -- response )
|
||||
"text/plain" <content> swap >>body ;
|
||||
|
||||
: node-response ( responder id -- responder )
|
||||
load-node [ node-content ] [ "Unknown node" ] if* >>body ;
|
||||
: node-response ( id -- response )
|
||||
load-node [ node-content <text-response> ] [ <404> ] if* ;
|
||||
|
||||
M: node-responder call-responder* ( path responder -- response )
|
||||
: display-node ( params -- response )
|
||||
[
|
||||
"node_id" swap at* [
|
||||
string>number node-response
|
||||
] [
|
||||
drop <400>
|
||||
] if
|
||||
] [
|
||||
<400>
|
||||
] if* ;
|
||||
|
||||
: submit-node ( params -- response )
|
||||
[
|
||||
"node_content" swap at* [
|
||||
create-node id>> number>string <text-response>
|
||||
] [
|
||||
drop <400>
|
||||
] if
|
||||
] [
|
||||
<400>
|
||||
] if* ;
|
||||
|
||||
: <node-responder> ( -- responder )
|
||||
<action> [ params get display-node ] >>display
|
||||
[ params get submit-node ] >>submit ;
|
||||
|
||||
TUPLE: path-responder ;
|
||||
C: <path-responder> path-responder
|
||||
|
||||
M: path-responder call-responder* ( path responder -- response )
|
||||
drop path>file [ node-content <text-response> ] [ <404> ] if* ;
|
||||
|
||||
: <json-response> ( obj -- response )
|
||||
"application/json" <content> swap >json >>body ;
|
||||
|
||||
TUPLE: tangle-dispatcher < dispatcher tangle ;
|
||||
|
||||
: <tangle-dispatcher> ( tangle -- dispatcher )
|
||||
tangle-dispatcher new-dispatcher swap >>tangle
|
||||
<path-responder> >>default
|
||||
"extra/tangle/resources" resource-path <static> "resources" add-responder
|
||||
<node-responder> "node" add-responder
|
||||
<action> [ all-node-ids <json-response> ] >>display "all" add-responder ;
|
||||
|
||||
M: tangle-dispatcher call-responder* ( path dispatcher -- response )
|
||||
dup tangle>> [
|
||||
"text/plain" <content> nip request get request-params
|
||||
[ "node-id" swap at* [ string>number node-response ] [ drop ] if ] when* nip
|
||||
find-responder call-responder
|
||||
] with-tangle ;
|
||||
|
||||
|
|
Loading…
Reference in New Issue