ramaze 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +360 -0
- data/bin/ramaze +152 -0
- data/doc/CHANGELOG +2021 -0
- data/doc/COPYING +56 -0
- data/doc/COPYING.ja +51 -0
- data/doc/README +275 -0
- data/doc/TODO +33 -0
- data/doc/allison/LICENSE +184 -0
- data/doc/allison/README +37 -0
- data/doc/allison/allison.css +300 -0
- data/doc/allison/allison.gif +0 -0
- data/doc/allison/allison.js +307 -0
- data/doc/allison/allison.rb +287 -0
- data/doc/allison/cache/BODY +588 -0
- data/doc/allison/cache/CLASS_INDEX +4 -0
- data/doc/allison/cache/CLASS_PAGE +1 -0
- data/doc/allison/cache/FILE_INDEX +4 -0
- data/doc/allison/cache/FILE_PAGE +1 -0
- data/doc/allison/cache/FONTS +1 -0
- data/doc/allison/cache/FR_INDEX_BODY +1 -0
- data/doc/allison/cache/IMGPATH +1 -0
- data/doc/allison/cache/INDEX +1 -0
- data/doc/allison/cache/JAVASCRIPT +307 -0
- data/doc/allison/cache/METHOD_INDEX +4 -0
- data/doc/allison/cache/METHOD_LIST +1 -0
- data/doc/allison/cache/SRC_PAGE +1 -0
- data/doc/allison/cache/STYLE +322 -0
- data/doc/allison/cache/URL +1 -0
- data/examples/blog/main.rb +16 -0
- data/examples/blog/public/screen.css +106 -0
- data/examples/blog/src/controller.rb +50 -0
- data/examples/blog/src/element.rb +53 -0
- data/examples/blog/src/model.rb +29 -0
- data/examples/blog/template/edit.xhtml +6 -0
- data/examples/blog/template/index.xhtml +24 -0
- data/examples/blog/template/new.xhtml +5 -0
- data/examples/blog/template/view.xhtml +15 -0
- data/examples/blog/test/tc_entry.rb +18 -0
- data/examples/caching.rb +23 -0
- data/examples/element.rb +40 -0
- data/examples/hello.rb +23 -0
- data/examples/simple.rb +60 -0
- data/examples/templates/template/external.haml +21 -0
- data/examples/templates/template/external.liquid +28 -0
- data/examples/templates/template/external.mab +27 -0
- data/examples/templates/template/external.rhtml +29 -0
- data/examples/templates/template/external.rmze +24 -0
- data/examples/templates/template_erubis.rb +50 -0
- data/examples/templates/template_haml.rb +48 -0
- data/examples/templates/template_liquid.rb +64 -0
- data/examples/templates/template_markaby.rb +52 -0
- data/examples/templates/template_ramaze.rb +49 -0
- data/examples/whywiki/main.rb +56 -0
- data/examples/whywiki/template/edit.xhtml +14 -0
- data/examples/whywiki/template/show.xhtml +17 -0
- data/lib/proto/conf/benchmark.yaml +35 -0
- data/lib/proto/conf/debug.yaml +34 -0
- data/lib/proto/conf/live.yaml +33 -0
- data/lib/proto/conf/silent.yaml +31 -0
- data/lib/proto/conf/stage.yaml +33 -0
- data/lib/proto/main.rb +18 -0
- data/lib/proto/public/404.jpg +0 -0
- data/lib/proto/public/css/coderay.css +105 -0
- data/lib/proto/public/css/ramaze_error.css +42 -0
- data/lib/proto/public/error.xhtml +74 -0
- data/lib/proto/public/favicon.ico +0 -0
- data/lib/proto/public/js/jquery.js +1923 -0
- data/lib/proto/public/ramaze.png +0 -0
- data/lib/proto/src/controller/main.rb +7 -0
- data/lib/proto/src/element/page.rb +16 -0
- data/lib/proto/src/model.rb +5 -0
- data/lib/proto/template/index.xhtml +6 -0
- data/lib/ramaze.rb +317 -0
- data/lib/ramaze/adapter/mongrel.rb +111 -0
- data/lib/ramaze/adapter/webrick.rb +161 -0
- data/lib/ramaze/cache.rb +11 -0
- data/lib/ramaze/cache/memcached.rb +52 -0
- data/lib/ramaze/cache/memory.rb +6 -0
- data/lib/ramaze/cache/yaml_store.rb +37 -0
- data/lib/ramaze/controller.rb +10 -0
- data/lib/ramaze/dispatcher.rb +315 -0
- data/lib/ramaze/error.rb +11 -0
- data/lib/ramaze/gestalt.rb +108 -0
- data/lib/ramaze/global.rb +120 -0
- data/lib/ramaze/helper.rb +32 -0
- data/lib/ramaze/helper/aspect.rb +189 -0
- data/lib/ramaze/helper/auth.rb +120 -0
- data/lib/ramaze/helper/cache.rb +52 -0
- data/lib/ramaze/helper/feed.rb +135 -0
- data/lib/ramaze/helper/form.rb +204 -0
- data/lib/ramaze/helper/link.rb +80 -0
- data/lib/ramaze/helper/redirect.rb +48 -0
- data/lib/ramaze/helper/stack.rb +67 -0
- data/lib/ramaze/http_status.rb +66 -0
- data/lib/ramaze/inform.rb +166 -0
- data/lib/ramaze/snippets.rb +5 -0
- data/lib/ramaze/snippets/hash/keys_to_sym.rb +19 -0
- data/lib/ramaze/snippets/kernel/aquire.rb +22 -0
- data/lib/ramaze/snippets/kernel/autoreload.rb +79 -0
- data/lib/ramaze/snippets/kernel/caller_lines.rb +58 -0
- data/lib/ramaze/snippets/kernel/constant.rb +24 -0
- data/lib/ramaze/snippets/kernel/rescue_require.rb +12 -0
- data/lib/ramaze/snippets/kernel/self_method.rb +41 -0
- data/lib/ramaze/snippets/kernel/silently.rb +13 -0
- data/lib/ramaze/snippets/object/traits.rb +60 -0
- data/lib/ramaze/snippets/openstruct/temp.rb +10 -0
- data/lib/ramaze/snippets/string/DIVIDE.rb +16 -0
- data/lib/ramaze/snippets/string/camel_case.rb +14 -0
- data/lib/ramaze/snippets/string/snake_case.rb +12 -0
- data/lib/ramaze/snippets/symbol/to_proc.rb +14 -0
- data/lib/ramaze/snippets/thread/deadQUESTIONMARK.rb +11 -0
- data/lib/ramaze/store/default.rb +48 -0
- data/lib/ramaze/template.rb +102 -0
- data/lib/ramaze/template/amrita2.rb +40 -0
- data/lib/ramaze/template/erubis.rb +58 -0
- data/lib/ramaze/template/haml.rb +65 -0
- data/lib/ramaze/template/haml/actionview_stub.rb +20 -0
- data/lib/ramaze/template/liquid.rb +74 -0
- data/lib/ramaze/template/markaby.rb +68 -0
- data/lib/ramaze/template/ramaze.rb +177 -0
- data/lib/ramaze/template/ramaze/element.rb +166 -0
- data/lib/ramaze/template/ramaze/morpher.rb +156 -0
- data/lib/ramaze/tool/create.rb +70 -0
- data/lib/ramaze/tool/tidy.rb +71 -0
- data/lib/ramaze/trinity.rb +38 -0
- data/lib/ramaze/trinity/request.rb +244 -0
- data/lib/ramaze/trinity/response.rb +41 -0
- data/lib/ramaze/trinity/session.rb +129 -0
- data/lib/ramaze/version.rb +14 -0
- data/spec/spec_all.rb +73 -0
- data/spec/spec_helper.rb +215 -0
- data/spec/tc_adapter_mongrel.rb +24 -0
- data/spec/tc_adapter_webrick.rb +22 -0
- data/spec/tc_cache.rb +79 -0
- data/spec/tc_controller.rb +39 -0
- data/spec/tc_element.rb +100 -0
- data/spec/tc_error.rb +23 -0
- data/spec/tc_gestalt.rb +90 -0
- data/spec/tc_global.rb +46 -0
- data/spec/tc_helper_aspect.rb +65 -0
- data/spec/tc_helper_auth.rb +61 -0
- data/spec/tc_helper_cache.rb +81 -0
- data/spec/tc_helper_feed.rb +129 -0
- data/spec/tc_helper_form.rb +146 -0
- data/spec/tc_helper_link.rb +58 -0
- data/spec/tc_helper_redirect.rb +51 -0
- data/spec/tc_helper_stack.rb +55 -0
- data/spec/tc_morpher.rb +90 -0
- data/spec/tc_params.rb +84 -0
- data/spec/tc_request.rb +111 -0
- data/spec/tc_session.rb +56 -0
- data/spec/tc_store.rb +25 -0
- data/spec/tc_template_amrita2.rb +34 -0
- data/spec/tc_template_erubis.rb +41 -0
- data/spec/tc_template_haml.rb +44 -0
- data/spec/tc_template_liquid.rb +98 -0
- data/spec/tc_template_markaby.rb +74 -0
- data/spec/tc_template_ramaze.rb +54 -0
- data/spec/tc_tidy.rb +14 -0
- data/spec/template/amrita2/data.html +6 -0
- data/spec/template/amrita2/index.html +1 -0
- data/spec/template/amrita2/sum.html +1 -0
- data/spec/template/erubis/sum.rhtml +1 -0
- data/spec/template/haml/index.haml +5 -0
- data/spec/template/haml/with_vars.haml +4 -0
- data/spec/template/liquid/index.liquid +1 -0
- data/spec/template/liquid/products.liquid +45 -0
- data/spec/template/markaby/external.mab +8 -0
- data/spec/template/markaby/sum.mab +1 -0
- data/spec/template/ramaze/file_only.rmze +1 -0
- data/spec/template/ramaze/index.rmze +1 -0
- data/spec/template/ramaze/nested.rmze +1 -0
- data/spec/template/ramaze/sum.rmze +1 -0
- metadata +317 -0
@@ -0,0 +1,120 @@
|
|
1
|
+
# Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
|
2
|
+
# All files in this distribution are subject to the terms of the Ruby license.
|
3
|
+
|
4
|
+
require 'digest/sha1'
|
5
|
+
|
6
|
+
module Ramaze
|
7
|
+
|
8
|
+
# A really, really, totally stupid way to do authentication. It has no
|
9
|
+
# roles and only a single password without usernames.
|
10
|
+
#
|
11
|
+
# It is intended to be a simple way to protect various partions of a page
|
12
|
+
# when you start working on it. Also it is a nice way to see how you could
|
13
|
+
# implement your own authentication.
|
14
|
+
|
15
|
+
module AuthHelper
|
16
|
+
def self.included(klass)
|
17
|
+
klass.class_eval do
|
18
|
+
helper :aspect, :stack
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# The default Element to use (if any)
|
23
|
+
|
24
|
+
AUTH_ELEMENT = 'Page'
|
25
|
+
|
26
|
+
# action for login, takes a password
|
27
|
+
# ( ?password=passwort or /login/passwort or via a form )
|
28
|
+
# if no password given, shows a simple form to input it.
|
29
|
+
|
30
|
+
def login
|
31
|
+
if check_auth(request['username'], request['password'])
|
32
|
+
session[:logged_in] = true
|
33
|
+
inside_stack? ? answer : redirect( R(self) )
|
34
|
+
else
|
35
|
+
%{
|
36
|
+
<#{AUTH_ELEMENT}>
|
37
|
+
<form method="POST" action="#{R(self, :login)}"
|
38
|
+
<ul style="list-style:none;">
|
39
|
+
<li>Username: <input type="text" name="username" /></li>
|
40
|
+
<li>Password: <input type="password" name="password" /></li>
|
41
|
+
<li><input type="submit" /></li>
|
42
|
+
</ul>
|
43
|
+
</form>
|
44
|
+
</#{AUTH_ELEMENT}>
|
45
|
+
}
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# clear the session and redirect to the index action of the mapping of the
|
50
|
+
# current controller.
|
51
|
+
|
52
|
+
def logout
|
53
|
+
session.clear
|
54
|
+
redirect_referer
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
# call( R(self, :login) ) if not logged in
|
60
|
+
|
61
|
+
def login_required
|
62
|
+
call(R(self, :login)) unless logged_in?
|
63
|
+
end
|
64
|
+
|
65
|
+
# checks if the user is already logged in.
|
66
|
+
# session[:logged_in] is not nil/false
|
67
|
+
|
68
|
+
def logged_in?
|
69
|
+
!!session[:logged_in]
|
70
|
+
end
|
71
|
+
|
72
|
+
# check the authentication (username and password) against the auth_table.
|
73
|
+
#
|
74
|
+
# auth_table is a trait, it may be the name of a method, a Proc or a simple
|
75
|
+
# Hash.
|
76
|
+
# If it is neither of the above it has at least to respond to #[]
|
77
|
+
# which will pass it the username as key and it should answer with the
|
78
|
+
# password as a SHA1.hexdigest.
|
79
|
+
#
|
80
|
+
# The method and Proc are both called on demand.
|
81
|
+
#
|
82
|
+
# If you want to change the way the password is hashed, change
|
83
|
+
# trait[:auth_hashify]
|
84
|
+
#
|
85
|
+
# The default looks like:
|
86
|
+
# lambda{ |pass| Digest::SHA1.hexdigest(pass.to_s) }
|
87
|
+
#
|
88
|
+
# As with the auth_table, this has to be an object that responds to #[]
|
89
|
+
#
|
90
|
+
# If you want all your controllers to use the same mechanism set the trait
|
91
|
+
# on one of the ancestors, the traits are looked up by #ancestral_trait
|
92
|
+
#
|
93
|
+
# Examples:
|
94
|
+
#
|
95
|
+
# # The method to be called.
|
96
|
+
# trait :auth_table => :auth_table
|
97
|
+
# trait :auth_tagle => 'auth_table'
|
98
|
+
#
|
99
|
+
# # Lambda that will be called upon demand
|
100
|
+
# trait :auth_table => lambda{ {'manveru' => SHA1.hexdigest 'password'} }
|
101
|
+
#
|
102
|
+
# # Hash holding the data.
|
103
|
+
# trait :auth_table => {'manveru' => SHA1.hexdigest('password')}
|
104
|
+
|
105
|
+
def check_auth user, pass
|
106
|
+
auth_table = ancestral_trait[:auth_table] ||= {}
|
107
|
+
|
108
|
+
auth_table = method(auth_table) if auth_table.is_a?(Symbol)
|
109
|
+
auth_table = method(auth_table) if auth_table.respond_to?(:to_str)
|
110
|
+
auth_table = auth_table.call if auth_table.respond_to?(:call)
|
111
|
+
|
112
|
+
default_hashify = lambda{ |pass| Digest::SHA1.hexdigest(pass.to_s) }
|
113
|
+
|
114
|
+
hashify = (ancestral_trait[:auth_hashify] ||= default_hashify)
|
115
|
+
password = hashify[pass.to_s]
|
116
|
+
|
117
|
+
auth_table[user.to_s] == password
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
|
2
|
+
# All files in this distribution are subject to the terms of the Ruby license.
|
3
|
+
module Ramaze
|
4
|
+
module CacheHelper
|
5
|
+
private
|
6
|
+
|
7
|
+
# a simple cache for values based on Global.cache
|
8
|
+
|
9
|
+
def value_cache
|
10
|
+
@@cache ||= Global.cache.new
|
11
|
+
end
|
12
|
+
|
13
|
+
# forget about one cached action
|
14
|
+
|
15
|
+
def uncache action
|
16
|
+
Global.cached_actions[self.class].each do |e|
|
17
|
+
e.include?(action.to_s)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# uncache all actions
|
22
|
+
|
23
|
+
def uncache_all
|
24
|
+
Global.cached_actions.delete(self.class)
|
25
|
+
end
|
26
|
+
alias uncache_all_actions uncache_all
|
27
|
+
|
28
|
+
# cache all given methods
|
29
|
+
|
30
|
+
def cache(*actions)
|
31
|
+
self.class.cache(*actions)
|
32
|
+
end
|
33
|
+
alias cache_actions cache
|
34
|
+
|
35
|
+
# define the cache class-method on inclusion
|
36
|
+
|
37
|
+
def self.included(klass)
|
38
|
+
klass.class_eval do
|
39
|
+
class << self
|
40
|
+
|
41
|
+
# mark actions for caching
|
42
|
+
|
43
|
+
def cache(*actions)
|
44
|
+
Global.cache_actions[self].merge(*actions.flatten.map{|a| a.to_s })
|
45
|
+
end
|
46
|
+
alias cache_actions cache
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
# Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
|
2
|
+
# All files in this distribution are subject to the terms of the Ruby license.
|
3
|
+
|
4
|
+
module Ramaze
|
5
|
+
module FeedHelper
|
6
|
+
|
7
|
+
# just a stub, for the moment, doing nothing more than calling
|
8
|
+
# #to_xml on the object you pass
|
9
|
+
|
10
|
+
def feed object
|
11
|
+
object.to_xml
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module ReFeed
|
17
|
+
|
18
|
+
# Does a couple of things on include.
|
19
|
+
#
|
20
|
+
# defines #xml_accessor, which in turn offers a way to define
|
21
|
+
# both an attr_accessor and xml-annotation.
|
22
|
+
# xml_accessor :name, :age
|
23
|
+
#
|
24
|
+
# defines #xml, a little DSLy way to add an attribute that
|
25
|
+
# is later used to generate/read XML
|
26
|
+
# xml :name, :age
|
27
|
+
#
|
28
|
+
# defines #from_xml, which takes XML and maps the structure of the
|
29
|
+
# XML to your instances accessors.
|
30
|
+
# Foo.new.from_xml('<name>manveru</name><age>22</age>')
|
31
|
+
# # #<Foo @name='manveru', @age=22>
|
32
|
+
|
33
|
+
def self.included(klass)
|
34
|
+
klass.class_eval do
|
35
|
+
const_set('XML_ATTRIBUTES', {})
|
36
|
+
|
37
|
+
class << self
|
38
|
+
|
39
|
+
# Offers a way to define
|
40
|
+
# both an attr_accessor and xml-annotation.
|
41
|
+
# xml_accessor :name, :age
|
42
|
+
|
43
|
+
def xml_accessor(*args)
|
44
|
+
args = xml(*args)
|
45
|
+
attr_accessor(*args)
|
46
|
+
end
|
47
|
+
|
48
|
+
# A little DSLy way to add an attribute that
|
49
|
+
# is later used to generate/read XML
|
50
|
+
# xml :name, :age
|
51
|
+
|
52
|
+
def xml(*arguments)
|
53
|
+
args = []
|
54
|
+
hash = nil
|
55
|
+
klass = Object.const_get(self.to_s)
|
56
|
+
|
57
|
+
arguments.each do |arg|
|
58
|
+
if arg.respond_to?(:to_sym)
|
59
|
+
args << arg.to_sym
|
60
|
+
elsif arg.respond_to?(:to_hash)
|
61
|
+
hash = arg
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
args.each do |arg|
|
66
|
+
klass::XML_ATTRIBUTES[arg] = hash
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Which takes XML and maps the structure of the
|
71
|
+
# XML to your instances accessors.
|
72
|
+
# Foo.new.from_xml('<name>manveru</name><age>22</age>')
|
73
|
+
# # #<Foo @name='manveru', @age=22>
|
74
|
+
|
75
|
+
def from_xml(text)
|
76
|
+
instance = self.new
|
77
|
+
|
78
|
+
require 'hpricot'
|
79
|
+
|
80
|
+
xml = Hpricot(text.to_s)
|
81
|
+
attributes = instance.xml_attributes
|
82
|
+
|
83
|
+
attributes.each do |attribute, opts|
|
84
|
+
value = xml.at(attribute)
|
85
|
+
instance.send("#{attribute}=", value.inner_html) if value
|
86
|
+
end
|
87
|
+
instance
|
88
|
+
rescue LoadError => ex
|
89
|
+
error ex
|
90
|
+
ensure
|
91
|
+
instance
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# return the XML_ATTRIBUTES of self.class
|
98
|
+
|
99
|
+
def xml_attributes
|
100
|
+
self.class::XML_ATTRIBUTES
|
101
|
+
end
|
102
|
+
|
103
|
+
# convert this instance to XML
|
104
|
+
|
105
|
+
def to_xml
|
106
|
+
name = self.class.name
|
107
|
+
xml = xml_attributes.map do |key, opts|
|
108
|
+
value = send(key)
|
109
|
+
|
110
|
+
next unless value
|
111
|
+
next if (opts[:type] == :attribute rescue false)
|
112
|
+
|
113
|
+
if opts and not opts.empty?
|
114
|
+
case opts[:type]
|
115
|
+
when nil, :text : "<#{key}>#{value}</#{key}>"
|
116
|
+
when :cdata : "<#{key}><![CDATA[#{value}]]></#{key}>"
|
117
|
+
when :collection : value.map{|v| v.to_xml }
|
118
|
+
end
|
119
|
+
elsif value.respond_to?(:to_xml)
|
120
|
+
value.to_xml
|
121
|
+
elsif value.respond_to?(:all?) and value.all?{|v| v.respond_to?(:to_xml) }
|
122
|
+
value.map{|v| v.to_xml }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
attributes = xml_attributes.select{|k, o| o && o[:type] == :attribute}
|
127
|
+
attributes.map!{|k, o| %{#{k}="#{send(k)}"} }
|
128
|
+
|
129
|
+
unless attributes or attributes.empty?
|
130
|
+
"<#{name}>#{xml}</#{name}>"
|
131
|
+
else
|
132
|
+
"<#{name} #{attributes.join(' ')}><#{xml}></#{name}>"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
@@ -0,0 +1,204 @@
|
|
1
|
+
# Copyright (c) 2006 Michael Fellinger m.fellinger@gmail.com
|
2
|
+
# All files in this distribution are subject to the terms of the Ruby license.
|
3
|
+
|
4
|
+
module Ramaze
|
5
|
+
module FormHelper
|
6
|
+
|
7
|
+
# Mapping different classes to an specific method on FormHelper::Control.
|
8
|
+
|
9
|
+
ClassMap = {
|
10
|
+
String => :text,
|
11
|
+
Time => :time,
|
12
|
+
Date => :date,
|
13
|
+
Fixnum => :number,
|
14
|
+
}
|
15
|
+
|
16
|
+
# Create the contents of a <form> for Og-objects.
|
17
|
+
# This can be an instance or the class itself. Depending if you
|
18
|
+
# want to edit an object or create a new one.
|
19
|
+
#
|
20
|
+
# Please note that the enclosing <form> itself is not (yet) generated.
|
21
|
+
#
|
22
|
+
# attributes that have no mapping in ClassMap are silently ignored.
|
23
|
+
|
24
|
+
def form obj, options = {}
|
25
|
+
default = {:deny => /oid/, :submit => true}
|
26
|
+
options = default.merge(options)
|
27
|
+
|
28
|
+
if obj.respond_to? :serializable_attributes
|
29
|
+
instance = obj.new
|
30
|
+
else
|
31
|
+
instance = obj
|
32
|
+
obj = obj.class
|
33
|
+
end
|
34
|
+
|
35
|
+
attributes = obj.serializable_attributes
|
36
|
+
out = []
|
37
|
+
|
38
|
+
chosen_attributes(attributes, options).each do |attribute|
|
39
|
+
|
40
|
+
o = OpenStruct.new :klass => obj.ann[attribute].class,
|
41
|
+
:value => (instance.send(attribute) rescue nil),
|
42
|
+
:name => attribute.to_s,
|
43
|
+
:title => (options.has_key?(attribute) ? options[attribute] : attribute)
|
44
|
+
|
45
|
+
control = obj.ann[attribute].control
|
46
|
+
control = ClassMap[o.klass] unless control.is_a?(Symbol)
|
47
|
+
|
48
|
+
out << Control.send(control, o) unless control.nil? or control == :none
|
49
|
+
end
|
50
|
+
if options[:submit] == true
|
51
|
+
out << %{<input type="submit" />}
|
52
|
+
elsif options[:submit]
|
53
|
+
out << %{<input type="submit" value="#{options[:submit]}" />}
|
54
|
+
end
|
55
|
+
out.join("<br />\n")
|
56
|
+
end
|
57
|
+
|
58
|
+
# options #=>
|
59
|
+
# { :deny => /oid/ }
|
60
|
+
# { :deny => [/time/, /oid/]}
|
61
|
+
|
62
|
+
def chosen_attributes(attributes, options)
|
63
|
+
attributes.reject do |attribute|
|
64
|
+
attribute = attribute.to_s
|
65
|
+
[options[:deny]].flatten.find do |d|
|
66
|
+
first_comp = attribute =~ d rescue attribute == d
|
67
|
+
first_comp || attribute == d
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Home of all the methods that output a tag for a specific
|
73
|
+
# attribute.
|
74
|
+
# They take objects that respond to :value and :name, preferably
|
75
|
+
# an modified OpenStruct that responds to :temp to allow for easy
|
76
|
+
# forking. ( lib/ramaze/snippets/openstruct/temp.rb )
|
77
|
+
|
78
|
+
module Control
|
79
|
+
class << self
|
80
|
+
|
81
|
+
# A simple text-control, default to 0
|
82
|
+
|
83
|
+
def number o
|
84
|
+
o.value ||= 0
|
85
|
+
text(o)
|
86
|
+
end
|
87
|
+
|
88
|
+
# <input type="text" />
|
89
|
+
|
90
|
+
def text o
|
91
|
+
o.value ||= ""
|
92
|
+
tag = ''
|
93
|
+
tag << "#{o.title}: " if o.title
|
94
|
+
tag << %{<input type="text" name="#{o.name}" value="#{o.value}" />}
|
95
|
+
end
|
96
|
+
|
97
|
+
# <textarea></textarea>
|
98
|
+
|
99
|
+
def textarea o
|
100
|
+
o.value ||= ""
|
101
|
+
%{<textarea name="#{o.name}">#{o.value}</textarea>}
|
102
|
+
end
|
103
|
+
|
104
|
+
# compound of #date_day, #date_month, #date_year, #time_hour,
|
105
|
+
# #time_minute and #time_second
|
106
|
+
|
107
|
+
def time o
|
108
|
+
o.value ||= Time.now
|
109
|
+
[
|
110
|
+
date_day(o.temp(:value => o.value.day)),
|
111
|
+
date_month(o.temp(:value => o.value.month)),
|
112
|
+
date_year(o.temp(:value => o.value.year)),
|
113
|
+
time_hour(o.temp(:value => o.value.hour)),
|
114
|
+
time_minute(o.temp(:value => o.value.min)),
|
115
|
+
time_second(o.temp(:value => o.value.sec)),
|
116
|
+
].join("\n")
|
117
|
+
end
|
118
|
+
|
119
|
+
# <select name="xxx[sec]">
|
120
|
+
# <option value="0">0</option>
|
121
|
+
# ...
|
122
|
+
# <option value="60">60</option>
|
123
|
+
# </select>
|
124
|
+
|
125
|
+
def time_second(o)
|
126
|
+
select(o.name + '[sec]', (0...60), o.value)
|
127
|
+
end
|
128
|
+
|
129
|
+
# <select name="xxx[min]">
|
130
|
+
# <option value="0">0</option>
|
131
|
+
# ...
|
132
|
+
# <option value="60">60</option>
|
133
|
+
# </select>
|
134
|
+
|
135
|
+
def time_minute(o)
|
136
|
+
select(o.name + '[min]', (0...60), o.value)
|
137
|
+
end
|
138
|
+
|
139
|
+
# <select name="xxx[hour]">
|
140
|
+
# <option value="1">1</option>
|
141
|
+
# ...
|
142
|
+
# <option value="23">23</option>
|
143
|
+
# </select>
|
144
|
+
|
145
|
+
def time_hour(o)
|
146
|
+
select(o.name + '[hour]', (0...23), o.value)
|
147
|
+
end
|
148
|
+
|
149
|
+
# compound of #date_day, #date_month and #date_year
|
150
|
+
|
151
|
+
def date o
|
152
|
+
o.value ||= Date.today
|
153
|
+
[
|
154
|
+
date_day(o.temp(:value => o.value.day)),
|
155
|
+
date_month(o.temp(:value => o.value.month)),
|
156
|
+
date_year(o.temp(:value => o.value.year)),
|
157
|
+
].join("\n")
|
158
|
+
end
|
159
|
+
|
160
|
+
# <select name="xxx[day]">
|
161
|
+
# <option value="1">1</option>
|
162
|
+
# ...
|
163
|
+
# <option value="31">31</option>
|
164
|
+
# </select>
|
165
|
+
|
166
|
+
def date_day(o)
|
167
|
+
select(o.name + '[day]', (1..31), o.value)
|
168
|
+
end
|
169
|
+
|
170
|
+
# <select name="xxx[month]">
|
171
|
+
# <option value="1">1950</option>
|
172
|
+
# ...
|
173
|
+
# <option value="12">12</option>
|
174
|
+
# </select>
|
175
|
+
|
176
|
+
def date_month(o)
|
177
|
+
select(o.name + '[month]', (1..12), o.value)
|
178
|
+
end
|
179
|
+
|
180
|
+
# <select name="xxx[year]">
|
181
|
+
# <option value="1950">1950</option>
|
182
|
+
# ...
|
183
|
+
# <option value="2050">2050</option>
|
184
|
+
# </select>
|
185
|
+
|
186
|
+
def date_year(o)
|
187
|
+
select(o.name + '[year]', (1950..2050), o.value)
|
188
|
+
end
|
189
|
+
|
190
|
+
# <select>
|
191
|
+
# <option></option>
|
192
|
+
# </select>
|
193
|
+
|
194
|
+
def select name, range, default
|
195
|
+
out = %{<select name="#{name}">\n}
|
196
|
+
range.each do |i|
|
197
|
+
out << %{<option value="#{i}"#{' selected="selected"' if default == i}>#{i}</option>\n}
|
198
|
+
end
|
199
|
+
out << "</select>\n"
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|