Hello there Cherokee folks,
Here is a rough attempt to simply get config entries displayed out onto
the web-based admin page as form fields based on a JSON version of a
ConfigNode based tree.
baby steps ;)
Index: admin.js
===================================================================
--- admin.js (revision 930)
+++ admin.js (working copy)
@@ -1,3 +1,117 @@
+/*
+ConfigObject :
+{ 'simple value key' : 'simple value'
+, 'just child values key' : ConfigObject
+, 'value + child values key' : [ 'simple value', ConfigObject ]
+}
+*/
+
+// main call for turning configNodes into form objects
+function formDisplayResponse(container, response) {
+ container.innerHTML = "";
+ var configObject = Ext.util.JSON.decode(response.responseText);
+ var configObjectDom = configObjectToDom(configObject);
+ container.appendChild(configObjectDom);
+}
+
+// top call, recursable call for turning configObjects
+// into form fields
+function configObjectToDom(configObject, depth) {
+
+ // contain fields in a section
+ var div = document.createElement("div");
+ div.className = "section";
+
+ // first collect keys by type... simple and complex
+ var simpleKeys = [];
+ var complexKeys = [];
+ for(var entry in configObject) {
+ var value = configObject[entry];
+ if(typeof(value) == "string") {
+ simpleKeys[simpleKeys.length] = entry;
+ } else {
+ complexKeys[complexKeys.length] = entry;
+ }
+ }
+
+ // first display simple key value pairs, sorted alphabetically
+ simpleKeys.sort();
+ for(var i = 0; i < simpleKeys.length; i++) {
+ var key = simpleKeys[i];
+ var node = toFormField(key, configObject[key]);
+ div.appendChild(node);
+ }
+
+ // now display move complex information sections, sorted alphabetically
+ if(!depth) depth = 1;
+ complexKeys.sort();
+ for(var i = 0; i < complexKeys.length; i++) {
+ var key = complexKeys[i];
+
+ // toSection will recurse back this function when child information is complex
+ var node = toSection(key, configObject[key], depth);
+ div.appendChild(node);
+ }
+
+ return div;
+}
+
+// given key and value, return a div with a label and an imput box
+// TODO: add a name to assocate with it
+function toFormField(key, value) {
+ var div = document.createElement("div");
+ div.className = "entry";
+ var label = document.createElement("label");
+ label.appendChild(document.createTextNode(key + ": "));
+ var input = toInput(value);
+ label.appendChild(input);
+ div.appendChild(label);
+ return div;
+}
+
+// given a value, return an imput object
+// length adjusted based on current value
+// TODO: add a name to assocate with it
+function toInput(value) {
+ var input = document.createElement("input");
+ input.value = value;
+ input.size = value.length;
+ return input;
+}
+
+// give a key, complexConfigObject, and depth
+// return a header
+// followed (ala configObjectToDom) by key/value inputs, then more complex sections
+function toSection(key, complexConfigObject, depth) {
+ var div = document.createElement("div");
+ var hNumber = Math.min(depth, 6); // limit h tags to h6
+ var h = document.createElement("h" + hNumber);
+ h.appendChild(document.createTextNode(key));
+ var kids = complexConfigObject;
+ if(complexConfigObject.length) {
+ // this is an array... [value, kids]
+ value = complexConfigObject[0];
+ var input = toInput(value);
+ h.appendChild(document.createTextNode(" "));
+ h.appendChild(input);
+ kids = complexConfigObject[1];
+ }
+ var innerSection = configObjectToDom(kids, depth + 1);
+
+ div.appendChild(h);
+ div.appendChild(innerSection);
+ return div;
+}
+
+// just show us the JSON
+function simpleDisplayResponse(container, response) {
+ container.innerHTML = response.responseText;
+}
+
+// swith between JSON display and form field display
+//var processResponse = simpleDisplayResponse;
+var processResponse = formDisplayResponse;
+
Ext.onReady(function () {
function render_configuration_objects (path) {
@@ -3,6 +117,6 @@
function onSuccess (response) {
var targetElement = document.getElementById("vserver-options");
- targetElement.innerHTML = response.responseText;
-
+ // display config options for selected vserver
+ processResponse(targetElement, response);
}
var connection = new Ext.data.Connection();
Index: admin.html
===================================================================
--- admin.html (revision 930)
+++ admin.html (working copy)
@@ -1,11 +1,15 @@
<html>
<head>
<link rel="stylesheet" type="text/css" href="js/resources/css/ext-all.css" />
-</head>
-<body>
<script text="text/javascript" src="js/adapter/ext/ext-base.js"></script>
<script text="text/javascript" src="js/ext-all.js"></script>
<script type="text/javascript" src="admin.js"></script>
+<style>
+ .section { padding: 0 0 0 1em; }
+</style>
+</head>
+<body>
+
<div id="vserver-list" style="width: 180px;"></div>
<div id="vserver-options"></div>
</body>
Index: server.py
===================================================================
--- server.py (revision 930)
+++ server.py (working copy)
@@ -71,7 +71,7 @@
return
if config_node:
- self._return_node_as_json(config_node)
+ self._node_as_json(config_node)
def _admin_request(self, request_uri):
"""Javascript or CSS content request handler."""
@@ -102,7 +102,6 @@
self.wfile.write('{"vservers": %s}' % records)
-
def _return_vserver_treeview(self, config_node):
"""JSON formatted EXT JS vserver treeview response."""
@@ -121,8 +120,42 @@
comma = True
self.wfile.write("]")
-
+ def _node_as_json(self, config_node):
+ """Recursive JSON formatted response
+
+ConfigObject :
+{ 'simple value key' : 'simple value'
+, 'just child values key' : ConfigObject
+, 'value + child values key' : [ 'simple value', ConfigObject ]
+}
+ """
+ children = []
+ for child in config_node:
+ children.append(child)
+ children.sort()
+
+ if not children:
+ value = config_node.value or ""
+ self.wfile.write('"%s"' % value)
+
+ else:
+ if config_node.value:
+ self.wfile.write('[ "%s" ,' % config_node.value)
+
+ self.wfile.write('{ ')
+
+ comma = ""
+ for child in children:
+ self.wfile.write('%s"%s" : ' % (comma, child))
+ comma = ", "
+ self._node_as_json(config_node[child])
+
+ self.wfile.write(' }')
+
+ if config_node.value:
+ self.wfile.write(' ]')
+
def _return_node_as_json(self, config_node):
"""JSON formatted configuration response."""
_______________________________________________
Cherokee mailing list
[email protected]
http://cherokee-project.com/cgi-bin/mailman/listinfo/cherokee