nitro 0.28.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. data/CHANGELOG +382 -0
  2. data/ProjectInfo +4 -4
  3. data/README +1 -1
  4. data/doc/AUTHORS +15 -15
  5. data/doc/MIGRATION +13 -0
  6. data/doc/RELEASES +102 -0
  7. data/lib/glue/sweeper.rb +1 -1
  8. data/lib/nitro.rb +38 -9
  9. data/lib/nitro/adapter/acgi.rb +1 -3
  10. data/lib/nitro/adapter/cgi.rb +1 -1
  11. data/lib/nitro/adapter/fastcgi.rb +1 -3
  12. data/lib/nitro/adapter/mongrel.rb +8 -6
  13. data/lib/nitro/adapter/webrick.rb +1 -2
  14. data/lib/nitro/cgi.rb +1 -1
  15. data/lib/nitro/compiler.rb +21 -40
  16. data/lib/nitro/compiler/elements.rb +72 -32
  17. data/lib/nitro/compiler/errors.rb +92 -42
  18. data/lib/nitro/compiler/include.rb +47 -17
  19. data/lib/nitro/compiler/morphing.rb +1 -3
  20. data/lib/nitro/compiler/script.rb +2 -2
  21. data/lib/nitro/context.rb +36 -0
  22. data/lib/nitro/controller.rb +140 -31
  23. data/lib/nitro/dispatcher.rb +27 -28
  24. data/lib/nitro/element.rb +52 -15
  25. data/lib/nitro/flash.rb +44 -0
  26. data/lib/nitro/helper/buffer.rb +0 -2
  27. data/lib/nitro/helper/form.rb +2 -2
  28. data/lib/nitro/helper/form/controls.rb +14 -3
  29. data/lib/nitro/helper/pager.rb +1 -1
  30. data/lib/nitro/helper/table.rb +4 -3
  31. data/lib/nitro/helper/xml.rb +1 -1
  32. data/lib/nitro/part.rb +20 -0
  33. data/lib/nitro/render.rb +44 -5
  34. data/lib/nitro/router.rb +81 -0
  35. data/lib/nitro/scaffolding.rb +24 -23
  36. data/lib/nitro/server.rb +12 -1
  37. data/lib/nitro/server/runner.rb +12 -0
  38. data/lib/nitro/session.rb +3 -12
  39. data/lib/nitro/session/drb.rb +2 -5
  40. data/lib/nitro/session/file.rb +2 -2
  41. data/lib/nitro/session/memcached.rb +14 -0
  42. data/lib/nitro/session/memory.rb +3 -26
  43. data/lib/nitro/session/og.rb +1 -1
  44. data/lib/nitro/test/assertions.rb +1 -1
  45. data/lib/nitro/test/context.rb +8 -2
  46. data/lib/nitro/test/testcase.rb +16 -7
  47. data/proto/public/error.xhtml +58 -21
  48. data/proto/public/js/controls.js +60 -15
  49. data/proto/public/js/dragdrop.js +105 -16
  50. data/proto/public/js/effects.js +19 -12
  51. data/proto/public/js/scriptaculous.js +1 -1
  52. data/proto/public/js/slider.js +2 -2
  53. data/proto/public/js/unittest.js +29 -20
  54. data/proto/public/scaffold/edit.xhtml +1 -1
  55. data/proto/public/scaffold/index.xhtml +2 -2
  56. data/proto/public/scaffold/list.xhtml +2 -2
  57. data/proto/public/scaffold/new.xhtml +1 -1
  58. data/proto/public/scaffold/search.xhtml +1 -1
  59. data/src/part/admin/controller.rb +5 -5
  60. data/src/part/admin/template/index.xhtml +2 -2
  61. data/test/nitro/compiler/tc_compiler.rb +23 -0
  62. data/test/nitro/helper/tc_table.rb +35 -0
  63. data/test/nitro/tc_cgi.rb +1 -1
  64. data/test/nitro/tc_controller.rb +3 -3
  65. data/test/nitro/tc_controller_aspect.rb +2 -0
  66. data/test/nitro/tc_dispatcher.rb +10 -1
  67. data/test/nitro/tc_flash.rb +14 -0
  68. data/test/nitro/tc_router.rb +58 -0
  69. data/test/nitro/tc_session.rb +26 -9
  70. metadata +13 -12
  71. data/lib/nitro/routing.rb +0 -41
  72. data/test/nitro/caching/tc_stores.rb +0 -17
  73. data/test/nitro/tc_table.rb +0 -66
