nitro 0.31.0 → 0.40.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/nitro +135 -37
- data/doc/CHANGELOG.1 +108 -108
- data/doc/CHANGELOG.2 +89 -89
- data/doc/CHANGELOG.3 +105 -105
- data/{CHANGELOG → doc/CHANGELOG.4} +509 -509
- data/doc/{AUTHORS → CONTRIBUTORS} +49 -37
- data/doc/LIBRARIES +13 -0
- data/doc/LICENSE +2 -3
- data/doc/MIGRATION +45 -0
- data/doc/RELEASES +131 -11
- data/doc/TODO +67 -0
- data/lib/glue/magick.rb +0 -3
- data/lib/glue/sweeper.rb +30 -15
- data/lib/glue/thumbnails.rb +0 -2
- data/lib/glue/webfile.rb +23 -11
- data/lib/nitro.rb +37 -44
- data/lib/nitro/adapter/cgi.rb +0 -3
- data/lib/nitro/adapter/console.rb +0 -2
- data/lib/nitro/adapter/fastcgi.rb +6 -3
- data/lib/nitro/adapter/mongrel.rb +97 -58
- data/lib/nitro/adapter/script.rb +4 -6
- data/lib/nitro/adapter/webrick.rb +33 -87
- data/lib/nitro/adapter/webrick/vcr.rb +85 -0
- data/lib/nitro/caching.rb +0 -2
- data/lib/nitro/caching/actions.rb +0 -2
- data/lib/nitro/caching/fragments.rb +0 -2
- data/lib/nitro/caching/output.rb +45 -16
- data/lib/nitro/caching/proxy.rb +49 -0
- data/lib/nitro/cgi.rb +3 -6
- data/lib/nitro/cgi/cookie.rb +0 -3
- data/lib/nitro/cgi/request.rb +67 -24
- data/lib/nitro/cgi/response.rb +0 -2
- data/lib/nitro/cgi/{sendfile.rb → send_file.rb} +7 -6
- data/lib/nitro/compiler.rb +62 -55
- data/lib/nitro/compiler/cleanup.rb +0 -3
- data/lib/nitro/compiler/elements.rb +31 -28
- data/lib/nitro/compiler/errors.rb +2 -5
- data/lib/nitro/compiler/include.rb +10 -8
- data/lib/nitro/compiler/layout.rb +0 -2
- data/lib/nitro/compiler/localization.rb +0 -2
- data/lib/nitro/compiler/markup.rb +14 -6
- data/lib/nitro/compiler/morphing.rb +1 -5
- data/lib/nitro/compiler/script.rb +2 -4
- data/lib/nitro/compiler/squeeze.rb +0 -2
- data/lib/nitro/compiler/xslt.rb +0 -2
- data/lib/nitro/context.rb +10 -5
- data/lib/nitro/control.rb +18 -0
- data/lib/nitro/control/attribute.rb +88 -0
- data/lib/nitro/control/attribute/checkbox.rb +19 -0
- data/lib/nitro/control/attribute/datetime.rb +21 -0
- data/lib/nitro/control/attribute/file.rb +20 -0
- data/lib/nitro/control/attribute/fixnum.rb +26 -0
- data/lib/nitro/control/attribute/float.rb +26 -0
- data/lib/nitro/control/attribute/options.rb +38 -0
- data/lib/nitro/control/attribute/password.rb +16 -0
- data/lib/nitro/control/attribute/text.rb +16 -0
- data/lib/nitro/control/attribute/textarea.rb +16 -0
- data/lib/nitro/control/none.rb +16 -0
- data/lib/nitro/control/relation.rb +53 -0
- data/lib/nitro/control/relation/belongs_to.rb +0 -0
- data/lib/nitro/control/relation/has_many.rb +97 -0
- data/lib/nitro/control/relation/joins_many.rb +0 -0
- data/lib/nitro/control/relation/many_to_many.rb +0 -0
- data/lib/nitro/control/relation/refers_to.rb +29 -0
- data/lib/nitro/controller.rb +7 -296
- data/lib/nitro/dispatcher.rb +72 -34
- data/lib/nitro/element.rb +36 -10
- data/lib/nitro/element/javascript.rb +0 -2
- data/lib/nitro/flash.rb +23 -10
- data/lib/nitro/global.rb +36 -11
- data/lib/nitro/helper.rb +22 -8
- data/lib/nitro/helper/benchmark.rb +0 -2
- data/lib/nitro/helper/buffer.rb +0 -3
- data/lib/nitro/helper/css.rb +12 -0
- data/lib/nitro/helper/debug.rb +1 -3
- data/lib/nitro/helper/default.rb +1 -0
- data/lib/nitro/helper/feed.rb +400 -386
- data/lib/nitro/helper/form.rb +246 -116
- data/lib/nitro/helper/javascript.rb +28 -2
- data/lib/nitro/helper/javascript/morphing.rb +0 -2
- data/lib/nitro/helper/javascript/prototype.rb +0 -2
- data/lib/nitro/helper/javascript/scriptaculous.rb +0 -1
- data/lib/nitro/helper/layout.rb +0 -2
- data/lib/nitro/helper/navigation.rb +87 -0
- data/lib/nitro/helper/pager.rb +11 -22
- data/lib/nitro/helper/table.rb +9 -32
- data/lib/nitro/helper/url.rb +104 -0
- data/lib/nitro/helper/xhtml.rb +20 -4
- data/lib/nitro/helper/xml.rb +0 -2
- data/lib/nitro/markup.rb +131 -0
- data/lib/nitro/part.rb +52 -7
- data/lib/nitro/publishable.rb +328 -0
- data/lib/nitro/render.rb +30 -61
- data/lib/nitro/router.rb +12 -4
- data/lib/nitro/sanitize.rb +48 -0
- data/lib/nitro/scaffold.rb +9 -11
- data/lib/nitro/scaffold/controller.rb +25 -0
- data/lib/nitro/scaffold/model.rb +150 -0
- data/lib/nitro/scaffolding.rb +1 -3
- data/lib/nitro/server.rb +57 -32
- data/lib/nitro/server/drb.rb +16 -2
- data/lib/nitro/server/runner.rb +80 -102
- data/lib/nitro/service.rb +0 -1
- data/lib/nitro/service/xmlrpc.rb +0 -2
- data/lib/nitro/session.rb +26 -18
- data/lib/nitro/session/drb.rb +2 -16
- data/lib/nitro/session/memory.rb +0 -2
- data/lib/nitro/template.rb +219 -0
- data/lib/nitro/test/assertions.rb +1 -3
- data/lib/nitro/test/context.rb +0 -1
- data/lib/nitro/test/testcase.rb +0 -1
- data/lib/nitro/version.rb +6 -0
- data/lib/part/admin.rb +16 -0
- data/lib/part/admin/controller.rb +19 -0
- data/lib/part/admin/helper.rb +30 -0
- data/lib/part/admin/og/controller.rb +114 -0
- data/lib/part/admin/og/customize.rb +4 -0
- data/lib/part/admin/og/template/index.xhtml +27 -0
- data/lib/part/admin/og/template/list.xhtml +38 -0
- data/lib/part/admin/og/template/search.xhtml +20 -0
- data/lib/part/admin/og/template/update.xhtml +25 -0
- data/lib/part/admin/skin.rb +207 -0
- data/lib/part/admin/template/denied.xhtml +13 -0
- data/lib/part/admin/template/index.xhtml +12 -0
- data/lib/part/admin/todo.txt +2 -0
- data/proto/public/error.xhtml +4 -2
- data/proto/run.rb +0 -2
- data/test/glue/tc_webfile.rb +1 -0
- data/test/nitro/cgi/tc_request.rb +23 -0
- data/test/nitro/helper/tc_feed.rb +0 -3
- data/test/nitro/helper/tc_navbar.rb +74 -0
- data/test/nitro/helper/tc_table.rb +2 -0
- data/test/nitro/tc_cgi.rb +72 -19
- data/test/nitro/tc_controller.rb +35 -26
- data/test/nitro/tc_controller_aspect.rb +1 -0
- data/test/nitro/tc_controller_params.rb +864 -0
- data/test/nitro/tc_dispatcher.rb +2 -2
- data/test/nitro/tc_element.rb +16 -16
- data/test/nitro/tc_flash.rb +3 -3
- data/test/nitro/tc_markup.rb +31 -0
- data/test/nitro/tc_render.rb +12 -14
- data/test/nitro/tc_session.rb +9 -7
- data/test/nitro/tc_template.rb +34 -0
- metadata +217 -198
- data/INSTALL +0 -121
- data/ProjectInfo +0 -74
- data/README +0 -555
- data/doc/apache.txt +0 -9
- data/doc/config.txt +0 -28
- data/doc/faq.txt +0 -7
- data/doc/lhttpd.txt +0 -7
- data/lib/nitro/adapter/scgi.rb +0 -239
- data/lib/nitro/helper/form/builder.rb +0 -144
- data/lib/nitro/helper/form/controls.rb +0 -389
- data/lib/nitro/helper/rss.rb +0 -72
- data/proto/conf/apache.conf +0 -51
- data/proto/public/scaffold/advanced_search.xhtml +0 -30
- data/proto/public/scaffold/edit.xhtml +0 -11
- data/proto/public/scaffold/form.xhtml +0 -1
- data/proto/public/scaffold/index.xhtml +0 -20
- data/proto/public/scaffold/list.xhtml +0 -32
- data/proto/public/scaffold/new.xhtml +0 -11
- data/proto/public/scaffold/search.xhtml +0 -29
- data/proto/public/scaffold/view.xhtml +0 -8
- data/proto/script/scgi_ctl +0 -221
- data/proto/script/scgi_service +0 -128
- data/setup.rb +0 -1585
- data/src/part/admin.rb +0 -16
- data/src/part/admin/controller.rb +0 -81
- data/src/part/admin/skin.rb +0 -21
- data/src/part/admin/system.css +0 -135
- data/src/part/admin/template/denied.xhtml +0 -1
- data/src/part/admin/template/index.xhtml +0 -43
- data/test/nitro/helper/tc_rss.rb +0 -24
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'nitro/control/attribute'
|
2
|
+
|
3
|
+
module Nitro
|
4
|
+
|
5
|
+
# Controls a Fixnum attribute that can contain discreet values
|
6
|
+
# (options).
|
7
|
+
#
|
8
|
+
# === Example
|
9
|
+
#
|
10
|
+
# Pass a 'reverse' dictionary. Reverse to reuse the has for
|
11
|
+
# easy rendering of labels. Dictionary to allow for ordered
|
12
|
+
# keys.
|
13
|
+
#
|
14
|
+
# PRIORITY_VALUES = Dictionary[
|
15
|
+
# 0, :trivial,
|
16
|
+
# 1, :minor,
|
17
|
+
# 2, :major,
|
18
|
+
# 3, :blocker
|
19
|
+
# ]
|
20
|
+
#
|
21
|
+
# attr_accessor :priority, Fixnum, :control => :options, :options_data => PRIORITY_VALUES
|
22
|
+
|
23
|
+
class OptionsControl < AttributeControl
|
24
|
+
setting :style, :default => 'width: 100px', :doc => 'The default style'
|
25
|
+
|
26
|
+
def render
|
27
|
+
style = @anno.control_style || self.class.style
|
28
|
+
data = @anno[:options_data]
|
29
|
+
%{
|
30
|
+
#{emit_label}
|
31
|
+
<select id="#{@attribute}_ctl" name="#{@attribute}">
|
32
|
+
#{options :labels => data.values, :values => data.keys, :selected => value}
|
33
|
+
</select>
|
34
|
+
}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'nitro/control/attribute'
|
2
|
+
|
3
|
+
module Nitro
|
4
|
+
|
5
|
+
class PasswordControl < AttributeControl
|
6
|
+
setting :style, :default => 'width: 250px', :doc => 'The default style'
|
7
|
+
|
8
|
+
def render
|
9
|
+
%{
|
10
|
+
#{emit_label}
|
11
|
+
<input type="password" id="#{@attribute}_ctl" name="#{@attribute}" value="#{@object.send(@attribute)}"#{emit_style}#{emit_disabled} />
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'nitro/control/attribute'
|
2
|
+
|
3
|
+
module Nitro
|
4
|
+
|
5
|
+
class TextControl < AttributeControl
|
6
|
+
setting :style, :default => 'width: 250px', :doc => 'The default style'
|
7
|
+
|
8
|
+
def render
|
9
|
+
%{
|
10
|
+
#{emit_label}
|
11
|
+
<input type="text" id="#{@attribute}_ctl" name="#{@attribute}" value="#{@object.send(@attribute)}"#{emit_style}#{emit_disabled} />
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'nitro/control/attribute'
|
2
|
+
|
3
|
+
module Nitro
|
4
|
+
|
5
|
+
class TextareaControl < AttributeControl
|
6
|
+
setting :style, :default => 'width: 500px; height: 100px', :doc => 'The default style'
|
7
|
+
|
8
|
+
def render
|
9
|
+
%{
|
10
|
+
#{emit_label}
|
11
|
+
<textarea id="#{@attribute}_ctl" name="#{@attribute}"#{emit_style}#{emit_disabled}>#{@object.send(@attribute)}</textarea>
|
12
|
+
}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'nitro/control/attribute'
|
2
|
+
|
3
|
+
module Nitro
|
4
|
+
|
5
|
+
# The base class for controls used to inspect object
|
6
|
+
# relations.
|
7
|
+
#--
|
8
|
+
# FIXME: this is a temp hack.
|
9
|
+
# TODO: Fix mismatches with attributes.
|
10
|
+
#++
|
11
|
+
|
12
|
+
class RelationControl < AttributeControl
|
13
|
+
|
14
|
+
# === Input
|
15
|
+
#
|
16
|
+
# * object = the object to inspect
|
17
|
+
# * symbol = the relation symbol
|
18
|
+
# * anno = the relation annotations
|
19
|
+
# * options = additional options
|
20
|
+
|
21
|
+
def initialize object, rel, options
|
22
|
+
@object = object
|
23
|
+
@anno = rel
|
24
|
+
@value = options[:value] || object.send(rel.name.to_sym)
|
25
|
+
@options = options
|
26
|
+
end
|
27
|
+
|
28
|
+
def symbol
|
29
|
+
@anno[:symbol]
|
30
|
+
end
|
31
|
+
|
32
|
+
def rel
|
33
|
+
@anno
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
# Emit the label for this control.
|
39
|
+
# The label is skipped if the control is created with the
|
40
|
+
# option :no_label set to true.
|
41
|
+
#--
|
42
|
+
# TODO: reuse attribute control version.
|
43
|
+
#++
|
44
|
+
|
45
|
+
def emit_label
|
46
|
+
return '' if @options[:no_label]
|
47
|
+
title = @anno[:title] || @options[:label] || @anno[:name].to_s.humanize
|
48
|
+
%{<label for="#{@anno[:name]}">#{title}</label>}
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
File without changes
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'nitro/control/relation'
|
2
|
+
|
3
|
+
module Nitro
|
4
|
+
|
5
|
+
# HasMany, ManyToMany and JoinsMany
|
6
|
+
|
7
|
+
class HasManyControl < RelationControl
|
8
|
+
|
9
|
+
#pre :do_this, :on => :populate_object
|
10
|
+
|
11
|
+
def render
|
12
|
+
str = "#{emit_label}"
|
13
|
+
str << emit_container_start
|
14
|
+
str << emit_js
|
15
|
+
if selected_items.empty?
|
16
|
+
str << emit_selector(:removable => false)
|
17
|
+
else
|
18
|
+
removable = selected_items.size != 1 ? true : false
|
19
|
+
selected_items.each do |item|
|
20
|
+
str << emit_selector(:selected => item.pk)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
str << emit_container_end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
# these parts are seperated from render to make it easier
|
29
|
+
# to extend and customise the HasManyControl
|
30
|
+
|
31
|
+
def all_items
|
32
|
+
return @all_items unless @all_items.nil?
|
33
|
+
@all_items = rel.target_class.all
|
34
|
+
end
|
35
|
+
|
36
|
+
def selected_items
|
37
|
+
if @object.saved?
|
38
|
+
values
|
39
|
+
else
|
40
|
+
[] # gmosx, THINK: this is a hack fix!
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def emit_container_start
|
45
|
+
%{<div class="many_to_many_container">}
|
46
|
+
end
|
47
|
+
|
48
|
+
def emit_container_end
|
49
|
+
'</div>'
|
50
|
+
end
|
51
|
+
|
52
|
+
# :removable controls wether the minus button is active
|
53
|
+
# :selected denotes the oid to flag as selected in the list
|
54
|
+
|
55
|
+
def emit_selector(options={})
|
56
|
+
removable = options.fetch(:removable, true)
|
57
|
+
selected = options.fetch(:selected, nil)
|
58
|
+
%{
|
59
|
+
<div>
|
60
|
+
<select class="has_many_ctl" name="#{rel.name}[]" #{emit_style}#{emit_disabled}>
|
61
|
+
<option value="">None</option>
|
62
|
+
#{options(:labels => all_items.map{|o| o.to_s}, :values => all_items.map{|o| o.pk}, :selected => selected)}
|
63
|
+
</select>
|
64
|
+
<input type="button" class="#{rel.name}_remove_btn" value=" - " onclick="rm_#{rel.name}_rel(this);" #{'disabled="disabled"' unless removable} />
|
65
|
+
<input type="button" class="#{rel.name}_add_btn" value=" + " onclick="add_#{rel.name}_rel(this);"#{emit_disabled} />
|
66
|
+
</div>
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
# Inline script: override this to change behavior
|
71
|
+
|
72
|
+
def emit_js
|
73
|
+
%{
|
74
|
+
<script type="text/javascript">
|
75
|
+
rm_#{rel.name}_rel = function(el){
|
76
|
+
ctl=el.parentNode;
|
77
|
+
container=ctl.parentNode;
|
78
|
+
container.removeChild(ctl);
|
79
|
+
inputTags = container.getElementsByTagName('input');
|
80
|
+
if(inputTags.length==2)
|
81
|
+
inputTags[0].disabled='disabled';
|
82
|
+
}
|
83
|
+
add_#{rel.name}_rel = function(el){
|
84
|
+
ctl=el.parentNode;
|
85
|
+
container=ctl.parentNode;
|
86
|
+
node=ctl.cloneNode(true);
|
87
|
+
node.getElementsByTagName('input')[0].removeAttribute('disabled');
|
88
|
+
if(container.lastChild==ctl) container.appendChild(node);
|
89
|
+
else container.insertBefore(node, ctl.nextSibling);
|
90
|
+
if(container.childNodes.length>1) container.getElementsByTagName('input')[0].disabled='';
|
91
|
+
}
|
92
|
+
</script>
|
93
|
+
}
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
File without changes
|
File without changes
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'nitro/control/relation'
|
2
|
+
|
3
|
+
module Nitro
|
4
|
+
|
5
|
+
# RefersTo. Also used for BelongsTo.
|
6
|
+
|
7
|
+
class RefersToControl < RelationControl
|
8
|
+
|
9
|
+
def render
|
10
|
+
%{
|
11
|
+
#{emit_label}
|
12
|
+
<select id="#{rel.name}_ctl" name="#{rel.name}"#{emit_disabled}>
|
13
|
+
#{emit_options}
|
14
|
+
</select>
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
def emit_options
|
19
|
+
objs = rel.target_class.all
|
20
|
+
selected = selected.pk if selected = value
|
21
|
+
%{
|
22
|
+
<option value="">--</option>
|
23
|
+
#{options(:labels => objs.map{|o| o.to_s}, :values => objs.map{|o| o.pk}, :selected => selected)}
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
data/lib/nitro/controller.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'facets/more/annotation'
|
2
|
+
require 'facets/more/inheritor'
|
3
3
|
require 'facets/more/aspects'
|
4
4
|
|
5
|
-
require '
|
5
|
+
require 'nitro/markup'
|
6
6
|
|
7
7
|
require 'nitro'
|
8
8
|
require 'nitro/render'
|
@@ -11,297 +11,10 @@ require 'nitro/caching'
|
|
11
11
|
require 'nitro/flash'
|
12
12
|
require 'nitro/helper'
|
13
13
|
require 'nitro/compiler'
|
14
|
+
require 'nitro/publishable'
|
14
15
|
|
15
16
|
module Nitro
|
16
17
|
|
17
|
-
# Include this Mixin to a class to make objects of this class
|
18
|
-
# publishable, ie accessible through a standard web (REST)
|
19
|
-
# interface.
|
20
|
-
#
|
21
|
-
# === Instance variables
|
22
|
-
#
|
23
|
-
# ==== mount_path
|
24
|
-
#
|
25
|
-
# Where the publishable is mounted.
|
26
|
-
#
|
27
|
-
# ==== template_root
|
28
|
-
#
|
29
|
-
# Where to look for templates for this publishable
|
30
|
-
# object / controller. The template root is actually a stack
|
31
|
-
# to implement some form of template root inheritance,
|
32
|
-
# thus allowing for more reusable controllers. Ie you can
|
33
|
-
# 'extend' a controller, and only override the templates
|
34
|
-
# you want to change. The compiler will traverse the
|
35
|
-
# template root stack and use the templates from parent
|
36
|
-
# controllers if they are not overriden.
|
37
|
-
|
38
|
-
|
39
|
-
module Publishable
|
40
|
-
|
41
|
-
def self.included(base)
|
42
|
-
super
|
43
|
-
|
44
|
-
base.module_eval do
|
45
|
-
include Render
|
46
|
-
include ::Aspects
|
47
|
-
include Flashing
|
48
|
-
include Helpers
|
49
|
-
|
50
|
-
# The collection of 'models' ie classes that are linked
|
51
|
-
# to this Publishable/Controller.
|
52
|
-
|
53
|
-
ann :self, :models => []
|
54
|
-
|
55
|
-
# This is a helper that 'links' one or more classes to this
|
56
|
-
# controller. In practice it annotates each class with the
|
57
|
-
# controller and stores the controller's list of 'models'.
|
58
|
-
|
59
|
-
def self.model *classes
|
60
|
-
for c in classes
|
61
|
-
c.ann :self, :controller => self
|
62
|
-
self.ann.self.models! << c
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Aliases an action
|
68
|
-
#--
|
69
|
-
# gmosx, FIXME: better implementation needed.
|
70
|
-
# gmosx, FIXME: copy all annotations.
|
71
|
-
#++
|
72
|
-
|
73
|
-
base.module_eval do
|
74
|
-
def self.alias_action(new, old)
|
75
|
-
alias_method new, old
|
76
|
-
ann new, :view => old
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# Return the 'action' methods for this Controller.
|
81
|
-
# Some dangerous methods from ancestors are removed.
|
82
|
-
# All private methods are ignored.
|
83
|
-
|
84
|
-
base.module_eval do
|
85
|
-
def self.action_methods
|
86
|
-
classes = self.ancestors.reject do |a|
|
87
|
-
[Object, Kernel, Render, Controller, Caching].include?(a)
|
88
|
-
end
|
89
|
-
|
90
|
-
classes.delete(PP::ObjectMixin) if defined?(PP::ObjectMixin)
|
91
|
-
|
92
|
-
methods = classes.inject([]) do |action_methods, klass|
|
93
|
-
action_methods + klass.public_instance_methods(false)
|
94
|
-
end
|
95
|
-
|
96
|
-
# gmosx: add the default action (leave this?)
|
97
|
-
# methods << 'index'
|
98
|
-
|
99
|
-
return methods
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
# Use the method_missing hook to compile the actions
|
104
|
-
# for this controller.
|
105
|
-
|
106
|
-
base.module_eval do
|
107
|
-
def method_missing(action, *args)
|
108
|
-
if Compiler.new(self.class).compile(action)
|
109
|
-
send(action, *args)
|
110
|
-
else
|
111
|
-
super
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
# Does this publishable respond to the given action?
|
117
|
-
|
118
|
-
base.module_eval do
|
119
|
-
class << self
|
120
|
-
def respond_to_action?(action)
|
121
|
-
action_methods.include?(action.to_s)
|
122
|
-
end
|
123
|
-
alias_method :action?, :respond_to_action?
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
# Does this class respond to the given action?
|
128
|
-
# Also looks for templates in the template root.
|
129
|
-
#
|
130
|
-
# Prefer to use the compiler for this.
|
131
|
-
#--
|
132
|
-
# THINK: maybe move template? here
|
133
|
-
#++
|
134
|
-
|
135
|
-
base.module_eval do
|
136
|
-
class << self
|
137
|
-
def respond_to_action_or_template?(sym)
|
138
|
-
return self.respond_to_action?(sym.to_s) || Compiler.new(self).template?(sym)
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
base.module_eval do
|
144
|
-
class << self
|
145
|
-
# Override this method to customize the template_root.
|
146
|
-
# Typically used in controllers defined in reusable Parts.
|
147
|
-
# Call super to include the parent class's customizations.
|
148
|
-
#
|
149
|
-
# def setup_template_root(path)
|
150
|
-
# super
|
151
|
-
# @template_root << "custom/route/#{path}"
|
152
|
-
# @template_root << "another/route/#{path}"
|
153
|
-
# end
|
154
|
-
|
155
|
-
def setup_template_root(path)
|
156
|
-
end
|
157
|
-
|
158
|
-
def mount_at(path)
|
159
|
-
# Store the mount_path (where the controller is mounted).
|
160
|
-
|
161
|
-
@mount_path = path
|
162
|
-
|
163
|
-
# Update template_root. Unshift the PROTO_TEMPLATE_ROOT,
|
164
|
-
# and unshift a template_root relative to the
|
165
|
-
# application template root.
|
166
|
-
|
167
|
-
@template_root = []
|
168
|
-
@template_root << File.join(Compiler::PROTO_TEMPLATE_ROOT, path).gsub(/\/$/, '')
|
169
|
-
setup_template_root(path)
|
170
|
-
@template_root << File.join(Glue::Template.root, path).gsub(/\/$/, '')
|
171
|
-
@template_root.reverse!
|
172
|
-
end
|
173
|
-
alias_method :mount, :mount_at
|
174
|
-
|
175
|
-
# Returns the path where this controller is mounted.
|
176
|
-
|
177
|
-
def mount_path
|
178
|
-
@mount_path
|
179
|
-
end
|
180
|
-
alias_method :mount_point, :mount_path
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
end
|
185
|
-
|
186
|
-
private
|
187
|
-
|
188
|
-
# Cookie helpers.
|
189
|
-
#--
|
190
|
-
# TODO: move elsewhere, probably to a default helper.
|
191
|
-
#++
|
192
|
-
|
193
|
-
def cookies
|
194
|
-
@context.cookies
|
195
|
-
end
|
196
|
-
|
197
|
-
# Send the cookie to the response stream.
|
198
|
-
|
199
|
-
def send_cookie(name, value = nil)
|
200
|
-
@context.add_cookie(name, value)
|
201
|
-
end
|
202
|
-
|
203
|
-
# Delete the cookie by setting the expire time to now and
|
204
|
-
# clearing the value.
|
205
|
-
|
206
|
-
def delete_cookie(name)
|
207
|
-
cookie = Cookie.new(name, '')
|
208
|
-
cookie.expires = Time.now
|
209
|
-
@context.add_cookie(cookie)
|
210
|
-
end
|
211
|
-
|
212
|
-
# Encode controller, action, params into a valid url.
|
213
|
-
# Automatically respects nice urls and routing.
|
214
|
-
#
|
215
|
-
# Handles parameters either as a hash or as an array.
|
216
|
-
# Use the array method to pass parameters to 'nice' actions.
|
217
|
-
#
|
218
|
-
# Pass Controller, action, and (param_name, param_value)
|
219
|
-
# pairs.
|
220
|
-
#
|
221
|
-
# === Examples
|
222
|
-
#
|
223
|
-
# encode_url ForaController, :post, :title, 'Hello', :body, 'World'
|
224
|
-
# encode_url :post, :title, 'Hello', :body, 'World' # => implies controller == self
|
225
|
-
# encode_url :kick, :oid, 4
|
226
|
-
# encode_url article # => article.to_href
|
227
|
-
#
|
228
|
-
# Alternatively you can pass options with a hash:
|
229
|
-
#
|
230
|
-
# encode_url :controller => ForaController, :action => :delete, :params => { :title => 'Hello' }
|
231
|
-
# encode_url :action => :delete
|
232
|
-
#--
|
233
|
-
# FIXME: better implementation? optimize this?
|
234
|
-
# TODO: move elsewhere.
|
235
|
-
#++
|
236
|
-
|
237
|
-
def encode_url *args
|
238
|
-
f = args.first
|
239
|
-
|
240
|
-
# A standard url as string, return as is.
|
241
|
-
|
242
|
-
if f.is_a? String
|
243
|
-
return f
|
244
|
-
end
|
245
|
-
|
246
|
-
# If the passed param is an object that responds to :to_href
|
247
|
-
# returns the url to this object.
|
248
|
-
|
249
|
-
if f.respond_to? :to_href
|
250
|
-
return args.first.to_href
|
251
|
-
end
|
252
|
-
|
253
|
-
if f.is_a? Symbol
|
254
|
-
# no controller passed, imply controller == self!
|
255
|
-
args.unshift(self.class)
|
256
|
-
end
|
257
|
-
|
258
|
-
# Try to encode using the router.
|
259
|
-
|
260
|
-
if url = context.dispatcher.encode_route(*args)
|
261
|
-
return url
|
262
|
-
end
|
263
|
-
|
264
|
-
# No routing rule, manual encoding.
|
265
|
-
|
266
|
-
controller = args.shift
|
267
|
-
action = args.shift.to_sym
|
268
|
-
|
269
|
-
url = "#{controller.mount_path}/#{action}"
|
270
|
-
|
271
|
-
unless args.empty?
|
272
|
-
if controller.respond_to_action_or_template? action
|
273
|
-
param_count = controller.instance_method(action).arity
|
274
|
-
if param_count != 0
|
275
|
-
param_count.times do
|
276
|
-
args.shift # name
|
277
|
-
url << "/#{CGI.escape(args.shift.to_s)}"
|
278
|
-
end
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
unless args.empty?
|
283
|
-
url << '?'
|
284
|
-
params = []
|
285
|
-
(args.size / 2).times do
|
286
|
-
params << "#{args.shift}=#{args.shift}"
|
287
|
-
end
|
288
|
-
url << params.join(';')
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
return url
|
293
|
-
end
|
294
|
-
alias_method :R, :encode_url
|
295
|
-
|
296
|
-
# Just like encode_url, but generates an absolute url instead.
|
297
|
-
|
298
|
-
def encode_absolute_url(*args)
|
299
|
-
return "#{request.host_url}#{encode_url(*args)}"
|
300
|
-
end
|
301
|
-
alias_method :RA, :encode_absolute_url
|
302
|
-
|
303
|
-
end
|
304
|
-
|
305
18
|
# The Controller part in the MVC paradigm. The controller's
|
306
19
|
# published methods are called actrions. The controller class
|
307
20
|
# contains the Publishable mixin and additional helper mixins.
|
@@ -311,11 +24,11 @@ class Controller
|
|
311
24
|
include Scaffolding
|
312
25
|
include Caching
|
313
26
|
include Helpers
|
314
|
-
helper
|
27
|
+
helper Nitro::Markup
|
315
28
|
|
316
29
|
# This callback is called after the Controller is mounted.
|
317
30
|
|
318
|
-
def self.mounted
|
31
|
+
def self.mounted(path)
|
319
32
|
# Resolve aspects.
|
320
33
|
|
321
34
|
Aspects.include_advice_modules(self)
|
@@ -338,7 +51,7 @@ class Controller
|
|
338
51
|
# This is an internal method.
|
339
52
|
#++
|
340
53
|
|
341
|
-
def self.replace_current
|
54
|
+
def self.replace_current(controller) # :nodoc:
|
342
55
|
old = Thread.current[:CURRENT_CONTROLLER]
|
343
56
|
Thread.current[:CURRENT_CONTROLLER] = controller
|
344
57
|
return old
|
@@ -347,5 +60,3 @@ class Controller
|
|
347
60
|
end
|
348
61
|
|
349
62
|
end
|
350
|
-
|
351
|
-
# * George Moschovitis <gm@navel.gr>
|