r9679 - in helma-ng/trunk: apps/demo apps/demo/skins apps/filestore apps/filestore/skins apps/googlestore apps/googlestore/skins modules/helma
[email protected] Mon, 27 Apr 2009 16:46:18 +0200 (CEST)
| Newsgroups | gmane.comp.java.helma.cvs |
|---|---|
| Message-ID | <20090427144618.116653D0D6@mia> |
Author: hannes
Date: 2009-04-27 16:46:17 +0200 (Mon, 27 Apr 2009)
New Revision: 9679
Modified:
helma-ng/trunk/apps/demo/config.js
helma-ng/trunk/apps/demo/skins/base.html
helma-ng/trunk/apps/filestore/config.js
helma-ng/trunk/apps/filestore/main.js
helma-ng/trunk/apps/filestore/skins/base.html
helma-ng/trunk/apps/filestore/skins/index.html
helma-ng/trunk/apps/googlestore/config.js
helma-ng/trunk/apps/googlestore/main.js
helma-ng/trunk/apps/googlestore/skins/base.html
helma-ng/trunk/apps/googlestore/skins/index.html
helma-ng/trunk/modules/helma/webapp.js
Log:
Make webapps nestable by pointing to a nested config file in the urls map. Make storage apps nestable in demo apps, plus a lot of cosmetic fixes: update to new skin features, use strings instead of regexps as url mapping keys, and more.
Details at http://dev.helma.org/trac/helma/changeset/9679
Modified: helma-ng/trunk/apps/demo/config.js
===================================================================
--- helma-ng/trunk/apps/demo/config.js 2009-04-27 14:46:15 UTC (rev 9678)
+++ helma-ng/trunk/apps/demo/config.js 2009-04-27 14:46:17 UTC (rev 9679)
@@ -3,15 +3,15 @@
};
exports.urls = [
- [ /^mount\/point/, 'webmodule' ],
- [ /^/, 'actions' ],
+ [ '/mount/point', 'webmodule' ],
+ [ '/storage', 'storage/config' ],
+ [ '/', 'actions' ],
];
exports.middleware = [
'helma/webapp/continuation',
- // 'helma/profiler',
'helma/logging',
];
-exports.charset = 'utf8';
+exports.charset = 'UTF-8';
exports.contentType = 'text/html';
Modified: helma-ng/trunk/apps/demo/skins/base.html
===================================================================
--- helma-ng/trunk/apps/demo/skins/base.html 2009-04-27 14:46:15 UTC (rev 9678)
+++ helma-ng/trunk/apps/demo/skins/base.html 2009-04-27 14:46:17 UTC (rev 9679)
@@ -26,6 +26,7 @@
<li><a href="/continuation">continuations</a></li>
<li><a href="/logging">logging</a></li>
<li><a href="/profiler">profiler</a></li>
+ <!-- <li><a href="/storage">storage</a></li> -->
</ul>
</div>
<div id="footer"><% footer %></div>
Modified: helma-ng/trunk/apps/filestore/config.js
===================================================================
--- helma-ng/trunk/apps/filestore/config.js 2009-04-27 14:46:15 UTC (rev 9678)
+++ helma-ng/trunk/apps/filestore/config.js 2009-04-27 14:46:17 UTC (rev 9679)
@@ -1,10 +1,10 @@
exports.urls = [
- [ /^$/, 'main' ]
+ [ '/', 'main' ]
];
exports.middleware = [
'helma/logging'
]
-exports.charset = 'utf8';
-exports.contentType = 'text/html';
\ No newline at end of file
+exports.charset = 'UTF-8';
+exports.contentType = 'text/html';
Modified: helma-ng/trunk/apps/filestore/main.js
===================================================================
--- helma-ng/trunk/apps/filestore/main.js 2009-04-27 14:46:15 UTC (rev 9678)
+++ helma-ng/trunk/apps/filestore/main.js 2009-04-27 14:46:17 UTC (rev 9679)
@@ -1,5 +1,5 @@
include('helma/webapp/response');
-include('model');
+include('./model');
export('index');
@@ -12,14 +12,10 @@
if (req.params.remove) {
return removeBook(req);
}
- return SkinnedResponse('skins/index.html', {
- title: 'Storage Demo',
- books: function(/*tag, skin, context*/) {
- var books = Book.all();
- return books.map(function(book) {
- return book.getFullTitle() + ' ' + getDeleteLink(book);
- }).join('<br>\r\n');
- }
+ return SkinnedResponse(getResource('./skins/index.html'), {
+ title: 'Storage',
+ books: Book.all(),
+ action: req.path
});
}
@@ -28,20 +24,16 @@
var book = new Book({author: author, title: req.params.title});
// author is saved transitively
book.save();
- return new RedirectResponse('/');
+ return new RedirectResponse(req.path);
}
function removeBook(req) {
var book = Book.get(req.params.remove);
// author is removed through cascading delete
book.remove();
- return new RedirectResponse('/');
+ return new RedirectResponse(req.path);
}
-function getDeleteLink(book) {
- return '<a href="/?remove=' + book._id + '">delete</a>';
-}
-
if (__name__ == "__main__") {
require('helma/webapp').start();
}
Modified: helma-ng/trunk/apps/filestore/skins/base.html
===================================================================
--- helma-ng/trunk/apps/filestore/skins/base.html 2009-04-27 14:46:15 UTC (rev 9678)
+++ helma-ng/trunk/apps/filestore/skins/base.html 2009-04-27 14:46:17 UTC (rev 9679)
@@ -4,6 +4,7 @@
<title>Helma NG Storage API</title>
</head>
<body>
+<h1><% title %></h1>
<% render 'content' %>
</body>
</html>
Modified: helma-ng/trunk/apps/filestore/skins/index.html
===================================================================
--- helma-ng/trunk/apps/filestore/skins/index.html 2009-04-27 14:46:15 UTC (rev 9678)
+++ helma-ng/trunk/apps/filestore/skins/index.html 2009-04-27 14:46:17 UTC (rev 9679)
@@ -1,17 +1,20 @@
-<% extends 'base.html' %>
+<% extends 'skins/base.html' %>
-<% subskin 'content' %>
-<h1><% title %></h1>
+<% subskin 'content' ----------------------------------- %>
<% message | prefix "<p>" | suffix "</p>" %>
<h3>Add a new book</h3>
-<form action="/" method="post">
- <label>Author: </label><input name="author" size="30"/>
- <label>Title: </label><input name="title" size="30"/>
- <input type="submit" name="save" value="Save"/>
+<form action="<% action %>" method="post">
+ <div><label>Author: </label></div><div><input name="author" size="30"/></div>
+ <div><label>Title: </label></div><div><input name="title" size="30"/></div>
+ <p><input type="submit" name="save" value="Save"/></p>
</form>
<h3>Available Books</h3>
<p>
-<% books %>
+<% for book in <% books %> render book %>
</p>
+
+<% subskin 'book' ----------------------------------- %>
+<div><% book.author.name %>: <% book.title %>
+ <a href="?remove=<% book._id %>">[remove]</a></div>
Modified: helma-ng/trunk/apps/googlestore/config.js
===================================================================
--- helma-ng/trunk/apps/googlestore/config.js 2009-04-27 14:46:15 UTC (rev 9678)
+++ helma-ng/trunk/apps/googlestore/config.js 2009-04-27 14:46:17 UTC (rev 9679)
@@ -1,10 +1,10 @@
exports.urls = [
- [ /^$/, 'main' ]
+ [ '/', 'main' ]
];
exports.middleware = [
'helma/logging'
]
-exports.charset = 'utf8';
-exports.contentType = 'text/html';
\ No newline at end of file
+exports.charset = 'UTF-8';
+exports.contentType = 'text/html';
Modified: helma-ng/trunk/apps/googlestore/main.js
===================================================================
--- helma-ng/trunk/apps/googlestore/main.js 2009-04-27 14:46:15 UTC (rev 9678)
+++ helma-ng/trunk/apps/googlestore/main.js 2009-04-27 14:46:17 UTC (rev 9679)
@@ -1,5 +1,5 @@
include('helma/webapp/response');
-include('model');
+include('./model');
export('index');
@@ -12,13 +12,10 @@
if (req.params.remove) {
return removeBook(req);
}
- return new SkinnedResponse('skins/index.html', {
- title: 'Storage Demo',
- books: function(/*tag, skin, context*/) {
- return Book.all().map(function(book) {
- return book.getFullTitle() + ' ' + getDeleteLink(book);
- }).join('<br>\r\n');
- }
+ return SkinnedResponse(getResource('./skins/index.html'), {
+ title: 'Storage',
+ books: Book.all(),
+ action: req.path
});
}
@@ -27,7 +24,7 @@
author.save(); // no cascading save yet
var book = new Book({author: author, title: req.params.title});
book.save();
- return new RedirectResponse('/');
+ return new RedirectResponse(req.path);
}
function removeBook(req) {
@@ -35,9 +32,5 @@
// no cascading delete
book.author.remove();
book.remove();
- return new RedirectResponse('/');
+ return new RedirectResponse(req.path);
}
-
-function getDeleteLink(book) {
- return '<a href="/?remove=' + book.getId() + '">delete</a>';
-}
Modified: helma-ng/trunk/apps/googlestore/skins/base.html
===================================================================
--- helma-ng/trunk/apps/googlestore/skins/base.html 2009-04-27 14:46:15 UTC (rev 9678)
+++ helma-ng/trunk/apps/googlestore/skins/base.html 2009-04-27 14:46:17 UTC (rev 9679)
@@ -4,6 +4,7 @@
<title>Helma NG Storage API</title>
</head>
<body>
+<h1><% title %></h1>
<% render 'content' %>
</body>
</html>
Modified: helma-ng/trunk/apps/googlestore/skins/index.html
===================================================================
--- helma-ng/trunk/apps/googlestore/skins/index.html 2009-04-27 14:46:15 UTC (rev 9678)
+++ helma-ng/trunk/apps/googlestore/skins/index.html 2009-04-27 14:46:17 UTC (rev 9679)
@@ -1,17 +1,20 @@
-<% extends 'base.html' %>
+<% extends 'skins/base.html' %>
-<% subskin 'content' %>
-<h1><% title %></h1>
+<% subskin 'content' ----------------------------------- %>
<% message | prefix "<p>" | suffix "</p>" %>
<h3>Add a new book</h3>
-<form action="/" method="post">
- <label>Author: </label><input name="author" size="30"/>
- <label>Title: </label><input name="title" size="30"/>
- <input type="submit" name="save" value="Save"/>
+<form action="<% action %>" method="post">
+ <div><label>Author: </label></div><div><input name="author" size="30"/></div>
+ <div><label>Title: </label></div><div><input name="title" size="30"/></div>
+ <p><input type="submit" name="save" value="Save"/></p>
</form>
<h3>Available Books</h3>
<p>
-<% books %>
+<% for book in <% books %> render book %>
</p>
+
+<% subskin 'book' ----------------------------------- %>
+<div><% book.author.name %>: <% book.title %>
+ <a href="?remove=<% book.getId %>">[remove]</a></div>
Modified: helma-ng/trunk/modules/helma/webapp.js
===================================================================
--- helma-ng/trunk/modules/helma/webapp.js 2009-04-27 14:46:15 UTC (rev 9678)
+++ helma-ng/trunk/modules/helma/webapp.js 2009-04-27 14:46:17 UTC (rev 9679)
@@ -46,6 +46,8 @@
function getPattern(spec) {
var pattern = spec[0];
if (typeof pattern == "string") {
+ if (pattern.startsWith("/"))
+ pattern = pattern.replace("/", "^");
pattern = spec[0] = new RegExp(pattern);
} else if (!(pattern instanceof RegExp)) {
throw Error("Pattern must be a regular expression or string");
@@ -53,10 +55,10 @@
return pattern;
}
- function getModule(spec) {
+ function getModule(spec, prefix) {
var module = spec[1];
if (typeof module == "string") {
- module = require(module);
+ module = require(prefix + module);
} else if (!(module instanceof Object)) {
throw Error("Module must be a string or object");
}
@@ -72,29 +74,28 @@
return null;
}
-
-
- try {
- log.debug('resolving path ' + path);
+ function resolveInConfig(config, path, prefix) {
+ if (log.isDebugEnabled) log.debug('resolving path ' + path);
if (config.urls instanceof Array) {
var urls = config.urls;
for (var i = 0; i < urls.length; i++) {
- log.debug("checking url line: " + urls[i]);
+ if (log.isDebugEnabled) log.debug("checking url line: " + urls[i]);
var match = getPattern(urls[i]).exec(path);
- log.debug("got match: " + match);
+ if (log.isDebugEnabled) log.debug("got match: " + match);
if (match != null) {
- var module = getModule(urls[i]);
- log.debug("module: " + module);
+ var module = getModule(urls[i], prefix);
+ if (log.isDebugEnabled) log.debug("module: " + module);
// cut matching prefix from path
path = path.substring(match[0].length);
// remove leading and trailing slashes
path = path.replace(/^\/+|\/+$/g, "");
//split
- path = path.split(/\/+/);
- var action = getAction(module, path[0]);
- if (typeof action == "function" && path.length <= action.length) {
+ var pathArray = path.split(/\/+/);
+ var action = getAction(module, pathArray[0]);
+ // log.debug("got action: " + action);
+ if (typeof action == "function" && pathArray.length <= action.length) {
// add remaining path elements as additional action arguments
- var actionArgs = path.slice(1).map(decodeURIComponent);
+ var actionArgs = pathArray.slice(1).map(decodeURIComponent);
var matchedArgs = match.slice(1).map(decodeURIComponent);
var args = [req].concat(matchedArgs).concat(actionArgs);
var middleware = config.middleware;
@@ -107,12 +108,20 @@
return action.apply(module, args);
}
}
- res = req.process();
+ return req.process();
+ } else if (module.urls instanceof Array) {
+ // nested app
+ return resolveInConfig(module, path, match[0] + "/");
+ } else {
+ break;
}
- break;
}
}
}
+ }
+
+ try {
+ res = resolveInConfig(config, path, "");
} catch (e) {
if (e.retry) {
throw e;