nitro 0.31.0 → 0.40.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.
- 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>
|