@@ -128,7 +128,7 @@ var Draggables = {
128
128
  this.activeDraggable = draggable;
129
129
  },
130
130
 
131
- deactivate: function(draggbale) {
131
+ deactivate: function() {
132
132
  this.activeDraggable = null;
133
133
  },
134
134
 
@@ -199,6 +199,9 @@ Draggable.prototype = {
199
199
  },
200
200
  zindex: 1000,
201
201
  revert: false,
202
+ scroll: false,
203
+ scrollSensitivity: 20,
204
+ scrollSpeed: 15,
202
205
  snap: false // false, or xy or [x,y] or function(x,y){ return [x,y] }
203
206
  }, arguments[1] || {});
204
207
 
@@ -208,6 +211,8 @@ Draggable.prototype = {
208
211
  this.handle = Element.childrenWithClassName(this.element, options.handle)[0];
209
212
  if(!this.handle) this.handle = $(options.handle);
210
213
  if(!this.handle) this.handle = this.element;
214
+
215
+ if(options.scroll) options.scroll = $(options.scroll);
211
216
 
212
217
  Element.makePositioned(this.element); // fix IE
213
218
 
@@ -239,6 +244,7 @@ Draggable.prototype = {
239
244
  if(src.tagName && (
240
245
  src.tagName=='INPUT' ||
241
246
  src.tagName=='SELECT' ||
247
+ src.tagName=='OPTION' ||
242
248
  src.tagName=='BUTTON' ||
243
249
  src.tagName=='TEXTAREA')) return;
244
250
 
@@ -270,6 +276,11 @@ Draggable.prototype = {
270
276
  this.element.parentNode.insertBefore(this._clone, this.element);
271
277
  }
272
278
 
279
+ if(this.options.scroll) {
280
+ this.originalScrollLeft = this.options.scroll.scrollLeft;
281
+ this.originalScrollTop = this.options.scroll.scrollTop;
282
+ }
283
+
273
284
  Draggables.notify('onStart', this, event);
274
285
  if(this.options.starteffect) this.options.starteffect(this.element);
275
286
  },
@@ -282,8 +293,25 @@ Draggable.prototype = {
282
293
  this.draw(pointer);
283
294
  if(this.options.change) this.options.change(this);
284
295
 
296
+ if(this.options.scroll) {
297
+ //if(this.scrollInterval) this.scroll();
298
+ this.stopScrolling();
299
+ var p = Position.page(this.options.scroll);
300
+ p[0] += this.options.scroll.scrollLeft;
301
+ p[1] += this.options.scroll.scrollTop;
302
+ p.push(p[0]+this.options.scroll.offsetWidth);
303
+ p.push(p[1]+this.options.scroll.offsetHeight);
304
+ var speed = [0,0];
305
+ if(pointer[0] < (p[0]+this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[0]+this.options.scrollSensitivity);
306
+ if(pointer[1] < (p[1]+this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[1]+this.options.scrollSensitivity);
307
+ if(pointer[0] > (p[2]-this.options.scrollSensitivity)) speed[0] = pointer[0]-(p[2]-this.options.scrollSensitivity);
308
+ if(pointer[1] > (p[3]-this.options.scrollSensitivity)) speed[1] = pointer[1]-(p[3]-this.options.scrollSensitivity);
309
+ this.startScrolling(speed);
310
+ }
311
+
285
312
  // fix AppleWebKit rendering
286
313
  if(navigator.appVersion.indexOf('AppleWebKit')>0) window.scrollBy(0,0);
314
+
287
315
  Event.stop(event);
288
316
  },
289
317
 
@@ -321,13 +349,14 @@ Draggable.prototype = {
321
349
  },
322
350
 
323
351
  keyPress: function(event) {
324
- if(!event.keyCode==Event.KEY_ESC) return;
352
+ if(event.keyCode!=Event.KEY_ESC) return;
325
353
  this.finishDrag(event, false);
326
354
  Event.stop(event);
327
355
  },
328
356
 
329
357
  endDrag: function(event) {
330
358
  if(!this.dragging) return;
359
+ this.stopScrolling();
331
360
  this.finishDrag(event, true);
332
361
  Event.stop(event);
333
362
  },
@@ -337,7 +366,14 @@ Draggable.prototype = {
337
366
  var d = this.currentDelta();
338
367
  pos[0] -= d[0]; pos[1] -= d[1];
339
368
 
340
- var p = [0,1].map(function(i){ return (point[i]-pos[i]-this.offset[i]) }.bind(this));
369
+ if(this.options.scroll) {
370
+ pos[0] -= this.options.scroll.scrollLeft-this.originalScrollLeft;
371
+ pos[1] -= this.options.scroll.scrollTop-this.originalScrollTop;
372
+ }
373
+
374
+ var p = [0,1].map(function(i){
375
+ return (point[i]-pos[i]-this.offset[i])
376
+ }.bind(this));
341
377
 
342
378
  if(this.options.snap) {
343
379
  if(typeof this.options.snap == 'function') {
@@ -358,6 +394,34 @@ Draggable.prototype = {
358
394
  if((!this.options.constraint) || (this.options.constraint=='vertical'))
359
395
  style.top = p[1] + "px";
360
396
  if(style.visibility=="hidden") style.visibility = ""; // fix gecko rendering
397
+ },
398
+
399
+ stopScrolling: function() {
400
+ if(this.scrollInterval) {
401
+ clearInterval(this.scrollInterval);
402
+ this.scrollInterval = null;
403
+ }
404
+ },
405
+
406
+ startScrolling: function(speed) {
407
+ this.scrollSpeed = [speed[0]*this.options.scrollSpeed,speed[1]*this.options.scrollSpeed];
408
+ this.lastScrolled = new Date();
409
+ this.scrollInterval = setInterval(this.scroll.bind(this), 10);
410
+ },
411
+
412
+ scroll: function() {
413
+ var current = new Date();
414
+ var delta = current - this.lastScrolled;
415
+ this.lastScrolled = current;
416
+ this.options.scroll.scrollLeft += this.scrollSpeed[0] * delta / 1000;
417
+ this.options.scroll.scrollTop += this.scrollSpeed[1] * delta / 1000;
418
+
419
+ Position.prepare();
420
+ Droppables.show(Draggables._lastPointer, this.element);
421
+ Draggables.notify('onDrag', this);
422
+ this.draw(Draggables._lastPointer);
423
+
424
+ if(this.options.change) this.options.change(this);
361
425
  }
362
426
  }
363
427
 
@@ -414,7 +478,8 @@ var Sortable = {
414
478
  only: false,
415
479
  hoverclass: null,
416
480
  ghosting: false,
417
- format: null,
481
+ scroll: false,
482
+ format: /^[^_]*_(.*)$/,
418
483
  onChange: Prototype.emptyFunction,
419
484
  onUpdate: Prototype.emptyFunction
420
485
  }, arguments[1] || {});
@@ -425,6 +490,7 @@ var Sortable = {
425
490
  // build options for the draggables
426
491
  var options_for_draggable = {
427
492
  revert: true,
493
+ scroll: options.scroll,
428
494
  ghosting: options.ghosting,
429
495
  constraint: options.constraint,
430
496
  handle: options.handle };
@@ -568,18 +634,41 @@ var Sortable = {
568
634
  Element.show(Sortable._marker);
569
635
  },
570
636
 
571
- serialize: function(element) {
637
+ sequence: function(element) {
572
638
  element = $(element);
573
- var sortableOptions = this.options(element);
574
- var options = Object.extend({
575
- tag: sortableOptions.tag,
576
- only: sortableOptions.only,
577
- name: element.id,
578
- format: sortableOptions.format || /^[^_]*_(.*)$/
579
- }, arguments[1] || {});
639
+ var options = Object.extend(this.options(element), arguments[1] || {});
640
+
580
641
  return $(this.findElements(element, options) || []).map( function(item) {
581
- return (encodeURIComponent(options.name) + "[]=" +
582
- encodeURIComponent(item.id.match(options.format) ? item.id.match(options.format)[1] : ''));
583
- }).join("&");
642
+ return item.id.match(options.format) ? item.id.match(options.format)[1] : '';
643
+ });
644
+ },
645
+
646
+ setSequence: function(element, new_sequence) {
647
+ element = $(element);
648
+ var options = Object.extend(this.options(element), arguments[2] || {});
649
+
650
+ var nodeMap = {};
651
+ this.findElements(element, options).each( function(n) {
652
+ if (n.id.match(options.format))
653
+ nodeMap[n.id.match(options.format)[1]] = [n, n.parentNode];
654
+ n.parentNode.removeChild(n);
655
+ });
656
+
657
+ new_sequence.each(function(ident) {
658
+ var n = nodeMap[ident];
659
+ if (n) {
660
+ n[1].appendChild(n[0]);
661
+ delete nodeMap[ident];
662
+ }
663
+ });
664
+ },
665
+
666
+ serialize: function(element) {
667
+ element = $(element);
668
+ var name = encodeURIComponent(
669
+ (arguments[1] && arguments[1].name) ? arguments[1].name : element.id);
670
+ return Sortable.sequence(element, arguments[1]).map( function(item) {
671
+ return name + "[]=" + encodeURIComponent(item);
672
+ }).join('&');
584
673
  }
585
- }
674
+ }
@@ -35,7 +35,7 @@ Element.collectTextNodesIgnoreClass = function(element, className) {
35
35
  return $A($(element).childNodes).collect( function(node) {
36
36
  return (node.nodeType==3 ? node.nodeValue :
37
37
  ((node.hasChildNodes() && !Element.hasClassName(node,className)) ?
38
- Element.collectTextNodes(node) : ''));
38
+ Element.collectTextNodesIgnoreClass(node, className) : ''));
39
39
  }).flatten().join('');
40
40
  }
