On 19 Mar 2009, at 17:09, Tyson Norris wrote:
Hi -
In working on a CMS project, using a jackrabbit/jcr based product, we
wanted similar functionality - a way to browse the repo.
We found a google code project called jc-rest:
http://code.google.com/p/jc-rest/
It has this type of functionality, and is based on YUI. It works well
for getting an easy view into all details of the repository.
Currently,
it only exposes a single workspace, but I don't think it would be hard
to change that to expose all workspaces.
As for running it as a bundle in sling, you may be able to refactor
the
YUI/JavaScript code in the browser to use sling urls, instead of the
RESTful services that jc-rest provides on server side.
Here's a very simple adaptation of the jc-rest browser to use sling
JSON requests (run it in firefox).
There's a limit to what you can do without any server side component
though, and I think that determining which capabilities to incorporate
into that component is much more interesting than the client side
javascript implementation. The latter could probably be "left as an
exercise to the reader", as it's mostly about the JS framework, not
sling per se. A nice, compact default one wouldn't hurt though.
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd
">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=UTF-8">
<meta http-equiv="Cache-Control" content="No-Cache">
<title>Repository Browser</title>
<!-- Combo-handled YUI CSS files: -->
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/combo?2.6.0/build/assets/skins/sam/skin.css
">
<!-- Additional custom style rules from yahoo treeview example
-->
<link rel="stylesheet" type="text/css" href="http://developer.yahoo.com/yui/examples/treeview/assets/css/folders/tree.css
">
<style type="text/css">
.icon-leaf { display:block; height: 22px; padding-left: 20px;
background: transparent url(http://developer.yahoo.com/yui/examples/treeview/assets/img/icons.png
) 0 -108px no-repeat; }
* { font: 10pt verdana, sans-serif; }
</style>
<!-- Combo-handled YUI JS files: -->
<script type="text/javascript" src="http://yui.yahooapis.com/combo?2.6.0/build/yahoo-dom-event/yahoo-dom-event.js&2.6.0/build/connection/connection-min.js&2.6.0/build/datasource/datasource-min.js&2.6.0/build/dragdrop/dragdrop-min.js&2.6.0/build/element/element-beta-min.js&2.6.0/build/datatable/datatable-min.js&2.6.0/build/resize/resize-min.js&2.6.0/build/layout/layout-min.js&2.6.0/build/treeview/treeview-min.js
"></script>
</head>
<body class="yui-skin-sam">
<div id="tree"></div>
<div id="detail"></div>
<div id="blank"></div>
<script>
(function() {
var Dom = YAHOO.util.Dom, Event =
YAHOO.util.Event;
Event.onDOMReady(function() {
var layout = new YAHOO.widget.Layout({
units: [
{position: 'left', body: 'tree', width: 512, gutter: '5px',
resize: true, scroll: true},
{position: 'center', body: 'detail', gutter: '5px', resize:
true, scroll: true},
{position: 'right',
body: 'blank', width: 0, gutter: '5px'}
]
});
layout.render();
});
})();
</script>
<script type="text/javascript">
var myDataSource;
var myDataTable;
YAHOO.example.treeExample = function() {
var tree;
function loadNodeData(node, fnLoadComplete) {
// construct node path
var path = "/";
if (node.depth > 0) {
for (var i = 1, j = node.depth; i
< j; i++) {
path = path +
node.getAncestor(i).label + "/";
}
path = path + node.label;
}
// append .1.json to fetch immediate
children with their properties
var sUrl = "" + path + ".1.json";
var callback = {
success: function(oResponse) {
YAHOO.log("XHR transaction was
successful.", "info", "example");
var oResults = eval("(" +
oResponse.responseText + ")");
if ((oResults)) {
if
(YAHOO.lang.isObject(oResults)) {
for (i
in oResults) {
if (YAHOO.lang.isObject(oResults[i])) {
var tempNode = new YAHOO.widget.TextNode(i, node, false);
// should probably determine isLeaf based on wether node
can have children
if
(oResults[i]["jcr:primaryType"] != 'sling:Folder' &&
oResults[i]["jcr:primaryType"] != 'nt:folder' &&
oResults[i]["jcr:primaryType"] != 'nt:unstructured' &&
(oResults[i]["jcr:primaryType"] && oResults[i]
["jcr:primaryType"].substr(0,4) != 'rep:')) {
tempNode.isLeaf = true;
tempNode.labelStyle = "icon-leaf";
}
}
}
} else {
alert(YAHOO.lang.dump(oResults));
var tempNode = new YAHOO.widget.TextNode(oresul...@name,
node, false);
}
}
oResponse.argument.fnLoadComplete();
},
failure: function(oResponse) {
YAHOO.log("Failed to process XHR transaction.", "info",
"example");
oResponse.argument.fnLoadComplete();
},
argument: {
"node": node,
"fnLoadComplete":
fnLoadComplete
},
timeout: 7000
};
YAHOO.util.Connect.asyncRequest('GET',
sUrl, callback);
}
function buildTree() {
tree = new
YAHOO.widget.TreeView("tree");
tree.setDynamicLoad(loadNodeData,
"mode0");
var root = tree.getRoot();
var tempNode = new
YAHOO.widget.TextNode("/", root, false);
// add node click callback to show node properties in right hand
pane
tree.subscribe("labelClick",
function(node) {
var myCallback = function() {
this.set("sortedBy",
null);
this.onDataReturnReplaceRows.apply(this, arguments);
};
var callback1 = {
success : myCallback,
failure : myCallback,
scope : myDataTable
};
// construct path for node
var path = "/";
if (node.depth > 0) {
for (var i = 1, j =
node.depth; i < j; i++) {
path = path +
node.getAncestor(i).label + "/";
}
path = path +
node.label;
}
// append .json to fetch node
properties in json format
myDataSource.sendRequest(path +
".json", callback1);
});
tree.draw();
}
return {
init: function() {
buildTree();
}
}
} ();
YAHOO.util.Event.onDOMReady(YAHOO.example.treeExample.init,
YAHOO.example.treeExample,true);
YAHOO.util.Event.addListener(window, "load", function()
{
YAHOO.example.XHR_JSON = function() {
var myColumnDefs = [
{key:"name", sortable:true,
resizeable:true},
{key:"value", sortable:true,
resizeable:true}
];
myDataSource = new
YAHOO.util.DataSource("");
myDataSource.responseType =
YAHOO.util.DataSource.TYPE_JSON;
myDataSource.connXhrMode =
"queueRequests";
myDataSource.responseSchema = {
resultsList: "properties",
fields: [ "name", "value" ]
};
myDataTable = new YAHOO.widget.DataTable("detail", myColumnDefs,
myDataSource, {scrollable:true, initialRequest:".json"});
// custom handling of data, since json returned contains object
properties, not array items
myDataSource.doBeforeParseData = function (oRequest,
oFullResponse) {
var oNewResponse = "";
for (var j in oFullResponse) {
oNewResponse = oNewResponse + '{"name":"'+j
+'","value":"'+oFullResponse[j]+'"},\n';
}
oNewResponse = '({"properties":[' + oNewResponse
+ ']})';
return eval(oNewResponse);
};
var mySuccessHandler =
function(request, response, payload) {
for (var rate in response) {
alert(YAHOO.lang.dump(rate));
}
this.set("sortedBy", null);
this.onDataReturnAppendRows.apply(this, arguments);
};
var myFailureHandler = function() {
this.showTableMessage(YAHOO.widget.DataTable.MSG_ERROR,
YAHOO.widget.DataTable.CLASS_ERROR);
this.onDataReturnAppendRows.apply(this, arguments);
};
var callbackObj = {
success : mySuccessHandler,
failure : myFailureHandler,
scope : myDataTable
};
return {
oDS: myDataSource,
oDT: myDataTable
};
}();
});
</script>
</body>
</html>
--
Torgeir Veimo
torg...@pobox.com