41
41
 
@@ -137,7 +137,7 @@ var Effect = {
137
137
  element = $(element);
138
138
  effect = (effect || 'appear').toLowerCase();
139
139
  var options = Object.extend({
140
- queue: { position:'end', scope:(element.id || 'global') }
140
+ queue: { position:'end', scope:(element.id || 'global'), limit: 1 }
141
141
  }, arguments[2] || {});
142
142
  Effect[Element.visible(element) ?
143
143
  Effect.PAIRS[effect][1] : Effect.PAIRS[effect][0]](element, options);
@@ -209,7 +209,10 @@ Object.extend(Object.extend(Effect.ScopedQueue.prototype, Enumerable), {
209
209
 
210
210
  effect.startOn += timestamp;
211
211
  effect.finishOn += timestamp;
212
- this.effects.push(effect);
212
+
213
+ if(!effect.options.queue.limit || (this.effects.length < effect.options.queue.limit))
214
+ this.effects.push(effect);
215
+
213
216
  if(!this.interval)
214
217
  this.interval = setInterval(this.loop.bind(this), 40);
215
218
  },
@@ -581,7 +584,6 @@ Effect.BlindUp = function(element) {
581
584
 
582
585
  Effect.BlindDown = function(element) {
583
586
  element = $(element);
584
- var oldHeight = Element.getStyle(element, 'height');
585
587
  var elementDimensions = Element.getDimensions(element);
586
588
  return new Effect.Scale(element, 100,
587
589
  Object.extend({ scaleContent: false,
@@ -594,10 +596,9 @@ Effect.BlindDown = function(element) {
594
596
  setStyle(effect.element, {height: '0px'});
595
597
  show(effect.element);
596
598
  }},
597
- afterFinishInternal: function(effect) { with(Element) {
598
- undoClipping(effect.element);
599
- setStyle(effect.element, {height: oldHeight});
600
- }}
599
+ afterFinishInternal: function(effect) {
600
+ Element.undoClipping(effect.element);
601
+ }
601
602
  }, arguments[1] || {})
602
603
  );
603
604
  }
@@ -690,8 +691,14 @@ Effect.SlideDown = function(element) {
690
691
  (effect.dims[0] - effect.element.clientHeight) + 'px' }); }},
691
692
  afterFinishInternal: function(effect) { with(Element) {
692
693
  undoClipping(effect.element);
693
- undoPositioned(effect.element.firstChild);
694
- undoPositioned(effect.element);
694
+ // IE will crash if child is undoPositioned first
695
+ if(/MSIE/.test(navigator.userAgent)){
696
+ undoPositioned(effect.element);
697
+ undoPositioned(effect.element.firstChild);
698
+ }else{
699
+ undoPositioned(effect.element.firstChild);
700
+ undoPositioned(effect.element);
701
+ }
695
702
  setStyle(effect.element.firstChild, {bottom: oldInnerBottom}); }}
696
703
  }, arguments[1] || {})
697
704
  );
@@ -741,7 +748,7 @@ Effect.Grow = function(element) {
741
748
  element = $(element);
742
749
  var options = Object.extend({
743
750
  direction: 'center',
744
- moveTransistion: Effect.Transitions.sinoidal,
751
+ moveTransition: Effect.Transitions.sinoidal,
745
752
  scaleTransition: Effect.Transitions.sinoidal,
746
753
  opacityTransition: Effect.Transitions.full
747
754
  }, arguments[1] || {});
@@ -817,7 +824,7 @@ Effect.Shrink = function(element) {
817
824
  element = $(element);
818
825
  var options = Object.extend({
819
826
  direction: 'center',
820
- moveTransistion: Effect.Transitions.sinoidal,
827
+ moveTransition: Effect.Transitions.sinoidal,
821
828
  scaleTransition: Effect.Transitions.sinoidal,
822
829
  opacityTransition: Effect.Transitions.none
823
830
  }, arguments[1] || {});
@@ -20,7 +20,7 @@
20
20
  // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
22
  var Scriptaculous = {
23
- Version: '1.5.1',
23
+ Version: '1.5.3',
24
24
  require: function(libraryName) {
25
25
  // inserting via DOM fails in Safari 2.0, so brute force approach
26
26
  document.write('<script type="text/javascript" src="'+libraryName+'"></script>');
@@ -200,10 +200,10 @@ Control.Slider.prototype = {
200
200
  setSpan: function(span, range) {
201
201
  if(this.isVertical()) {
202
202
  span.style.top = this.translateToPx(range.start);
203
- span.style.height = this.translateToPx(range.end - range.start);
203
+ span.style.height = this.translateToPx(range.end - range.start + this.range.start);
204
204
  } else {
205
205
  span.style.left = this.translateToPx(range.start);
206
- span.style.width = this.translateToPx(range.end - range.start);
206
+ span.style.width = this.translateToPx(range.end - range.start + this.range.start);
207
207
  }
208
208
  },
209
209
  updateStyles: function() {
@@ -2,7 +2,25 @@
2
2
  // (c) 2005 Jon Tirsen (http://www.tirsen.com)
3
3
  // (c) 2005 Michael Schuerig (http://www.schuerig.de/michael/)
4
4
  //
5
- // See scriptaculous.js for full license.
5
+ // Permission is hereby granted, free of charge, to any person obtaining
6
+ // a copy of this software and associated documentation files (the
7
+ // "Software"), to deal in the Software without restriction, including
8
+ // without limitation the rights to use, copy, modify, merge, publish,
9
+ // distribute, sublicense, and/or sell copies of the Software, and to
10
+ // permit persons to whom the Software is furnished to do so, subject to
11
+ // the following conditions:
12
+ //
13
+ // The above copyright notice and this permission notice shall be
14
+ // included in all copies or substantial portions of the Software.
15
+ //
16
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+
6
24
 
7
25
  // experimental, Firefox-only
8
26
  Event.simulateMouse = function(element, eventName) {
@@ -64,24 +82,7 @@ var Test = {}
64
82
  Test.Unit = {};
65
83
 
66
84
  // security exception workaround
67
- Test.Unit.inspect = function(obj) {
68
- var info = [];
69
-
70
- if(typeof obj=="string" ||
71
- typeof obj=="number") {
72
- return obj;
73
- } else {
74
- for(property in obj)
75
- if(typeof obj[property]!="function")
76
- info.push(property + ' => ' +
77
- (typeof obj[property] == "string" ?
78
- '"' + obj[property] + '"' :
79
- obj[property]));
80
- }
81
-
82
- return ("'" + obj + "' #" + typeof obj +
83
- ": {" + info.join(", ") + "}");
84
- }
85
+ Test.Unit.inspect = Object.inspect;
85
86
 
86
87
  Test.Unit.Logger = Class.create();
87
88
  Test.Unit.Logger.prototype = {
@@ -279,6 +280,14 @@ Test.Unit.Assertions.prototype = {
279
280
  '", actual "' + Test.Unit.inspect(actual) + '"'); }
280
281
  catch(e) { this.error(e); }
281
282
  },
283
+ assertEnumEqual: function(expected, actual) {
284
+ var message = arguments[2] || "assertEnumEqual";
285
+ try { $A(expected).length == $A(actual).length &&
286
+ expected.zip(actual).all(function(pair) { return pair[0] == pair[1] }) ?
287
+ this.pass() : this.fail(message + ': expected ' + Test.Unit.inspect(expected) +
288
+ ', actual ' + Test.Unit.inspect(actual)); }
289
+ catch(e) { this.error(e); }
290
+ },
282
291
  assertNotEqual: function(expected, actual) {
283
292
  var message = arguments[2] || "assertNotEqual";
284
293
  try { (expected != actual) ? this.pass() :
@@ -360,4 +369,4 @@ Object.extend(Object.extend(Test.Unit.Testcase.prototype, Test.Unit.Assertions.p
360
369
  }
361
370
  catch(e) { this.error(e); }
362
371
  }
363
- });
372
+ });
@@ -1,6 +1,6 @@
1
1
  <SystemPage>
2
2
  <?r base = "#{@base}/%base%" ?>
3
- <h1><a href="/"> Home</a> > <a href="#@base">System</a> > <a href="#{base}/list">#{"%plural%".humanize}</a> > Edit %name%</h1>
3
+ <h1><a href="/"> Home</a> > <a href="#@base">System</a> > <a href="#{base}/list">#{"%plural%".humanize}</a> > Edit #{"%name%".humanize} </h1>
4
4
  <?r if @all ?>
5
5
  <a href="#{request.uri.gsub(/\/all$/, '')}">Show editable</a>
6
6
  #{form_for @obj, :action => "#{base}/save", :cancel => "#{base}/list", :all => true}
@@ -1,9 +1,9 @@
1
1
  <SystemPage>
2
2
  <?r base = "#{@base}/%base%" ?>
3
3
  <h1>#{"%plural%".humanize}</h1>
4
- <h2><a href="#{base}/new">New %name%</a></h2>
4
+ <h2><a href="#{base}/new">New #{"%name%".humanize}</a></h2>
5
5
  <form action="search">
6
- Search %plural%: <input type="text" name="q" />&nbsp;<input type="submit" value="Search" />
6
+ Search #{"%plural%".humanize}: <input type="text" name="q" />&nbsp;<input type="submit" value="Search" />
7
7
  </form>
8
8
  <table>
9
9
  <?r for obj in @list ?>
@@ -1,10 +1,10 @@
1
1
  <SystemPage>
2
2
  <?r base = "#{@base}/%base%" ?>
3
3
  <h1><a href="/"> Home</a> > <a href="#@base">System</a> > #{"%plural%".humanize}</h1>
4
- <a href="#{base}/new">New %name%</a>
4
+ <a href="#{base}/new">New #{"%name%".humanize}</a>
5
5
  <p>
6
6
  <form action="#{base}/search">
7
- Search %plural%: <input type="text" name="q" />&nbsp;<input type="submit" value="Search" />
7
+ Search #{"%plural%".humanize}: <input type="text" name="q" />&nbsp;<input type="submit" value="Search" />
8
8
  </form>
9
9
  </p>
10
10
  <table>
@@ -1,6 +1,6 @@
1
1
  <SystemPage>
2
2
  <?r base = "#{@base}/%base%" ?>
3
- <h1><a href="/"> Home</a> > <a href="#@base">System</a> > <a href="#{base}/list">#{"%plural%".humanize}</a> > New %name%</h1>
3
+ <h1><a href="/"> Home</a> > <a href="#@base">System</a> > <a href="#{base}/list">#{"%plural%".humanize}</a> > New #{"%name%".humanize}</h1>
4
4
  <?r if @all ?>
5
5
  <a href="#{request.uri.gsub(/\/all$/, '')}">Show editable</a>
6
6
  #{form_for @obj, :action => "#{base}/save", :cancel => "#{base}/list", :all => true, :enctype => "multipart/form-data"}
@@ -3,7 +3,7 @@
3
3
  <h1><a href="/"> Home</a> > <a href="#@base">System</a> > <a href="#{base}/list">#{"%plural%".humanize}</a> > Search for '#@query'</h1>
4
4
  <p>
5
5
  <form action="#{base}/search">
6
- Search %plural%: <input type="text" name="q" />&nbsp;<input type="submit" value="Search" />
6
+ Search #{"%plural%".humanize}: <input type="text" name="q" />&nbsp;<input type="submit" value="Search" />
7
7
  </form>
8
8
  </p>
9
9
  <?r if @list.nil? ?>
@@ -16,16 +16,16 @@ class AdminController < Nitro::Controller
16
16
 
17
17
  scaffold_all
18
18
 
19
- # Default to views in part dir
20
-
21
- def self.template_root
22
- File.join(File.dirname(__FILE__), 'template')
19
+ def self.setup_template_root(path)
20
+ super
21
+ @template_root << File.join(File.dirname(__FILE__), 'template')
23
22
  end
24
23
 
25
24
  # default method for controller
26
25
 
27
26
  def index
28
- @classes = self.class.scaffolding_classes.keys
27
+ @classes = self.class.scaffolding_classes.keys.sort { |c1, c2| c1.name <=> c2.name }
28
+ @settings = Configuration.settings.sort { |s1, s2| "#{s1.owner}.#{s1.name}" <=> "#{s2.owner}.#{s2.name}" }
29
29
  end
30
30
 
31
31
  # Delete all instances of the class.